aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/bluetooth/btusb.c1
-rw-r--r--drivers/net/wireless/at76c50x-usb.c85
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.c60
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523_hw.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c15
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c12
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c5
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c6
-rw-r--r--drivers/net/wireless/ath/ath6kl/Kconfig9
-rw-r--r--drivers/net/wireless/ath/ath6kl/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c406
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.c21
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h69
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.c12
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_mbox.c13
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_pipe.c14
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c92
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c55
-rw-r--r--drivers/net/wireless/ath/ath6kl/recovery.c160
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c27
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c47
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c32
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c284
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h78
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c76
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h46
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9485_initvals.h338
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h34
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c198
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h18
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c58
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c24
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c28
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c78
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c39
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c53
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c12
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c5
-rw-r--r--drivers/net/wireless/b43/xmit.c2
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c2
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig15
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c43
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c140
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h186
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c72
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c452
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c509
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c252
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c509
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h207
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c26
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c278
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.h18
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c1010
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h120
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/Makefile3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.c723
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.h29
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/antsel.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h175
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/debug.c44
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/debug.h52
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.c343
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.h11
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c123
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c1195
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.h48
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pub.h37
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/stf.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/types.h3
-rw-r--r--drivers/net/wireless/brcm80211/include/defs.h11
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c5
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c40
-rw-r--r--drivers/net/wireless/ipw2x00/libipw.h2
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_geo.c3
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c2
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c4
-rw-r--r--drivers/net/wireless/iwlegacy/common.h5
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/debugfs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h1
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c37
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c16
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c20
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h27
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c1
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h117
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c396
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c1047
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c1225
-rw-r--r--drivers/net/wireless/libertas/cfg.c24
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c39
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c580
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c8
-rw-r--r--drivers/net/wireless/mwifiex/Kconfig1
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c54
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c3
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c10
-rw-r--r--drivers/net/wireless/mwifiex/init.c20
-rw-r--r--drivers/net/wireless/mwifiex/join.c6
-rw-r--r--drivers/net/wireless/mwifiex/main.c86
-rw-r--r--drivers/net/wireless/mwifiex/main.h6
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c39
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h1
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c10
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c9
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c28
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c7
-rw-r--r--drivers/net/wireless/mwifiex/usb.c2
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c12
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h2
-rw-r--r--drivers/net/wireless/mwl8k.c57
-rw-r--r--drivers/net/wireless/orinoco/cfg.c11
-rw-r--r--drivers/net/wireless/p54/txrx.c6
-rw-r--r--drivers/net/wireless/rndis_wlan.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c19
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c6
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/dev.c2
-rw-r--r--drivers/net/wireless/rtlwifi/Kconfig11
-rw-r--r--drivers/net/wireless/rtlwifi/Makefile4
-rw-r--r--drivers/net/wireless/rtlwifi/base.c24
-rw-r--r--drivers/net/wireless/rtlwifi/base.h2
-rw-r--r--drivers/net/wireless/rtlwifi/cam.c2
-rw-r--r--drivers/net/wireless/rtlwifi/core.c5
-rw-r--r--drivers/net/wireless/rtlwifi/debug.h2
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c20
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rc.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/Makefile22
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/btc.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/def.h163
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.c920
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.h149
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.c745
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.h101
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c542
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h160
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c1786
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h151
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c2380
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.h73
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/led.c151
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/led.h39
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/phy.c2044
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/phy.h224
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c109
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h322
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c129
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h98
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/reg.h2097
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/rf.c505
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/rf.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.c387
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/table.c738
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/table.h50
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/trx.c670
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/trx.h725
-rw-r--r--drivers/net/wireless/rtlwifi/stats.c268
-rw-r--r--drivers/net/wireless/rtlwifi/stats.h46
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h108
-rw-r--r--drivers/net/wireless/ti/wl1251/rx.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c11
-rw-r--r--drivers/nfc/pn544/i2c.c2
-rw-r--r--include/linux/bcma/bcma.h5
-rw-r--r--include/linux/ieee80211.h72
-rw-r--r--include/linux/nfc/pn544.h104
-rw-r--r--include/linux/platform_data/pn544.h44
-rw-r--r--include/linux/ssb/ssb_regs.h2
-rw-r--r--include/net/bluetooth/amp.h4
-rw-r--r--include/net/bluetooth/hci.h29
-rw-r--r--include/net/bluetooth/hci_core.h48
-rw-r--r--include/net/bluetooth/l2cap.h38
-rw-r--r--include/net/cfg80211.h223
-rw-r--r--include/net/mac80211.h158
-rw-r--r--include/net/nfc/hci.h3
-rw-r--r--include/uapi/linux/nl80211.h113
-rw-r--r--net/bluetooth/Kconfig1
-rw-r--r--net/bluetooth/a2mp.c4
-rw-r--r--net/bluetooth/amp.c97
-rw-r--r--net/bluetooth/bnep/netdev.c1
-rw-r--r--net/bluetooth/cmtp/capi.c2
-rw-r--r--net/bluetooth/cmtp/sock.c2
-rw-r--r--net/bluetooth/hci_conn.c6
-rw-r--r--net/bluetooth/hci_core.c163
-rw-r--r--net/bluetooth/hci_event.c351
-rw-r--r--net/bluetooth/l2cap_core.c1010
-rw-r--r--net/bluetooth/l2cap_sock.c5
-rw-r--r--net/bluetooth/mgmt.c100
-rw-r--r--net/mac80211/aes_cmac.c1
-rw-r--r--net/mac80211/agg-rx.c2
-rw-r--r--net/mac80211/agg-tx.c12
-rw-r--r--net/mac80211/cfg.c258
-rw-r--r--net/mac80211/chan.c130
-rw-r--r--net/mac80211/debugfs_key.c6
-rw-r--r--net/mac80211/debugfs_netdev.c68
-rw-r--r--net/mac80211/debugfs_sta.c19
-rw-r--r--net/mac80211/driver-ops.h75
-rw-r--r--net/mac80211/ht.c4
-rw-r--r--net/mac80211/ibss.c75
-rw-r--r--net/mac80211/ieee80211_i.h50
-rw-r--r--net/mac80211/iface.c60
-rw-r--r--net/mac80211/key.c15
-rw-r--r--net/mac80211/key.h8
-rw-r--r--net/mac80211/main.c50
-rw-r--r--net/mac80211/mesh.c36
-rw-r--r--net/mac80211/mesh.h14
-rw-r--r--net/mac80211/mesh_plink.c47
-rw-r--r--net/mac80211/mesh_sync.c46
-rw-r--r--net/mac80211/mlme.c198
-rw-r--r--net/mac80211/offchannel.c13
-rw-r--r--net/mac80211/pm.c48
-rw-r--r--net/mac80211/rate.c5
-rw-r--r--net/mac80211/rate.h2
-rw-r--r--net/mac80211/rx.c169
-rw-r--r--net/mac80211/scan.c9
-rw-r--r--net/mac80211/sta_info.c12
-rw-r--r--net/mac80211/sta_info.h27
-rw-r--r--net/mac80211/status.c145
-rw-r--r--net/mac80211/trace.h116
-rw-r--r--net/mac80211/tx.c21
-rw-r--r--net/mac80211/util.c194
-rw-r--r--net/mac80211/wme.c40
-rw-r--r--net/nfc/hci/command.c4
-rw-r--r--net/nfc/hci/core.c25
-rw-r--r--net/nfc/llcp/commands.c32
-rw-r--r--net/nfc/llcp/llcp.c17
-rw-r--r--net/wireless/Kconfig5
-rw-r--r--net/wireless/ap.c1
-rw-r--r--net/wireless/chan.c280
-rw-r--r--net/wireless/core.c7
-rw-r--r--net/wireless/core.h30
-rw-r--r--net/wireless/ibss.c27
-rw-r--r--net/wireless/mesh.c49
-rw-r--r--net/wireless/mlme.c36
-rw-r--r--net/wireless/nl80211.c590
-rw-r--r--net/wireless/nl80211.h8
-rw-r--r--net/wireless/rdev-ops.h53
-rw-r--r--net/wireless/scan.c45
-rw-r--r--net/wireless/trace.h338
-rw-r--r--net/wireless/util.c174
-rw-r--r--net/wireless/wext-compat.c32
-rw-r--r--net/wireless/wext-sme.c11
289 files changed, 27487 insertions, 8355 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 9087e0d6f1a..5d72dd57b78 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5157,6 +5157,7 @@ F: net/nfc/
5157F: include/linux/nfc.h 5157F: include/linux/nfc.h
5158F: include/net/nfc/ 5158F: include/net/nfc/
5159F: drivers/nfc/ 5159F: drivers/nfc/
5160F: include/linux/platform_data/pn544.h
5160 5161
5161NFS, SUNRPC, AND LOCKD CLIENTS 5162NFS, SUNRPC, AND LOCKD CLIENTS
5162M: Trond Myklebust <Trond.Myklebust@netapp.com> 5163M: Trond Myklebust <Trond.Myklebust@netapp.com>
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index ee82f2fb65f..a1d4ede5b89 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -96,6 +96,7 @@ static struct usb_device_id btusb_table[] = {
96 { USB_DEVICE(0x0c10, 0x0000) }, 96 { USB_DEVICE(0x0c10, 0x0000) },
97 97
98 /* Broadcom BCM20702A0 */ 98 /* Broadcom BCM20702A0 */
99 { USB_DEVICE(0x0b05, 0x17b5) },
99 { USB_DEVICE(0x04ca, 0x2003) }, 100 { USB_DEVICE(0x04ca, 0x2003) },
100 { USB_DEVICE(0x0489, 0xe042) }, 101 { USB_DEVICE(0x0489, 0xe042) },
101 { USB_DEVICE(0x413c, 0x8197) }, 102 { USB_DEVICE(0x413c, 0x8197) },
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 99b9ddf2127..77fa4286e5e 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -379,7 +379,7 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
379 manifest_sync_timeout); 379 manifest_sync_timeout);
380 380
381 if (!size) { 381 if (!size) {
382 dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n"); 382 dev_err(&udev->dev, "FW buffer length invalid!\n");
383 return -EINVAL; 383 return -EINVAL;
384 } 384 }
385 385
@@ -391,8 +391,8 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
391 if (need_dfu_state) { 391 if (need_dfu_state) {
392 ret = at76_dfu_get_state(udev, &dfu_state); 392 ret = at76_dfu_get_state(udev, &dfu_state);
393 if (ret < 0) { 393 if (ret < 0) {
394 dev_printk(KERN_ERR, &udev->dev, 394 dev_err(&udev->dev,
395 "cannot get DFU state: %d\n", ret); 395 "cannot get DFU state: %d\n", ret);
396 goto exit; 396 goto exit;
397 } 397 }
398 need_dfu_state = 0; 398 need_dfu_state = 0;
@@ -407,9 +407,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
407 dfu_timeout = at76_get_timeout(&dfu_stat_buf); 407 dfu_timeout = at76_get_timeout(&dfu_stat_buf);
408 need_dfu_state = 0; 408 need_dfu_state = 0;
409 } else 409 } else
410 dev_printk(KERN_ERR, &udev->dev, 410 dev_err(&udev->dev,
411 "at76_dfu_get_status returned %d\n", 411 "at76_dfu_get_status returned %d\n",
412 ret); 412 ret);
413 break; 413 break;
414 414
415 case STATE_DFU_DOWNLOAD_BUSY: 415 case STATE_DFU_DOWNLOAD_BUSY:
@@ -438,9 +438,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
438 blockno++; 438 blockno++;
439 439
440 if (ret != bsize) 440 if (ret != bsize)
441 dev_printk(KERN_ERR, &udev->dev, 441 dev_err(&udev->dev,
442 "at76_load_int_fw_block " 442 "at76_load_int_fw_block returned %d\n",
443 "returned %d\n", ret); 443 ret);
444 need_dfu_state = 1; 444 need_dfu_state = 1;
445 break; 445 break;
446 446
@@ -1255,8 +1255,7 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
1255 at76_dbg(DBG_DEVSTART, "opmode %d", op_mode); 1255 at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
1256 1256
1257 if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { 1257 if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
1258 dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n", 1258 dev_err(&udev->dev, "unexpected opmode %d\n", op_mode);
1259 op_mode);
1260 return -EINVAL; 1259 return -EINVAL;
1261 } 1260 }
1262 1261
@@ -1275,9 +1274,9 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
1275 size, bsize, blockno); 1274 size, bsize, blockno);
1276 ret = at76_load_ext_fw_block(udev, blockno, block, bsize); 1275 ret = at76_load_ext_fw_block(udev, blockno, block, bsize);
1277 if (ret != bsize) { 1276 if (ret != bsize) {
1278 dev_printk(KERN_ERR, &udev->dev, 1277 dev_err(&udev->dev,
1279 "loading %dth firmware block failed: %d\n", 1278 "loading %dth firmware block failed: %d\n",
1280 blockno, ret); 1279 blockno, ret);
1281 goto exit; 1280 goto exit;
1282 } 1281 }
1283 buf += bsize; 1282 buf += bsize;
@@ -1293,8 +1292,8 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
1293exit: 1292exit:
1294 kfree(block); 1293 kfree(block);
1295 if (ret < 0) 1294 if (ret < 0)
1296 dev_printk(KERN_ERR, &udev->dev, 1295 dev_err(&udev->dev,
1297 "downloading external firmware failed: %d\n", ret); 1296 "downloading external firmware failed: %d\n", ret);
1298 return ret; 1297 return ret;
1299} 1298}
1300 1299
@@ -1308,8 +1307,8 @@ static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
1308 need_remap ? 0 : 2 * HZ); 1307 need_remap ? 0 : 2 * HZ);
1309 1308
1310 if (ret < 0) { 1309 if (ret < 0) {
1311 dev_printk(KERN_ERR, &udev->dev, 1310 dev_err(&udev->dev,
1312 "downloading internal fw failed with %d\n", ret); 1311 "downloading internal fw failed with %d\n", ret);
1313 goto exit; 1312 goto exit;
1314 } 1313 }
1315 1314
@@ -1319,8 +1318,8 @@ static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
1319 if (need_remap) { 1318 if (need_remap) {
1320 ret = at76_remap(udev); 1319 ret = at76_remap(udev);
1321 if (ret < 0) { 1320 if (ret < 0) {
1322 dev_printk(KERN_ERR, &udev->dev, 1321 dev_err(&udev->dev,
1323 "sending REMAP failed with %d\n", ret); 1322 "sending REMAP failed with %d\n", ret);
1324 goto exit; 1323 goto exit;
1325 } 1324 }
1326 } 1325 }
@@ -1555,11 +1554,10 @@ static struct fwentry *at76_load_firmware(struct usb_device *udev,
1555 at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); 1554 at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
1556 ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); 1555 ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
1557 if (ret < 0) { 1556 if (ret < 0) {
1558 dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n", 1557 dev_err(&udev->dev, "firmware %s not found!\n",
1559 fwe->fwname); 1558 fwe->fwname);
1560 dev_printk(KERN_ERR, &udev->dev, 1559 dev_err(&udev->dev,
1561 "you may need to download the firmware from " 1560 "you may need to download the firmware from http://developer.berlios.de/projects/at76c503a/\n");
1562 "http://developer.berlios.de/projects/at76c503a/\n");
1563 goto exit; 1561 goto exit;
1564 } 1562 }
1565 1563
@@ -1567,17 +1565,17 @@ static struct fwentry *at76_load_firmware(struct usb_device *udev,
1567 fwh = (struct at76_fw_header *)(fwe->fw->data); 1565 fwh = (struct at76_fw_header *)(fwe->fw->data);
1568 1566
1569 if (fwe->fw->size <= sizeof(*fwh)) { 1567 if (fwe->fw->size <= sizeof(*fwh)) {
1570 dev_printk(KERN_ERR, &udev->dev, 1568 dev_err(&udev->dev,
1571 "firmware is too short (0x%zx)\n", fwe->fw->size); 1569 "firmware is too short (0x%zx)\n", fwe->fw->size);
1572 goto exit; 1570 goto exit;
1573 } 1571 }
1574 1572
1575 /* CRC currently not checked */ 1573 /* CRC currently not checked */
1576 fwe->board_type = le32_to_cpu(fwh->board_type); 1574 fwe->board_type = le32_to_cpu(fwh->board_type);
1577 if (fwe->board_type != board_type) { 1575 if (fwe->board_type != board_type) {
1578 dev_printk(KERN_ERR, &udev->dev, 1576 dev_err(&udev->dev,
1579 "board type mismatch, requested %u, got %u\n", 1577 "board type mismatch, requested %u, got %u\n",
1580 board_type, fwe->board_type); 1578 board_type, fwe->board_type);
1581 goto exit; 1579 goto exit;
1582 } 1580 }
1583 1581
@@ -2150,8 +2148,7 @@ static int at76_alloc_urbs(struct at76_priv *priv,
2150 } 2148 }
2151 2149
2152 if (!ep_in || !ep_out) { 2150 if (!ep_in || !ep_out) {
2153 dev_printk(KERN_ERR, &interface->dev, 2151 dev_err(&interface->dev, "bulk endpoints missing\n");
2154 "bulk endpoints missing\n");
2155 return -ENXIO; 2152 return -ENXIO;
2156 } 2153 }
2157 2154
@@ -2161,15 +2158,14 @@ static int at76_alloc_urbs(struct at76_priv *priv,
2161 priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL); 2158 priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
2162 priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL); 2159 priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
2163 if (!priv->rx_urb || !priv->tx_urb) { 2160 if (!priv->rx_urb || !priv->tx_urb) {
2164 dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n"); 2161 dev_err(&interface->dev, "cannot allocate URB\n");
2165 return -ENOMEM; 2162 return -ENOMEM;
2166 } 2163 }
2167 2164
2168 buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE; 2165 buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE;
2169 priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); 2166 priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
2170 if (!priv->bulk_out_buffer) { 2167 if (!priv->bulk_out_buffer) {
2171 dev_printk(KERN_ERR, &interface->dev, 2168 dev_err(&interface->dev, "cannot allocate output buffer\n");
2172 "cannot allocate output buffer\n");
2173 return -ENOMEM; 2169 return -ENOMEM;
2174 } 2170 }
2175 2171
@@ -2230,8 +2226,7 @@ static int at76_init_new_device(struct at76_priv *priv,
2230 /* MAC address */ 2226 /* MAC address */
2231 ret = at76_get_hw_config(priv); 2227 ret = at76_get_hw_config(priv);
2232 if (ret < 0) { 2228 if (ret < 0) {
2233 dev_printk(KERN_ERR, &interface->dev, 2229 dev_err(&interface->dev, "cannot get MAC address\n");
2234 "cannot get MAC address\n");
2235 goto exit; 2230 goto exit;
2236 } 2231 }
2237 2232
@@ -2358,8 +2353,8 @@ static int at76_probe(struct usb_interface *interface,
2358 we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */ 2353 we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
2359 2354
2360 if (op_mode == OPMODE_HW_CONFIG_MODE) { 2355 if (op_mode == OPMODE_HW_CONFIG_MODE) {
2361 dev_printk(KERN_ERR, &interface->dev, 2356 dev_err(&interface->dev,
2362 "cannot handle a device in HW_CONFIG_MODE\n"); 2357 "cannot handle a device in HW_CONFIG_MODE\n");
2363 ret = -EBUSY; 2358 ret = -EBUSY;
2364 goto error; 2359 goto error;
2365 } 2360 }
@@ -2371,9 +2366,9 @@ static int at76_probe(struct usb_interface *interface,
2371 "downloading internal firmware\n"); 2366 "downloading internal firmware\n");
2372 ret = at76_load_internal_fw(udev, fwe); 2367 ret = at76_load_internal_fw(udev, fwe);
2373 if (ret < 0) { 2368 if (ret < 0) {
2374 dev_printk(KERN_ERR, &interface->dev, 2369 dev_err(&interface->dev,
2375 "error %d downloading internal firmware\n", 2370 "error %d downloading internal firmware\n",
2376 ret); 2371 ret);
2377 goto error; 2372 goto error;
2378 } 2373 }
2379 usb_put_dev(udev); 2374 usb_put_dev(udev);
@@ -2408,8 +2403,8 @@ static int at76_probe(struct usb_interface *interface,
2408 /* Re-check firmware version */ 2403 /* Re-check firmware version */
2409 ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv)); 2404 ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
2410 if (ret < 0) { 2405 if (ret < 0) {
2411 dev_printk(KERN_ERR, &interface->dev, 2406 dev_err(&interface->dev,
2412 "error %d getting firmware version\n", ret); 2407 "error %d getting firmware version\n", ret);
2413 goto error; 2408 goto error;
2414 } 2409 }
2415 } 2410 }
@@ -2449,7 +2444,7 @@ static void at76_disconnect(struct usb_interface *interface)
2449 2444
2450 wiphy_info(priv->hw->wiphy, "disconnecting\n"); 2445 wiphy_info(priv->hw->wiphy, "disconnecting\n");
2451 at76_delete_device(priv); 2446 at76_delete_device(priv);
2452 dev_printk(KERN_INFO, &interface->dev, "disconnected\n"); 2447 dev_info(&interface->dev, "disconnected\n");
2453} 2448}
2454 2449
2455/* Structure for registering this driver with the USB subsystem */ 2450/* Structure for registering this driver with the USB subsystem */
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
index f782b6e502b..7157f7d311c 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -50,18 +50,19 @@ static void ar5523_read_reply(struct ar5523 *ar, struct ar5523_cmd_hdr *hdr,
50 struct ar5523_tx_cmd *cmd) 50 struct ar5523_tx_cmd *cmd)
51{ 51{
52 int dlen, olen; 52 int dlen, olen;
53 u32 *rp; 53 __be32 *rp;
54 54
55 dlen = hdr->len - sizeof(*hdr); 55 dlen = be32_to_cpu(hdr->len) - sizeof(*hdr);
56 56
57 if (dlen < 0) { 57 if (dlen < 0) {
58 WARN_ON(1); 58 WARN_ON(1);
59 goto out; 59 goto out;
60 } 60 }
61 61
62 ar5523_dbg(ar, "Code = %d len = %d\n", hdr->code & 0xff, dlen); 62 ar5523_dbg(ar, "Code = %d len = %d\n", be32_to_cpu(hdr->code) & 0xff,
63 dlen);
63 64
64 rp = (u32 *)(hdr + 1); 65 rp = (__be32 *)(hdr + 1);
65 if (dlen >= sizeof(u32)) { 66 if (dlen >= sizeof(u32)) {
66 olen = be32_to_cpu(rp[0]); 67 olen = be32_to_cpu(rp[0]);
67 dlen -= sizeof(u32); 68 dlen -= sizeof(u32);
@@ -95,6 +96,7 @@ static void ar5523_cmd_rx_cb(struct urb *urb)
95 struct ar5523_tx_cmd *cmd = &ar->tx_cmd; 96 struct ar5523_tx_cmd *cmd = &ar->tx_cmd;
96 struct ar5523_cmd_hdr *hdr = ar->rx_cmd_buf; 97 struct ar5523_cmd_hdr *hdr = ar->rx_cmd_buf;
97 int dlen; 98 int dlen;
99 u32 code, hdrlen;
98 100
99 if (urb->status) { 101 if (urb->status) {
100 if (urb->status != -ESHUTDOWN) 102 if (urb->status != -ESHUTDOWN)
@@ -110,15 +112,15 @@ static void ar5523_cmd_rx_cb(struct urb *urb)
110 ar5523_dbg(ar, "%s code %02x priv %d\n", __func__, 112 ar5523_dbg(ar, "%s code %02x priv %d\n", __func__,
111 be32_to_cpu(hdr->code) & 0xff, hdr->priv); 113 be32_to_cpu(hdr->code) & 0xff, hdr->priv);
112 114
113 hdr->code = be32_to_cpu(hdr->code); 115 code = be32_to_cpu(hdr->code);
114 hdr->len = be32_to_cpu(hdr->len); 116 hdrlen = be32_to_cpu(hdr->len);
115 117
116 switch (hdr->code & 0xff) { 118 switch (code & 0xff) {
117 default: 119 default:
118 /* reply to a read command */ 120 /* reply to a read command */
119 if (hdr->priv != AR5523_CMD_ID) { 121 if (hdr->priv != AR5523_CMD_ID) {
120 ar5523_err(ar, "Unexpected command id: %02x\n", 122 ar5523_err(ar, "Unexpected command id: %02x\n",
121 hdr->code & 0xff); 123 code & 0xff);
122 goto skip; 124 goto skip;
123 } 125 }
124 ar5523_read_reply(ar, hdr, cmd); 126 ar5523_read_reply(ar, hdr, cmd);
@@ -147,7 +149,7 @@ static void ar5523_cmd_rx_cb(struct urb *urb)
147 case WDCMSG_TARGET_START: 149 case WDCMSG_TARGET_START:
148 /* This command returns a bogus id so it needs special 150 /* This command returns a bogus id so it needs special
149 handling */ 151 handling */
150 dlen = hdr->len - sizeof(*hdr); 152 dlen = hdrlen - sizeof(*hdr);
151 if (dlen != (int)sizeof(u32)) { 153 if (dlen != (int)sizeof(u32)) {
152 ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START"); 154 ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START");
153 return; 155 return;
@@ -303,7 +305,7 @@ static int ar5523_config(struct ar5523 *ar, u32 reg, u32 val)
303 305
304 write.reg = cpu_to_be32(reg); 306 write.reg = cpu_to_be32(reg);
305 write.len = cpu_to_be32(0); /* 0 = single write */ 307 write.len = cpu_to_be32(0); /* 0 = single write */
306 *(u32 *)write.data = cpu_to_be32(val); 308 *(__be32 *)write.data = cpu_to_be32(val);
307 309
308 error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, &write, 310 error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, &write,
309 3 * sizeof(u32), 0); 311 3 * sizeof(u32), 0);
@@ -335,29 +337,30 @@ static int ar5523_get_status(struct ar5523 *ar, u32 which, void *odata,
335 int olen) 337 int olen)
336{ 338{
337 int error; 339 int error;
340 __be32 which_be;
338 341
339 which = cpu_to_be32(which); 342 which_be = cpu_to_be32(which);
340 error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_STATUS, 343 error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_STATUS,
341 &which, sizeof(which), odata, olen, AR5523_CMD_FLAG_MAGIC); 344 &which_be, sizeof(which_be), odata, olen, AR5523_CMD_FLAG_MAGIC);
342 if (error != 0) 345 if (error != 0)
343 ar5523_err(ar, "could not read EEPROM offset 0x%02x\n", 346 ar5523_err(ar, "could not read EEPROM offset 0x%02x\n", which);
344 be32_to_cpu(which));
345 return error; 347 return error;
346} 348}
347 349
348static int ar5523_get_capability(struct ar5523 *ar, u32 cap, u32 *val) 350static int ar5523_get_capability(struct ar5523 *ar, u32 cap, u32 *val)
349{ 351{
350 int error; 352 int error;
353 __be32 cap_be, val_be;
351 354
352 cap = cpu_to_be32(cap); 355 cap_be = cpu_to_be32(cap);
353 error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY, 356 error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY, &cap_be,
354 &cap, sizeof(cap), val, sizeof(u32), AR5523_CMD_FLAG_MAGIC); 357 sizeof(cap_be), &val_be, sizeof(__be32),
358 AR5523_CMD_FLAG_MAGIC);
355 if (error != 0) { 359 if (error != 0) {
356 ar5523_err(ar, "could not read capability %u\n", 360 ar5523_err(ar, "could not read capability %u\n", cap);
357 be32_to_cpu(cap));
358 return error; 361 return error;
359 } 362 }
360 *val = be32_to_cpu(*val); 363 *val = be32_to_cpu(val_be);
361 return error; 364 return error;
362} 365}
363 366
@@ -1193,8 +1196,8 @@ static void ar5523_create_rateset(struct ar5523 *ar,
1193 if (!sta) { 1196 if (!sta) {
1194 ar5523_info(ar, "STA not found. Cannot set rates\n"); 1197 ar5523_info(ar, "STA not found. Cannot set rates\n");
1195 sta_rate_set = bss_conf->basic_rates; 1198 sta_rate_set = bss_conf->basic_rates;
1196 } 1199 } else
1197 sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; 1200 sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band];
1198 1201
1199 ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set); 1202 ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set);
1200 1203
@@ -1789,18 +1792,7 @@ static struct usb_driver ar5523_driver = {
1789 .disconnect = ar5523_disconnect, 1792 .disconnect = ar5523_disconnect,
1790}; 1793};
1791 1794
1792static int __init ar5523_init(void) 1795module_usb_driver(ar5523_driver);
1793{
1794 return usb_register(&ar5523_driver);
1795}
1796
1797static void __exit ar5523_exit(void)
1798{
1799 usb_deregister(&ar5523_driver);
1800}
1801 1796
1802MODULE_LICENSE("Dual BSD/GPL"); 1797MODULE_LICENSE("Dual BSD/GPL");
1803MODULE_FIRMWARE(AR5523_FIRMWARE_FILE); 1798MODULE_FIRMWARE(AR5523_FIRMWARE_FILE);
1804
1805module_init(ar5523_init);
1806module_exit(ar5523_exit);
diff --git a/drivers/net/wireless/ath/ar5523/ar5523_hw.h b/drivers/net/wireless/ath/ar5523/ar5523_hw.h
index a0e8bf46031..0fe2c803f48 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523_hw.h
+++ b/drivers/net/wireless/ath/ar5523/ar5523_hw.h
@@ -161,7 +161,7 @@ struct ar5523_rx_desc {
161 161
162struct ar5523_tx_desc { 162struct ar5523_tx_desc {
163 __be32 msglen; 163 __be32 msglen;
164 __be32 msgid; /* msg id (supplied by host) */ 164 u32 msgid; /* msg id (supplied by host) */
165 __be32 type; /* opcode: WDMSG_SEND or WDCMSG_FLUSH */ 165 __be32 type; /* opcode: WDMSG_SEND or WDCMSG_FLUSH */
166 __be32 txqid; /* tx queue id and flags */ 166 __be32 txqid; /* tx queue id and flags */
167#define UATH_TXQID_MASK 0x0f 167#define UATH_TXQID_MASK 0x0f
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
index aec33cc207f..8e8bcc7a480 100644
--- a/drivers/net/wireless/ath/ath5k/ahb.c
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -236,17 +236,4 @@ static struct platform_driver ath_ahb_driver = {
236 }, 236 },
237}; 237};
238 238
239static int __init 239module_platform_driver(ath_ahb_driver);
240ath5k_ahb_init(void)
241{
242 return platform_driver_register(&ath_ahb_driver);
243}
244
245static void __exit
246ath5k_ahb_exit(void)
247{
248 platform_driver_unregister(&ath_ahb_driver);
249}
250
251module_init(ath5k_ahb_init);
252module_exit(ath5k_ahb_exit);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 9f31cfa56cc..2fd5bab2e22 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -511,8 +511,9 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
511 ath5k_vif_iter(&iter_data, vif->addr, vif); 511 ath5k_vif_iter(&iter_data, vif->addr, vif);
512 512
513 /* Get list of all active MAC addresses */ 513 /* Get list of all active MAC addresses */
514 ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, 514 ieee80211_iterate_active_interfaces_atomic(
515 &iter_data); 515 ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
516 ath5k_vif_iter, &iter_data);
516 memcpy(ah->bssidmask, iter_data.mask, ETH_ALEN); 517 memcpy(ah->bssidmask, iter_data.mask, ETH_ALEN);
517 518
518 ah->opmode = iter_data.opmode; 519 ah->opmode = iter_data.opmode;
@@ -1348,7 +1349,7 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
1348 * right now, so it's not too bad... 1349 * right now, so it's not too bad...
1349 */ 1350 */
1350 rxs->mactime = ath5k_extend_tsf(ah, rs->rs_tstamp); 1351 rxs->mactime = ath5k_extend_tsf(ah, rs->rs_tstamp);
1351 rxs->flag |= RX_FLAG_MACTIME_MPDU; 1352 rxs->flag |= RX_FLAG_MACTIME_START;
1352 1353
1353 rxs->freq = ah->curchan->center_freq; 1354 rxs->freq = ah->curchan->center_freq;
1354 rxs->band = ah->curchan->band; 1355 rxs->band = ah->curchan->band;
@@ -3045,8 +3046,9 @@ ath5k_any_vif_assoc(struct ath5k_hw *ah)
3045 iter_data.need_set_hw_addr = false; 3046 iter_data.need_set_hw_addr = false;
3046 iter_data.found_active = true; 3047 iter_data.found_active = true;
3047 3048
3048 ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, 3049 ieee80211_iterate_active_interfaces_atomic(
3049 &iter_data); 3050 ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
3051 ath5k_vif_iter, &iter_data);
3050 return iter_data.any_assoc; 3052 return iter_data.any_assoc;
3051} 3053}
3052 3054
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 7a28538e6e0..1ea8c8795c8 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -452,8 +452,9 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
452 iter_data.hw_macaddr = NULL; 452 iter_data.hw_macaddr = NULL;
453 iter_data.n_stas = 0; 453 iter_data.n_stas = 0;
454 iter_data.need_set_hw_addr = false; 454 iter_data.need_set_hw_addr = false;
455 ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, 455 ieee80211_iterate_active_interfaces_atomic(
456 &iter_data); 456 ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
457 ath5k_vif_iter, &iter_data);
457 458
458 /* Set up RX Filter */ 459 /* Set up RX Filter */
459 if (iter_data.n_stas > 1) { 460 if (iter_data.n_stas > 1) {
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 0c2dd4771c3..4084b107628 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -789,9 +789,9 @@ ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel)
789 * (I don't think it supports 44MHz) */ 789 * (I don't think it supports 44MHz) */
790 /* On 2425 initvals TURBO_SHORT is not present */ 790 /* On 2425 initvals TURBO_SHORT is not present */
791 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { 791 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
792 turbo = AR5K_PHY_TURBO_MODE | 792 turbo = AR5K_PHY_TURBO_MODE;
793 (ah->ah_radio == AR5K_RF2425) ? 0 : 793 if (ah->ah_radio != AR5K_RF2425)
794 AR5K_PHY_TURBO_SHORT; 794 turbo |= AR5K_PHY_TURBO_SHORT;
795 } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) { 795 } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) {
796 if (ah->ah_radio == AR5K_RF5413) { 796 if (ah->ah_radio == AR5K_RF5413) {
797 mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ? 797 mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
index d755a5e7ed2..26c4b722085 100644
--- a/drivers/net/wireless/ath/ath6kl/Kconfig
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -30,3 +30,12 @@ config ATH6KL_DEBUG
30 depends on ATH6KL 30 depends on ATH6KL
31 ---help--- 31 ---help---
32 Enables debug support 32 Enables debug support
33
34config ATH6KL_REGDOMAIN
35 bool "Atheros ath6kl regdomain support"
36 depends on ATH6KL
37 depends on CFG80211_CERTIFICATION_ONUS
38 ---help---
39 Enabling this makes it possible to change the regdomain in
40 the firmware. This can be only enabled if regulatory requirements
41 are taken into account.
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
index 8cae8886f17..cab0ec0d538 100644
--- a/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -34,6 +34,7 @@ ath6kl_core-y += main.o
34ath6kl_core-y += txrx.o 34ath6kl_core-y += txrx.o
35ath6kl_core-y += wmi.o 35ath6kl_core-y += wmi.o
36ath6kl_core-y += core.o 36ath6kl_core-y += core.o
37ath6kl_core-y += recovery.o
37ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o 38ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
38 39
39obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o 40obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 277089963eb..5516a8ccc3c 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -147,15 +147,15 @@ static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
147{ 147{
148 struct ath6kl *ar = vif->ar; 148 struct ath6kl *ar = vif->ar;
149 149
150 if (ar->state != ATH6KL_STATE_SCHED_SCAN) 150 if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags))
151 return false; 151 return false;
152 152
153 del_timer_sync(&vif->sched_scan_timer); 153 del_timer_sync(&vif->sched_scan_timer);
154 154
155 ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, 155 if (ar->state == ATH6KL_STATE_RECOVERY)
156 ATH6KL_HOST_MODE_AWAKE); 156 return true;
157 157
158 ar->state = ATH6KL_STATE_ON; 158 ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false);
159 159
160 return true; 160 return true;
161} 161}
@@ -369,17 +369,13 @@ static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
369{ 369{
370 switch (type) { 370 switch (type) {
371 case NL80211_IFTYPE_STATION: 371 case NL80211_IFTYPE_STATION:
372 case NL80211_IFTYPE_P2P_CLIENT:
372 *nw_type = INFRA_NETWORK; 373 *nw_type = INFRA_NETWORK;
373 break; 374 break;
374 case NL80211_IFTYPE_ADHOC: 375 case NL80211_IFTYPE_ADHOC:
375 *nw_type = ADHOC_NETWORK; 376 *nw_type = ADHOC_NETWORK;
376 break; 377 break;
377 case NL80211_IFTYPE_AP: 378 case NL80211_IFTYPE_AP:
378 *nw_type = AP_NETWORK;
379 break;
380 case NL80211_IFTYPE_P2P_CLIENT:
381 *nw_type = INFRA_NETWORK;
382 break;
383 case NL80211_IFTYPE_P2P_GO: 379 case NL80211_IFTYPE_P2P_GO:
384 *nw_type = AP_NETWORK; 380 *nw_type = AP_NETWORK;
385 break; 381 break;
@@ -1031,30 +1027,15 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy,
1031 1027
1032 vif->scan_req = request; 1028 vif->scan_req = request;
1033 1029
1034 if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, 1030 ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
1035 ar->fw_capabilities)) { 1031 WMI_LONG_SCAN, force_fg_scan,
1036 /* 1032 false, 0,
1037 * If capable of doing P2P mgmt operations using 1033 ATH6KL_FG_SCAN_INTERVAL,
1038 * station interface, send additional information like 1034 n_channels, channels,
1039 * supported rates to advertise and xmit rates for 1035 request->no_cck,
1040 * probe requests 1036 request->rates);
1041 */
1042 ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
1043 WMI_LONG_SCAN, force_fg_scan,
1044 false, 0,
1045 ATH6KL_FG_SCAN_INTERVAL,
1046 n_channels, channels,
1047 request->no_cck,
1048 request->rates);
1049 } else {
1050 ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx,
1051 WMI_LONG_SCAN, force_fg_scan,
1052 false, 0,
1053 ATH6KL_FG_SCAN_INTERVAL,
1054 n_channels, channels);
1055 }
1056 if (ret) { 1037 if (ret) {
1057 ath6kl_err("wmi_startscan_cmd failed\n"); 1038 ath6kl_err("failed to start scan: %d\n", ret);
1058 vif->scan_req = NULL; 1039 vif->scan_req = NULL;
1059 } 1040 }
1060 1041
@@ -1093,15 +1074,18 @@ out:
1093void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, 1074void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1094 enum wmi_phy_mode mode) 1075 enum wmi_phy_mode mode)
1095{ 1076{
1096 enum nl80211_channel_type type; 1077 struct cfg80211_chan_def chandef;
1097 1078
1098 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 1079 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1099 "channel switch notify nw_type %d freq %d mode %d\n", 1080 "channel switch notify nw_type %d freq %d mode %d\n",
1100 vif->nw_type, freq, mode); 1081 vif->nw_type, freq, mode);
1101 1082
1102 type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT; 1083 cfg80211_chandef_create(&chandef,
1084 ieee80211_get_channel(vif->ar->wiphy, freq),
1085 (mode == WMI_11G_HT20) ?
1086 NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
1103 1087
1104 cfg80211_ch_switch_notify(vif->ndev, freq, type); 1088 cfg80211_ch_switch_notify(vif->ndev, &chandef);
1105} 1089}
1106 1090
1107static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, 1091static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
@@ -1384,11 +1368,8 @@ static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1384 return 0; 1368 return 0;
1385} 1369}
1386 1370
1387/*
1388 * The type nl80211_tx_power_setting replaces the following
1389 * data type from 2.6.36 onwards
1390*/
1391static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, 1371static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1372 struct wireless_dev *wdev,
1392 enum nl80211_tx_power_setting type, 1373 enum nl80211_tx_power_setting type,
1393 int mbm) 1374 int mbm)
1394{ 1375{
@@ -1423,7 +1404,9 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1423 return 0; 1404 return 0;
1424} 1405}
1425 1406
1426static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) 1407static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
1408 struct wireless_dev *wdev,
1409 int *dbm)
1427{ 1410{
1428 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); 1411 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1429 struct ath6kl_vif *vif; 1412 struct ath6kl_vif *vif;
@@ -1614,8 +1597,8 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1614 vif->ssid_len = ibss_param->ssid_len; 1597 vif->ssid_len = ibss_param->ssid_len;
1615 memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len); 1598 memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1616 1599
1617 if (ibss_param->channel) 1600 if (ibss_param->chandef.chan)
1618 vif->ch_hint = ibss_param->channel->center_freq; 1601 vif->ch_hint = ibss_param->chandef.chan->center_freq;
1619 1602
1620 if (ibss_param->channel_fixed) { 1603 if (ibss_param->channel_fixed) {
1621 /* 1604 /*
@@ -1889,7 +1872,7 @@ static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1889 struct cfg80211_wowlan *wow, u32 *filter) 1872 struct cfg80211_wowlan *wow, u32 *filter)
1890{ 1873{
1891 int ret, pos; 1874 int ret, pos;
1892 u8 mask[WOW_MASK_SIZE]; 1875 u8 mask[WOW_PATTERN_SIZE];
1893 u16 i; 1876 u16 i;
1894 1877
1895 /* Configure the patterns that we received from the user. */ 1878 /* Configure the patterns that we received from the user. */
@@ -2107,33 +2090,16 @@ static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
2107 return ret; 2090 return ret;
2108} 2091}
2109 2092
2110static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) 2093static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif,
2094 struct cfg80211_wowlan *wow, u32 *filter)
2111{ 2095{
2096 struct ath6kl *ar = vif->ar;
2112 struct in_device *in_dev; 2097 struct in_device *in_dev;
2113 struct in_ifaddr *ifa; 2098 struct in_ifaddr *ifa;
2114 struct ath6kl_vif *vif;
2115 int ret; 2099 int ret;
2116 u32 filter = 0;
2117 u16 i, bmiss_time; 2100 u16 i, bmiss_time;
2118 u8 index = 0;
2119 __be32 ips[MAX_IP_ADDRS]; 2101 __be32 ips[MAX_IP_ADDRS];
2120 2102 u8 index = 0;
2121 /* The FW currently can't support multi-vif WoW properly. */
2122 if (ar->num_vif > 1)
2123 return -EIO;
2124
2125 vif = ath6kl_vif_first(ar);
2126 if (!vif)
2127 return -EIO;
2128
2129 if (!ath6kl_cfg80211_ready(vif))
2130 return -EIO;
2131
2132 if (!test_bit(CONNECTED, &vif->flags))
2133 return -ENOTCONN;
2134
2135 if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2136 return -EINVAL;
2137 2103
2138 if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) && 2104 if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
2139 test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, 2105 test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
@@ -2155,7 +2121,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2155 * the user. 2121 * the user.
2156 */ 2122 */
2157 if (wow) 2123 if (wow)
2158 ret = ath6kl_wow_usr(ar, vif, wow, &filter); 2124 ret = ath6kl_wow_usr(ar, vif, wow, filter);
2159 else if (vif->nw_type == AP_NETWORK) 2125 else if (vif->nw_type == AP_NETWORK)
2160 ret = ath6kl_wow_ap(ar, vif); 2126 ret = ath6kl_wow_ap(ar, vif);
2161 else 2127 else
@@ -2190,12 +2156,10 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2190 return ret; 2156 return ret;
2191 } 2157 }
2192 2158
2193 ar->state = ATH6KL_STATE_SUSPENDING;
2194
2195 /* Setup own IP addr for ARP agent. */ 2159 /* Setup own IP addr for ARP agent. */
2196 in_dev = __in_dev_get_rtnl(vif->ndev); 2160 in_dev = __in_dev_get_rtnl(vif->ndev);
2197 if (!in_dev) 2161 if (!in_dev)
2198 goto skip_arp; 2162 return 0;
2199 2163
2200 ifa = in_dev->ifa_list; 2164 ifa = in_dev->ifa_list;
2201 memset(&ips, 0, sizeof(ips)); 2165 memset(&ips, 0, sizeof(ips));
@@ -2218,41 +2182,61 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2218 return ret; 2182 return ret;
2219 } 2183 }
2220 2184
2221skip_arp: 2185 return ret;
2222 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, 2186}
2187
2188static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2189{
2190 struct ath6kl_vif *first_vif, *vif;
2191 int ret = 0;
2192 u32 filter = 0;
2193 bool connected = false;
2194
2195 /* enter / leave wow suspend on first vif always */
2196 first_vif = ath6kl_vif_first(ar);
2197 if (WARN_ON(unlikely(!first_vif)) ||
2198 !ath6kl_cfg80211_ready(first_vif))
2199 return -EIO;
2200
2201 if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2202 return -EINVAL;
2203
2204 /* install filters for each connected vif */
2205 spin_lock_bh(&ar->list_lock);
2206 list_for_each_entry(vif, &ar->vif_list, list) {
2207 if (!test_bit(CONNECTED, &vif->flags) ||
2208 !ath6kl_cfg80211_ready(vif))
2209 continue;
2210 connected = true;
2211
2212 ret = ath6kl_wow_suspend_vif(vif, wow, &filter);
2213 if (ret)
2214 break;
2215 }
2216 spin_unlock_bh(&ar->list_lock);
2217
2218 if (!connected)
2219 return -ENOTCONN;
2220 else if (ret)
2221 return ret;
2222
2223 ar->state = ATH6KL_STATE_SUSPENDING;
2224
2225 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx,
2223 ATH6KL_WOW_MODE_ENABLE, 2226 ATH6KL_WOW_MODE_ENABLE,
2224 filter, 2227 filter,
2225 WOW_HOST_REQ_DELAY); 2228 WOW_HOST_REQ_DELAY);
2226 if (ret) 2229 if (ret)
2227 return ret; 2230 return ret;
2228 2231
2229 ret = ath6kl_cfg80211_host_sleep(ar, vif); 2232 return ath6kl_cfg80211_host_sleep(ar, first_vif);
2230 if (ret)
2231 return ret;
2232
2233 return 0;
2234} 2233}
2235 2234
2236static int ath6kl_wow_resume(struct ath6kl *ar) 2235static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif)
2237{ 2236{
2238 struct ath6kl_vif *vif; 2237 struct ath6kl *ar = vif->ar;
2239 int ret; 2238 int ret;
2240 2239
2241 vif = ath6kl_vif_first(ar);
2242 if (!vif)
2243 return -EIO;
2244
2245 ar->state = ATH6KL_STATE_RESUMING;
2246
2247 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2248 ATH6KL_HOST_MODE_AWAKE);
2249 if (ret) {
2250 ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
2251 ret);
2252 ar->state = ATH6KL_STATE_WOW;
2253 return ret;
2254 }
2255
2256 if (vif->nw_type != AP_NETWORK) { 2240 if (vif->nw_type != AP_NETWORK) {
2257 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 2241 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2258 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); 2242 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
@@ -2270,13 +2254,11 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
2270 return ret; 2254 return ret;
2271 } 2255 }
2272 2256
2273 ar->state = ATH6KL_STATE_ON;
2274
2275 if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) && 2257 if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
2276 test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, 2258 test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2277 ar->fw_capabilities)) { 2259 ar->fw_capabilities)) {
2278 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, 2260 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2279 vif->fw_vif_idx, true); 2261 vif->fw_vif_idx, true);
2280 if (ret) 2262 if (ret)
2281 return ret; 2263 return ret;
2282 } 2264 }
@@ -2286,6 +2268,48 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
2286 return 0; 2268 return 0;
2287} 2269}
2288 2270
2271static int ath6kl_wow_resume(struct ath6kl *ar)
2272{
2273 struct ath6kl_vif *vif;
2274 int ret;
2275
2276 vif = ath6kl_vif_first(ar);
2277 if (WARN_ON(unlikely(!vif)) ||
2278 !ath6kl_cfg80211_ready(vif))
2279 return -EIO;
2280
2281 ar->state = ATH6KL_STATE_RESUMING;
2282
2283 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2284 ATH6KL_HOST_MODE_AWAKE);
2285 if (ret) {
2286 ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
2287 ret);
2288 goto cleanup;
2289 }
2290
2291 spin_lock_bh(&ar->list_lock);
2292 list_for_each_entry(vif, &ar->vif_list, list) {
2293 if (!test_bit(CONNECTED, &vif->flags) ||
2294 !ath6kl_cfg80211_ready(vif))
2295 continue;
2296 ret = ath6kl_wow_resume_vif(vif);
2297 if (ret)
2298 break;
2299 }
2300 spin_unlock_bh(&ar->list_lock);
2301
2302 if (ret)
2303 goto cleanup;
2304
2305 ar->state = ATH6KL_STATE_ON;
2306 return 0;
2307
2308cleanup:
2309 ar->state = ATH6KL_STATE_WOW;
2310 return ret;
2311}
2312
2289static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar) 2313static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2290{ 2314{
2291 struct ath6kl_vif *vif; 2315 struct ath6kl_vif *vif;
@@ -2422,13 +2446,6 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2422 2446
2423 break; 2447 break;
2424 2448
2425 case ATH6KL_CFG_SUSPEND_SCHED_SCAN:
2426 /*
2427 * Nothing needed for schedule scan, firmware is already in
2428 * wow mode and sleeping most of the time.
2429 */
2430 break;
2431
2432 default: 2449 default:
2433 break; 2450 break;
2434 } 2451 }
@@ -2476,9 +2493,6 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
2476 } 2493 }
2477 break; 2494 break;
2478 2495
2479 case ATH6KL_STATE_SCHED_SCAN:
2480 break;
2481
2482 default: 2496 default:
2483 break; 2497 break;
2484 } 2498 }
@@ -2495,14 +2509,23 @@ static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
2495{ 2509{
2496 struct ath6kl *ar = wiphy_priv(wiphy); 2510 struct ath6kl *ar = wiphy_priv(wiphy);
2497 2511
2512 ath6kl_recovery_suspend(ar);
2513
2498 return ath6kl_hif_suspend(ar, wow); 2514 return ath6kl_hif_suspend(ar, wow);
2499} 2515}
2500 2516
2501static int __ath6kl_cfg80211_resume(struct wiphy *wiphy) 2517static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
2502{ 2518{
2503 struct ath6kl *ar = wiphy_priv(wiphy); 2519 struct ath6kl *ar = wiphy_priv(wiphy);
2520 int err;
2521
2522 err = ath6kl_hif_resume(ar);
2523 if (err)
2524 return err;
2504 2525
2505 return ath6kl_hif_resume(ar); 2526 ath6kl_recovery_resume(ar);
2527
2528 return 0;
2506} 2529}
2507 2530
2508/* 2531/*
@@ -2739,6 +2762,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2739 int res; 2762 int res;
2740 int i, ret; 2763 int i, ret;
2741 u16 rsn_capab = 0; 2764 u16 rsn_capab = 0;
2765 int inactivity_timeout = 0;
2742 2766
2743 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__); 2767 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2744 2768
@@ -2857,7 +2881,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2857 p.ssid_len = vif->ssid_len; 2881 p.ssid_len = vif->ssid_len;
2858 memcpy(p.ssid, vif->ssid, vif->ssid_len); 2882 memcpy(p.ssid, vif->ssid, vif->ssid_len);
2859 p.dot11_auth_mode = vif->dot11_auth_mode; 2883 p.dot11_auth_mode = vif->dot11_auth_mode;
2860 p.ch = cpu_to_le16(info->channel->center_freq); 2884 p.ch = cpu_to_le16(info->chandef.chan->center_freq);
2861 2885
2862 /* Enable uAPSD support by default */ 2886 /* Enable uAPSD support by default */
2863 res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); 2887 res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
@@ -2875,14 +2899,22 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2875 } 2899 }
2876 2900
2877 if (info->inactivity_timeout) { 2901 if (info->inactivity_timeout) {
2902
2903 inactivity_timeout = info->inactivity_timeout;
2904
2905 if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
2906 inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
2907 60);
2908
2878 res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx, 2909 res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
2879 info->inactivity_timeout); 2910 inactivity_timeout);
2880 if (res < 0) 2911 if (res < 0)
2881 return res; 2912 return res;
2882 } 2913 }
2883 2914
2884 if (ath6kl_set_htcap(vif, info->channel->band, 2915 if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2885 info->channel_type != NL80211_CHAN_NO_HT)) 2916 cfg80211_get_chandef_type(&info->chandef)
2917 != NL80211_CHAN_NO_HT))
2886 return -EIO; 2918 return -EIO;
2887 2919
2888 /* 2920 /*
@@ -2898,6 +2930,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2898 WLAN_EID_RSN, WMI_RSN_IE_CAPB, 2930 WLAN_EID_RSN, WMI_RSN_IE_CAPB,
2899 (const u8 *) &rsn_capab, 2931 (const u8 *) &rsn_capab,
2900 sizeof(rsn_capab)); 2932 sizeof(rsn_capab));
2933 vif->rsn_capab = rsn_capab;
2901 if (res < 0) 2934 if (res < 0)
2902 return res; 2935 return res;
2903 } 2936 }
@@ -2977,7 +3010,6 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
2977static int ath6kl_remain_on_channel(struct wiphy *wiphy, 3010static int ath6kl_remain_on_channel(struct wiphy *wiphy,
2978 struct wireless_dev *wdev, 3011 struct wireless_dev *wdev,
2979 struct ieee80211_channel *chan, 3012 struct ieee80211_channel *chan,
2980 enum nl80211_channel_type channel_type,
2981 unsigned int duration, 3013 unsigned int duration,
2982 u64 *cookie) 3014 u64 *cookie)
2983{ 3015{
@@ -3136,10 +3168,8 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3136 3168
3137static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3169static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3138 struct ieee80211_channel *chan, bool offchan, 3170 struct ieee80211_channel *chan, bool offchan,
3139 enum nl80211_channel_type channel_type, 3171 unsigned int wait, const u8 *buf, size_t len,
3140 bool channel_type_valid, unsigned int wait, 3172 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3141 const u8 *buf, size_t len, bool no_cck,
3142 bool dont_wait_for_ack, u64 *cookie)
3143{ 3173{
3144 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); 3174 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3145 struct ath6kl *ar = ath6kl_priv(vif->ndev); 3175 struct ath6kl *ar = ath6kl_priv(vif->ndev);
@@ -3211,7 +3241,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3211 struct ath6kl *ar = ath6kl_priv(dev); 3241 struct ath6kl *ar = ath6kl_priv(dev);
3212 struct ath6kl_vif *vif = netdev_priv(dev); 3242 struct ath6kl_vif *vif = netdev_priv(dev);
3213 u16 interval; 3243 u16 interval;
3214 int ret; 3244 int ret, rssi_thold;
3215 3245
3216 if (ar->state != ATH6KL_STATE_ON) 3246 if (ar->state != ATH6KL_STATE_ON)
3217 return -EIO; 3247 return -EIO;
@@ -3219,10 +3249,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3219 if (vif->sme_state != SME_DISCONNECTED) 3249 if (vif->sme_state != SME_DISCONNECTED)
3220 return -EBUSY; 3250 return -EBUSY;
3221 3251
3222 /* The FW currently can't support multi-vif WoW properly. */
3223 if (ar->num_vif > 1)
3224 return -EIO;
3225
3226 ath6kl_cfg80211_scan_complete_event(vif, true); 3252 ath6kl_cfg80211_scan_complete_event(vif, true);
3227 3253
3228 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, 3254 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
@@ -3244,6 +3270,23 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3244 return ret; 3270 return ret;
3245 } 3271 }
3246 3272
3273 if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
3274 ar->fw_capabilities)) {
3275 if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
3276 rssi_thold = 0;
3277 else if (request->rssi_thold < -127)
3278 rssi_thold = -127;
3279 else
3280 rssi_thold = request->rssi_thold;
3281
3282 ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
3283 rssi_thold);
3284 if (ret) {
3285 ath6kl_err("failed to set RSSI threshold for scan\n");
3286 return ret;
3287 }
3288 }
3289
3247 /* fw uses seconds, also make sure that it's >0 */ 3290 /* fw uses seconds, also make sure that it's >0 */
3248 interval = max_t(u16, 1, request->interval / 1000); 3291 interval = max_t(u16, 1, request->interval / 1000);
3249 3292
@@ -3251,15 +3294,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3251 interval, interval, 3294 interval, interval,
3252 vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0); 3295 vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
3253 3296
3254 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
3255 ATH6KL_WOW_MODE_ENABLE,
3256 WOW_FILTER_SSID,
3257 WOW_HOST_REQ_DELAY);
3258 if (ret) {
3259 ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret);
3260 return ret;
3261 }
3262
3263 /* this also clears IE in fw if it's not set */ 3297 /* this also clears IE in fw if it's not set */
3264 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, 3298 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
3265 WMI_FRAME_PROBE_REQ, 3299 WMI_FRAME_PROBE_REQ,
@@ -3270,17 +3304,13 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3270 return ret; 3304 return ret;
3271 } 3305 }
3272 3306
3273 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, 3307 ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
3274 ATH6KL_HOST_MODE_ASLEEP); 3308 if (ret)
3275 if (ret) {
3276 ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n",
3277 ret);
3278 return ret; 3309 return ret;
3279 }
3280 3310
3281 ar->state = ATH6KL_STATE_SCHED_SCAN; 3311 set_bit(SCHED_SCANNING, &vif->flags);
3282 3312
3283 return ret; 3313 return 0;
3284} 3314}
3285 3315
3286static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy, 3316static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
@@ -3309,6 +3339,27 @@ static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3309 mask); 3339 mask);
3310} 3340}
3311 3341
3342static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
3343 struct net_device *dev,
3344 u32 rate, u32 pkts, u32 intvl)
3345{
3346 struct ath6kl *ar = ath6kl_priv(dev);
3347 struct ath6kl_vif *vif = netdev_priv(dev);
3348
3349 if (vif->nw_type != INFRA_NETWORK ||
3350 !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
3351 return -EOPNOTSUPP;
3352
3353 if (vif->sme_state != SME_CONNECTED)
3354 return -ENOTCONN;
3355
3356 /* save this since the firmware won't report the interval */
3357 vif->txe_intvl = intvl;
3358
3359 return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
3360 rate, pkts, intvl);
3361}
3362
3312static const struct ieee80211_txrx_stypes 3363static const struct ieee80211_txrx_stypes
3313ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { 3364ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3314 [NL80211_IFTYPE_STATION] = { 3365 [NL80211_IFTYPE_STATION] = {
@@ -3375,6 +3426,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
3375 .sched_scan_start = ath6kl_cfg80211_sscan_start, 3426 .sched_scan_start = ath6kl_cfg80211_sscan_start,
3376 .sched_scan_stop = ath6kl_cfg80211_sscan_stop, 3427 .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
3377 .set_bitrate_mask = ath6kl_cfg80211_set_bitrate, 3428 .set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
3429 .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
3378}; 3430};
3379 3431
3380void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) 3432void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
@@ -3395,16 +3447,22 @@ void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
3395 break; 3447 break;
3396 } 3448 }
3397 3449
3398 if (test_bit(CONNECTED, &vif->flags) || 3450 if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3399 test_bit(CONNECT_PEND, &vif->flags)) 3451 (test_bit(CONNECTED, &vif->flags) ||
3452 test_bit(CONNECT_PEND, &vif->flags)))
3400 ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx); 3453 ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
3401 3454
3402 vif->sme_state = SME_DISCONNECTED; 3455 vif->sme_state = SME_DISCONNECTED;
3403 clear_bit(CONNECTED, &vif->flags); 3456 clear_bit(CONNECTED, &vif->flags);
3404 clear_bit(CONNECT_PEND, &vif->flags); 3457 clear_bit(CONNECT_PEND, &vif->flags);
3405 3458
3459 /* Stop netdev queues, needed during recovery */
3460 netif_stop_queue(vif->ndev);
3461 netif_carrier_off(vif->ndev);
3462
3406 /* disable scanning */ 3463 /* disable scanning */
3407 if (ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF, 3464 if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3465 ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
3408 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0) 3466 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
3409 ath6kl_warn("failed to disable scan during stop\n"); 3467 ath6kl_warn("failed to disable scan during stop\n");
3410 3468
@@ -3416,7 +3474,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3416 struct ath6kl_vif *vif; 3474 struct ath6kl_vif *vif;
3417 3475
3418 vif = ath6kl_vif_first(ar); 3476 vif = ath6kl_vif_first(ar);
3419 if (!vif) { 3477 if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
3420 /* save the current power mode before enabling power save */ 3478 /* save the current power mode before enabling power save */
3421 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; 3479 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3422 3480
@@ -3434,6 +3492,56 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3434 ath6kl_cfg80211_stop(vif); 3492 ath6kl_cfg80211_stop(vif);
3435} 3493}
3436 3494
3495static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
3496 struct regulatory_request *request)
3497{
3498 struct ath6kl *ar = wiphy_priv(wiphy);
3499 u32 rates[IEEE80211_NUM_BANDS];
3500 int ret, i;
3501
3502 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
3503 "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
3504 request->alpha2[0], request->alpha2[1],
3505 request->intersect ? " intersect" : "",
3506 request->processed ? " processed" : "",
3507 request->initiator, request->user_reg_hint_type);
3508
3509 /*
3510 * As firmware is not able intersect regdoms, we can only listen to
3511 * cellular hints.
3512 */
3513 if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
3514 return -EOPNOTSUPP;
3515
3516 ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
3517 if (ret) {
3518 ath6kl_err("failed to set regdomain: %d\n", ret);
3519 return ret;
3520 }
3521
3522 /*
3523 * Firmware will apply the regdomain change only after a scan is
3524 * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
3525 * changed.
3526 */
3527
3528 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
3529 if (wiphy->bands[i])
3530 rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
3531
3532
3533 ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
3534 false, 0, ATH6KL_FG_SCAN_INTERVAL,
3535 0, NULL, false, rates);
3536 if (ret) {
3537 ath6kl_err("failed to start scan for a regdomain change: %d\n",
3538 ret);
3539 return ret;
3540 }
3541
3542 return 0;
3543}
3544
3437static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) 3545static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
3438{ 3546{
3439 vif->aggr_cntxt = aggr_init(vif); 3547 vif->aggr_cntxt = aggr_init(vif);
@@ -3506,9 +3614,13 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
3506 vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true; 3614 vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true;
3507 3615
3508 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); 3616 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
3509 if (fw_vif_idx != 0) 3617 if (fw_vif_idx != 0) {
3510 ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) | 3618 ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
3511 0x2; 3619 0x2;
3620 if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
3621 ar->fw_capabilities))
3622 ndev->dev_addr[4] ^= 0x80;
3623 }
3512 3624
3513 init_netdev(ndev); 3625 init_netdev(ndev);
3514 3626
@@ -3562,6 +3674,12 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3562 BIT(NL80211_IFTYPE_P2P_CLIENT); 3674 BIT(NL80211_IFTYPE_P2P_CLIENT);
3563 } 3675 }
3564 3676
3677 if (config_enabled(CONFIG_ATH6KL_REGDOMAIN) &&
3678 test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
3679 wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
3680 ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
3681 }
3682
3565 /* max num of ssids that can be probed during scanning */ 3683 /* max num of ssids that can be probed during scanning */
3566 wiphy->max_scan_ssids = MAX_PROBED_SSIDS; 3684 wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3567 3685
@@ -3607,7 +3725,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3607 ath6kl_band_5ghz.ht_cap.ht_supported = false; 3725 ath6kl_band_5ghz.ht_cap.ht_supported = false;
3608 } 3726 }
3609 3727
3610 if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) { 3728 if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) {
3611 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; 3729 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3612 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; 3730 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3613 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff; 3731 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
@@ -3646,7 +3764,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3646 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | 3764 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3647 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; 3765 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3648 3766
3649 if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) 3767 if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
3650 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 3768 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3651 3769
3652 if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, 3770 if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
index 780f77775a9..e5e70f3a8ca 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.h
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -22,7 +22,6 @@ enum ath6kl_cfg_suspend_mode {
22 ATH6KL_CFG_SUSPEND_DEEPSLEEP, 22 ATH6KL_CFG_SUSPEND_DEEPSLEEP,
23 ATH6KL_CFG_SUSPEND_CUTPOWER, 23 ATH6KL_CFG_SUSPEND_CUTPOWER,
24 ATH6KL_CFG_SUSPEND_WOW, 24 ATH6KL_CFG_SUSPEND_WOW,
25 ATH6KL_CFG_SUSPEND_SCHED_SCAN,
26}; 25};
27 26
28struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, 27struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
index 82c4dd2a960..4b46adbe8c9 100644
--- a/drivers/net/wireless/ath/ath6kl/core.c
+++ b/drivers/net/wireless/ath/ath6kl/core.c
@@ -33,6 +33,8 @@ static unsigned int wow_mode;
33static unsigned int uart_debug; 33static unsigned int uart_debug;
34static unsigned int ath6kl_p2p; 34static unsigned int ath6kl_p2p;
35static unsigned int testmode; 35static unsigned int testmode;
36static unsigned int recovery_enable;
37static unsigned int heart_beat_poll;
36 38
37module_param(debug_mask, uint, 0644); 39module_param(debug_mask, uint, 0644);
38module_param(suspend_mode, uint, 0644); 40module_param(suspend_mode, uint, 0644);
@@ -40,6 +42,12 @@ module_param(wow_mode, uint, 0644);
40module_param(uart_debug, uint, 0644); 42module_param(uart_debug, uint, 0644);
41module_param(ath6kl_p2p, uint, 0644); 43module_param(ath6kl_p2p, uint, 0644);
42module_param(testmode, uint, 0644); 44module_param(testmode, uint, 0644);
45module_param(recovery_enable, uint, 0644);
46module_param(heart_beat_poll, uint, 0644);
47MODULE_PARM_DESC(recovery_enable, "Enable recovery from firmware error");
48MODULE_PARM_DESC(heart_beat_poll, "Enable fw error detection periodic" \
49 "polling. This also specifies the polling interval in" \
50 "msecs. Set reocvery_enable for this to be effective");
43 51
44void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb) 52void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb)
45{ 53{
@@ -202,6 +210,17 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
202 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", 210 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
203 __func__, wdev->netdev->name, wdev->netdev, ar); 211 __func__, wdev->netdev->name, wdev->netdev, ar);
204 212
213 ar->fw_recovery.enable = !!recovery_enable;
214 if (!ar->fw_recovery.enable)
215 return ret;
216
217 if (heart_beat_poll &&
218 test_bit(ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL,
219 ar->fw_capabilities))
220 ar->fw_recovery.hb_poll = heart_beat_poll;
221
222 ath6kl_recovery_init(ar);
223
205 return ret; 224 return ret;
206 225
207err_rxbuf_cleanup: 226err_rxbuf_cleanup:
@@ -291,6 +310,8 @@ void ath6kl_core_cleanup(struct ath6kl *ar)
291{ 310{
292 ath6kl_hif_power_off(ar); 311 ath6kl_hif_power_off(ar);
293 312
313 ath6kl_recovery_cleanup(ar);
314
294 destroy_workqueue(ar->ath6kl_wq); 315 destroy_workqueue(ar->ath6kl_wq);
295 316
296 if (ar->htc_target) 317 if (ar->htc_target)
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index cec49a31029..189d8faf8c8 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -115,6 +115,27 @@ enum ath6kl_fw_capability {
115 */ 115 */
116 ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, 116 ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
117 117
118 /* Firmware supports filtering BSS results by RSSI */
119 ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
120
121 /* FW sets mac_addr[4] ^= 0x80 for newly created interfaces */
122 ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
123
124 /* Firmware supports TX error rate notification */
125 ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY,
126
127 /* supports WMI_SET_REGDOMAIN_CMDID command */
128 ATH6KL_FW_CAPABILITY_REGDOMAIN,
129
130 /* Firmware supports sched scan decoupled from host sleep */
131 ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2,
132
133 /*
134 * Firmware capability for hang detection through heart beat
135 * challenge messages.
136 */
137 ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL,
138
118 /* this needs to be last */ 139 /* this needs to be last */
119 ATH6KL_FW_CAPABILITY_MAX, 140 ATH6KL_FW_CAPABILITY_MAX,
120}; 141};
@@ -128,11 +149,15 @@ struct ath6kl_fw_ie {
128}; 149};
129 150
130enum ath6kl_hw_flags { 151enum ath6kl_hw_flags {
131 ATH6KL_HW_FLAG_64BIT_RATES = BIT(0), 152 ATH6KL_HW_64BIT_RATES = BIT(0),
153 ATH6KL_HW_AP_INACTIVITY_MINS = BIT(1),
154 ATH6KL_HW_MAP_LP_ENDPOINT = BIT(2),
155 ATH6KL_HW_SDIO_CRC_ERROR_WAR = BIT(3),
132}; 156};
133 157
134#define ATH6KL_FW_API2_FILE "fw-2.bin" 158#define ATH6KL_FW_API2_FILE "fw-2.bin"
135#define ATH6KL_FW_API3_FILE "fw-3.bin" 159#define ATH6KL_FW_API3_FILE "fw-3.bin"
160#define ATH6KL_FW_API4_FILE "fw-4.bin"
136 161
137/* AR6003 1.0 definitions */ 162/* AR6003 1.0 definitions */
138#define AR6003_HW_1_0_VERSION 0x300002ba 163#define AR6003_HW_1_0_VERSION 0x300002ba
@@ -186,6 +211,13 @@ enum ath6kl_hw_flags {
186#define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \ 211#define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \
187 AR6004_HW_1_2_FW_DIR "/bdata.bin" 212 AR6004_HW_1_2_FW_DIR "/bdata.bin"
188 213
214/* AR6004 1.3 definitions */
215#define AR6004_HW_1_3_VERSION 0x31c8088a
216#define AR6004_HW_1_3_FW_DIR "ath6k/AR6004/hw1.3"
217#define AR6004_HW_1_3_FIRMWARE_FILE "fw.ram.bin"
218#define AR6004_HW_1_3_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin"
219#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin"
220
189/* Per STA data, used in AP mode */ 221/* Per STA data, used in AP mode */
190#define STA_PS_AWAKE BIT(0) 222#define STA_PS_AWAKE BIT(0)
191#define STA_PS_SLEEP BIT(1) 223#define STA_PS_SLEEP BIT(1)
@@ -536,6 +568,7 @@ enum ath6kl_vif_state {
536 HOST_SLEEP_MODE_CMD_PROCESSED, 568 HOST_SLEEP_MODE_CMD_PROCESSED,
537 NETDEV_MCAST_ALL_ON, 569 NETDEV_MCAST_ALL_ON,
538 NETDEV_MCAST_ALL_OFF, 570 NETDEV_MCAST_ALL_OFF,
571 SCHED_SCANNING,
539}; 572};
540 573
541struct ath6kl_vif { 574struct ath6kl_vif {
@@ -580,11 +613,13 @@ struct ath6kl_vif {
580 u16 assoc_bss_beacon_int; 613 u16 assoc_bss_beacon_int;
581 u16 listen_intvl_t; 614 u16 listen_intvl_t;
582 u16 bmiss_time_t; 615 u16 bmiss_time_t;
616 u32 txe_intvl;
583 u16 bg_scan_period; 617 u16 bg_scan_period;
584 u8 assoc_bss_dtim_period; 618 u8 assoc_bss_dtim_period;
585 struct net_device_stats net_stats; 619 struct net_device_stats net_stats;
586 struct target_stats target_stats; 620 struct target_stats target_stats;
587 struct wmi_connect_cmd profile; 621 struct wmi_connect_cmd profile;
622 u16 rsn_capab;
588 623
589 struct list_head mc_filter; 624 struct list_head mc_filter;
590}; 625};
@@ -609,6 +644,7 @@ enum ath6kl_dev_state {
609 SKIP_SCAN, 644 SKIP_SCAN,
610 ROAM_TBL_PEND, 645 ROAM_TBL_PEND,
611 FIRST_BOOT, 646 FIRST_BOOT,
647 RECOVERY_CLEANUP,
612}; 648};
613 649
614enum ath6kl_state { 650enum ath6kl_state {
@@ -619,7 +655,16 @@ enum ath6kl_state {
619 ATH6KL_STATE_DEEPSLEEP, 655 ATH6KL_STATE_DEEPSLEEP,
620 ATH6KL_STATE_CUTPOWER, 656 ATH6KL_STATE_CUTPOWER,
621 ATH6KL_STATE_WOW, 657 ATH6KL_STATE_WOW,
622 ATH6KL_STATE_SCHED_SCAN, 658 ATH6KL_STATE_RECOVERY,
659};
660
661/* Fw error recovery */
662#define ATH6KL_HB_RESP_MISS_THRES 5
663
664enum ath6kl_fw_err {
665 ATH6KL_FW_ASSERT,
666 ATH6KL_FW_HB_RESP_FAILURE,
667 ATH6KL_FW_EP_FULL,
623}; 668};
624 669
625struct ath6kl { 670struct ath6kl {
@@ -679,6 +724,7 @@ struct ath6kl {
679 struct ath6kl_req_key ap_mode_bkey; 724 struct ath6kl_req_key ap_mode_bkey;
680 struct sk_buff_head mcastpsq; 725 struct sk_buff_head mcastpsq;
681 u32 want_ch_switch; 726 u32 want_ch_switch;
727 u16 last_ch;
682 728
683 /* 729 /*
684 * FIXME: protects access to mcastpsq but is actually useless as 730 * FIXME: protects access to mcastpsq but is actually useless as
@@ -764,6 +810,17 @@ struct ath6kl {
764 810
765 bool wiphy_registered; 811 bool wiphy_registered;
766 812
813 struct ath6kl_fw_recovery {
814 struct work_struct recovery_work;
815 unsigned long err_reason;
816 unsigned long hb_poll;
817 struct timer_list hb_timer;
818 u32 seq_num;
819 bool hb_pending;
820 u8 hb_misscnt;
821 bool enable;
822 } fw_recovery;
823
767#ifdef CONFIG_ATH6KL_DEBUG 824#ifdef CONFIG_ATH6KL_DEBUG
768 struct { 825 struct {
769 struct sk_buff_head fwlog_queue; 826 struct sk_buff_head fwlog_queue;
@@ -899,4 +956,12 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type);
899void ath6kl_core_cleanup(struct ath6kl *ar); 956void ath6kl_core_cleanup(struct ath6kl *ar);
900void ath6kl_core_destroy(struct ath6kl *ar); 957void ath6kl_core_destroy(struct ath6kl *ar);
901 958
959/* Fw error recovery */
960void ath6kl_init_hw_restart(struct ath6kl *ar);
961void ath6kl_recovery_err_notify(struct ath6kl *ar, enum ath6kl_fw_err reason);
962void ath6kl_recovery_hb_event(struct ath6kl *ar, u32 cookie);
963void ath6kl_recovery_init(struct ath6kl *ar);
964void ath6kl_recovery_cleanup(struct ath6kl *ar);
965void ath6kl_recovery_suspend(struct ath6kl *ar);
966void ath6kl_recovery_resume(struct ath6kl *ar);
902#endif /* CORE_H */ 967#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index 49639d8266c..f97cd4ead54 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -44,6 +44,7 @@ enum ATH6K_DEBUG_MASK {
44 ATH6KL_DBG_SUSPEND = BIT(20), 44 ATH6KL_DBG_SUSPEND = BIT(20),
45 ATH6KL_DBG_USB = BIT(21), 45 ATH6KL_DBG_USB = BIT(21),
46 ATH6KL_DBG_USB_BULK = BIT(22), 46 ATH6KL_DBG_USB_BULK = BIT(22),
47 ATH6KL_DBG_RECOVERY = BIT(23),
47 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ 48 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
48}; 49};
49 50
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
index 68ed6c2665b..a6b614421fa 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ b/drivers/net/wireless/ath/ath6kl/hif.c
@@ -136,6 +136,7 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev)
136 136
137 ath6kl_hif_dump_fw_crash(dev->ar); 137 ath6kl_hif_dump_fw_crash(dev->ar);
138 ath6kl_read_fwlogs(dev->ar); 138 ath6kl_read_fwlogs(dev->ar);
139 ath6kl_recovery_err_notify(dev->ar, ATH6KL_FW_ASSERT);
139 140
140 return ret; 141 return ret;
141} 142}
@@ -338,8 +339,7 @@ static int ath6kl_hif_proc_err_intr(struct ath6kl_device *dev)
338 status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS, 339 status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS,
339 reg_buf, 4, HIF_WR_SYNC_BYTE_FIX); 340 reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
340 341
341 if (status) 342 WARN_ON(status);
342 WARN_ON(1);
343 343
344 return status; 344 return status;
345} 345}
@@ -383,8 +383,7 @@ static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev)
383 status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS, 383 status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS,
384 reg_buf, 4, HIF_WR_SYNC_BYTE_FIX); 384 reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
385 385
386 if (status) 386 WARN_ON(status);
387 WARN_ON(1);
388 387
389 return status; 388 return status;
390} 389}
@@ -695,11 +694,6 @@ int ath6kl_hif_setup(struct ath6kl_device *dev)
695 ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", 694 ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n",
696 dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); 695 dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);
697 696
698 /* usb doesn't support enabling interrupts */
699 /* FIXME: remove check once USB support is implemented */
700 if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB)
701 return 0;
702
703 status = ath6kl_hif_disable_intrs(dev); 697 status = ath6kl_hif_disable_intrs(dev);
704 698
705fail_setup: 699fail_setup:
diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index cd0e1ba410d..fbb78dfe078 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -2492,7 +2492,8 @@ static int ath6kl_htc_mbox_conn_service(struct htc_target *target,
2492 max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz); 2492 max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz);
2493 } 2493 }
2494 2494
2495 if (assigned_ep >= ENDPOINT_MAX || !max_msg_sz) { 2495 if (WARN_ON_ONCE(assigned_ep == ENDPOINT_UNUSED ||
2496 assigned_ep >= ENDPOINT_MAX || !max_msg_sz)) {
2496 status = -ENOMEM; 2497 status = -ENOMEM;
2497 goto fail_tx; 2498 goto fail_tx;
2498 } 2499 }
@@ -2655,12 +2656,6 @@ static int ath6kl_htc_mbox_wait_target(struct htc_target *target)
2655 struct htc_service_connect_resp resp; 2656 struct htc_service_connect_resp resp;
2656 int status; 2657 int status;
2657 2658
2658 /* FIXME: remove once USB support is implemented */
2659 if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) {
2660 ath6kl_err("HTC doesn't support USB yet. Patience!\n");
2661 return -EOPNOTSUPP;
2662 }
2663
2664 /* we should be getting 1 control message that the target is ready */ 2659 /* we should be getting 1 control message that the target is ready */
2665 packet = htc_wait_for_ctrl_msg(target); 2660 packet = htc_wait_for_ctrl_msg(target);
2666 2661
@@ -2890,9 +2885,7 @@ static void ath6kl_htc_mbox_cleanup(struct htc_target *target)
2890{ 2885{
2891 struct htc_packet *packet, *tmp_packet; 2886 struct htc_packet *packet, *tmp_packet;
2892 2887
2893 /* FIXME: remove check once USB support is implemented */ 2888 ath6kl_hif_cleanup_scatter(target->dev->ar);
2894 if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB)
2895 ath6kl_hif_cleanup_scatter(target->dev->ar);
2896 2889
2897 list_for_each_entry_safe(packet, tmp_packet, 2890 list_for_each_entry_safe(packet, tmp_packet,
2898 &target->free_ctrl_txbuf, list) { 2891 &target->free_ctrl_txbuf, list) {
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
index f9626c72369..ba6bd497b78 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
@@ -374,9 +374,8 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target,
374 packet = list_first_entry(txq, 374 packet = list_first_entry(txq,
375 struct htc_packet, 375 struct htc_packet,
376 list); 376 list);
377 list_del(&packet->list); 377 /* move to local queue */
378 /* insert into local queue */ 378 list_move_tail(&packet->list, &send_queue);
379 list_add_tail(&packet->list, &send_queue);
380 } 379 }
381 380
382 /* 381 /*
@@ -399,11 +398,10 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target,
399 * for cleanup */ 398 * for cleanup */
400 } else { 399 } else {
401 /* callback wants to keep this packet, 400 /* callback wants to keep this packet,
402 * remove from caller's queue */ 401 * move from caller's queue to the send
403 list_del(&packet->list); 402 * queue */
404 /* put it in the send queue */ 403 list_move_tail(&packet->list,
405 list_add_tail(&packet->list, 404 &send_queue);
406 &send_queue);
407 } 405 }
408 406
409 } 407 }
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index f90b5db741c..f21fa322e5c 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -42,7 +42,7 @@ static const struct ath6kl_hw hw_list[] = {
42 .reserved_ram_size = 6912, 42 .reserved_ram_size = 6912,
43 .refclk_hz = 26000000, 43 .refclk_hz = 26000000,
44 .uarttx_pin = 8, 44 .uarttx_pin = 8,
45 .flags = 0, 45 .flags = ATH6KL_HW_SDIO_CRC_ERROR_WAR,
46 46
47 /* hw2.0 needs override address hardcoded */ 47 /* hw2.0 needs override address hardcoded */
48 .app_start_override_addr = 0x944C00, 48 .app_start_override_addr = 0x944C00,
@@ -68,7 +68,7 @@ static const struct ath6kl_hw hw_list[] = {
68 .refclk_hz = 26000000, 68 .refclk_hz = 26000000,
69 .uarttx_pin = 8, 69 .uarttx_pin = 8,
70 .testscript_addr = 0x57ef74, 70 .testscript_addr = 0x57ef74,
71 .flags = 0, 71 .flags = ATH6KL_HW_SDIO_CRC_ERROR_WAR,
72 72
73 .fw = { 73 .fw = {
74 .dir = AR6003_HW_2_1_1_FW_DIR, 74 .dir = AR6003_HW_2_1_1_FW_DIR,
@@ -93,7 +93,8 @@ static const struct ath6kl_hw hw_list[] = {
93 .board_addr = 0x433900, 93 .board_addr = 0x433900,
94 .refclk_hz = 26000000, 94 .refclk_hz = 26000000,
95 .uarttx_pin = 11, 95 .uarttx_pin = 11,
96 .flags = ATH6KL_HW_FLAG_64BIT_RATES, 96 .flags = ATH6KL_HW_64BIT_RATES |
97 ATH6KL_HW_AP_INACTIVITY_MINS,
97 98
98 .fw = { 99 .fw = {
99 .dir = AR6004_HW_1_0_FW_DIR, 100 .dir = AR6004_HW_1_0_FW_DIR,
@@ -113,8 +114,8 @@ static const struct ath6kl_hw hw_list[] = {
113 .board_addr = 0x43d400, 114 .board_addr = 0x43d400,
114 .refclk_hz = 40000000, 115 .refclk_hz = 40000000,
115 .uarttx_pin = 11, 116 .uarttx_pin = 11,
116 .flags = ATH6KL_HW_FLAG_64BIT_RATES, 117 .flags = ATH6KL_HW_64BIT_RATES |
117 118 ATH6KL_HW_AP_INACTIVITY_MINS,
118 .fw = { 119 .fw = {
119 .dir = AR6004_HW_1_1_FW_DIR, 120 .dir = AR6004_HW_1_1_FW_DIR,
120 .fw = AR6004_HW_1_1_FIRMWARE_FILE, 121 .fw = AR6004_HW_1_1_FIRMWARE_FILE,
@@ -133,7 +134,8 @@ static const struct ath6kl_hw hw_list[] = {
133 .board_addr = 0x435c00, 134 .board_addr = 0x435c00,
134 .refclk_hz = 40000000, 135 .refclk_hz = 40000000,
135 .uarttx_pin = 11, 136 .uarttx_pin = 11,
136 .flags = ATH6KL_HW_FLAG_64BIT_RATES, 137 .flags = ATH6KL_HW_64BIT_RATES |
138 ATH6KL_HW_AP_INACTIVITY_MINS,
137 139
138 .fw = { 140 .fw = {
139 .dir = AR6004_HW_1_2_FW_DIR, 141 .dir = AR6004_HW_1_2_FW_DIR,
@@ -142,6 +144,28 @@ static const struct ath6kl_hw hw_list[] = {
142 .fw_board = AR6004_HW_1_2_BOARD_DATA_FILE, 144 .fw_board = AR6004_HW_1_2_BOARD_DATA_FILE,
143 .fw_default_board = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE, 145 .fw_default_board = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE,
144 }, 146 },
147 {
148 .id = AR6004_HW_1_3_VERSION,
149 .name = "ar6004 hw 1.3",
150 .dataset_patch_addr = 0x437860,
151 .app_load_addr = 0x1234,
152 .board_ext_data_addr = 0x437000,
153 .reserved_ram_size = 7168,
154 .board_addr = 0x436400,
155 .refclk_hz = 40000000,
156 .uarttx_pin = 11,
157 .flags = ATH6KL_HW_64BIT_RATES |
158 ATH6KL_HW_AP_INACTIVITY_MINS |
159 ATH6KL_HW_MAP_LP_ENDPOINT,
160
161 .fw = {
162 .dir = AR6004_HW_1_3_FW_DIR,
163 .fw = AR6004_HW_1_3_FIRMWARE_FILE,
164 },
165
166 .fw_board = AR6004_HW_1_3_BOARD_DATA_FILE,
167 .fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE,
168 },
145}; 169};
146 170
147/* 171/*
@@ -337,7 +361,7 @@ static int ath6kl_init_service_ep(struct ath6kl *ar)
337 if (ath6kl_connectservice(ar, &connect, "WMI DATA BK")) 361 if (ath6kl_connectservice(ar, &connect, "WMI DATA BK"))
338 return -EIO; 362 return -EIO;
339 363
340 /* connect to Video service, map this to to HI PRI */ 364 /* connect to Video service, map this to HI PRI */
341 connect.svc_id = WMI_DATA_VI_SVC; 365 connect.svc_id = WMI_DATA_VI_SVC;
342 if (ath6kl_connectservice(ar, &connect, "WMI DATA VI")) 366 if (ath6kl_connectservice(ar, &connect, "WMI DATA VI"))
343 return -EIO; 367 return -EIO;
@@ -1088,6 +1112,12 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
1088 if (ret) 1112 if (ret)
1089 return ret; 1113 return ret;
1090 1114
1115 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE);
1116 if (ret == 0) {
1117 ar->fw_api = 4;
1118 goto out;
1119 }
1120
1091 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE); 1121 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE);
1092 if (ret == 0) { 1122 if (ret == 0) {
1093 ar->fw_api = 3; 1123 ar->fw_api = 3;
@@ -1401,8 +1431,7 @@ static int ath6kl_init_upload(struct ath6kl *ar)
1401 return status; 1431 return status;
1402 1432
1403 /* WAR to avoid SDIO CRC err */ 1433 /* WAR to avoid SDIO CRC err */
1404 if (ar->version.target_ver == AR6003_HW_2_0_VERSION || 1434 if (ar->hw.flags & ATH6KL_HW_SDIO_CRC_ERROR_WAR) {
1405 ar->version.target_ver == AR6003_HW_2_1_1_VERSION) {
1406 ath6kl_err("temporary war to avoid sdio crc error\n"); 1435 ath6kl_err("temporary war to avoid sdio crc error\n");
1407 1436
1408 param = 0x28; 1437 param = 0x28;
@@ -1520,7 +1549,7 @@ static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type)
1520 return NULL; 1549 return NULL;
1521} 1550}
1522 1551
1523int ath6kl_init_hw_start(struct ath6kl *ar) 1552static int __ath6kl_init_hw_start(struct ath6kl *ar)
1524{ 1553{
1525 long timeleft; 1554 long timeleft;
1526 int ret, i; 1555 int ret, i;
@@ -1616,8 +1645,6 @@ int ath6kl_init_hw_start(struct ath6kl *ar)
1616 goto err_htc_stop; 1645 goto err_htc_stop;
1617 } 1646 }
1618 1647
1619 ar->state = ATH6KL_STATE_ON;
1620
1621 return 0; 1648 return 0;
1622 1649
1623err_htc_stop: 1650err_htc_stop:
@@ -1630,7 +1657,18 @@ err_power_off:
1630 return ret; 1657 return ret;
1631} 1658}
1632 1659
1633int ath6kl_init_hw_stop(struct ath6kl *ar) 1660int ath6kl_init_hw_start(struct ath6kl *ar)
1661{
1662 int err;
1663
1664 err = __ath6kl_init_hw_start(ar);
1665 if (err)
1666 return err;
1667 ar->state = ATH6KL_STATE_ON;
1668 return 0;
1669}
1670
1671static int __ath6kl_init_hw_stop(struct ath6kl *ar)
1634{ 1672{
1635 int ret; 1673 int ret;
1636 1674
@@ -1646,11 +1684,37 @@ int ath6kl_init_hw_stop(struct ath6kl *ar)
1646 if (ret) 1684 if (ret)
1647 ath6kl_warn("failed to power off hif: %d\n", ret); 1685 ath6kl_warn("failed to power off hif: %d\n", ret);
1648 1686
1649 ar->state = ATH6KL_STATE_OFF; 1687 return 0;
1688}
1650 1689
1690int ath6kl_init_hw_stop(struct ath6kl *ar)
1691{
1692 int err;
1693
1694 err = __ath6kl_init_hw_stop(ar);
1695 if (err)
1696 return err;
1697 ar->state = ATH6KL_STATE_OFF;
1651 return 0; 1698 return 0;
1652} 1699}
1653 1700
1701void ath6kl_init_hw_restart(struct ath6kl *ar)
1702{
1703 clear_bit(WMI_READY, &ar->flag);
1704
1705 ath6kl_cfg80211_stop_all(ar);
1706
1707 if (__ath6kl_init_hw_stop(ar)) {
1708 ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to stop during fw error recovery\n");
1709 return;
1710 }
1711
1712 if (__ath6kl_init_hw_start(ar)) {
1713 ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to restart during fw error recovery\n");
1714 return;
1715 }
1716}
1717
1654/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */ 1718/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */
1655void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) 1719void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
1656{ 1720{
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index c189e28e86a..bd50b6b7b49 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -293,13 +293,17 @@ int ath6kl_read_fwlogs(struct ath6kl *ar)
293 } 293 }
294 294
295 address = TARG_VTOP(ar->target_type, debug_hdr_addr); 295 address = TARG_VTOP(ar->target_type, debug_hdr_addr);
296 ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr)); 296 ret = ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr));
297 if (ret)
298 goto out;
297 299
298 address = TARG_VTOP(ar->target_type, 300 address = TARG_VTOP(ar->target_type,
299 le32_to_cpu(debug_hdr.dbuf_addr)); 301 le32_to_cpu(debug_hdr.dbuf_addr));
300 firstbuf = address; 302 firstbuf = address;
301 dropped = le32_to_cpu(debug_hdr.dropped); 303 dropped = le32_to_cpu(debug_hdr.dropped);
302 ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); 304 ret = ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
305 if (ret)
306 goto out;
303 307
304 loop = 100; 308 loop = 100;
305 309
@@ -322,7 +326,8 @@ int ath6kl_read_fwlogs(struct ath6kl *ar)
322 326
323 address = TARG_VTOP(ar->target_type, 327 address = TARG_VTOP(ar->target_type,
324 le32_to_cpu(debug_buf.next)); 328 le32_to_cpu(debug_buf.next));
325 ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); 329 ret = ath6kl_diag_read(ar, address, &debug_buf,
330 sizeof(debug_buf));
326 if (ret) 331 if (ret)
327 goto out; 332 goto out;
328 333
@@ -436,12 +441,9 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
436 break; 441 break;
437 } 442 }
438 443
439 if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) { 444 if (ar->last_ch != channel)
440 ar->want_ch_switch &= ~(1 << vif->fw_vif_idx);
441 /* we actually don't know the phymode, default to HT20 */ 445 /* we actually don't know the phymode, default to HT20 */
442 ath6kl_cfg80211_ch_switch_notify(vif, channel, 446 ath6kl_cfg80211_ch_switch_notify(vif, channel, WMI_11G_HT20);
443 WMI_11G_HT20);
444 }
445 447
446 ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); 448 ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0);
447 set_bit(CONNECTED, &vif->flags); 449 set_bit(CONNECTED, &vif->flags);
@@ -606,6 +608,18 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)
606 608
607 switch (vif->nw_type) { 609 switch (vif->nw_type) {
608 case AP_NETWORK: 610 case AP_NETWORK:
611 /*
612 * reconfigure any saved RSN IE capabilites in the beacon /
613 * probe response to stay in sync with the supplicant.
614 */
615 if (vif->rsn_capab &&
616 test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
617 ar->fw_capabilities))
618 ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
619 WLAN_EID_RSN, WMI_RSN_IE_CAPB,
620 (const u8 *) &vif->rsn_capab,
621 sizeof(vif->rsn_capab));
622
609 return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, 623 return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx,
610 &vif->profile); 624 &vif->profile);
611 default: 625 default:
@@ -628,6 +642,9 @@ static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel)
628 if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) 642 if (ar->want_ch_switch & (1 << vif->fw_vif_idx))
629 res = ath6kl_commit_ch_switch(vif, channel); 643 res = ath6kl_commit_ch_switch(vif, channel);
630 644
645 /* if channel switch failed, oh well we tried */
646 ar->want_ch_switch &= ~(1 << vif->fw_vif_idx);
647
631 if (res) 648 if (res)
632 ath6kl_err("channel switch failed nw_type %d res %d\n", 649 ath6kl_err("channel switch failed nw_type %d res %d\n",
633 vif->nw_type, res); 650 vif->nw_type, res);
@@ -981,8 +998,25 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
981 if (vif->nw_type == AP_NETWORK) { 998 if (vif->nw_type == AP_NETWORK) {
982 /* disconnect due to other STA vif switching channels */ 999 /* disconnect due to other STA vif switching channels */
983 if (reason == BSS_DISCONNECTED && 1000 if (reason == BSS_DISCONNECTED &&
984 prot_reason_status == WMI_AP_REASON_STA_ROAM) 1001 prot_reason_status == WMI_AP_REASON_STA_ROAM) {
985 ar->want_ch_switch |= 1 << vif->fw_vif_idx; 1002 ar->want_ch_switch |= 1 << vif->fw_vif_idx;
1003 /* bail back to this channel if STA vif fails connect */
1004 ar->last_ch = le16_to_cpu(vif->profile.ch);
1005 }
1006
1007 if (prot_reason_status == WMI_AP_REASON_MAX_STA) {
1008 /* send max client reached notification to user space */
1009 cfg80211_conn_failed(vif->ndev, bssid,
1010 NL80211_CONN_FAIL_MAX_CLIENTS,
1011 GFP_KERNEL);
1012 }
1013
1014 if (prot_reason_status == WMI_AP_REASON_ACL) {
1015 /* send blocked client notification to user space */
1016 cfg80211_conn_failed(vif->ndev, bssid,
1017 NL80211_CONN_FAIL_BLOCKED_CLIENT,
1018 GFP_KERNEL);
1019 }
986 1020
987 if (!ath6kl_remove_sta(ar, bssid, prot_reason_status)) 1021 if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
988 return; 1022 return;
@@ -1041,6 +1075,9 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
1041 } 1075 }
1042 } 1076 }
1043 1077
1078 /* restart disconnected concurrent vifs waiting for new channel */
1079 ath6kl_check_ch_switch(ar, ar->last_ch);
1080
1044 /* update connect & link status atomically */ 1081 /* update connect & link status atomically */
1045 spin_lock_bh(&vif->if_lock); 1082 spin_lock_bh(&vif->if_lock);
1046 clear_bit(CONNECTED, &vif->flags); 1083 clear_bit(CONNECTED, &vif->flags);
diff --git a/drivers/net/wireless/ath/ath6kl/recovery.c b/drivers/net/wireless/ath/ath6kl/recovery.c
new file mode 100644
index 00000000000..3a8d5e97dc8
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/recovery.c
@@ -0,0 +1,160 @@
1/*
2 * Copyright (c) 2012 Qualcomm Atheros, 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#include "core.h"
18#include "cfg80211.h"
19#include "debug.h"
20
21static void ath6kl_recovery_work(struct work_struct *work)
22{
23 struct ath6kl *ar = container_of(work, struct ath6kl,
24 fw_recovery.recovery_work);
25
26 ar->state = ATH6KL_STATE_RECOVERY;
27
28 del_timer_sync(&ar->fw_recovery.hb_timer);
29
30 ath6kl_init_hw_restart(ar);
31
32 ar->state = ATH6KL_STATE_ON;
33 clear_bit(WMI_CTRL_EP_FULL, &ar->flag);
34
35 ar->fw_recovery.err_reason = 0;
36
37 if (ar->fw_recovery.hb_poll)
38 mod_timer(&ar->fw_recovery.hb_timer, jiffies +
39 msecs_to_jiffies(ar->fw_recovery.hb_poll));
40}
41
42void ath6kl_recovery_err_notify(struct ath6kl *ar, enum ath6kl_fw_err reason)
43{
44 if (!ar->fw_recovery.enable)
45 return;
46
47 ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Fw error detected, reason:%d\n",
48 reason);
49
50 set_bit(reason, &ar->fw_recovery.err_reason);
51
52 if (!test_bit(RECOVERY_CLEANUP, &ar->flag) &&
53 ar->state != ATH6KL_STATE_RECOVERY)
54 queue_work(ar->ath6kl_wq, &ar->fw_recovery.recovery_work);
55}
56
57void ath6kl_recovery_hb_event(struct ath6kl *ar, u32 cookie)
58{
59 if (cookie == ar->fw_recovery.seq_num)
60 ar->fw_recovery.hb_pending = false;
61}
62
63static void ath6kl_recovery_hb_timer(unsigned long data)
64{
65 struct ath6kl *ar = (struct ath6kl *) data;
66 int err;
67
68 if (test_bit(RECOVERY_CLEANUP, &ar->flag) ||
69 (ar->state == ATH6KL_STATE_RECOVERY))
70 return;
71
72 if (ar->fw_recovery.hb_pending)
73 ar->fw_recovery.hb_misscnt++;
74 else
75 ar->fw_recovery.hb_misscnt = 0;
76
77 if (ar->fw_recovery.hb_misscnt > ATH6KL_HB_RESP_MISS_THRES) {
78 ar->fw_recovery.hb_misscnt = 0;
79 ar->fw_recovery.seq_num = 0;
80 ar->fw_recovery.hb_pending = false;
81 ath6kl_recovery_err_notify(ar, ATH6KL_FW_HB_RESP_FAILURE);
82 return;
83 }
84
85 ar->fw_recovery.seq_num++;
86 ar->fw_recovery.hb_pending = true;
87
88 err = ath6kl_wmi_get_challenge_resp_cmd(ar->wmi,
89 ar->fw_recovery.seq_num, 0);
90 if (err)
91 ath6kl_warn("Failed to send hb challenge request, err:%d\n",
92 err);
93
94 mod_timer(&ar->fw_recovery.hb_timer, jiffies +
95 msecs_to_jiffies(ar->fw_recovery.hb_poll));
96}
97
98void ath6kl_recovery_init(struct ath6kl *ar)
99{
100 struct ath6kl_fw_recovery *recovery = &ar->fw_recovery;
101
102 clear_bit(RECOVERY_CLEANUP, &ar->flag);
103 INIT_WORK(&recovery->recovery_work, ath6kl_recovery_work);
104 recovery->seq_num = 0;
105 recovery->hb_misscnt = 0;
106 ar->fw_recovery.hb_pending = false;
107 ar->fw_recovery.hb_timer.function = ath6kl_recovery_hb_timer;
108 ar->fw_recovery.hb_timer.data = (unsigned long) ar;
109 init_timer_deferrable(&ar->fw_recovery.hb_timer);
110
111 if (ar->fw_recovery.hb_poll)
112 mod_timer(&ar->fw_recovery.hb_timer, jiffies +
113 msecs_to_jiffies(ar->fw_recovery.hb_poll));
114}
115
116void ath6kl_recovery_cleanup(struct ath6kl *ar)
117{
118 if (!ar->fw_recovery.enable)
119 return;
120
121 set_bit(RECOVERY_CLEANUP, &ar->flag);
122
123 del_timer_sync(&ar->fw_recovery.hb_timer);
124 cancel_work_sync(&ar->fw_recovery.recovery_work);
125}
126
127void ath6kl_recovery_suspend(struct ath6kl *ar)
128{
129 if (!ar->fw_recovery.enable)
130 return;
131
132 ath6kl_recovery_cleanup(ar);
133
134 if (!ar->fw_recovery.err_reason)
135 return;
136
137 /* Process pending fw error detection */
138 ar->fw_recovery.err_reason = 0;
139 WARN_ON(ar->state != ATH6KL_STATE_ON);
140 ar->state = ATH6KL_STATE_RECOVERY;
141 ath6kl_init_hw_restart(ar);
142 ar->state = ATH6KL_STATE_ON;
143}
144
145void ath6kl_recovery_resume(struct ath6kl *ar)
146{
147 if (!ar->fw_recovery.enable)
148 return;
149
150 clear_bit(RECOVERY_CLEANUP, &ar->flag);
151
152 if (!ar->fw_recovery.hb_poll)
153 return;
154
155 ar->fw_recovery.hb_pending = false;
156 ar->fw_recovery.seq_num = 0;
157 ar->fw_recovery.hb_misscnt = 0;
158 mod_timer(&ar->fw_recovery.hb_timer,
159 jiffies + msecs_to_jiffies(ar->fw_recovery.hb_poll));
160}
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 05b95405f7b..d111980d44c 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -709,7 +709,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
709{ 709{
710 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); 710 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
711 struct htc_target *target = ar->htc_target; 711 struct htc_target *target = ar->htc_target;
712 int ret; 712 int ret = 0;
713 bool virt_scat = false; 713 bool virt_scat = false;
714 714
715 if (ar_sdio->scatter_enabled) 715 if (ar_sdio->scatter_enabled)
@@ -844,22 +844,6 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
844 bool try_deepsleep = false; 844 bool try_deepsleep = false;
845 int ret; 845 int ret;
846 846
847 if (ar->state == ATH6KL_STATE_SCHED_SCAN) {
848 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n");
849
850 ret = ath6kl_set_sdio_pm_caps(ar);
851 if (ret)
852 goto cut_pwr;
853
854 ret = ath6kl_cfg80211_suspend(ar,
855 ATH6KL_CFG_SUSPEND_SCHED_SCAN,
856 NULL);
857 if (ret)
858 goto cut_pwr;
859
860 return 0;
861 }
862
863 if (ar->suspend_mode == WLAN_POWER_STATE_WOW || 847 if (ar->suspend_mode == WLAN_POWER_STATE_WOW ||
864 (!ar->suspend_mode && wow)) { 848 (!ar->suspend_mode && wow)) {
865 849
@@ -942,14 +926,14 @@ static int ath6kl_sdio_resume(struct ath6kl *ar)
942 case ATH6KL_STATE_WOW: 926 case ATH6KL_STATE_WOW:
943 break; 927 break;
944 928
945 case ATH6KL_STATE_SCHED_SCAN:
946 break;
947
948 case ATH6KL_STATE_SUSPENDING: 929 case ATH6KL_STATE_SUSPENDING:
949 break; 930 break;
950 931
951 case ATH6KL_STATE_RESUMING: 932 case ATH6KL_STATE_RESUMING:
952 break; 933 break;
934
935 case ATH6KL_STATE_RECOVERY:
936 break;
953 } 937 }
954 938
955 ath6kl_cfg80211_resume(ar); 939 ath6kl_cfg80211_resume(ar);
@@ -1462,3 +1446,6 @@ MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
1462MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE); 1446MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE);
1463MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); 1447MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE);
1464MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); 1448MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE);
1449MODULE_FIRMWARE(AR6004_HW_1_3_FW_DIR "/" AR6004_HW_1_3_FIRMWARE_FILE);
1450MODULE_FIRMWARE(AR6004_HW_1_3_BOARD_DATA_FILE);
1451MODULE_FIRMWARE(AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 7dfa0fd86d7..78b36928657 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -288,8 +288,16 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
288 int status = 0; 288 int status = 0;
289 struct ath6kl_cookie *cookie = NULL; 289 struct ath6kl_cookie *cookie = NULL;
290 290
291 if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) 291 if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) {
292 dev_kfree_skb(skb);
292 return -EACCES; 293 return -EACCES;
294 }
295
296 if (WARN_ON_ONCE(eid == ENDPOINT_UNUSED ||
297 eid >= ENDPOINT_MAX)) {
298 status = -EINVAL;
299 goto fail_ctrl_tx;
300 }
293 301
294 spin_lock_bh(&ar->lock); 302 spin_lock_bh(&ar->lock);
295 303
@@ -591,6 +599,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
591 */ 599 */
592 set_bit(WMI_CTRL_EP_FULL, &ar->flag); 600 set_bit(WMI_CTRL_EP_FULL, &ar->flag);
593 ath6kl_err("wmi ctrl ep is full\n"); 601 ath6kl_err("wmi ctrl ep is full\n");
602 ath6kl_recovery_err_notify(ar, ATH6KL_FW_EP_FULL);
594 return action; 603 return action;
595 } 604 }
596 605
@@ -695,22 +704,31 @@ void ath6kl_tx_complete(struct htc_target *target,
695 list); 704 list);
696 list_del(&packet->list); 705 list_del(&packet->list);
697 706
707 if (WARN_ON_ONCE(packet->endpoint == ENDPOINT_UNUSED ||
708 packet->endpoint >= ENDPOINT_MAX))
709 continue;
710
698 ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt; 711 ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt;
699 if (!ath6kl_cookie) 712 if (WARN_ON_ONCE(!ath6kl_cookie))
700 goto fatal; 713 continue;
701 714
702 status = packet->status; 715 status = packet->status;
703 skb = ath6kl_cookie->skb; 716 skb = ath6kl_cookie->skb;
704 eid = packet->endpoint; 717 eid = packet->endpoint;
705 map_no = ath6kl_cookie->map_no; 718 map_no = ath6kl_cookie->map_no;
706 719
707 if (!skb || !skb->data) 720 if (WARN_ON_ONCE(!skb || !skb->data)) {
708 goto fatal; 721 dev_kfree_skb(skb);
722 ath6kl_free_cookie(ar, ath6kl_cookie);
723 continue;
724 }
709 725
710 __skb_queue_tail(&skb_queue, skb); 726 __skb_queue_tail(&skb_queue, skb);
711 727
712 if (!status && (packet->act_len != skb->len)) 728 if (WARN_ON_ONCE(!status && (packet->act_len != skb->len))) {
713 goto fatal; 729 ath6kl_free_cookie(ar, ath6kl_cookie);
730 continue;
731 }
714 732
715 ar->tx_pending[eid]--; 733 ar->tx_pending[eid]--;
716 734
@@ -792,11 +810,6 @@ void ath6kl_tx_complete(struct htc_target *target,
792 wake_up(&ar->event_wq); 810 wake_up(&ar->event_wq);
793 811
794 return; 812 return;
795
796fatal:
797 WARN_ON(1);
798 spin_unlock_bh(&ar->lock);
799 return;
800} 813}
801 814
802void ath6kl_tx_data_cleanup(struct ath6kl *ar) 815void ath6kl_tx_data_cleanup(struct ath6kl *ar)
@@ -885,8 +898,11 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
885 break; 898 break;
886 899
887 packet = (struct htc_packet *) skb->head; 900 packet = (struct htc_packet *) skb->head;
888 if (!IS_ALIGNED((unsigned long) skb->data, 4)) 901 if (!IS_ALIGNED((unsigned long) skb->data, 4)) {
902 size_t len = skb_headlen(skb);
889 skb->data = PTR_ALIGN(skb->data - 4, 4); 903 skb->data = PTR_ALIGN(skb->data - 4, 4);
904 skb_set_tail_pointer(skb, len);
905 }
890 set_htc_rxpkt_info(packet, skb, skb->data, 906 set_htc_rxpkt_info(packet, skb, skb->data,
891 ATH6KL_BUFFER_SIZE, endpoint); 907 ATH6KL_BUFFER_SIZE, endpoint);
892 packet->skb = skb; 908 packet->skb = skb;
@@ -908,8 +924,11 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
908 return; 924 return;
909 925
910 packet = (struct htc_packet *) skb->head; 926 packet = (struct htc_packet *) skb->head;
911 if (!IS_ALIGNED((unsigned long) skb->data, 4)) 927 if (!IS_ALIGNED((unsigned long) skb->data, 4)) {
928 size_t len = skb_headlen(skb);
912 skb->data = PTR_ALIGN(skb->data - 4, 4); 929 skb->data = PTR_ALIGN(skb->data - 4, 4);
930 skb_set_tail_pointer(skb, len);
931 }
913 set_htc_rxpkt_info(packet, skb, skb->data, 932 set_htc_rxpkt_info(packet, skb, skb->data,
914 ATH6KL_AMSDU_BUFFER_SIZE, 0); 933 ATH6KL_AMSDU_BUFFER_SIZE, 0);
915 packet->skb = skb; 934 packet->skb = skb;
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index 3740c3d6ab8..62bcc0d5bc2 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -185,9 +185,10 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe,
185 for (i = 0; i < urb_cnt; i++) { 185 for (i = 0; i < urb_cnt; i++) {
186 urb_context = kzalloc(sizeof(struct ath6kl_urb_context), 186 urb_context = kzalloc(sizeof(struct ath6kl_urb_context),
187 GFP_KERNEL); 187 GFP_KERNEL);
188 if (urb_context == NULL) 188 if (urb_context == NULL) {
189 /* FIXME: set status to -ENOMEM */ 189 status = -ENOMEM;
190 break; 190 goto fail_alloc_pipe_resources;
191 }
191 192
192 urb_context->pipe = pipe; 193 urb_context->pipe = pipe;
193 194
@@ -204,6 +205,7 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe,
204 pipe->logical_pipe_num, pipe->usb_pipe_handle, 205 pipe->logical_pipe_num, pipe->usb_pipe_handle,
205 pipe->urb_alloc); 206 pipe->urb_alloc);
206 207
208fail_alloc_pipe_resources:
207 return status; 209 return status;
208} 210}
209 211
@@ -803,7 +805,11 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
803 *dl_pipe = ATH6KL_USB_PIPE_RX_DATA; 805 *dl_pipe = ATH6KL_USB_PIPE_RX_DATA;
804 break; 806 break;
805 case WMI_DATA_VI_SVC: 807 case WMI_DATA_VI_SVC:
806 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; 808
809 if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
810 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
811 else
812 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
807 /* 813 /*
808 * Disable rxdata2 directly, it will be enabled 814 * Disable rxdata2 directly, it will be enabled
809 * if FW enable rxdata2 815 * if FW enable rxdata2
@@ -811,7 +817,11 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
811 *dl_pipe = ATH6KL_USB_PIPE_RX_DATA; 817 *dl_pipe = ATH6KL_USB_PIPE_RX_DATA;
812 break; 818 break;
813 case WMI_DATA_VO_SVC: 819 case WMI_DATA_VO_SVC:
814 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_HP; 820
821 if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
822 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
823 else
824 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
815 /* 825 /*
816 * Disable rxdata2 directly, it will be enabled 826 * Disable rxdata2 directly, it will be enabled
817 * if FW enable rxdata2 827 * if FW enable rxdata2
@@ -1196,7 +1206,14 @@ static struct usb_driver ath6kl_usb_driver = {
1196 1206
1197static int ath6kl_usb_init(void) 1207static int ath6kl_usb_init(void)
1198{ 1208{
1199 usb_register(&ath6kl_usb_driver); 1209 int ret;
1210
1211 ret = usb_register(&ath6kl_usb_driver);
1212 if (ret) {
1213 ath6kl_err("usb registration failed: %d\n", ret);
1214 return ret;
1215 }
1216
1200 return 0; 1217 return 0;
1201} 1218}
1202 1219
@@ -1220,3 +1237,6 @@ MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
1220MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE); 1237MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE);
1221MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); 1238MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE);
1222MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); 1239MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE);
1240MODULE_FIRMWARE(AR6004_HW_1_3_FW_DIR "/" AR6004_HW_1_3_FIRMWARE_FILE);
1241MODULE_FIRMWARE(AR6004_HW_1_3_BOARD_DATA_FILE);
1242MODULE_FIRMWARE(AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index c30ab4b11d6..998f8b0f62f 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -474,7 +474,7 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
474 return -EINVAL; 474 return -EINVAL;
475 } 475 }
476 id = vif->last_roc_id; 476 id = vif->last_roc_id;
477 cfg80211_ready_on_channel(&vif->wdev, id, chan, NL80211_CHAN_NO_HT, 477 cfg80211_ready_on_channel(&vif->wdev, id, chan,
478 dur, GFP_ATOMIC); 478 dur, GFP_ATOMIC);
479 479
480 return 0; 480 return 0;
@@ -513,8 +513,7 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
513 else 513 else
514 id = vif->last_roc_id; /* timeout on uncanceled r-o-c */ 514 id = vif->last_roc_id; /* timeout on uncanceled r-o-c */
515 vif->last_cancel_roc_id = 0; 515 vif->last_cancel_roc_id = 0;
516 cfg80211_remain_on_channel_expired(&vif->wdev, id, chan, 516 cfg80211_remain_on_channel_expired(&vif->wdev, id, chan, GFP_ATOMIC);
517 NL80211_CHAN_NO_HT, GFP_ATOMIC);
518 517
519 return 0; 518 return 0;
520} 519}
@@ -936,8 +935,12 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
936 935
937 regpair = ath6kl_get_regpair((u16) reg_code); 936 regpair = ath6kl_get_regpair((u16) reg_code);
938 country = ath6kl_regd_find_country_by_rd((u16) reg_code); 937 country = ath6kl_regd_find_country_by_rd((u16) reg_code);
939 ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", 938 if (regpair)
940 regpair->regDmnEnum); 939 ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n",
940 regpair->regDmnEnum);
941 else
942 ath6kl_warn("Regpair not found reg_code 0x%0x\n",
943 reg_code);
941 } 944 }
942 945
943 if (country && wmi->parent_dev->wiphy_registered) { 946 if (country && wmi->parent_dev->wiphy_registered) {
@@ -1116,7 +1119,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len,
1116 * the timer would not ever fire if the scan interval is short 1119 * the timer would not ever fire if the scan interval is short
1117 * enough. 1120 * enough.
1118 */ 1121 */
1119 if (ar->state == ATH6KL_STATE_SCHED_SCAN && 1122 if (test_bit(SCHED_SCANNING, &vif->flags) &&
1120 !timer_pending(&vif->sched_scan_timer)) { 1123 !timer_pending(&vif->sched_scan_timer)) {
1121 mod_timer(&vif->sched_scan_timer, jiffies + 1124 mod_timer(&vif->sched_scan_timer, jiffies +
1122 msecs_to_jiffies(ATH6KL_SCHED_SCAN_RESULT_DELAY)); 1125 msecs_to_jiffies(ATH6KL_SCHED_SCAN_RESULT_DELAY));
@@ -1170,6 +1173,9 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
1170 rate = RATE_AUTO; 1173 rate = RATE_AUTO;
1171 } else { 1174 } else {
1172 index = reply->rate_index & 0x7f; 1175 index = reply->rate_index & 0x7f;
1176 if (WARN_ON_ONCE(index > (RATE_MCS_7_40 + 1)))
1177 return -EINVAL;
1178
1173 sgi = (reply->rate_index & 0x80) ? 1 : 0; 1179 sgi = (reply->rate_index & 0x80) ? 1 : 0;
1174 rate = wmi_rate_tbl[index][sgi]; 1180 rate = wmi_rate_tbl[index][sgi];
1175 } 1181 }
@@ -1531,6 +1537,68 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len,
1531 return 0; 1537 return 0;
1532} 1538}
1533 1539
1540static int ath6kl_wmi_txe_notify_event_rx(struct wmi *wmi, u8 *datap, int len,
1541 struct ath6kl_vif *vif)
1542{
1543 struct wmi_txe_notify_event *ev;
1544 u32 rate, pkts;
1545
1546 if (len < sizeof(*ev))
1547 return -EINVAL;
1548
1549 if (vif->sme_state != SME_CONNECTED)
1550 return -ENOTCONN;
1551
1552 ev = (struct wmi_txe_notify_event *) datap;
1553 rate = le32_to_cpu(ev->rate);
1554 pkts = le32_to_cpu(ev->pkts);
1555
1556 ath6kl_dbg(ATH6KL_DBG_WMI, "TXE notify event: peer %pM rate %d% pkts %d intvl %ds\n",
1557 vif->bssid, rate, pkts, vif->txe_intvl);
1558
1559 cfg80211_cqm_txe_notify(vif->ndev, vif->bssid, pkts,
1560 rate, vif->txe_intvl, GFP_KERNEL);
1561
1562 return 0;
1563}
1564
1565int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx,
1566 u32 rate, u32 pkts, u32 intvl)
1567{
1568 struct sk_buff *skb;
1569 struct wmi_txe_notify_cmd *cmd;
1570
1571 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1572 if (!skb)
1573 return -ENOMEM;
1574
1575 cmd = (struct wmi_txe_notify_cmd *) skb->data;
1576 cmd->rate = cpu_to_le32(rate);
1577 cmd->pkts = cpu_to_le32(pkts);
1578 cmd->intvl = cpu_to_le32(intvl);
1579
1580 return ath6kl_wmi_cmd_send(wmi, idx, skb, WMI_SET_TXE_NOTIFY_CMDID,
1581 NO_SYNC_WMIFLAG);
1582}
1583
1584int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi)
1585{
1586 struct sk_buff *skb;
1587 struct wmi_set_rssi_filter_cmd *cmd;
1588 int ret;
1589
1590 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1591 if (!skb)
1592 return -ENOMEM;
1593
1594 cmd = (struct wmi_set_rssi_filter_cmd *) skb->data;
1595 cmd->rssi = rssi;
1596
1597 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_RSSI_FILTER_CMDID,
1598 NO_SYNC_WMIFLAG);
1599 return ret;
1600}
1601
1534static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi, 1602static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi,
1535 struct wmi_snr_threshold_params_cmd *snr_cmd) 1603 struct wmi_snr_threshold_params_cmd *snr_cmd)
1536{ 1604{
@@ -1677,8 +1745,11 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb,
1677 int ret; 1745 int ret;
1678 u16 info1; 1746 u16 info1;
1679 1747
1680 if (WARN_ON(skb == NULL || (if_idx > (wmi->parent_dev->vif_max - 1)))) 1748 if (WARN_ON(skb == NULL ||
1749 (if_idx > (wmi->parent_dev->vif_max - 1)))) {
1750 dev_kfree_skb(skb);
1681 return -EINVAL; 1751 return -EINVAL;
1752 }
1682 1753
1683 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n", 1754 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n",
1684 cmd_id, skb->len, sync_flag); 1755 cmd_id, skb->len, sync_flag);
@@ -1833,6 +1904,59 @@ int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx)
1833 return ret; 1904 return ret;
1834} 1905}
1835 1906
1907/* ath6kl_wmi_start_scan_cmd is to be deprecated. Use
1908 * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P
1909 * mgmt operations using station interface.
1910 */
1911static int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx,
1912 enum wmi_scan_type scan_type,
1913 u32 force_fgscan, u32 is_legacy,
1914 u32 home_dwell_time,
1915 u32 force_scan_interval,
1916 s8 num_chan, u16 *ch_list)
1917{
1918 struct sk_buff *skb;
1919 struct wmi_start_scan_cmd *sc;
1920 s8 size;
1921 int i, ret;
1922
1923 size = sizeof(struct wmi_start_scan_cmd);
1924
1925 if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
1926 return -EINVAL;
1927
1928 if (num_chan > WMI_MAX_CHANNELS)
1929 return -EINVAL;
1930
1931 if (num_chan)
1932 size += sizeof(u16) * (num_chan - 1);
1933
1934 skb = ath6kl_wmi_get_new_buf(size);
1935 if (!skb)
1936 return -ENOMEM;
1937
1938 sc = (struct wmi_start_scan_cmd *) skb->data;
1939 sc->scan_type = scan_type;
1940 sc->force_fg_scan = cpu_to_le32(force_fgscan);
1941 sc->is_legacy = cpu_to_le32(is_legacy);
1942 sc->home_dwell_time = cpu_to_le32(home_dwell_time);
1943 sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
1944 sc->num_ch = num_chan;
1945
1946 for (i = 0; i < num_chan; i++)
1947 sc->ch_list[i] = cpu_to_le16(ch_list[i]);
1948
1949 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID,
1950 NO_SYNC_WMIFLAG);
1951
1952 return ret;
1953}
1954
1955/*
1956 * beginscan supports (compared to old startscan) P2P mgmt operations using
1957 * station interface, send additional information like supported rates to
1958 * advertise and xmit rates for probe requests
1959 */
1836int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, 1960int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
1837 enum wmi_scan_type scan_type, 1961 enum wmi_scan_type scan_type,
1838 u32 force_fgscan, u32 is_legacy, 1962 u32 force_fgscan, u32 is_legacy,
@@ -1848,6 +1972,15 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
1848 int num_rates; 1972 int num_rates;
1849 u32 ratemask; 1973 u32 ratemask;
1850 1974
1975 if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
1976 ar->fw_capabilities)) {
1977 return ath6kl_wmi_startscan_cmd(wmi, if_idx,
1978 scan_type, force_fgscan,
1979 is_legacy, home_dwell_time,
1980 force_scan_interval,
1981 num_chan, ch_list);
1982 }
1983
1851 size = sizeof(struct wmi_begin_scan_cmd); 1984 size = sizeof(struct wmi_begin_scan_cmd);
1852 1985
1853 if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) 1986 if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
@@ -1900,50 +2033,24 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
1900 return ret; 2033 return ret;
1901} 2034}
1902 2035
1903/* ath6kl_wmi_start_scan_cmd is to be deprecated. Use 2036int ath6kl_wmi_enable_sched_scan_cmd(struct wmi *wmi, u8 if_idx, bool enable)
1904 * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P
1905 * mgmt operations using station interface.
1906 */
1907int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx,
1908 enum wmi_scan_type scan_type,
1909 u32 force_fgscan, u32 is_legacy,
1910 u32 home_dwell_time, u32 force_scan_interval,
1911 s8 num_chan, u16 *ch_list)
1912{ 2037{
1913 struct sk_buff *skb; 2038 struct sk_buff *skb;
1914 struct wmi_start_scan_cmd *sc; 2039 struct wmi_enable_sched_scan_cmd *sc;
1915 s8 size; 2040 int ret;
1916 int i, ret;
1917
1918 size = sizeof(struct wmi_start_scan_cmd);
1919
1920 if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
1921 return -EINVAL;
1922
1923 if (num_chan > WMI_MAX_CHANNELS)
1924 return -EINVAL;
1925
1926 if (num_chan)
1927 size += sizeof(u16) * (num_chan - 1);
1928 2041
1929 skb = ath6kl_wmi_get_new_buf(size); 2042 skb = ath6kl_wmi_get_new_buf(sizeof(*sc));
1930 if (!skb) 2043 if (!skb)
1931 return -ENOMEM; 2044 return -ENOMEM;
1932 2045
1933 sc = (struct wmi_start_scan_cmd *) skb->data; 2046 ath6kl_dbg(ATH6KL_DBG_WMI, "%s scheduled scan on vif %d\n",
1934 sc->scan_type = scan_type; 2047 enable ? "enabling" : "disabling", if_idx);
1935 sc->force_fg_scan = cpu_to_le32(force_fgscan); 2048 sc = (struct wmi_enable_sched_scan_cmd *) skb->data;
1936 sc->is_legacy = cpu_to_le32(is_legacy); 2049 sc->enable = enable ? 1 : 0;
1937 sc->home_dwell_time = cpu_to_le32(home_dwell_time);
1938 sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
1939 sc->num_ch = num_chan;
1940
1941 for (i = 0; i < num_chan; i++)
1942 sc->ch_list[i] = cpu_to_le16(ch_list[i]);
1943 2050
1944 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID, 2051 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
2052 WMI_ENABLE_SCHED_SCAN_CMDID,
1945 NO_SYNC_WMIFLAG); 2053 NO_SYNC_WMIFLAG);
1946
1947 return ret; 2054 return ret;
1948} 2055}
1949 2056
@@ -2275,8 +2382,10 @@ static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb,
2275 struct wmi_data_hdr *data_hdr; 2382 struct wmi_data_hdr *data_hdr;
2276 int ret; 2383 int ret;
2277 2384
2278 if (WARN_ON(skb == NULL || ep_id == wmi->ep_id)) 2385 if (WARN_ON(skb == NULL || ep_id == wmi->ep_id)) {
2386 dev_kfree_skb(skb);
2279 return -EINVAL; 2387 return -EINVAL;
2388 }
2280 2389
2281 skb_push(skb, sizeof(struct wmi_data_hdr)); 2390 skb_push(skb, sizeof(struct wmi_data_hdr));
2282 2391
@@ -2313,10 +2422,8 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
2313 spin_unlock_bh(&wmi->lock); 2422 spin_unlock_bh(&wmi->lock);
2314 2423
2315 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); 2424 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2316 if (!skb) { 2425 if (!skb)
2317 ret = -ENOMEM; 2426 return -ENOMEM;
2318 goto free_skb;
2319 }
2320 2427
2321 cmd = (struct wmi_sync_cmd *) skb->data; 2428 cmd = (struct wmi_sync_cmd *) skb->data;
2322 2429
@@ -2339,7 +2446,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
2339 * then do not send the Synchronize cmd on the control ep 2446 * then do not send the Synchronize cmd on the control ep
2340 */ 2447 */
2341 if (ret) 2448 if (ret)
2342 goto free_skb; 2449 goto free_cmd_skb;
2343 2450
2344 /* 2451 /*
2345 * Send sync cmd followed by sync data messages on all 2452 * Send sync cmd followed by sync data messages on all
@@ -2349,15 +2456,12 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
2349 NO_SYNC_WMIFLAG); 2456 NO_SYNC_WMIFLAG);
2350 2457
2351 if (ret) 2458 if (ret)
2352 goto free_skb; 2459 goto free_data_skb;
2353
2354 /* cmd buffer sent, we no longer own it */
2355 skb = NULL;
2356 2460
2357 for (index = 0; index < num_pri_streams; index++) { 2461 for (index = 0; index < num_pri_streams; index++) {
2358 2462
2359 if (WARN_ON(!data_sync_bufs[index].skb)) 2463 if (WARN_ON(!data_sync_bufs[index].skb))
2360 break; 2464 goto free_data_skb;
2361 2465
2362 ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, 2466 ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev,
2363 data_sync_bufs[index]. 2467 data_sync_bufs[index].
@@ -2366,17 +2470,20 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
2366 ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb, 2470 ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb,
2367 ep_id, if_idx); 2471 ep_id, if_idx);
2368 2472
2369 if (ret)
2370 break;
2371
2372 data_sync_bufs[index].skb = NULL; 2473 data_sync_bufs[index].skb = NULL;
2474
2475 if (ret)
2476 goto free_data_skb;
2373 } 2477 }
2374 2478
2375free_skb: 2479 return 0;
2480
2481free_cmd_skb:
2376 /* free up any resources left over (possibly due to an error) */ 2482 /* free up any resources left over (possibly due to an error) */
2377 if (skb) 2483 if (skb)
2378 dev_kfree_skb(skb); 2484 dev_kfree_skb(skb);
2379 2485
2486free_data_skb:
2380 for (index = 0; index < num_pri_streams; index++) { 2487 for (index = 0; index < num_pri_streams; index++) {
2381 if (data_sync_bufs[index].skb != NULL) { 2488 if (data_sync_bufs[index].skb != NULL) {
2382 dev_kfree_skb((struct sk_buff *)data_sync_bufs[index]. 2489 dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].
@@ -2618,11 +2725,13 @@ static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx,
2618{ 2725{
2619 struct sk_buff *skb; 2726 struct sk_buff *skb;
2620 int ret, mode, band; 2727 int ret, mode, band;
2621 u64 mcsrate, ratemask[IEEE80211_NUM_BANDS]; 2728 u64 mcsrate, ratemask[ATH6KL_NUM_BANDS];
2622 struct wmi_set_tx_select_rates64_cmd *cmd; 2729 struct wmi_set_tx_select_rates64_cmd *cmd;
2623 2730
2624 memset(&ratemask, 0, sizeof(ratemask)); 2731 memset(&ratemask, 0, sizeof(ratemask));
2625 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 2732
2733 /* only check 2.4 and 5 GHz bands, skip the rest */
2734 for (band = 0; band <= IEEE80211_BAND_5GHZ; band++) {
2626 /* copy legacy rate mask */ 2735 /* copy legacy rate mask */
2627 ratemask[band] = mask->control[band].legacy; 2736 ratemask[band] = mask->control[band].legacy;
2628 if (band == IEEE80211_BAND_5GHZ) 2737 if (band == IEEE80211_BAND_5GHZ)
@@ -2668,11 +2777,13 @@ static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx,
2668{ 2777{
2669 struct sk_buff *skb; 2778 struct sk_buff *skb;
2670 int ret, mode, band; 2779 int ret, mode, band;
2671 u32 mcsrate, ratemask[IEEE80211_NUM_BANDS]; 2780 u32 mcsrate, ratemask[ATH6KL_NUM_BANDS];
2672 struct wmi_set_tx_select_rates32_cmd *cmd; 2781 struct wmi_set_tx_select_rates32_cmd *cmd;
2673 2782
2674 memset(&ratemask, 0, sizeof(ratemask)); 2783 memset(&ratemask, 0, sizeof(ratemask));
2675 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 2784
2785 /* only check 2.4 and 5 GHz bands, skip the rest */
2786 for (band = 0; band <= IEEE80211_BAND_5GHZ; band++) {
2676 /* copy legacy rate mask */ 2787 /* copy legacy rate mask */
2677 ratemask[band] = mask->control[band].legacy; 2788 ratemask[band] = mask->control[band].legacy;
2678 if (band == IEEE80211_BAND_5GHZ) 2789 if (band == IEEE80211_BAND_5GHZ)
@@ -2716,7 +2827,7 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
2716{ 2827{
2717 struct ath6kl *ar = wmi->parent_dev; 2828 struct ath6kl *ar = wmi->parent_dev;
2718 2829
2719 if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) 2830 if (ar->hw.flags & ATH6KL_HW_64BIT_RATES)
2720 return ath6kl_set_bitrate_mask64(wmi, if_idx, mask); 2831 return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
2721 else 2832 else
2722 return ath6kl_set_bitrate_mask32(wmi, if_idx, mask); 2833 return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
@@ -3139,12 +3250,40 @@ int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance)
3139 return ret; 3250 return ret;
3140} 3251}
3141 3252
3253int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2)
3254{
3255 struct sk_buff *skb;
3256 struct wmi_set_regdomain_cmd *cmd;
3257
3258 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
3259 if (!skb)
3260 return -ENOMEM;
3261
3262 cmd = (struct wmi_set_regdomain_cmd *) skb->data;
3263 memcpy(cmd->iso_name, alpha2, 2);
3264
3265 return ath6kl_wmi_cmd_send(wmi, 0, skb,
3266 WMI_SET_REGDOMAIN_CMDID,
3267 NO_SYNC_WMIFLAG);
3268}
3269
3142s32 ath6kl_wmi_get_rate(s8 rate_index) 3270s32 ath6kl_wmi_get_rate(s8 rate_index)
3143{ 3271{
3272 u8 sgi = 0;
3273
3144 if (rate_index == RATE_AUTO) 3274 if (rate_index == RATE_AUTO)
3145 return 0; 3275 return 0;
3146 3276
3147 return wmi_rate_tbl[(u32) rate_index][0]; 3277 /* SGI is stored as the MSB of the rate_index */
3278 if (rate_index & RATE_INDEX_MSB) {
3279 rate_index &= RATE_INDEX_WITHOUT_SGI_MASK;
3280 sgi = 1;
3281 }
3282
3283 if (WARN_ON(rate_index > RATE_MCS_7_40))
3284 rate_index = RATE_MCS_7_40;
3285
3286 return wmi_rate_tbl[(u32) rate_index][sgi];
3148} 3287}
3149 3288
3150static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap, 3289static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
@@ -3634,6 +3773,19 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout)
3634 NO_SYNC_WMIFLAG); 3773 NO_SYNC_WMIFLAG);
3635} 3774}
3636 3775
3776static void ath6kl_wmi_hb_challenge_resp_event(struct wmi *wmi, u8 *datap,
3777 int len)
3778{
3779 struct wmix_hb_challenge_resp_cmd *cmd;
3780
3781 if (len < sizeof(struct wmix_hb_challenge_resp_cmd))
3782 return;
3783
3784 cmd = (struct wmix_hb_challenge_resp_cmd *) datap;
3785 ath6kl_recovery_hb_event(wmi->parent_dev,
3786 le32_to_cpu(cmd->cookie));
3787}
3788
3637static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) 3789static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
3638{ 3790{
3639 struct wmix_cmd_hdr *cmd; 3791 struct wmix_cmd_hdr *cmd;
@@ -3658,6 +3810,7 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
3658 switch (id) { 3810 switch (id) {
3659 case WMIX_HB_CHALLENGE_RESP_EVENTID: 3811 case WMIX_HB_CHALLENGE_RESP_EVENTID:
3660 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event hb challenge resp\n"); 3812 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event hb challenge resp\n");
3813 ath6kl_wmi_hb_challenge_resp_event(wmi, datap, len);
3661 break; 3814 break;
3662 case WMIX_DBGLOG_EVENTID: 3815 case WMIX_DBGLOG_EVENTID:
3663 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event dbglog len %d\n", len); 3816 ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event dbglog len %d\n", len);
@@ -3750,6 +3903,9 @@ static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id,
3750 case WMI_RX_ACTION_EVENTID: 3903 case WMI_RX_ACTION_EVENTID:
3751 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); 3904 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
3752 return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); 3905 return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif);
3906 case WMI_TXE_NOTIFY_EVENTID:
3907 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TXE_NOTIFY_EVENTID\n");
3908 return ath6kl_wmi_txe_notify_event_rx(wmi, datap, len, vif);
3753 default: 3909 default:
3754 ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id); 3910 ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id);
3755 return -EINVAL; 3911 return -EINVAL;
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 43339aca585..98b1755e67f 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -48,7 +48,7 @@
48 48
49#define A_BAND_24GHZ 0 49#define A_BAND_24GHZ 0
50#define A_BAND_5GHZ 1 50#define A_BAND_5GHZ 1
51#define A_NUM_BANDS 2 51#define ATH6KL_NUM_BANDS 2
52 52
53/* in ms */ 53/* in ms */
54#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 54#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000
@@ -628,6 +628,20 @@ enum wmi_cmd_id {
628 WMI_SET_MCASTRATE, 628 WMI_SET_MCASTRATE,
629 629
630 WMI_STA_BMISS_ENHANCE_CMDID, 630 WMI_STA_BMISS_ENHANCE_CMDID,
631
632 WMI_SET_REGDOMAIN_CMDID,
633
634 WMI_SET_RSSI_FILTER_CMDID,
635
636 WMI_SET_KEEP_ALIVE_EXT,
637
638 WMI_VOICE_DETECTION_ENABLE_CMDID,
639
640 WMI_SET_TXE_NOTIFY_CMDID,
641
642 WMI_SET_RECOVERY_TEST_PARAMETER_CMDID, /*0xf094*/
643
644 WMI_ENABLE_SCHED_SCAN_CMDID,
631}; 645};
632 646
633enum wmi_mgmt_frame_type { 647enum wmi_mgmt_frame_type {
@@ -843,7 +857,7 @@ struct wmi_begin_scan_cmd {
843 u8 scan_type; 857 u8 scan_type;
844 858
845 /* Supported rates to advertise in the probe request frames */ 859 /* Supported rates to advertise in the probe request frames */
846 struct wmi_supp_rates supp_rates[IEEE80211_NUM_BANDS]; 860 struct wmi_supp_rates supp_rates[ATH6KL_NUM_BANDS];
847 861
848 /* how many channels follow */ 862 /* how many channels follow */
849 u8 num_ch; 863 u8 num_ch;
@@ -941,6 +955,11 @@ struct wmi_scan_params_cmd {
941 __le32 max_dfsch_act_time; 955 __le32 max_dfsch_act_time;
942} __packed; 956} __packed;
943 957
958/* WMI_ENABLE_SCHED_SCAN_CMDID */
959struct wmi_enable_sched_scan_cmd {
960 u8 enable;
961} __packed;
962
944/* WMI_SET_BSS_FILTER_CMDID */ 963/* WMI_SET_BSS_FILTER_CMDID */
945enum wmi_bss_filter { 964enum wmi_bss_filter {
946 /* no beacons forwarded */ 965 /* no beacons forwarded */
@@ -1032,6 +1051,11 @@ struct wmi_sta_bmiss_enhance_cmd {
1032 u8 enable; 1051 u8 enable;
1033} __packed; 1052} __packed;
1034 1053
1054struct wmi_set_regdomain_cmd {
1055 u8 length;
1056 u8 iso_name[2];
1057} __packed;
1058
1035/* WMI_SET_POWER_MODE_CMDID */ 1059/* WMI_SET_POWER_MODE_CMDID */
1036enum wmi_power_mode { 1060enum wmi_power_mode {
1037 REC_POWER = 0x01, 1061 REC_POWER = 0x01,
@@ -1276,6 +1300,11 @@ struct wmi_snr_threshold_params_cmd {
1276 u8 reserved[3]; 1300 u8 reserved[3];
1277} __packed; 1301} __packed;
1278 1302
1303/* Don't report BSSs with signal (RSSI) below this threshold */
1304struct wmi_set_rssi_filter_cmd {
1305 s8 rssi;
1306} __packed;
1307
1279enum wmi_preamble_policy { 1308enum wmi_preamble_policy {
1280 WMI_IGNORE_BARKER_IN_ERP = 0, 1309 WMI_IGNORE_BARKER_IN_ERP = 0,
1281 WMI_FOLLOW_BARKER_IN_ERP, 1310 WMI_FOLLOW_BARKER_IN_ERP,
@@ -1455,6 +1484,20 @@ enum wmi_event_id {
1455 WMI_P2P_CAPABILITIES_EVENTID, 1484 WMI_P2P_CAPABILITIES_EVENTID,
1456 WMI_RX_ACTION_EVENTID, 1485 WMI_RX_ACTION_EVENTID,
1457 WMI_P2P_INFO_EVENTID, 1486 WMI_P2P_INFO_EVENTID,
1487
1488 /* WPS Events */
1489 WMI_WPS_GET_STATUS_EVENTID,
1490 WMI_WPS_PROFILE_EVENTID,
1491
1492 /* more P2P events */
1493 WMI_NOA_INFO_EVENTID,
1494 WMI_OPPPS_INFO_EVENTID,
1495 WMI_PORT_STATUS_EVENTID,
1496
1497 /* 802.11w */
1498 WMI_GET_RSN_CAP_EVENTID,
1499
1500 WMI_TXE_NOTIFY_EVENTID,
1458}; 1501};
1459 1502
1460struct wmi_ready_event_2 { 1503struct wmi_ready_event_2 {
@@ -1749,6 +1792,9 @@ struct rx_stats {
1749 a_sle32 ucast_rate; 1792 a_sle32 ucast_rate;
1750} __packed; 1793} __packed;
1751 1794
1795#define RATE_INDEX_WITHOUT_SGI_MASK 0x7f
1796#define RATE_INDEX_MSB 0x80
1797
1752struct tkip_ccmp_stats { 1798struct tkip_ccmp_stats {
1753 __le32 tkip_local_mic_fail; 1799 __le32 tkip_local_mic_fail;
1754 __le32 tkip_cnter_measures_invoked; 1800 __le32 tkip_cnter_measures_invoked;
@@ -2019,7 +2065,6 @@ struct wmi_set_ie_cmd {
2019 2065
2020#define WOW_MAX_FILTERS_PER_LIST 4 2066#define WOW_MAX_FILTERS_PER_LIST 4
2021#define WOW_PATTERN_SIZE 64 2067#define WOW_PATTERN_SIZE 64
2022#define WOW_MASK_SIZE 64
2023 2068
2024#define MAC_MAX_FILTERS_PER_LIST 4 2069#define MAC_MAX_FILTERS_PER_LIST 4
2025 2070
@@ -2028,7 +2073,7 @@ struct wow_filter {
2028 u8 wow_filter_id; 2073 u8 wow_filter_id;
2029 u8 wow_filter_size; 2074 u8 wow_filter_size;
2030 u8 wow_filter_offset; 2075 u8 wow_filter_offset;
2031 u8 wow_filter_mask[WOW_MASK_SIZE]; 2076 u8 wow_filter_mask[WOW_PATTERN_SIZE];
2032 u8 wow_filter_pattern[WOW_PATTERN_SIZE]; 2077 u8 wow_filter_pattern[WOW_PATTERN_SIZE];
2033} __packed; 2078} __packed;
2034 2079
@@ -2087,6 +2132,19 @@ struct wmi_del_wow_pattern_cmd {
2087 __le16 filter_id; 2132 __le16 filter_id;
2088} __packed; 2133} __packed;
2089 2134
2135/* WMI_SET_TXE_NOTIFY_CMDID */
2136struct wmi_txe_notify_cmd {
2137 __le32 rate;
2138 __le32 pkts;
2139 __le32 intvl;
2140} __packed;
2141
2142/* WMI_TXE_NOTIFY_EVENTID */
2143struct wmi_txe_notify_event {
2144 __le32 rate;
2145 __le32 pkts;
2146} __packed;
2147
2090/* WMI_SET_AKMP_PARAMS_CMD */ 2148/* WMI_SET_AKMP_PARAMS_CMD */
2091 2149
2092struct wmi_pmkid { 2150struct wmi_pmkid {
@@ -2505,11 +2563,6 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx,
2505int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid, 2563int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid,
2506 u16 channel); 2564 u16 channel);
2507int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx); 2565int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx);
2508int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx,
2509 enum wmi_scan_type scan_type,
2510 u32 force_fgscan, u32 is_legacy,
2511 u32 home_dwell_time, u32 force_scan_interval,
2512 s8 num_chan, u16 *ch_list);
2513 2566
2514int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, 2567int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
2515 enum wmi_scan_type scan_type, 2568 enum wmi_scan_type scan_type,
@@ -2517,6 +2570,7 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
2517 u32 home_dwell_time, u32 force_scan_interval, 2570 u32 home_dwell_time, u32 force_scan_interval,
2518 s8 num_chan, u16 *ch_list, u32 no_cck, 2571 s8 num_chan, u16 *ch_list, u32 no_cck,
2519 u32 *rates); 2572 u32 *rates);
2573int ath6kl_wmi_enable_sched_scan_cmd(struct wmi *wmi, u8 if_idx, bool enable);
2520 2574
2521int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec, 2575int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec,
2522 u16 fg_end_sec, u16 bg_sec, 2576 u16 fg_end_sec, u16 bg_sec,
@@ -2592,6 +2646,7 @@ int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
2592 const u8 *mask); 2646 const u8 *mask);
2593int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, 2647int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
2594 u16 list_id, u16 filter_id); 2648 u16 list_id, u16 filter_id);
2649int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi);
2595int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); 2650int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
2596int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period); 2651int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period);
2597int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); 2652int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
@@ -2600,6 +2655,9 @@ int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
2600int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, 2655int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
2601 u8 *filter, bool add_filter); 2656 u8 *filter, bool add_filter);
2602int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable); 2657int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable);
2658int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx,
2659 u32 rate, u32 pkts, u32 intvl);
2660int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2);
2603 2661
2604/* AP mode uAPSD */ 2662/* AP mode uAPSD */
2605int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); 2663int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
@@ -2658,6 +2716,8 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout);
2658 2716
2659void ath6kl_wmi_sscan_timer(unsigned long ptr); 2717void ath6kl_wmi_sscan_timer(unsigned long ptr);
2660 2718
2719int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
2720
2661struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx); 2721struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx);
2662void *ath6kl_wmi_init(struct ath6kl *devt); 2722void *ath6kl_wmi_init(struct ath6kl *devt);
2663void ath6kl_wmi_shutdown(struct wmi *wmi); 2723void ath6kl_wmi_shutdown(struct wmi *wmi);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 162401f22f8..8b0d8dcd762 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -891,6 +891,74 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
891 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 891 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
892} 892}
893 893
894static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
895{
896 int offset[8], total = 0, test;
897 int agc_out, i;
898
899 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
900 AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1);
901 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
902 AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0);
903 if (is_2g)
904 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
905 AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0);
906 else
907 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
908 AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0);
909
910 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
911 AR_PHY_65NM_RXTX2_RXON_OVR, 0x1);
912 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
913 AR_PHY_65NM_RXTX2_RXON, 0x0);
914
915 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
916 AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
917 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
918 AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1);
919 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
920 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1);
921 if (is_2g)
922 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
923 AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0);
924 else
925 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
926 AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0);
927
928 for (i = 6; i > 0; i--) {
929 offset[i] = BIT(i - 1);
930 test = total + offset[i];
931
932 if (is_2g)
933 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
934 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
935 test);
936 else
937 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
938 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
939 test);
940 udelay(100);
941 agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
942 AR_PHY_65NM_RXRF_AGC_AGC_OUT);
943 offset[i] = (agc_out) ? 0 : 1;
944 total += (offset[i] << (i - 1));
945 }
946
947 if (is_2g)
948 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
949 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total);
950 else
951 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
952 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total);
953
954 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
955 AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0);
956 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
957 AR_PHY_65NM_RXTX2_RXON_OVR, 0);
958 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
959 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
960}
961
894static bool ar9003_hw_init_cal(struct ath_hw *ah, 962static bool ar9003_hw_init_cal(struct ath_hw *ah,
895 struct ath9k_channel *chan) 963 struct ath9k_channel *chan)
896{ 964{
@@ -989,6 +1057,14 @@ skip_tx_iqcal:
989 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, 1057 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
990 AR_PHY_AGC_CONTROL_CAL, 1058 AR_PHY_AGC_CONTROL_CAL,
991 0, AH_WAIT_TIMEOUT); 1059 0, AH_WAIT_TIMEOUT);
1060 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
1061 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1062 if (!(ah->rxchainmask & (1 << i)))
1063 continue;
1064 ar9003_hw_manual_peak_cal(ah, i,
1065 IS_CHAN_2GHZ(chan));
1066 }
1067 }
992 } 1068 }
993 1069
994 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) 1070 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 0693cd95b74..74fd3977fee 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -35,12 +35,6 @@
35 */ 35 */
36static void ar9003_hw_init_mode_regs(struct ath_hw *ah) 36static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
37{ 37{
38#define AR9462_BB_CTX_COEFJ(x) \
39 ar9462_##x##_baseband_core_txfir_coeff_japan_2484
40
41#define AR9462_BBC_TXIFR_COEFFJ \
42 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
43
44 if (AR_SREV_9330_11(ah)) { 38 if (AR_SREV_9330_11(ah)) {
45 /* mac */ 39 /* mac */
46 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], 40 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
@@ -70,6 +64,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
70 INIT_INI_ARRAY(&ah->iniModesTxGain, 64 INIT_INI_ARRAY(&ah->iniModesTxGain,
71 ar9331_modes_lowest_ob_db_tx_gain_1p1); 65 ar9331_modes_lowest_ob_db_tx_gain_1p1);
72 66
67 /* Japan 2484 Mhz CCK */
68 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
69 ar9331_1p1_baseband_core_txfir_coeff_japan_2484);
70
73 /* additional clock settings */ 71 /* additional clock settings */
74 if (ah->is_clk_25mhz) 72 if (ah->is_clk_25mhz)
75 INIT_INI_ARRAY(&ah->iniAdditional, 73 INIT_INI_ARRAY(&ah->iniAdditional,
@@ -106,6 +104,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
106 INIT_INI_ARRAY(&ah->iniModesTxGain, 104 INIT_INI_ARRAY(&ah->iniModesTxGain,
107 ar9331_modes_lowest_ob_db_tx_gain_1p2); 105 ar9331_modes_lowest_ob_db_tx_gain_1p2);
108 106
107 /* Japan 2484 Mhz CCK */
108 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
109 ar9331_1p2_baseband_core_txfir_coeff_japan_2484);
110
109 /* additional clock settings */ 111 /* additional clock settings */
110 if (ah->is_clk_25mhz) 112 if (ah->is_clk_25mhz)
111 INIT_INI_ARRAY(&ah->iniAdditional, 113 INIT_INI_ARRAY(&ah->iniAdditional,
@@ -180,6 +182,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
180 INIT_INI_ARRAY(&ah->iniModesTxGain, 182 INIT_INI_ARRAY(&ah->iniModesTxGain,
181 ar9485_modes_lowest_ob_db_tx_gain_1_1); 183 ar9485_modes_lowest_ob_db_tx_gain_1_1);
182 184
185 /* Japan 2484 Mhz CCK */
186 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
187 ar9485_1_1_baseband_core_txfir_coeff_japan_2484);
188
183 /* Load PCIE SERDES settings from INI */ 189 /* Load PCIE SERDES settings from INI */
184 190
185 /* Awake Setting */ 191 /* Awake Setting */
@@ -229,9 +235,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
229 ar9462_modes_fast_clock_2p0); 235 ar9462_modes_fast_clock_2p0);
230 236
231 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 237 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
232 AR9462_BB_CTX_COEFJ(2p0)); 238 ar9462_2p0_baseband_core_txfir_coeff_japan_2484);
233
234 INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ);
235 } else if (AR_SREV_9550(ah)) { 239 } else if (AR_SREV_9550(ah)) {
236 /* mac */ 240 /* mac */
237 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], 241 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index 42b4412d679..8dd069259e7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
@@ -714,7 +714,6 @@ bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan)
714 714
715 return true; 715 return true;
716} 716}
717EXPORT_SYMBOL(ar9003_mci_start_reset);
718 717
719int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, 718int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
720 struct ath9k_hw_cal_data *caldata) 719 struct ath9k_hw_cal_data *caldata)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 759f5f5a715..ce19c09fa8e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -784,7 +784,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
784 REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); 784 REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites);
785 785
786 if (chan->channel == 2484) 786 if (chan->channel == 2484)
787 ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); 787 ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1);
788 788
789 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) 789 if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
790 REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, 790 REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 8f585233a78..4c3d06de711 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -698,13 +698,6 @@
698#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00 698#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00
699#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8 699#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8
700 700
701#define AR_PHY_65NM_CH0_RXTX1 0x16100
702#define AR_PHY_65NM_CH0_RXTX2 0x16104
703#define AR_PHY_65NM_CH1_RXTX1 0x16500
704#define AR_PHY_65NM_CH1_RXTX2 0x16504
705#define AR_PHY_65NM_CH2_RXTX1 0x16900
706#define AR_PHY_65NM_CH2_RXTX2 0x16904
707
708#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ 701#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \
709 (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) 702 (AR_SREV_9462(ah) ? 0x16290 : 0x16284))
710#define AR_CH0_TOP2_XPABIASLVL 0xf000 703#define AR_CH0_TOP2_XPABIASLVL 0xf000
@@ -1286,4 +1279,43 @@
1286#define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD 0xFC000000 1279#define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD 0xFC000000
1287#define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD_S 26 1280#define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD_S 26
1288 1281
1282/* Manual Peak detector calibration */
1283#define AR_PHY_65NM_BASE 0x16000
1284#define AR_PHY_65NM_RXRF_GAINSTAGES(i) (AR_PHY_65NM_BASE + \
1285 (i * 0x400) + 0x8)
1286#define AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE 0x80000000
1287#define AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE_S 31
1288#define AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC 0x00000002
1289#define AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC_S 1
1290#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR 0x70000000
1291#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_S 28
1292#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR 0x03800000
1293#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_S 23
1294
1295#define AR_PHY_65NM_RXTX2(i) (AR_PHY_65NM_BASE + \
1296 (i * 0x400) + 0x104)
1297#define AR_PHY_65NM_RXTX2_RXON_OVR 0x00001000
1298#define AR_PHY_65NM_RXTX2_RXON_OVR_S 12
1299#define AR_PHY_65NM_RXTX2_RXON 0x00000800
1300#define AR_PHY_65NM_RXTX2_RXON_S 11
1301
1302#define AR_PHY_65NM_RXRF_AGC(i) (AR_PHY_65NM_BASE + \
1303 (i * 0x400) + 0xc)
1304#define AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE 0x80000000
1305#define AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE_S 31
1306#define AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR 0x40000000
1307#define AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR_S 30
1308#define AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR 0x20000000
1309#define AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR_S 29
1310#define AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR 0x1E000000
1311#define AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR_S 25
1312#define AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR 0x00078000
1313#define AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR_S 15
1314#define AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR 0x01F80000
1315#define AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR_S 19
1316#define AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR 0x00007e00
1317#define AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR_S 9
1318#define AR_PHY_65NM_RXRF_AGC_AGC_OUT 0x00000004
1319#define AR_PHY_65NM_RXRF_AGC_AGC_OUT_S 2
1320
1289#endif /* AR9003_PHY_H */ 1321#endif /* AR9003_PHY_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index 58f30f65c6b..ccc42a71b43 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -78,7 +78,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
78 {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, 78 {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
79 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, 79 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
80 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, 80 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
81 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 81 {0x0000a2c4, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18},
82 {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, 82 {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
83 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, 83 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
84 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 84 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
index fb4497fc7a3..a3710f3bb90 100644
--- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
@@ -18,7 +18,7 @@
18#ifndef INITVALS_9485_H 18#ifndef INITVALS_9485_H
19#define INITVALS_9485_H 19#define INITVALS_9485_H
20 20
21/* AR9485 1.0 */ 21/* AR9485 1.1 */
22 22
23#define ar9485_1_1_mac_postamble ar9300_2p2_mac_postamble 23#define ar9485_1_1_mac_postamble ar9300_2p2_mac_postamble
24 24
@@ -31,6 +31,11 @@ static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
31 31
32static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { 32static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = {
33 /* Addr allmodes */ 33 /* Addr allmodes */
34 {0x00009e00, 0x037216a0},
35 {0x00009e04, 0x00182020},
36 {0x00009e18, 0x00000000},
37 {0x00009e2c, 0x00004121},
38 {0x00009e44, 0x02282324},
34 {0x0000a000, 0x00060005}, 39 {0x0000a000, 0x00060005},
35 {0x0000a004, 0x00810080}, 40 {0x0000a004, 0x00810080},
36 {0x0000a008, 0x00830082}, 41 {0x0000a008, 0x00830082},
@@ -164,6 +169,11 @@ static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = {
164static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { 169static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
165 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 170 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
166 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 171 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
172 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a},
173 {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
174 {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
175 {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
176 {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
167 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, 177 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
168 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 178 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
169 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, 179 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
@@ -198,6 +208,22 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
198 {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, 208 {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
199 {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, 209 {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
200 {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, 210 {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
211 {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
212 {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
213 {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
214 {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
215 {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
216 {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
217 {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501},
218 {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
219 {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
220 {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803},
221 {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04},
222 {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
223 {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
224 {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
225 {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
226 {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
201 {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 227 {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
202 {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 228 {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
203 {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 229 {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -234,9 +260,193 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
234 {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, 260 {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
235}; 261};
236 262
237#define ar9485Modes_high_ob_db_tx_gain_1_1 ar9485Modes_high_power_tx_gain_1_1 263static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
264 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
265 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
266 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a},
267 {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
268 {0x0000a2e0, 0x00000000, 0x00000000, 0xffc63a84, 0xffc63a84},
269 {0x0000a2e4, 0x00000000, 0x00000000, 0xfe0fc000, 0xfe0fc000},
270 {0x0000a2e8, 0x00000000, 0x00000000, 0xfff00000, 0xfff00000},
271 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
272 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
273 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
274 {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
275 {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
276 {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
277 {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
278 {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
279 {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
280 {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
281 {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
282 {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
283 {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
284 {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
285 {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
286 {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
287 {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
288 {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
289 {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
290 {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
291 {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
292 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
293 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
294 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
295 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
296 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
297 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
298 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
299 {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
300 {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
301 {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
302 {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
303 {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
304 {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
305 {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
306 {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
307 {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
308 {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
309 {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
310 {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
311 {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501},
312 {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
313 {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
314 {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803},
315 {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04},
316 {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
317 {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
318 {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
319 {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
320 {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
321 {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
322 {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
323 {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
324 {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
325 {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
326 {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
327 {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
328 {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
329 {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
330 {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
331 {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
332 {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
333 {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
334 {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
335 {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
336 {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
337 {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
338 {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
339 {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
340 {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
341 {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
342 {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
343 {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
344 {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
345 {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
346 {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
347 {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
348 {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
349 {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
350 {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
351 {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
352 {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
353 {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
354 {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
355};
238 356
239#define ar9485Modes_low_ob_db_tx_gain_1_1 ar9485Modes_high_ob_db_tx_gain_1_1 357static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
358 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
359 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
360 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a},
361 {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
362 {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
363 {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
364 {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
365 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
366 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
367 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
368 {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
369 {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
370 {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
371 {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
372 {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
373 {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
374 {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
375 {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
376 {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
377 {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
378 {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
379 {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
380 {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
381 {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
382 {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
383 {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
384 {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
385 {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
386 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
387 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
388 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
389 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
390 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
391 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
392 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
393 {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
394 {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
395 {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
396 {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
397 {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
398 {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
399 {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
400 {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
401 {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
402 {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
403 {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
404 {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
405 {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501},
406 {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
407 {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
408 {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803},
409 {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04},
410 {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
411 {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
412 {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
413 {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
414 {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
415 {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
416 {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
417 {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
418 {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
419 {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
420 {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
421 {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
422 {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
423 {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
424 {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
425 {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
426 {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
427 {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
428 {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
429 {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
430 {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
431 {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
432 {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
433 {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
434 {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
435 {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
436 {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
437 {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
438 {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
439 {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
440 {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
441 {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
442 {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
443 {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
444 {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
445 {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
446 {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
447 {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
448 {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
449};
240 450
241#define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1 451#define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1
242 452
@@ -245,19 +455,19 @@ static const u32 ar9485_1_1[][2] = {
245 {0x0000a580, 0x00000000}, 455 {0x0000a580, 0x00000000},
246 {0x0000a584, 0x00000000}, 456 {0x0000a584, 0x00000000},
247 {0x0000a588, 0x00000000}, 457 {0x0000a588, 0x00000000},
248 {0x0000a58c, 0x00000000}, 458 {0x0000a58c, 0x01804000},
249 {0x0000a590, 0x00000000}, 459 {0x0000a590, 0x02808a02},
250 {0x0000a594, 0x00000000}, 460 {0x0000a594, 0x0340ca02},
251 {0x0000a598, 0x00000000}, 461 {0x0000a598, 0x0340cd03},
252 {0x0000a59c, 0x00000000}, 462 {0x0000a59c, 0x0340cd03},
253 {0x0000a5a0, 0x00000000}, 463 {0x0000a5a0, 0x06415304},
254 {0x0000a5a4, 0x00000000}, 464 {0x0000a5a4, 0x04c11905},
255 {0x0000a5a8, 0x00000000}, 465 {0x0000a5a8, 0x06415905},
256 {0x0000a5ac, 0x00000000}, 466 {0x0000a5ac, 0x06415905},
257 {0x0000a5b0, 0x00000000}, 467 {0x0000a5b0, 0x06415905},
258 {0x0000a5b4, 0x00000000}, 468 {0x0000a5b4, 0x06415905},
259 {0x0000a5b8, 0x00000000}, 469 {0x0000a5b8, 0x06415905},
260 {0x0000a5bc, 0x00000000}, 470 {0x0000a5bc, 0x06415905},
261}; 471};
262 472
263static const u32 ar9485_1_1_radio_core[][2] = { 473static const u32 ar9485_1_1_radio_core[][2] = {
@@ -340,7 +550,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = {
340 {0x00009880, 0x201fff00}, 550 {0x00009880, 0x201fff00},
341 {0x00009884, 0x00001042}, 551 {0x00009884, 0x00001042},
342 {0x000098a4, 0x00200400}, 552 {0x000098a4, 0x00200400},
343 {0x000098b0, 0x52440bbe}, 553 {0x000098b0, 0x32840bbe},
344 {0x000098d0, 0x004b6a8e}, 554 {0x000098d0, 0x004b6a8e},
345 {0x000098d4, 0x00000820}, 555 {0x000098d4, 0x00000820},
346 {0x000098dc, 0x00000000}, 556 {0x000098dc, 0x00000000},
@@ -362,7 +572,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = {
362 {0x00009d18, 0x00000000}, 572 {0x00009d18, 0x00000000},
363 {0x00009d1c, 0x00000000}, 573 {0x00009d1c, 0x00000000},
364 {0x00009e08, 0x0038233c}, 574 {0x00009e08, 0x0038233c},
365 {0x00009e24, 0x9927b515}, 575 {0x00009e24, 0x992bb515},
366 {0x00009e28, 0x12ef0200}, 576 {0x00009e28, 0x12ef0200},
367 {0x00009e30, 0x06336f77}, 577 {0x00009e30, 0x06336f77},
368 {0x00009e34, 0x6af6532f}, 578 {0x00009e34, 0x6af6532f},
@@ -427,7 +637,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = {
427 {0x0000a408, 0x0e79e5c6}, 637 {0x0000a408, 0x0e79e5c6},
428 {0x0000a40c, 0x00820820}, 638 {0x0000a40c, 0x00820820},
429 {0x0000a414, 0x1ce739cf}, 639 {0x0000a414, 0x1ce739cf},
430 {0x0000a418, 0x2d0019ce}, 640 {0x0000a418, 0x2d0021ce},
431 {0x0000a41c, 0x1ce739ce}, 641 {0x0000a41c, 0x1ce739ce},
432 {0x0000a420, 0x000001ce}, 642 {0x0000a420, 0x000001ce},
433 {0x0000a424, 0x1ce739ce}, 643 {0x0000a424, 0x1ce739ce},
@@ -443,8 +653,8 @@ static const u32 ar9485_1_1_baseband_core[][2] = {
443 {0x0000a44c, 0x00000001}, 653 {0x0000a44c, 0x00000001},
444 {0x0000a450, 0x00010000}, 654 {0x0000a450, 0x00010000},
445 {0x0000a5c4, 0xbfad9d74}, 655 {0x0000a5c4, 0xbfad9d74},
446 {0x0000a5c8, 0x0048060a}, 656 {0x0000a5c8, 0x00480605},
447 {0x0000a5cc, 0x00000637}, 657 {0x0000a5cc, 0x00002e37},
448 {0x0000a760, 0x03020100}, 658 {0x0000a760, 0x03020100},
449 {0x0000a764, 0x09080504}, 659 {0x0000a764, 0x09080504},
450 {0x0000a768, 0x0d0c0b0a}, 660 {0x0000a768, 0x0d0c0b0a},
@@ -464,17 +674,22 @@ static const u32 ar9485_1_1_baseband_core[][2] = {
464 674
465static const u32 ar9485_common_rx_gain_1_1[][2] = { 675static const u32 ar9485_common_rx_gain_1_1[][2] = {
466 /* Addr allmodes */ 676 /* Addr allmodes */
467 {0x0000a000, 0x00010000}, 677 {0x00009e00, 0x03721b20},
468 {0x0000a004, 0x00030002}, 678 {0x00009e04, 0x00082020},
469 {0x0000a008, 0x00050004}, 679 {0x00009e18, 0x0300501e},
470 {0x0000a00c, 0x00810080}, 680 {0x00009e2c, 0x00002e21},
471 {0x0000a010, 0x01800082}, 681 {0x00009e44, 0x02182324},
472 {0x0000a014, 0x01820181}, 682 {0x0000a000, 0x00060005},
473 {0x0000a018, 0x01840183}, 683 {0x0000a004, 0x00810080},
474 {0x0000a01c, 0x01880185}, 684 {0x0000a008, 0x00830082},
475 {0x0000a020, 0x018a0189}, 685 {0x0000a00c, 0x00850084},
476 {0x0000a024, 0x02850284}, 686 {0x0000a010, 0x01820181},
477 {0x0000a028, 0x02890288}, 687 {0x0000a014, 0x01840183},
688 {0x0000a018, 0x01880185},
689 {0x0000a01c, 0x018a0189},
690 {0x0000a020, 0x02850284},
691 {0x0000a024, 0x02890288},
692 {0x0000a028, 0x028b028a},
478 {0x0000a02c, 0x03850384}, 693 {0x0000a02c, 0x03850384},
479 {0x0000a030, 0x03890388}, 694 {0x0000a030, 0x03890388},
480 {0x0000a034, 0x038b038a}, 695 {0x0000a034, 0x038b038a},
@@ -496,15 +711,15 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = {
496 {0x0000a074, 0x00000000}, 711 {0x0000a074, 0x00000000},
497 {0x0000a078, 0x00000000}, 712 {0x0000a078, 0x00000000},
498 {0x0000a07c, 0x00000000}, 713 {0x0000a07c, 0x00000000},
499 {0x0000a080, 0x28282828}, 714 {0x0000a080, 0x18181818},
500 {0x0000a084, 0x28282828}, 715 {0x0000a084, 0x18181818},
501 {0x0000a088, 0x28282828}, 716 {0x0000a088, 0x18181818},
502 {0x0000a08c, 0x28282828}, 717 {0x0000a08c, 0x18181818},
503 {0x0000a090, 0x28282828}, 718 {0x0000a090, 0x18181818},
504 {0x0000a094, 0x21212128}, 719 {0x0000a094, 0x18181818},
505 {0x0000a098, 0x171c1c1c}, 720 {0x0000a098, 0x17181818},
506 {0x0000a09c, 0x02020212}, 721 {0x0000a09c, 0x02020b0b},
507 {0x0000a0a0, 0x00000202}, 722 {0x0000a0a0, 0x02020202},
508 {0x0000a0a4, 0x00000000}, 723 {0x0000a0a4, 0x00000000},
509 {0x0000a0a8, 0x00000000}, 724 {0x0000a0a8, 0x00000000},
510 {0x0000a0ac, 0x00000000}, 725 {0x0000a0ac, 0x00000000},
@@ -512,22 +727,22 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = {
512 {0x0000a0b4, 0x00000000}, 727 {0x0000a0b4, 0x00000000},
513 {0x0000a0b8, 0x00000000}, 728 {0x0000a0b8, 0x00000000},
514 {0x0000a0bc, 0x00000000}, 729 {0x0000a0bc, 0x00000000},
515 {0x0000a0c0, 0x001f0000}, 730 {0x0000a0c0, 0x22072208},
516 {0x0000a0c4, 0x111f1100}, 731 {0x0000a0c4, 0x22052206},
517 {0x0000a0c8, 0x111d111e}, 732 {0x0000a0c8, 0x22032204},
518 {0x0000a0cc, 0x111b111c}, 733 {0x0000a0cc, 0x22012202},
519 {0x0000a0d0, 0x22032204}, 734 {0x0000a0d0, 0x221f2200},
520 {0x0000a0d4, 0x22012202}, 735 {0x0000a0d4, 0x221d221e},
521 {0x0000a0d8, 0x221f2200}, 736 {0x0000a0d8, 0x33023303},
522 {0x0000a0dc, 0x221d221e}, 737 {0x0000a0dc, 0x33003301},
523 {0x0000a0e0, 0x33013302}, 738 {0x0000a0e0, 0x331e331f},
524 {0x0000a0e4, 0x331f3300}, 739 {0x0000a0e4, 0x4402331d},
525 {0x0000a0e8, 0x4402331e}, 740 {0x0000a0e8, 0x44004401},
526 {0x0000a0ec, 0x44004401}, 741 {0x0000a0ec, 0x441e441f},
527 {0x0000a0f0, 0x441e441f}, 742 {0x0000a0f0, 0x55025503},
528 {0x0000a0f4, 0x55015502}, 743 {0x0000a0f4, 0x55005501},
529 {0x0000a0f8, 0x551f5500}, 744 {0x0000a0f8, 0x551e551f},
530 {0x0000a0fc, 0x6602551e}, 745 {0x0000a0fc, 0x6602551d},
531 {0x0000a100, 0x66006601}, 746 {0x0000a100, 0x66006601},
532 {0x0000a104, 0x661e661f}, 747 {0x0000a104, 0x661e661f},
533 {0x0000a108, 0x7703661d}, 748 {0x0000a108, 0x7703661d},
@@ -636,17 +851,12 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = {
636 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, 851 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
637 {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, 852 {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
638 {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, 853 {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
639 {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
640 {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
641 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, 854 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
642 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, 855 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e},
643 {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, 856 {0x00009e14, 0x31395d53, 0x31396053, 0x312e6053, 0x312e5d53},
644 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
645 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, 857 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
646 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, 858 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
647 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
648 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, 859 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
649 {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
650 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, 860 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
651 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, 861 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
652 {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, 862 {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0},
@@ -850,4 +1060,6 @@ static const u32 ar9485_1_1_mac_core[][2] = {
850 {0x000083d0, 0x000301ff}, 1060 {0x000083d0, 0x000301ff},
851}; 1061};
852 1062
1063#define ar9485_1_1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
1064
853#endif /* INITVALS_9485_H */ 1065#endif /* INITVALS_9485_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 4e125d8904a..80bab1b8447 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -129,10 +129,10 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
129#define ATH_TXMAXTRY 13 129#define ATH_TXMAXTRY 13
130 130
131#define TID_TO_WME_AC(_tid) \ 131#define TID_TO_WME_AC(_tid) \
132 ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ 132 ((((_tid) == 0) || ((_tid) == 3)) ? IEEE80211_AC_BE : \
133 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ 133 (((_tid) == 1) || ((_tid) == 2)) ? IEEE80211_AC_BK : \
134 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ 134 (((_tid) == 4) || ((_tid) == 5)) ? IEEE80211_AC_VI : \
135 WME_AC_VO) 135 IEEE80211_AC_VO)
136 136
137#define ATH_AGGR_DELIM_SZ 4 137#define ATH_AGGR_DELIM_SZ 4
138#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ 138#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
@@ -259,13 +259,10 @@ struct ath_atx_tid {
259}; 259};
260 260
261struct ath_node { 261struct ath_node {
262#ifdef CONFIG_ATH9K_DEBUGFS
263 struct list_head list; /* for sc->nodes */
264#endif
265 struct ieee80211_sta *sta; /* station struct we're part of */ 262 struct ieee80211_sta *sta; /* station struct we're part of */
266 struct ieee80211_vif *vif; /* interface with which we're associated */ 263 struct ieee80211_vif *vif; /* interface with which we're associated */
267 struct ath_atx_tid tid[WME_NUM_TID]; 264 struct ath_atx_tid tid[WME_NUM_TID];
268 struct ath_atx_ac ac[WME_NUM_AC]; 265 struct ath_atx_ac ac[IEEE80211_NUM_ACS];
269 int ps_key; 266 int ps_key;
270 267
271 u16 maxampdu; 268 u16 maxampdu;
@@ -299,9 +296,9 @@ struct ath_tx {
299 struct list_head txbuf; 296 struct list_head txbuf;
300 struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; 297 struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
301 struct ath_descdma txdma; 298 struct ath_descdma txdma;
302 struct ath_txq *txq_map[WME_NUM_AC]; 299 struct ath_txq *txq_map[IEEE80211_NUM_ACS];
303 u32 txq_max_pending[WME_NUM_AC]; 300 u32 txq_max_pending[IEEE80211_NUM_ACS];
304 u16 max_aggr_framelen[WME_NUM_AC][4][32]; 301 u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32];
305}; 302};
306 303
307struct ath_rx_edma { 304struct ath_rx_edma {
@@ -461,6 +458,12 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
461/* BTCOEX */ 458/* BTCOEX */
462/**********/ 459/**********/
463 460
461#define ATH_DUMP_BTCOEX(_s, _val) \
462 do { \
463 len += snprintf(buf + len, size - len, \
464 "%20s : %10d\n", _s, (_val)); \
465 } while (0)
466
464enum bt_op_flags { 467enum bt_op_flags {
465 BT_OP_PRIORITY_DETECTED, 468 BT_OP_PRIORITY_DETECTED,
466 BT_OP_SCAN, 469 BT_OP_SCAN,
@@ -482,6 +485,7 @@ struct ath_btcoex {
482 int rssi_count; 485 int rssi_count;
483 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ 486 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
484 struct ath_mci_profile mci; 487 struct ath_mci_profile mci;
488 u8 stomp_audio;
485}; 489};
486 490
487#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 491#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
@@ -494,7 +498,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
494void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status); 498void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status);
495u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen); 499u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen);
496void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc); 500void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc);
497int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size); 501int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size);
498#else 502#else
499static inline int ath9k_init_btcoex(struct ath_softc *sc) 503static inline int ath9k_init_btcoex(struct ath_softc *sc)
500{ 504{
@@ -521,8 +525,7 @@ static inline u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc,
521static inline void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) 525static inline void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc)
522{ 526{
523} 527}
524static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, 528static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size)
525 u32 len, u32 size)
526{ 529{
527 return 0; 530 return 0;
528} 531}
@@ -717,9 +720,6 @@ struct ath_softc {
717 720
718#ifdef CONFIG_ATH9K_DEBUGFS 721#ifdef CONFIG_ATH9K_DEBUGFS
719 struct ath9k_debug debug; 722 struct ath9k_debug debug;
720 spinlock_t nodes_lock;
721 struct list_head nodes; /* basically, stations */
722 unsigned int tx_complete_poll_work_seen;
723#endif 723#endif
724 struct ath_beacon_config cur_beacon_conf; 724 struct ath_beacon_config cur_beacon_conf;
725 struct delayed_work tx_complete_work; 725 struct delayed_work tx_complete_work;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 1b48414dca9..531fffd801a 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -46,7 +46,7 @@ static void ath9k_beaconq_config(struct ath_softc *sc)
46 qi.tqi_cwmax = 0; 46 qi.tqi_cwmax = 0;
47 } else { 47 } else {
48 /* Adhoc mode; important thing is to use 2x cwmin. */ 48 /* Adhoc mode; important thing is to use 2x cwmin. */
49 txq = sc->tx.txq_map[WME_AC_BE]; 49 txq = sc->tx.txq_map[IEEE80211_AC_BE];
50 ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); 50 ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be);
51 qi.tqi_aifs = qi_be.tqi_aifs; 51 qi.tqi_aifs = qi_be.tqi_aifs;
52 if (ah->slottime == ATH9K_SLOT_TIME_20) 52 if (ah->slottime == ATH9K_SLOT_TIME_20)
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index c90e9bc4b02..9963b0bf9f7 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -49,6 +49,7 @@ static const u32 mci_wlan_weights[ATH_BTCOEX_STOMP_MAX]
49 { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */ 49 { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */
50 { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */ 50 { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */
51 { 0x01017d01, 0x013b0101, 0x3b3b0101, 0x3b3b013b }, /* STOMP_LOW_FTP */ 51 { 0x01017d01, 0x013b0101, 0x3b3b0101, 0x3b3b013b }, /* STOMP_LOW_FTP */
52 { 0xffffff01, 0xffffffff, 0xffffff01, 0xffffffff }, /* STOMP_AUDIO */
52}; 53};
53 54
54void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) 55void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 2f84ab273d0..6de26ea5d5f 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -50,6 +50,7 @@ enum ath_stomp_type {
50 ATH_BTCOEX_STOMP_LOW, 50 ATH_BTCOEX_STOMP_LOW,
51 ATH_BTCOEX_STOMP_NONE, 51 ATH_BTCOEX_STOMP_NONE,
52 ATH_BTCOEX_STOMP_LOW_FTP, 52 ATH_BTCOEX_STOMP_LOW_FTP,
53 ATH_BTCOEX_STOMP_AUDIO,
53 ATH_BTCOEX_STOMP_MAX 54 ATH_BTCOEX_STOMP_MAX
54}; 55};
55 56
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index ad14fecc76c..76b54390031 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -28,13 +28,6 @@
28#define WME_MAX_BA WME_BA_BMP_SIZE 28#define WME_MAX_BA WME_BA_BMP_SIZE
29#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) 29#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
30 30
31/* These must match mac80211 skb queue mapping numbers */
32#define WME_AC_VO 0
33#define WME_AC_VI 1
34#define WME_AC_BE 2
35#define WME_AC_BK 3
36#define WME_NUM_AC 4
37
38#define ATH_RSSI_DUMMY_MARKER 0x127 31#define ATH_RSSI_DUMMY_MARKER 0x127
39#define ATH_RSSI_LPF_LEN 10 32#define ATH_RSSI_LPF_LEN 10
40#define RSSI_LPF_THRESHOLD -20 33#define RSSI_LPF_THRESHOLD -20
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index a8be94b2a53..939308c2571 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -512,62 +512,19 @@ static const struct file_operations fops_interrupt = {
512 .llseek = default_llseek, 512 .llseek = default_llseek,
513}; 513};
514 514
515#define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum
516#define PR(str, elem) \
517 do { \
518 len += snprintf(buf + len, size - len, \
519 "%s%13u%11u%10u%10u\n", str, \
520 sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem, \
521 sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem, \
522 sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem, \
523 sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem); \
524 if (len >= size) \
525 goto done; \
526} while(0)
527
528#define PRX(str, elem) \
529do { \
530 len += snprintf(buf + len, size - len, \
531 "%s%13u%11u%10u%10u\n", str, \
532 (unsigned int)(sc->tx.txq_map[WME_AC_BE]->elem), \
533 (unsigned int)(sc->tx.txq_map[WME_AC_BK]->elem), \
534 (unsigned int)(sc->tx.txq_map[WME_AC_VI]->elem), \
535 (unsigned int)(sc->tx.txq_map[WME_AC_VO]->elem)); \
536 if (len >= size) \
537 goto done; \
538} while(0)
539
540#define PRQLE(str, elem) \
541do { \
542 len += snprintf(buf + len, size - len, \
543 "%s%13i%11i%10i%10i\n", str, \
544 list_empty(&sc->tx.txq_map[WME_AC_BE]->elem), \
545 list_empty(&sc->tx.txq_map[WME_AC_BK]->elem), \
546 list_empty(&sc->tx.txq_map[WME_AC_VI]->elem), \
547 list_empty(&sc->tx.txq_map[WME_AC_VO]->elem)); \
548 if (len >= size) \
549 goto done; \
550} while (0)
551
552static ssize_t read_file_xmit(struct file *file, char __user *user_buf, 515static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
553 size_t count, loff_t *ppos) 516 size_t count, loff_t *ppos)
554{ 517{
555 struct ath_softc *sc = file->private_data; 518 struct ath_softc *sc = file->private_data;
556 char *buf; 519 char *buf;
557 unsigned int len = 0, size = 8000; 520 unsigned int len = 0, size = 2048;
558 int i;
559 ssize_t retval = 0; 521 ssize_t retval = 0;
560 char tmp[32];
561 522
562 buf = kzalloc(size, GFP_KERNEL); 523 buf = kzalloc(size, GFP_KERNEL);
563 if (buf == NULL) 524 if (buf == NULL)
564 return -ENOMEM; 525 return -ENOMEM;
565 526
566 len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x" 527 len += sprintf(buf, "%30s %10s%10s%10s\n\n",
567 " poll-work-seen: %u\n"
568 "%30s %10s%10s%10s\n\n",
569 ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup,
570 sc->tx_complete_poll_work_seen,
571 "BE", "BK", "VI", "VO"); 528 "BE", "BK", "VI", "VO");
572 529
573 PR("MPDUs Queued: ", queued); 530 PR("MPDUs Queued: ", queued);
@@ -587,62 +544,11 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
587 PR("DELIM Underrun: ", delim_underrun); 544 PR("DELIM Underrun: ", delim_underrun);
588 PR("TX-Pkts-All: ", tx_pkts_all); 545 PR("TX-Pkts-All: ", tx_pkts_all);
589 PR("TX-Bytes-All: ", tx_bytes_all); 546 PR("TX-Bytes-All: ", tx_bytes_all);
590 PR("hw-put-tx-buf: ", puttxbuf); 547 PR("HW-put-tx-buf: ", puttxbuf);
591 PR("hw-tx-start: ", txstart); 548 PR("HW-tx-start: ", txstart);
592 PR("hw-tx-proc-desc: ", txprocdesc); 549 PR("HW-tx-proc-desc: ", txprocdesc);
593 PR("TX-Failed: ", txfailed); 550 PR("TX-Failed: ", txfailed);
594 len += snprintf(buf + len, size - len,
595 "%s%11p%11p%10p%10p\n", "txq-memory-address:",
596 sc->tx.txq_map[WME_AC_BE],
597 sc->tx.txq_map[WME_AC_BK],
598 sc->tx.txq_map[WME_AC_VI],
599 sc->tx.txq_map[WME_AC_VO]);
600 if (len >= size)
601 goto done;
602
603 PRX("axq-qnum: ", axq_qnum);
604 PRX("axq-depth: ", axq_depth);
605 PRX("axq-ampdu_depth: ", axq_ampdu_depth);
606 PRX("axq-stopped ", stopped);
607 PRX("tx-in-progress ", axq_tx_inprogress);
608 PRX("pending-frames ", pending_frames);
609 PRX("txq_headidx: ", txq_headidx);
610 PRX("txq_tailidx: ", txq_headidx);
611
612 PRQLE("axq_q empty: ", axq_q);
613 PRQLE("axq_acq empty: ", axq_acq);
614 for (i = 0; i < ATH_TXFIFO_DEPTH; i++) {
615 snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i);
616 PRQLE(tmp, txq_fifo[i]);
617 }
618
619 /* Print out more detailed queue-info */
620 for (i = 0; i <= WME_AC_BK; i++) {
621 struct ath_txq *txq = &(sc->tx.txq[i]);
622 struct ath_atx_ac *ac;
623 struct ath_atx_tid *tid;
624 if (len >= size)
625 goto done;
626 spin_lock_bh(&txq->axq_lock);
627 if (!list_empty(&txq->axq_acq)) {
628 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac,
629 list);
630 len += snprintf(buf + len, size - len,
631 "txq[%i] first-ac: %p sched: %i\n",
632 i, ac, ac->sched);
633 if (list_empty(&ac->tid_q) || (len >= size))
634 goto done_for;
635 tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
636 list);
637 len += snprintf(buf + len, size - len,
638 " first-tid: %p sched: %i paused: %i\n",
639 tid, tid->sched, tid->paused);
640 }
641 done_for:
642 spin_unlock_bh(&txq->axq_lock);
643 }
644 551
645done:
646 if (len > size) 552 if (len > size)
647 len = size; 553 len = size;
648 554
@@ -652,62 +558,41 @@ done:
652 return retval; 558 return retval;
653} 559}
654 560
655static ssize_t read_file_stations(struct file *file, char __user *user_buf, 561static ssize_t read_file_queues(struct file *file, char __user *user_buf,
656 size_t count, loff_t *ppos) 562 size_t count, loff_t *ppos)
657{ 563{
658 struct ath_softc *sc = file->private_data; 564 struct ath_softc *sc = file->private_data;
565 struct ath_txq *txq;
659 char *buf; 566 char *buf;
660 unsigned int len = 0, size = 64000; 567 unsigned int len = 0, size = 1024;
661 struct ath_node *an = NULL;
662 ssize_t retval = 0; 568 ssize_t retval = 0;
663 int q; 569 int i;
570 char *qname[4] = {"VO", "VI", "BE", "BK"};
664 571
665 buf = kzalloc(size, GFP_KERNEL); 572 buf = kzalloc(size, GFP_KERNEL);
666 if (buf == NULL) 573 if (buf == NULL)
667 return -ENOMEM; 574 return -ENOMEM;
668 575
669 len += snprintf(buf + len, size - len, 576 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
670 "Stations:\n" 577 txq = sc->tx.txq_map[i];
671 " tid: addr sched paused buf_q-empty an ac baw\n" 578 len += snprintf(buf + len, size - len, "(%s): ", qname[i]);
672 " ac: addr sched tid_q-empty txq\n");
673
674 spin_lock(&sc->nodes_lock);
675 list_for_each_entry(an, &sc->nodes, list) {
676 unsigned short ma = an->maxampdu;
677 if (ma == 0)
678 ma = 65535; /* see ath_lookup_rate */
679 len += snprintf(buf + len, size - len,
680 "iface: %pM sta: %pM max-ampdu: %hu mpdu-density: %uus\n",
681 an->vif->addr, an->sta->addr, ma,
682 (unsigned int)(an->mpdudensity));
683 if (len >= size)
684 goto done;
685
686 for (q = 0; q < WME_NUM_TID; q++) {
687 struct ath_atx_tid *tid = &(an->tid[q]);
688 len += snprintf(buf + len, size - len,
689 " tid: %p %s %s %i %p %p %hu\n",
690 tid, tid->sched ? "sched" : "idle",
691 tid->paused ? "paused" : "running",
692 skb_queue_empty(&tid->buf_q),
693 tid->an, tid->ac, tid->baw_size);
694 if (len >= size)
695 goto done;
696 }
697 579
698 for (q = 0; q < WME_NUM_AC; q++) { 580 ath_txq_lock(sc, txq);
699 struct ath_atx_ac *ac = &(an->ac[q]); 581
700 len += snprintf(buf + len, size - len, 582 len += snprintf(buf + len, size - len, "%s: %d ",
701 " ac: %p %s %i %p\n", 583 "qnum", txq->axq_qnum);
702 ac, ac->sched ? "sched" : "idle", 584 len += snprintf(buf + len, size - len, "%s: %2d ",
703 list_empty(&ac->tid_q), ac->txq); 585 "qdepth", txq->axq_depth);
704 if (len >= size) 586 len += snprintf(buf + len, size - len, "%s: %2d ",
705 goto done; 587 "ampdu-depth", txq->axq_ampdu_depth);
706 } 588 len += snprintf(buf + len, size - len, "%s: %3d ",
589 "pending", txq->pending_frames);
590 len += snprintf(buf + len, size - len, "%s: %d\n",
591 "stopped", txq->stopped);
592
593 ath_txq_unlock(sc, txq);
707 } 594 }
708 595
709done:
710 spin_unlock(&sc->nodes_lock);
711 if (len > size) 596 if (len > size)
712 len = size; 597 len = size;
713 598
@@ -837,6 +722,9 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf,
837 len += snprintf(buf + len, sizeof(buf) - len, 722 len += snprintf(buf + len, sizeof(buf) - len,
838 "%17s: %2d\n", "PLL RX Hang", 723 "%17s: %2d\n", "PLL RX Hang",
839 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); 724 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
725 len += snprintf(buf + len, sizeof(buf) - len,
726 "%17s: %2d\n", "MCI Reset",
727 sc->debug.stats.reset[RESET_TYPE_MCI]);
840 728
841 if (len > sizeof(buf)) 729 if (len > sizeof(buf))
842 len = sizeof(buf); 730 len = sizeof(buf);
@@ -919,8 +807,8 @@ static const struct file_operations fops_xmit = {
919 .llseek = default_llseek, 807 .llseek = default_llseek,
920}; 808};
921 809
922static const struct file_operations fops_stations = { 810static const struct file_operations fops_queues = {
923 .read = read_file_stations, 811 .read = read_file_queues,
924 .open = simple_open, 812 .open = simple_open,
925 .owner = THIS_MODULE, 813 .owner = THIS_MODULE,
926 .llseek = default_llseek, 814 .llseek = default_llseek,
@@ -1599,8 +1487,14 @@ static ssize_t read_file_btcoex(struct file *file, char __user *user_buf,
1599 if (buf == NULL) 1487 if (buf == NULL)
1600 return -ENOMEM; 1488 return -ENOMEM;
1601 1489
1602 len = ath9k_dump_btcoex(sc, buf, len, size); 1490 if (!sc->sc_ah->common.btcoex_enabled) {
1491 len = snprintf(buf, size, "%s\n",
1492 "BTCOEX is disabled");
1493 goto exit;
1494 }
1603 1495
1496 len = ath9k_dump_btcoex(sc, buf, size);
1497exit:
1604 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1498 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1605 kfree(buf); 1499 kfree(buf);
1606 1500
@@ -1638,16 +1532,16 @@ int ath9k_init_debug(struct ath_hw *ah)
1638 &fops_interrupt); 1532 &fops_interrupt);
1639 debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, 1533 debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
1640 &fops_xmit); 1534 &fops_xmit);
1535 debugfs_create_file("queues", S_IRUSR, sc->debug.debugfs_phy, sc,
1536 &fops_queues);
1641 debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1537 debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1642 &sc->tx.txq_max_pending[WME_AC_BK]); 1538 &sc->tx.txq_max_pending[IEEE80211_AC_BK]);
1643 debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1539 debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1644 &sc->tx.txq_max_pending[WME_AC_BE]); 1540 &sc->tx.txq_max_pending[IEEE80211_AC_BE]);
1645 debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1541 debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1646 &sc->tx.txq_max_pending[WME_AC_VI]); 1542 &sc->tx.txq_max_pending[IEEE80211_AC_VI]);
1647 debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1543 debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1648 &sc->tx.txq_max_pending[WME_AC_VO]); 1544 &sc->tx.txq_max_pending[IEEE80211_AC_VO]);
1649 debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
1650 &fops_stations);
1651 debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, 1545 debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
1652 &fops_misc); 1546 &fops_misc);
1653 debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc, 1547 debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc,
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 2ed9785a38f..f9bee18de5a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -41,6 +41,7 @@ enum ath_reset_type {
41 RESET_TYPE_PLL_HANG, 41 RESET_TYPE_PLL_HANG,
42 RESET_TYPE_MAC_HANG, 42 RESET_TYPE_MAC_HANG,
43 RESET_TYPE_BEACON_STUCK, 43 RESET_TYPE_BEACON_STUCK,
44 RESET_TYPE_MCI,
44 __RESET_TYPE_MAX 45 __RESET_TYPE_MAX
45}; 46};
46 47
@@ -178,6 +179,21 @@ struct ath_tx_stats {
178 u32 txfailed; 179 u32 txfailed;
179}; 180};
180 181
182/*
183 * Various utility macros to print TX/Queue counters.
184 */
185#define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum
186#define TXSTATS sc->debug.stats.txstats
187#define PR(str, elem) \
188 do { \
189 len += snprintf(buf + len, size - len, \
190 "%s%13u%11u%10u%10u\n", str, \
191 TXSTATS[PR_QNUM(IEEE80211_AC_BE)].elem, \
192 TXSTATS[PR_QNUM(IEEE80211_AC_BK)].elem, \
193 TXSTATS[PR_QNUM(IEEE80211_AC_VI)].elem, \
194 TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \
195 } while(0)
196
181#define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) 197#define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++)
182 198
183/** 199/**
@@ -226,7 +242,7 @@ struct ath_rx_stats {
226 242
227struct ath_stats { 243struct ath_stats {
228 struct ath_interrupt_stats istats; 244 struct ath_interrupt_stats istats;
229 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; 245 struct ath_tx_stats txstats[IEEE80211_NUM_ACS];
230 struct ath_rx_stats rxstats; 246 struct ath_rx_stats rxstats;
231 struct ath_dfs_stats dfs_stats; 247 struct ath_dfs_stats dfs_stats;
232 u32 reset[__RESET_TYPE_MAX]; 248 u32 reset[__RESET_TYPE_MAX];
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c
index ea2a6cf7ef2..24877b00cbf 100644
--- a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c
+++ b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c
@@ -42,10 +42,15 @@ struct radar_types {
42#define MIN_PPB_THRESH 50 42#define MIN_PPB_THRESH 50
43#define PPB_THRESH(PPB) ((PPB * MIN_PPB_THRESH + 50) / 100) 43#define PPB_THRESH(PPB) ((PPB * MIN_PPB_THRESH + 50) / 100)
44#define PRF2PRI(PRF) ((1000000 + PRF / 2) / PRF) 44#define PRF2PRI(PRF) ((1000000 + PRF / 2) / PRF)
45/* percentage of pulse width tolerance */
46#define WIDTH_TOLERANCE 5
47#define WIDTH_LOWER(X) ((X*(100-WIDTH_TOLERANCE)+50)/100)
48#define WIDTH_UPPER(X) ((X*(100+WIDTH_TOLERANCE)+50)/100)
45 49
46#define ETSI_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB) \ 50#define ETSI_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB) \
47{ \ 51{ \
48 ID, WMIN, WMAX, (PRF2PRI(PMAX) - PRI_TOLERANCE), \ 52 ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX), \
53 (PRF2PRI(PMAX) - PRI_TOLERANCE), \
49 (PRF2PRI(PMIN) * PRF + PRI_TOLERANCE), PRF, PPB * PRF, \ 54 (PRF2PRI(PMIN) * PRF + PRI_TOLERANCE), PRF, PPB * PRF, \
50 PPB_THRESH(PPB), PRI_TOLERANCE, \ 55 PPB_THRESH(PPB), PRI_TOLERANCE, \
51} 56}
@@ -274,7 +279,7 @@ static bool dpd_set_domain(struct dfs_pattern_detector *dpd,
274 279
275static struct dfs_pattern_detector default_dpd = { 280static struct dfs_pattern_detector default_dpd = {
276 .exit = dpd_exit, 281 .exit = dpd_exit,
277 .set_domain = dpd_set_domain, 282 .set_dfs_domain = dpd_set_domain,
278 .add_pulse = dpd_add_pulse, 283 .add_pulse = dpd_add_pulse,
279 .region = NL80211_DFS_UNSET, 284 .region = NL80211_DFS_UNSET,
280}; 285};
@@ -291,10 +296,11 @@ dfs_pattern_detector_init(enum nl80211_dfs_regions region)
291 *dpd = default_dpd; 296 *dpd = default_dpd;
292 INIT_LIST_HEAD(&dpd->channel_detectors); 297 INIT_LIST_HEAD(&dpd->channel_detectors);
293 298
294 if (dpd->set_domain(dpd, region)) 299 if (dpd->set_dfs_domain(dpd, region))
295 return dpd; 300 return dpd;
296 301
297 pr_err("Could not set DFS domain to %d. ", region); 302 pr_err("Could not set DFS domain to %d. ", region);
303 kfree(dpd);
298 return NULL; 304 return NULL;
299} 305}
300EXPORT_SYMBOL(dfs_pattern_detector_init); 306EXPORT_SYMBOL(dfs_pattern_detector_init);
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h
index fd0328a3099..cda52f39f28 100644
--- a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h
+++ b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h
@@ -62,7 +62,7 @@ struct radar_detector_specs {
62/** 62/**
63 * struct dfs_pattern_detector - DFS pattern detector 63 * struct dfs_pattern_detector - DFS pattern detector
64 * @exit(): destructor 64 * @exit(): destructor
65 * @set_domain(): set DFS domain, resets detector lines upon domain changes 65 * @set_dfs_domain(): set DFS domain, resets detector lines upon domain changes
66 * @add_pulse(): add radar pulse to detector, returns true on detection 66 * @add_pulse(): add radar pulse to detector, returns true on detection
67 * @region: active DFS region, NL80211_DFS_UNSET until set 67 * @region: active DFS region, NL80211_DFS_UNSET until set
68 * @num_radar_types: number of different radar types 68 * @num_radar_types: number of different radar types
@@ -72,7 +72,7 @@ struct radar_detector_specs {
72 */ 72 */
73struct dfs_pattern_detector { 73struct dfs_pattern_detector {
74 void (*exit)(struct dfs_pattern_detector *dpd); 74 void (*exit)(struct dfs_pattern_detector *dpd);
75 bool (*set_domain)(struct dfs_pattern_detector *dpd, 75 bool (*set_dfs_domain)(struct dfs_pattern_detector *dpd,
76 enum nl80211_dfs_regions region); 76 enum nl80211_dfs_regions region);
77 bool (*add_pulse)(struct dfs_pattern_detector *dpd, 77 bool (*add_pulse)(struct dfs_pattern_detector *dpd,
78 struct pulse_event *pe); 78 struct pulse_event *pe);
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index a8ea57b9f49..4b412aaf4f3 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -247,6 +247,9 @@ static void ath_btcoex_period_timer(unsigned long data)
247 stomp_type = ATH_BTCOEX_STOMP_ALL; 247 stomp_type = ATH_BTCOEX_STOMP_ALL;
248 timer_period = btcoex->btscan_no_stomp; 248 timer_period = btcoex->btscan_no_stomp;
249 } 249 }
250 } else if (btcoex->stomp_audio >= 5) {
251 stomp_type = ATH_BTCOEX_STOMP_AUDIO;
252 btcoex->stomp_audio = 0;
250 } 253 }
251 254
252 ath9k_hw_btcoex_bt_stomp(ah, stomp_type); 255 ath9k_hw_btcoex_bt_stomp(ah, stomp_type);
@@ -295,7 +298,7 @@ static void ath_btcoex_no_stomp_timer(void *arg)
295 (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && 298 (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI) &&
296 test_bit(BT_OP_SCAN, &btcoex->op_flags))) 299 test_bit(BT_OP_SCAN, &btcoex->op_flags)))
297 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); 300 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
298 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) 301 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
299 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); 302 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
300 303
301 ath9k_hw_btcoex_enable(ah); 304 ath9k_hw_btcoex_enable(ah);
@@ -471,7 +474,7 @@ int ath9k_init_btcoex(struct ath_softc *sc)
471 r = ath_init_btcoex_timer(sc); 474 r = ath_init_btcoex_timer(sc);
472 if (r) 475 if (r)
473 return -1; 476 return -1;
474 txq = sc->tx.txq_map[WME_AC_BE]; 477 txq = sc->tx.txq_map[IEEE80211_AC_BE];
475 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); 478 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
476 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; 479 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
477 if (ath9k_hw_mci_is_enabled(ah)) { 480 if (ath9k_hw_mci_is_enabled(ah)) {
@@ -494,35 +497,31 @@ int ath9k_init_btcoex(struct ath_softc *sc)
494 return 0; 497 return 0;
495} 498}
496 499
497int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size) 500static int ath9k_dump_mci_btcoex(struct ath_softc *sc, u8 *buf, u32 size)
498{ 501{
499#define ATH_DUMP_BTCOEX(_s, _val) \
500 do { \
501 len += snprintf(buf + len, size - len, \
502 "%20s : %10d\n", _s, (_val)); \
503 } while (0)
504
505 struct ath_btcoex *btcoex = &sc->btcoex; 502 struct ath_btcoex *btcoex = &sc->btcoex;
506 struct ath_mci_profile *mci = &btcoex->mci; 503 struct ath_mci_profile *mci = &btcoex->mci;
507 struct ath_hw *ah = sc->sc_ah; 504 struct ath_hw *ah = sc->sc_ah;
508 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 505 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
506 u32 len = 0;
509 int i; 507 int i;
510 508
511 ATH_DUMP_BTCOEX("Total BT profiles", NUM_PROF(mci)); 509 ATH_DUMP_BTCOEX("Total BT profiles", NUM_PROF(mci));
512 ATH_DUMP_BTCOEX("Number of MGMT", mci->num_mgmt); 510 ATH_DUMP_BTCOEX("MGMT", mci->num_mgmt);
513 ATH_DUMP_BTCOEX("Number of SCO", mci->num_sco); 511 ATH_DUMP_BTCOEX("SCO", mci->num_sco);
514 ATH_DUMP_BTCOEX("Number of A2DP", mci->num_a2dp); 512 ATH_DUMP_BTCOEX("A2DP", mci->num_a2dp);
515 ATH_DUMP_BTCOEX("Number of HID", mci->num_hid); 513 ATH_DUMP_BTCOEX("HID", mci->num_hid);
516 ATH_DUMP_BTCOEX("Number of PAN", mci->num_pan); 514 ATH_DUMP_BTCOEX("PAN", mci->num_pan);
517 ATH_DUMP_BTCOEX("Number of ACL", mci->num_other_acl); 515 ATH_DUMP_BTCOEX("ACL", mci->num_other_acl);
518 ATH_DUMP_BTCOEX("Number of BDR", mci->num_bdr); 516 ATH_DUMP_BTCOEX("BDR", mci->num_bdr);
519 ATH_DUMP_BTCOEX("Aggr. Limit", mci->aggr_limit); 517 ATH_DUMP_BTCOEX("Aggr. Limit", mci->aggr_limit);
520 ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type); 518 ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type);
521 ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period); 519 ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period);
522 ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle); 520 ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle);
523 ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time); 521 ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time);
524 ATH_DUMP_BTCOEX("Concurrent Tx", btcoex_hw->mci.concur_tx); 522 ATH_DUMP_BTCOEX("Concurrent Tx", btcoex_hw->mci.concur_tx);
525 ATH_DUMP_BTCOEX("Concur RSSI count", btcoex->rssi_count); 523 ATH_DUMP_BTCOEX("Concurrent RSSI cnt", btcoex->rssi_count);
524
526 len += snprintf(buf + len, size - len, "BT Weights: "); 525 len += snprintf(buf + len, size - len, "BT Weights: ");
527 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) 526 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++)
528 len += snprintf(buf + len, size - len, "%08x ", 527 len += snprintf(buf + len, size - len, "%08x ",
@@ -537,9 +536,32 @@ int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size)
537 for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++) 536 for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++)
538 len += snprintf(buf + len, size - len, "%08x ", 537 len += snprintf(buf + len, size - len, "%08x ",
539 btcoex_hw->tx_prio[i]); 538 btcoex_hw->tx_prio[i]);
539
540 len += snprintf(buf + len, size - len, "\n"); 540 len += snprintf(buf + len, size - len, "\n");
541#undef ATH_DUMP_BTCOEX
542 541
543 return len; 542 return len;
544} 543}
544
545static int ath9k_dump_legacy_btcoex(struct ath_softc *sc, u8 *buf, u32 size)
546{
547
548 struct ath_btcoex *btcoex = &sc->btcoex;
549 u32 len = 0;
550
551 ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type);
552 ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period);
553 ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle);
554 ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time);
555
556 return len;
557}
558
559int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size)
560{
561 if (ath9k_hw_mci_is_enabled(sc->sc_ah))
562 return ath9k_dump_mci_btcoex(sc, buf, size);
563 else
564 return ath9k_dump_legacy_btcoex(sc, buf, size);
565}
566
545#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ 567#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index b30596fcf73..96bfb18078f 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -331,7 +331,7 @@ struct ath_tx_stats {
331 u32 skb_success; 331 u32 skb_success;
332 u32 skb_failed; 332 u32 skb_failed;
333 u32 cab_queued; 333 u32 cab_queued;
334 u32 queue_stats[WME_NUM_AC]; 334 u32 queue_stats[IEEE80211_NUM_ACS];
335}; 335};
336 336
337struct ath_rx_stats { 337struct ath_rx_stats {
@@ -493,7 +493,7 @@ struct ath9k_htc_priv {
493 493
494 int beaconq; 494 int beaconq;
495 int cabq; 495 int cabq;
496 int hwq_map[WME_NUM_AC]; 496 int hwq_map[IEEE80211_NUM_ACS];
497 497
498#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 498#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
499 struct ath_btcoex btcoex; 499 struct ath_btcoex btcoex;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index f42d2eb6af9..d0ce1f5bba1 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -33,7 +33,7 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
33 qi.tqi_cwmin = 0; 33 qi.tqi_cwmin = 0;
34 qi.tqi_cwmax = 0; 34 qi.tqi_cwmax = 0;
35 } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { 35 } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
36 int qnum = priv->hwq_map[WME_AC_BE]; 36 int qnum = priv->hwq_map[IEEE80211_AC_BE];
37 37
38 ath9k_hw_get_txq_props(ah, qnum, &qi_be); 38 ath9k_hw_get_txq_props(ah, qnum, &qi_be);
39 39
@@ -587,9 +587,9 @@ static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv,
587 (priv->num_sta_vif > 1) && 587 (priv->num_sta_vif > 1) &&
588 (vif->type == NL80211_IFTYPE_STATION)) { 588 (vif->type == NL80211_IFTYPE_STATION)) {
589 beacon_configured = false; 589 beacon_configured = false;
590 ieee80211_iterate_active_interfaces_atomic(priv->hw, 590 ieee80211_iterate_active_interfaces_atomic(
591 ath9k_htc_beacon_iter, 591 priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
592 &beacon_configured); 592 ath9k_htc_beacon_iter, &beacon_configured);
593 593
594 if (beacon_configured) { 594 if (beacon_configured) {
595 ath_dbg(common, CONFIG, 595 ath_dbg(common, CONFIG,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index 3035deb7a0c..87110de577e 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -218,16 +218,16 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
218 218
219 len += snprintf(buf + len, sizeof(buf) - len, 219 len += snprintf(buf + len, sizeof(buf) - len,
220 "%20s : %10u\n", "BE queued", 220 "%20s : %10u\n", "BE queued",
221 priv->debug.tx_stats.queue_stats[WME_AC_BE]); 221 priv->debug.tx_stats.queue_stats[IEEE80211_AC_BE]);
222 len += snprintf(buf + len, sizeof(buf) - len, 222 len += snprintf(buf + len, sizeof(buf) - len,
223 "%20s : %10u\n", "BK queued", 223 "%20s : %10u\n", "BK queued",
224 priv->debug.tx_stats.queue_stats[WME_AC_BK]); 224 priv->debug.tx_stats.queue_stats[IEEE80211_AC_BK]);
225 len += snprintf(buf + len, sizeof(buf) - len, 225 len += snprintf(buf + len, sizeof(buf) - len,
226 "%20s : %10u\n", "VI queued", 226 "%20s : %10u\n", "VI queued",
227 priv->debug.tx_stats.queue_stats[WME_AC_VI]); 227 priv->debug.tx_stats.queue_stats[IEEE80211_AC_VI]);
228 len += snprintf(buf + len, sizeof(buf) - len, 228 len += snprintf(buf + len, sizeof(buf) - len,
229 "%20s : %10u\n", "VO queued", 229 "%20s : %10u\n", "VO queued",
230 priv->debug.tx_stats.queue_stats[WME_AC_VO]); 230 priv->debug.tx_stats.queue_stats[IEEE80211_AC_VO]);
231 231
232 if (len > sizeof(buf)) 232 if (len > sizeof(buf))
233 len = sizeof(buf); 233 len = sizeof(buf);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index 0eacfc13c91..105582d6b71 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -207,7 +207,7 @@ void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product)
207 priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; 207 priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
208 ath9k_hw_btcoex_init_3wire(priv->ah); 208 ath9k_hw_btcoex_init_3wire(priv->ah);
209 ath_htc_init_btcoex_work(priv); 209 ath_htc_init_btcoex_work(priv);
210 qnum = priv->hwq_map[WME_AC_BE]; 210 qnum = priv->hwq_map[IEEE80211_AC_BE];
211 ath9k_hw_init_btcoex_hw(priv->ah, qnum); 211 ath9k_hw_init_btcoex_hw(priv->ah, qnum);
212 break; 212 break;
213 default: 213 default:
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 5ecf1287ddd..05d5ba66cac 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -549,20 +549,20 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv)
549 goto err; 549 goto err;
550 } 550 }
551 551
552 if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) { 552 if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_BE)) {
553 ath_err(common, "Unable to setup xmit queue for BE traffic\n"); 553 ath_err(common, "Unable to setup xmit queue for BE traffic\n");
554 goto err; 554 goto err;
555 } 555 }
556 556
557 if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) { 557 if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_BK)) {
558 ath_err(common, "Unable to setup xmit queue for BK traffic\n"); 558 ath_err(common, "Unable to setup xmit queue for BK traffic\n");
559 goto err; 559 goto err;
560 } 560 }
561 if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) { 561 if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_VI)) {
562 ath_err(common, "Unable to setup xmit queue for VI traffic\n"); 562 ath_err(common, "Unable to setup xmit queue for VI traffic\n");
563 goto err; 563 goto err;
564 } 564 }
565 if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) { 565 if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_VO)) {
566 ath_err(common, "Unable to setup xmit queue for VO traffic\n"); 566 ath_err(common, "Unable to setup xmit queue for VO traffic\n");
567 goto err; 567 goto err;
568 } 568 }
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 66f6a74c508..9c07a8fa513 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -127,8 +127,9 @@ static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
127 priv->rearm_ani = false; 127 priv->rearm_ani = false;
128 priv->reconfig_beacon = false; 128 priv->reconfig_beacon = false;
129 129
130 ieee80211_iterate_active_interfaces_atomic(priv->hw, 130 ieee80211_iterate_active_interfaces_atomic(
131 ath9k_htc_vif_iter, priv); 131 priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
132 ath9k_htc_vif_iter, priv);
132 if (priv->rearm_ani) 133 if (priv->rearm_ani)
133 ath9k_htc_start_ani(priv); 134 ath9k_htc_start_ani(priv);
134 135
@@ -165,8 +166,9 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
165 ath9k_htc_bssid_iter(&iter_data, vif->addr, vif); 166 ath9k_htc_bssid_iter(&iter_data, vif->addr, vif);
166 167
167 /* Get list of all active MAC addresses */ 168 /* Get list of all active MAC addresses */
168 ieee80211_iterate_active_interfaces_atomic(priv->hw, ath9k_htc_bssid_iter, 169 ieee80211_iterate_active_interfaces_atomic(
169 &iter_data); 170 priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
171 ath9k_htc_bssid_iter, &iter_data);
170 172
171 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); 173 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
172 ath_hw_setbssidmask(common); 174 ath_hw_setbssidmask(common);
@@ -1144,8 +1146,9 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1144 */ 1146 */
1145 if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) { 1147 if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) {
1146 priv->rearm_ani = false; 1148 priv->rearm_ani = false;
1147 ieee80211_iterate_active_interfaces_atomic(priv->hw, 1149 ieee80211_iterate_active_interfaces_atomic(
1148 ath9k_htc_vif_iter, priv); 1150 priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1151 ath9k_htc_vif_iter, priv);
1149 if (!priv->rearm_ani) 1152 if (!priv->rearm_ani)
1150 ath9k_htc_stop_ani(priv); 1153 ath9k_htc_stop_ani(priv);
1151 } 1154 }
@@ -1346,7 +1349,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
1346 struct ath9k_tx_queue_info qi; 1349 struct ath9k_tx_queue_info qi;
1347 int ret = 0, qnum; 1350 int ret = 0, qnum;
1348 1351
1349 if (queue >= WME_NUM_AC) 1352 if (queue >= IEEE80211_NUM_ACS)
1350 return 0; 1353 return 0;
1351 1354
1352 mutex_lock(&priv->mutex); 1355 mutex_lock(&priv->mutex);
@@ -1373,7 +1376,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
1373 } 1376 }
1374 1377
1375 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) && 1378 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
1376 (qnum == priv->hwq_map[WME_AC_BE])) 1379 (qnum == priv->hwq_map[IEEE80211_AC_BE]))
1377 ath9k_htc_beaconq_config(priv); 1380 ath9k_htc_beaconq_config(priv);
1378out: 1381out:
1379 ath9k_htc_ps_restore(priv); 1382 ath9k_htc_ps_restore(priv);
@@ -1466,8 +1469,9 @@ static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1466static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv) 1469static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv)
1467{ 1470{
1468 if (priv->num_sta_assoc_vif == 1) { 1471 if (priv->num_sta_assoc_vif == 1) {
1469 ieee80211_iterate_active_interfaces_atomic(priv->hw, 1472 ieee80211_iterate_active_interfaces_atomic(
1470 ath9k_htc_bss_iter, priv); 1473 priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1474 ath9k_htc_bss_iter, priv);
1471 ath9k_htc_set_bssid(priv); 1475 ath9k_htc_set_bssid(priv);
1472 } 1476 }
1473} 1477}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 06cdcb772d7..28cd50ee521 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -21,10 +21,10 @@
21/******/ 21/******/
22 22
23static const int subtype_txq_to_hwq[] = { 23static const int subtype_txq_to_hwq[] = {
24 [WME_AC_BE] = ATH_TXQ_AC_BE, 24 [IEEE80211_AC_BE] = ATH_TXQ_AC_BE,
25 [WME_AC_BK] = ATH_TXQ_AC_BK, 25 [IEEE80211_AC_BK] = ATH_TXQ_AC_BK,
26 [WME_AC_VI] = ATH_TXQ_AC_VI, 26 [IEEE80211_AC_VI] = ATH_TXQ_AC_VI,
27 [WME_AC_VO] = ATH_TXQ_AC_VO, 27 [IEEE80211_AC_VO] = ATH_TXQ_AC_VO,
28}; 28};
29 29
30#define ATH9K_HTC_INIT_TXQ(subtype) do { \ 30#define ATH9K_HTC_INIT_TXQ(subtype) do { \
@@ -41,15 +41,15 @@ int get_hw_qnum(u16 queue, int *hwq_map)
41{ 41{
42 switch (queue) { 42 switch (queue) {
43 case 0: 43 case 0:
44 return hwq_map[WME_AC_VO]; 44 return hwq_map[IEEE80211_AC_VO];
45 case 1: 45 case 1:
46 return hwq_map[WME_AC_VI]; 46 return hwq_map[IEEE80211_AC_VI];
47 case 2: 47 case 2:
48 return hwq_map[WME_AC_BE]; 48 return hwq_map[IEEE80211_AC_BE];
49 case 3: 49 case 3:
50 return hwq_map[WME_AC_BK]; 50 return hwq_map[IEEE80211_AC_BK];
51 default: 51 default:
52 return hwq_map[WME_AC_BE]; 52 return hwq_map[IEEE80211_AC_BE];
53 } 53 }
54} 54}
55 55
@@ -106,20 +106,20 @@ static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv,
106 106
107 switch (qnum) { 107 switch (qnum) {
108 case 0: 108 case 0:
109 TX_QSTAT_INC(WME_AC_VO); 109 TX_QSTAT_INC(IEEE80211_AC_VO);
110 epid = priv->data_vo_ep; 110 epid = priv->data_vo_ep;
111 break; 111 break;
112 case 1: 112 case 1:
113 TX_QSTAT_INC(WME_AC_VI); 113 TX_QSTAT_INC(IEEE80211_AC_VI);
114 epid = priv->data_vi_ep; 114 epid = priv->data_vi_ep;
115 break; 115 break;
116 case 2: 116 case 2:
117 TX_QSTAT_INC(WME_AC_BE); 117 TX_QSTAT_INC(IEEE80211_AC_BE);
118 epid = priv->data_be_ep; 118 epid = priv->data_be_ep;
119 break; 119 break;
120 case 3: 120 case 3:
121 default: 121 default:
122 TX_QSTAT_INC(WME_AC_BK); 122 TX_QSTAT_INC(IEEE80211_AC_BK);
123 epid = priv->data_bk_ep; 123 epid = priv->data_bk_ep;
124 break; 124 break;
125 } 125 }
@@ -1082,7 +1082,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
1082 rx_status->freq = hw->conf.channel->center_freq; 1082 rx_status->freq = hw->conf.channel->center_freq;
1083 rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; 1083 rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
1084 rx_status->antenna = rxbuf->rxstatus.rs_antenna; 1084 rx_status->antenna = rxbuf->rxstatus.rs_antenna;
1085 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 1085 rx_status->flag |= RX_FLAG_MACTIME_START;
1086 1086
1087 return true; 1087 return true;
1088 1088
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 741e73dece3..e06bcec655a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2561,11 +2561,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2561 pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; 2561 pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
2562 } 2562 }
2563 2563
2564 if (AR_SREV_9485_10(ah)) {
2565 pCap->pcie_lcr_extsync_en = true;
2566 pCap->pcie_lcr_offset = 0x80;
2567 }
2568
2569 if (ath9k_hw_dfs_tested(ah)) 2564 if (ath9k_hw_dfs_tested(ah))
2570 pCap->hw_caps |= ATH9K_HW_CAP_DFS; 2565 pCap->hw_caps |= ATH9K_HW_CAP_DFS;
2571 2566
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 3e73bfe2315..3636dabf03e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -273,8 +273,6 @@ struct ath9k_hw_capabilities {
273 u8 rx_status_len; 273 u8 rx_status_len;
274 u8 tx_desc_len; 274 u8 tx_desc_len;
275 u8 txs_len; 275 u8 txs_len;
276 u16 pcie_lcr_offset;
277 bool pcie_lcr_extsync_en;
278}; 276};
279 277
280struct ath9k_ops_config { 278struct ath9k_ops_config {
@@ -877,7 +875,6 @@ struct ath_hw {
877 struct ar5416IniArray iniModesTxGain; 875 struct ar5416IniArray iniModesTxGain;
878 struct ar5416IniArray iniCckfirNormal; 876 struct ar5416IniArray iniCckfirNormal;
879 struct ar5416IniArray iniCckfirJapan2484; 877 struct ar5416IniArray iniCckfirJapan2484;
880 struct ar5416IniArray ini_japan2484;
881 struct ar5416IniArray iniModes_9271_ANI_reg; 878 struct ar5416IniArray iniModes_9271_ANI_reg;
882 struct ar5416IniArray ini_radio_post_sys2ant; 879 struct ar5416IniArray ini_radio_post_sys2ant;
883 880
@@ -930,7 +927,6 @@ struct ath_bus_ops {
930 void (*read_cachesize)(struct ath_common *common, int *csz); 927 void (*read_cachesize)(struct ath_common *common, int *csz);
931 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); 928 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
932 void (*bt_coex_prep)(struct ath_common *common); 929 void (*bt_coex_prep)(struct ath_common *common);
933 void (*extn_synch_en)(struct ath_common *common);
934 void (*aspm_init)(struct ath_common *common); 930 void (*aspm_init)(struct ath_common *common);
935}; 931};
936 932
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 546bae93647..80cae53a33e 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -435,7 +435,7 @@ static int ath9k_init_queues(struct ath_softc *sc)
435 sc->config.cabqReadytime = ATH_CABQ_READY_TIME; 435 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
436 ath_cabq_update(sc); 436 ath_cabq_update(sc);
437 437
438 for (i = 0; i < WME_NUM_AC; i++) { 438 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
439 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); 439 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
440 sc->tx.txq_map[i]->mac80211_qnum = i; 440 sc->tx.txq_map[i]->mac80211_qnum = i;
441 sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH; 441 sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH;
@@ -563,10 +563,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
563 spin_lock_init(&sc->sc_serial_rw); 563 spin_lock_init(&sc->sc_serial_rw);
564 spin_lock_init(&sc->sc_pm_lock); 564 spin_lock_init(&sc->sc_pm_lock);
565 mutex_init(&sc->mutex); 565 mutex_init(&sc->mutex);
566#ifdef CONFIG_ATH9K_DEBUGFS
567 spin_lock_init(&sc->nodes_lock);
568 INIT_LIST_HEAD(&sc->nodes);
569#endif
570#ifdef CONFIG_ATH9K_MAC_DEBUG 566#ifdef CONFIG_ATH9K_MAC_DEBUG
571 spin_lock_init(&sc->debug.samp_lock); 567 spin_lock_init(&sc->debug.samp_lock);
572#endif 568#endif
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 223b9693527..fc6b075ad63 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -27,9 +27,6 @@ void ath_tx_complete_poll_work(struct work_struct *work)
27 struct ath_txq *txq; 27 struct ath_txq *txq;
28 int i; 28 int i;
29 bool needreset = false; 29 bool needreset = false;
30#ifdef CONFIG_ATH9K_DEBUGFS
31 sc->tx_complete_poll_work_seen++;
32#endif
33 30
34 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) 31 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
35 if (ATH_TXQ_SETUP(sc, i)) { 32 if (ATH_TXQ_SETUP(sc, i)) {
@@ -211,7 +208,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int
211 int time_left; 208 int time_left;
212 209
213 memset(&txctl, 0, sizeof(txctl)); 210 memset(&txctl, 0, sizeof(txctl));
214 txctl.txq = sc->tx.txq_map[WME_AC_BE]; 211 txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE];
215 212
216 memset(tx_info, 0, sizeof(*tx_info)); 213 memset(tx_info, 0, sizeof(*tx_info));
217 tx_info->band = hw->conf.channel->band; 214 tx_info->band = hw->conf.channel->band;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 578a7234aa5..0653dbc99e3 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -331,11 +331,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
331 u8 density; 331 u8 density;
332 an = (struct ath_node *)sta->drv_priv; 332 an = (struct ath_node *)sta->drv_priv;
333 333
334#ifdef CONFIG_ATH9K_DEBUGFS
335 spin_lock(&sc->nodes_lock);
336 list_add(&an->list, &sc->nodes);
337 spin_unlock(&sc->nodes_lock);
338#endif
339 an->sta = sta; 334 an->sta = sta;
340 an->vif = vif; 335 an->vif = vif;
341 336
@@ -352,13 +347,6 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
352{ 347{
353 struct ath_node *an = (struct ath_node *)sta->drv_priv; 348 struct ath_node *an = (struct ath_node *)sta->drv_priv;
354 349
355#ifdef CONFIG_ATH9K_DEBUGFS
356 spin_lock(&sc->nodes_lock);
357 list_del(&an->list);
358 spin_unlock(&sc->nodes_lock);
359 an->sta = NULL;
360#endif
361
362 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) 350 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
363 ath_tx_node_cleanup(sc, an); 351 ath_tx_node_cleanup(sc, an);
364} 352}
@@ -494,17 +482,6 @@ irqreturn_t ath_isr(int irq, void *dev)
494 if (status & SCHED_INTR) 482 if (status & SCHED_INTR)
495 sched = true; 483 sched = true;
496 484
497#ifdef CONFIG_PM_SLEEP
498 if (status & ATH9K_INT_BMISS) {
499 if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
500 ath_dbg(common, ANY, "during WoW we got a BMISS\n");
501 atomic_inc(&sc->wow_got_bmiss_intr);
502 atomic_dec(&sc->wow_sleep_proc_intr);
503 }
504 ath_dbg(common, INTERRUPT, "beacon miss interrupt\n");
505 }
506#endif
507
508 /* 485 /*
509 * If a FATAL or RXORN interrupt is received, we have to reset the 486 * If a FATAL or RXORN interrupt is received, we have to reset the
510 * chip immediately. 487 * chip immediately.
@@ -523,7 +500,15 @@ irqreturn_t ath_isr(int irq, void *dev)
523 500
524 goto chip_reset; 501 goto chip_reset;
525 } 502 }
526 503#ifdef CONFIG_PM_SLEEP
504 if (status & ATH9K_INT_BMISS) {
505 if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
506 ath_dbg(common, ANY, "during WoW we got a BMISS\n");
507 atomic_inc(&sc->wow_got_bmiss_intr);
508 atomic_dec(&sc->wow_sleep_proc_intr);
509 }
510 }
511#endif
527 if (status & ATH9K_INT_SWBA) 512 if (status & ATH9K_INT_SWBA)
528 tasklet_schedule(&sc->bcon_tasklet); 513 tasklet_schedule(&sc->bcon_tasklet);
529 514
@@ -686,9 +671,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
686 671
687 spin_unlock_bh(&sc->sc_pcu_lock); 672 spin_unlock_bh(&sc->sc_pcu_lock);
688 673
689 if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
690 common->bus_ops->extn_synch_en(common);
691
692 mutex_unlock(&sc->mutex); 674 mutex_unlock(&sc->mutex);
693 675
694 ath9k_ps_restore(sc); 676 ath9k_ps_restore(sc);
@@ -924,8 +906,9 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
924 ath9k_vif_iter(iter_data, vif->addr, vif); 906 ath9k_vif_iter(iter_data, vif->addr, vif);
925 907
926 /* Get list of all active MAC addresses */ 908 /* Get list of all active MAC addresses */
927 ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter, 909 ieee80211_iterate_active_interfaces_atomic(
928 iter_data); 910 sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
911 ath9k_vif_iter, iter_data);
929} 912}
930 913
931/* Called with sc->mutex held. */ 914/* Called with sc->mutex held. */
@@ -975,8 +958,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
975 if (ah->opmode == NL80211_IFTYPE_STATION && 958 if (ah->opmode == NL80211_IFTYPE_STATION &&
976 old_opmode == NL80211_IFTYPE_AP && 959 old_opmode == NL80211_IFTYPE_AP &&
977 test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { 960 test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
978 ieee80211_iterate_active_interfaces_atomic(sc->hw, 961 ieee80211_iterate_active_interfaces_atomic(
979 ath9k_sta_vif_iter, sc); 962 sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
963 ath9k_sta_vif_iter, sc);
980 } 964 }
981} 965}
982 966
@@ -1329,7 +1313,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
1329 struct ath9k_tx_queue_info qi; 1313 struct ath9k_tx_queue_info qi;
1330 int ret = 0; 1314 int ret = 0;
1331 1315
1332 if (queue >= WME_NUM_AC) 1316 if (queue >= IEEE80211_NUM_ACS)
1333 return 0; 1317 return 0;
1334 1318
1335 txq = sc->tx.txq_map[queue]; 1319 txq = sc->tx.txq_map[queue];
@@ -1505,8 +1489,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1505 clear_bit(SC_OP_BEACONS, &sc->sc_flags); 1489 clear_bit(SC_OP_BEACONS, &sc->sc_flags);
1506 } 1490 }
1507 1491
1508 ieee80211_iterate_active_interfaces_atomic(sc->hw, 1492 ieee80211_iterate_active_interfaces_atomic(
1509 ath9k_bss_assoc_iter, sc); 1493 sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1494 ath9k_bss_assoc_iter, sc);
1510 1495
1511 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags) && 1496 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags) &&
1512 ah->opmode == NL80211_IFTYPE_STATION) { 1497 ah->opmode == NL80211_IFTYPE_STATION) {
@@ -1956,13 +1941,12 @@ static int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
1956 return 0; 1941 return 0;
1957} 1942}
1958 1943
1959#define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum)
1960#define AWDATA(elem) \ 1944#define AWDATA(elem) \
1961 do { \ 1945 do { \
1962 data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem; \ 1946 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \
1963 data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem; \ 1947 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \
1964 data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem; \ 1948 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem; \
1965 data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem; \ 1949 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem; \
1966 } while (0) 1950 } while (0)
1967 1951
1968#define AWDATA_RX(elem) \ 1952#define AWDATA_RX(elem) \
@@ -1977,14 +1961,14 @@ static void ath9k_get_et_stats(struct ieee80211_hw *hw,
1977 struct ath_softc *sc = hw->priv; 1961 struct ath_softc *sc = hw->priv;
1978 int i = 0; 1962 int i = 0;
1979 1963
1980 data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_pkts_all + 1964 data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all +
1981 sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_pkts_all + 1965 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all +
1982 sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_pkts_all + 1966 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all +
1983 sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_pkts_all); 1967 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all);
1984 data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_bytes_all + 1968 data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all +
1985 sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_bytes_all + 1969 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all +
1986 sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_bytes_all + 1970 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all +
1987 sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_bytes_all); 1971 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all);
1988 AWDATA_RX(rx_pkts_all); 1972 AWDATA_RX(rx_pkts_all);
1989 AWDATA_RX(rx_bytes_all); 1973 AWDATA_RX(rx_bytes_all);
1990 1974
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index 0dd2cbb52d6..706378ea3ba 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -207,23 +207,6 @@ skip_tuning:
207 ath9k_btcoex_timer_resume(sc); 207 ath9k_btcoex_timer_resume(sc);
208} 208}
209 209
210static void ath_mci_wait_btcal_done(struct ath_softc *sc)
211{
212 struct ath_hw *ah = sc->sc_ah;
213
214 /* Stop tx & rx */
215 ieee80211_stop_queues(sc->hw);
216 ath_stoprecv(sc);
217 ath_drain_all_txq(sc, false);
218
219 /* Wait for cal done */
220 ar9003_mci_start_reset(ah, ah->curchan);
221
222 /* Resume tx & rx */
223 ath_startrecv(sc);
224 ieee80211_wake_queues(sc->hw);
225}
226
227static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) 210static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
228{ 211{
229 struct ath_hw *ah = sc->sc_ah; 212 struct ath_hw *ah = sc->sc_ah;
@@ -235,7 +218,7 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
235 case MCI_GPM_BT_CAL_REQ: 218 case MCI_GPM_BT_CAL_REQ:
236 if (mci_hw->bt_state == MCI_BT_AWAKE) { 219 if (mci_hw->bt_state == MCI_BT_AWAKE) {
237 mci_hw->bt_state = MCI_BT_CAL_START; 220 mci_hw->bt_state = MCI_BT_CAL_START;
238 ath_mci_wait_btcal_done(sc); 221 ath9k_queue_reset(sc, RESET_TYPE_MCI);
239 } 222 }
240 ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); 223 ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state);
241 break; 224 break;
@@ -578,6 +561,8 @@ void ath_mci_intr(struct ath_softc *sc)
578 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM; 561 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM;
579 562
580 while (more_data == MCI_GPM_MORE) { 563 while (more_data == MCI_GPM_MORE) {
564 if (test_bit(SC_OP_HW_RESET, &sc->sc_flags))
565 return;
581 566
582 pgpm = mci->gpm_buf.bf_addr; 567 pgpm = mci->gpm_buf.bf_addr;
583 offset = ar9003_mci_get_next_gpm_offset(ah, false, 568 offset = ar9003_mci_get_next_gpm_offset(ah, false,
@@ -744,12 +729,30 @@ void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel,
744 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); 729 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
745} 730}
746 731
732static void ath9k_mci_stomp_audio(struct ath_softc *sc)
733{
734 struct ath_hw *ah = sc->sc_ah;
735 struct ath_btcoex *btcoex = &sc->btcoex;
736 struct ath_mci_profile *mci = &btcoex->mci;
737
738 if (!mci->num_sco && !mci->num_a2dp)
739 return;
740
741 if (ah->stats.avgbrssi > 25) {
742 btcoex->stomp_audio = 0;
743 return;
744 }
745
746 btcoex->stomp_audio++;
747}
747void ath9k_mci_update_rssi(struct ath_softc *sc) 748void ath9k_mci_update_rssi(struct ath_softc *sc)
748{ 749{
749 struct ath_hw *ah = sc->sc_ah; 750 struct ath_hw *ah = sc->sc_ah;
750 struct ath_btcoex *btcoex = &sc->btcoex; 751 struct ath_btcoex *btcoex = &sc->btcoex;
751 struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; 752 struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci;
752 753
754 ath9k_mci_stomp_audio(sc);
755
753 if (!(mci_hw->config & ATH_MCI_CONFIG_CONCUR_TX)) 756 if (!(mci_hw->config & ATH_MCI_CONFIG_CONCUR_TX))
754 return; 757 return;
755 758
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index f088f4bf9a2..9553203ee62 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -96,17 +96,6 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
96 return true; 96 return true;
97} 97}
98 98
99static void ath_pci_extn_synch_enable(struct ath_common *common)
100{
101 struct ath_softc *sc = (struct ath_softc *) common->priv;
102 struct pci_dev *pdev = to_pci_dev(sc->dev);
103 u8 lnkctl;
104
105 pci_read_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, &lnkctl);
106 lnkctl |= PCI_EXP_LNKCTL_ES;
107 pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl);
108}
109
110/* Need to be called after we discover btcoex capabilities */ 99/* Need to be called after we discover btcoex capabilities */
111static void ath_pci_aspm_init(struct ath_common *common) 100static void ath_pci_aspm_init(struct ath_common *common)
112{ 101{
@@ -153,7 +142,6 @@ static const struct ath_bus_ops ath_pci_bus_ops = {
153 .ath_bus_type = ATH_PCI, 142 .ath_bus_type = ATH_PCI,
154 .read_cachesize = ath_pci_read_cachesize, 143 .read_cachesize = ath_pci_read_cachesize,
155 .eeprom_read = ath_pci_eeprom_read, 144 .eeprom_read = ath_pci_eeprom_read,
156 .extn_synch_en = ath_pci_extn_synch_enable,
157 .aspm_init = ath_pci_aspm_init, 145 .aspm_init = ath_pci_aspm_init,
158}; 146};
159 147
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 27ed80b5488..714558d1ba7 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -982,16 +982,6 @@ static void ath_rc_update_per(struct ath_softc *sc,
982 } 982 }
983} 983}
984 984
985static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
986 int xretries, int retries, u8 per)
987{
988 struct ath_rc_stats *stats = &rc->rcstats[rix];
989
990 stats->xretries += xretries;
991 stats->retries += retries;
992 stats->per = per;
993}
994
995static void ath_rc_update_ht(struct ath_softc *sc, 985static void ath_rc_update_ht(struct ath_softc *sc,
996 struct ath_rate_priv *ath_rc_priv, 986 struct ath_rate_priv *ath_rc_priv,
997 struct ieee80211_tx_info *tx_info, 987 struct ieee80211_tx_info *tx_info,
@@ -1065,14 +1055,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1065 1055
1066} 1056}
1067 1057
1068static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
1069{
1070 struct ath_rc_stats *stats;
1071
1072 stats = &rc->rcstats[final_rate];
1073 stats->success++;
1074}
1075
1076static void ath_rc_tx_status(struct ath_softc *sc, 1058static void ath_rc_tx_status(struct ath_softc *sc,
1077 struct ath_rate_priv *ath_rc_priv, 1059 struct ath_rate_priv *ath_rc_priv,
1078 struct sk_buff *skb) 1060 struct sk_buff *skb)
@@ -1350,7 +1332,25 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1350 } 1332 }
1351} 1333}
1352 1334
1353#ifdef CONFIG_ATH9K_DEBUGFS 1335#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
1336
1337void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
1338{
1339 struct ath_rc_stats *stats;
1340
1341 stats = &rc->rcstats[final_rate];
1342 stats->success++;
1343}
1344
1345void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
1346 int xretries, int retries, u8 per)
1347{
1348 struct ath_rc_stats *stats = &rc->rcstats[rix];
1349
1350 stats->xretries += xretries;
1351 stats->retries += retries;
1352 stats->per = per;
1353}
1354 1354
1355static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, 1355static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
1356 size_t count, loff_t *ppos) 1356 size_t count, loff_t *ppos)
@@ -1428,10 +1428,17 @@ static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta,
1428 struct dentry *dir) 1428 struct dentry *dir)
1429{ 1429{
1430 struct ath_rate_priv *rc = priv_sta; 1430 struct ath_rate_priv *rc = priv_sta;
1431 debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat); 1431 rc->debugfs_rcstats = debugfs_create_file("rc_stats", S_IRUGO,
1432 dir, rc, &fops_rcstat);
1433}
1434
1435static void ath_rate_remove_sta_debugfs(void *priv, void *priv_sta)
1436{
1437 struct ath_rate_priv *rc = priv_sta;
1438 debugfs_remove(rc->debugfs_rcstats);
1432} 1439}
1433 1440
1434#endif /* CONFIG_ATH9K_DEBUGFS */ 1441#endif /* CONFIG_MAC80211_DEBUGFS && CONFIG_ATH9K_DEBUGFS */
1435 1442
1436static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 1443static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1437{ 1444{
@@ -1476,8 +1483,10 @@ static struct rate_control_ops ath_rate_ops = {
1476 .free = ath_rate_free, 1483 .free = ath_rate_free,
1477 .alloc_sta = ath_rate_alloc_sta, 1484 .alloc_sta = ath_rate_alloc_sta,
1478 .free_sta = ath_rate_free_sta, 1485 .free_sta = ath_rate_free_sta,
1479#ifdef CONFIG_ATH9K_DEBUGFS 1486
1487#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
1480 .add_sta_debugfs = ath_rate_add_sta_debugfs, 1488 .add_sta_debugfs = ath_rate_add_sta_debugfs,
1489 .remove_sta_debugfs = ath_rate_remove_sta_debugfs,
1481#endif 1490#endif
1482}; 1491};
1483 1492
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 268e67dc5fb..267dbfcfaa9 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -211,10 +211,26 @@ struct ath_rate_priv {
211 struct ath_rateset neg_ht_rates; 211 struct ath_rateset neg_ht_rates;
212 const struct ath_rate_table *rate_table; 212 const struct ath_rate_table *rate_table;
213 213
214#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
214 struct dentry *debugfs_rcstats; 215 struct dentry *debugfs_rcstats;
215 struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; 216 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
217#endif
216}; 218};
217 219
220#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
221void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate);
222void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
223 int xretries, int retries, u8 per);
224#else
225static inline void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
226{
227}
228static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
229 int xretries, int retries, u8 per)
230{
231}
232#endif
233
218#ifdef CONFIG_ATH9K_RATE_CONTROL 234#ifdef CONFIG_ATH9K_RATE_CONTROL
219int ath_rate_control_register(void); 235int ath_rate_control_register(void);
220void ath_rate_control_unregister(void); 236void ath_rate_control_unregister(void);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index a04028bce28..6aafbb77c49 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -976,7 +976,7 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
976 rx_status->freq = hw->conf.channel->center_freq; 976 rx_status->freq = hw->conf.channel->center_freq;
977 rx_status->signal = ah->noise + rx_stats->rs_rssi; 977 rx_status->signal = ah->noise + rx_stats->rs_rssi;
978 rx_status->antenna = rx_stats->rs_antenna; 978 rx_status->antenna = rx_stats->rs_antenna;
979 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 979 rx_status->flag |= RX_FLAG_MACTIME_START;
980 if (rx_stats->rs_moreaggr) 980 if (rx_stats->rs_moreaggr)
981 rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; 981 rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
982 982
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 741918a2027..34130943f9d 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1354,10 +1354,10 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
1354 struct ath_hw *ah = sc->sc_ah; 1354 struct ath_hw *ah = sc->sc_ah;
1355 struct ath9k_tx_queue_info qi; 1355 struct ath9k_tx_queue_info qi;
1356 static const int subtype_txq_to_hwq[] = { 1356 static const int subtype_txq_to_hwq[] = {
1357 [WME_AC_BE] = ATH_TXQ_AC_BE, 1357 [IEEE80211_AC_BE] = ATH_TXQ_AC_BE,
1358 [WME_AC_BK] = ATH_TXQ_AC_BK, 1358 [IEEE80211_AC_BK] = ATH_TXQ_AC_BK,
1359 [WME_AC_VI] = ATH_TXQ_AC_VI, 1359 [IEEE80211_AC_VI] = ATH_TXQ_AC_VI,
1360 [WME_AC_VO] = ATH_TXQ_AC_VO, 1360 [IEEE80211_AC_VO] = ATH_TXQ_AC_VO,
1361 }; 1361 };
1362 int axq_qnum, i; 1362 int axq_qnum, i;
1363 1363
@@ -2319,6 +2319,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2319 2319
2320 ath_txq_lock(sc, txq); 2320 ath_txq_lock(sc, txq);
2321 2321
2322 TX_STAT_INC(txq->axq_qnum, txprocdesc);
2323
2322 if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { 2324 if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
2323 ath_txq_unlock(sc, txq); 2325 ath_txq_unlock(sc, txq);
2324 return; 2326 return;
@@ -2464,7 +2466,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
2464 } 2466 }
2465 2467
2466 for (acno = 0, ac = &an->ac[acno]; 2468 for (acno = 0, ac = &an->ac[acno];
2467 acno < WME_NUM_AC; acno++, ac++) { 2469 acno < IEEE80211_NUM_ACS; acno++, ac++) {
2468 ac->sched = false; 2470 ac->sched = false;
2469 ac->txq = sc->tx.txq_map[acno]; 2471 ac->txq = sc->tx.txq_map[acno];
2470 INIT_LIST_HEAD(&ac->tid_q); 2472 INIT_LIST_HEAD(&ac->tid_q);
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
index 24ac2876a73..aaebecd19e5 100644
--- a/drivers/net/wireless/ath/carl9170/fw.c
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -28,11 +28,6 @@
28#include "fwcmd.h" 28#include "fwcmd.h"
29#include "version.h" 29#include "version.h"
30 30
31#define MAKE_STR(symbol) #symbol
32#define TO_STR(symbol) MAKE_STR(symbol)
33#define CARL9170FW_API_VER_STR TO_STR(CARL9170FW_API_MAX_VER)
34MODULE_VERSION(CARL9170FW_API_VER_STR ":" CARL9170FW_VERSION_GIT);
35
36static const u8 otus_magic[4] = { OTUS_MAGIC }; 31static const u8 otus_magic[4] = { OTUS_MAGIC };
37 32
38static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4], 33static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4],
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 136510edf3c..8cb206a8908 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -796,7 +796,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
796 status.mactime += mactime; 796 status.mactime += mactime;
797 if (low_mactime_now <= mactime) 797 if (low_mactime_now <= mactime)
798 status.mactime -= 0x10000; 798 status.mactime -= 0x10000;
799 status.flag |= RX_FLAG_MACTIME_MPDU; 799 status.flag |= RX_FLAG_MACTIME_START;
800 } 800 }
801 801
802 chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; 802 chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index b8ffea6f5c6..849a28c8030 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -557,7 +557,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
557 status.mactime += mactime; 557 status.mactime += mactime;
558 if (low_mactime_now <= mactime) 558 if (low_mactime_now <= mactime)
559 status.mactime -= 0x10000; 559 status.mactime -= 0x10000;
560 status.flag |= RX_FLAG_MACTIME_MPDU; 560 status.flag |= RX_FLAG_MACTIME_START;
561 } 561 }
562 562
563 chanid = (chanstat & B43legacy_RX_CHAN_ID) >> 563 chanid = (chanstat & B43legacy_RX_CHAN_ID) >>
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index c9d811eb655..1d92d874ebb 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -55,13 +55,16 @@ config BRCMFMAC_USB
55 IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to 55 IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
56 use the driver for an USB wireless card. 56 use the driver for an USB wireless card.
57 57
58config BRCMISCAN 58config BRCM_TRACING
59 bool "Broadcom I-Scan (OBSOLETE)" 59 bool "Broadcom device tracing"
60 depends on BRCMFMAC 60 depends on BRCMSMAC || BRCMFMAC
61 ---help--- 61 ---help---
62 This option enables the I-Scan method. By default fullmac uses the 62 If you say Y here, the Broadcom wireless drivers will register
63 new E-Scan method which uses less memory in firmware and gives no 63 with ftrace to dump event information into the trace ringbuffer.
64 limitation on the number of scan results. 64 Tracing can be enabled at runtime to aid in debugging wireless
65 issues. This option adds a small amount of overhead when tracing
66 is disabled. If unsure, say Y to allow developers to better help
67 you when wireless problems occur.
65 68
66config BRCMDBG 69config BRCMDBG
67 bool "Broadcom driver debug functions" 70 bool "Broadcom driver debug functions"
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index fe80b637c51..1a6661a9f00 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
25brcmfmac-objs += \ 25brcmfmac-objs += \
26 wl_cfg80211.o \ 26 wl_cfg80211.o \
27 fwil.o \ 27 fwil.o \
28 fweh.o \
28 dhd_cdc.o \ 29 dhd_cdc.o \
29 dhd_common.o \ 30 dhd_common.o \
30 dhd_linux.o 31 dhd_linux.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 3b2c4c20e7f..334ddab4a8c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -42,7 +42,8 @@
42#ifdef CONFIG_BRCMFMAC_SDIO_OOB 42#ifdef CONFIG_BRCMFMAC_SDIO_OOB
43static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) 43static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id)
44{ 44{
45 struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id); 45 struct brcmf_bus *bus_if = dev_get_drvdata(dev_id);
46 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
46 47
47 brcmf_dbg(INTR, "oob intr triggered\n"); 48 brcmf_dbg(INTR, "oob intr triggered\n");
48 49
@@ -71,7 +72,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
71 brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq); 72 brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq);
72 ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, 73 ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler,
73 sdiodev->irq_flags, "brcmf_oob_intr", 74 sdiodev->irq_flags, "brcmf_oob_intr",
74 &sdiodev->func[1]->card->dev); 75 &sdiodev->func[1]->dev);
75 if (ret != 0) 76 if (ret != 0)
76 return ret; 77 return ret;
77 spin_lock_init(&sdiodev->irq_en_lock); 78 spin_lock_init(&sdiodev->irq_en_lock);
@@ -84,6 +85,8 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
84 return ret; 85 return ret;
85 sdiodev->irq_wake = true; 86 sdiodev->irq_wake = true;
86 87
88 sdio_claim_host(sdiodev->func[1]);
89
87 /* must configure SDIO_CCCR_IENx to enable irq */ 90 /* must configure SDIO_CCCR_IENx to enable irq */
88 data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); 91 data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
89 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; 92 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
@@ -95,6 +98,8 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
95 data |= SDIO_SEPINT_ACT_HI; 98 data |= SDIO_SEPINT_ACT_HI;
96 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); 99 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
97 100
101 sdio_release_host(sdiodev->func[1]);
102
98 return 0; 103 return 0;
99} 104}
100 105
@@ -102,14 +107,16 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
102{ 107{
103 brcmf_dbg(TRACE, "Entering\n"); 108 brcmf_dbg(TRACE, "Entering\n");
104 109
110 sdio_claim_host(sdiodev->func[1]);
105 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); 111 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
106 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); 112 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
113 sdio_release_host(sdiodev->func[1]);
107 114
108 if (sdiodev->irq_wake) { 115 if (sdiodev->irq_wake) {
109 disable_irq_wake(sdiodev->irq); 116 disable_irq_wake(sdiodev->irq);
110 sdiodev->irq_wake = false; 117 sdiodev->irq_wake = false;
111 } 118 }
112 free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev); 119 free_irq(sdiodev->irq, &sdiodev->func[1]->dev);
113 sdiodev->irq_en = false; 120 sdiodev->irq_en = false;
114 121
115 return 0; 122 return 0;
@@ -117,7 +124,8 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
117#else /* CONFIG_BRCMFMAC_SDIO_OOB */ 124#else /* CONFIG_BRCMFMAC_SDIO_OOB */
118static void brcmf_sdio_irqhandler(struct sdio_func *func) 125static void brcmf_sdio_irqhandler(struct sdio_func *func)
119{ 126{
120 struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); 127 struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev);
128 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
121 129
122 brcmf_dbg(INTR, "ib intr triggered\n"); 130 brcmf_dbg(INTR, "ib intr triggered\n");
123 131
@@ -249,9 +257,7 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
249 int retval; 257 int retval;
250 258
251 brcmf_dbg(INFO, "addr:0x%08x\n", addr); 259 brcmf_dbg(INFO, "addr:0x%08x\n", addr);
252 sdio_claim_host(sdiodev->func[1]);
253 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); 260 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
254 sdio_release_host(sdiodev->func[1]);
255 brcmf_dbg(INFO, "data:0x%02x\n", data); 261 brcmf_dbg(INFO, "data:0x%02x\n", data);
256 262
257 if (ret) 263 if (ret)
@@ -266,9 +272,7 @@ u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
266 int retval; 272 int retval;
267 273
268 brcmf_dbg(INFO, "addr:0x%08x\n", addr); 274 brcmf_dbg(INFO, "addr:0x%08x\n", addr);
269 sdio_claim_host(sdiodev->func[1]);
270 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); 275 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
271 sdio_release_host(sdiodev->func[1]);
272 brcmf_dbg(INFO, "data:0x%08x\n", data); 276 brcmf_dbg(INFO, "data:0x%08x\n", data);
273 277
274 if (ret) 278 if (ret)
@@ -283,9 +287,7 @@ void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
283 int retval; 287 int retval;
284 288
285 brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); 289 brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data);
286 sdio_claim_host(sdiodev->func[1]);
287 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); 290 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
288 sdio_release_host(sdiodev->func[1]);
289 291
290 if (ret) 292 if (ret)
291 *ret = retval; 293 *ret = retval;
@@ -297,9 +299,7 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
297 int retval; 299 int retval;
298 300
299 brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); 301 brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data);
300 sdio_claim_host(sdiodev->func[1]);
301 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); 302 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
302 sdio_release_host(sdiodev->func[1]);
303 303
304 if (ret) 304 if (ret)
305 *ret = retval; 305 *ret = retval;
@@ -364,8 +364,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
364 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", 364 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
365 fn, addr, pkt->len); 365 fn, addr, pkt->len);
366 366
367 sdio_claim_host(sdiodev->func[1]);
368
369 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 367 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
370 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); 368 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
371 if (err) 369 if (err)
@@ -376,8 +374,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
376 fn, addr, pkt); 374 fn, addr, pkt);
377 375
378done: 376done:
379 sdio_release_host(sdiodev->func[1]);
380
381 return err; 377 return err;
382} 378}
383 379
@@ -391,8 +387,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
391 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", 387 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
392 fn, addr, pktq->qlen); 388 fn, addr, pktq->qlen);
393 389
394 sdio_claim_host(sdiodev->func[1]);
395
396 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 390 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
397 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); 391 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
398 if (err) 392 if (err)
@@ -403,8 +397,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
403 pktq); 397 pktq);
404 398
405done: 399done:
406 sdio_release_host(sdiodev->func[1]);
407
408 return err; 400 return err;
409} 401}
410 402
@@ -446,8 +438,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
446 if (flags & SDIO_REQ_ASYNC) 438 if (flags & SDIO_REQ_ASYNC)
447 return -ENOTSUPP; 439 return -ENOTSUPP;
448 440
449 sdio_claim_host(sdiodev->func[1]);
450
451 if (bar0 != sdiodev->sbwad) { 441 if (bar0 != sdiodev->sbwad) {
452 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); 442 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
453 if (err) 443 if (err)
@@ -467,8 +457,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
467 addr, pkt); 457 addr, pkt);
468 458
469done: 459done:
470 sdio_release_host(sdiodev->func[1]);
471
472 return err; 460 return err;
473} 461}
474 462
@@ -510,10 +498,8 @@ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
510 brcmf_dbg(TRACE, "Enter\n"); 498 brcmf_dbg(TRACE, "Enter\n");
511 499
512 /* issue abort cmd52 command through F0 */ 500 /* issue abort cmd52 command through F0 */
513 sdio_claim_host(sdiodev->func[1]);
514 brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, 501 brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
515 SDIO_CCCR_ABORT, &t_func); 502 SDIO_CCCR_ABORT, &t_func);
516 sdio_release_host(sdiodev->func[1]);
517 503
518 brcmf_dbg(TRACE, "Exit\n"); 504 brcmf_dbg(TRACE, "Exit\n");
519 return 0; 505 return 0;
@@ -530,9 +516,6 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
530 516
531 regs = SI_ENUM_BASE; 517 regs = SI_ENUM_BASE;
532 518
533 /* Report the BAR, to fix if needed */
534 sdiodev->sbwad = SI_ENUM_BASE;
535
536 /* try to attach to the target device */ 519 /* try to attach to the target device */
537 sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); 520 sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev);
538 if (!sdiodev->bus) { 521 if (!sdiodev->bus) {
@@ -551,6 +534,8 @@ EXPORT_SYMBOL(brcmf_sdio_probe);
551 534
552int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) 535int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
553{ 536{
537 sdiodev->bus_if->state = BRCMF_BUS_DOWN;
538
554 if (sdiodev->bus) { 539 if (sdiodev->bus) {
555 brcmf_sdbrcm_disconnect(sdiodev->bus); 540 brcmf_sdbrcm_disconnect(sdiodev->bus);
556 sdiodev->bus = NULL; 541 sdiodev->bus = NULL;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index c3247d5b3c2..a8005022371 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -372,9 +372,7 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
372 } 372 }
373 373
374 /* Enable Function 1 */ 374 /* Enable Function 1 */
375 sdio_claim_host(sdiodev->func[1]);
376 err_ret = sdio_enable_func(sdiodev->func[1]); 375 err_ret = sdio_enable_func(sdiodev->func[1]);
377 sdio_release_host(sdiodev->func[1]);
378 if (err_ret) 376 if (err_ret)
379 brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret); 377 brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret);
380 378
@@ -393,16 +391,14 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
393 sdiodev->num_funcs = 2; 391 sdiodev->num_funcs = 2;
394 392
395 sdio_claim_host(sdiodev->func[1]); 393 sdio_claim_host(sdiodev->func[1]);
394
396 err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); 395 err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
397 sdio_release_host(sdiodev->func[1]);
398 if (err_ret) { 396 if (err_ret) {
399 brcmf_dbg(ERROR, "Failed to set F1 blocksize\n"); 397 brcmf_dbg(ERROR, "Failed to set F1 blocksize\n");
400 goto out; 398 goto out;
401 } 399 }
402 400
403 sdio_claim_host(sdiodev->func[2]);
404 err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); 401 err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
405 sdio_release_host(sdiodev->func[2]);
406 if (err_ret) { 402 if (err_ret) {
407 brcmf_dbg(ERROR, "Failed to set F2 blocksize\n"); 403 brcmf_dbg(ERROR, "Failed to set F2 blocksize\n");
408 goto out; 404 goto out;
@@ -411,6 +407,7 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
411 brcmf_sdioh_enablefuncs(sdiodev); 407 brcmf_sdioh_enablefuncs(sdiodev);
412 408
413out: 409out:
410 sdio_release_host(sdiodev->func[1]);
414 brcmf_dbg(TRACE, "Done\n"); 411 brcmf_dbg(TRACE, "Done\n");
415 return err_ret; 412 return err_ret;
416} 413}
@@ -459,95 +456,106 @@ static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
459#endif /* CONFIG_BRCMFMAC_SDIO_OOB */ 456#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
460 457
461static int brcmf_ops_sdio_probe(struct sdio_func *func, 458static int brcmf_ops_sdio_probe(struct sdio_func *func,
462 const struct sdio_device_id *id) 459 const struct sdio_device_id *id)
463{ 460{
464 int ret = 0; 461 int err;
465 struct brcmf_sdio_dev *sdiodev; 462 struct brcmf_sdio_dev *sdiodev;
466 struct brcmf_bus *bus_if; 463 struct brcmf_bus *bus_if;
467 464
468 brcmf_dbg(TRACE, "Enter\n"); 465 brcmf_dbg(TRACE, "Enter\n");
469 brcmf_dbg(TRACE, "func->class=%x\n", func->class); 466 brcmf_dbg(TRACE, "Class=%x\n", func->class);
470 brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor); 467 brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor);
471 brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device); 468 brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device);
472 brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num); 469 brcmf_dbg(TRACE, "Function#: %d\n", func->num);
473 470
474 if (func->num == 1) { 471 /* Consume func num 1 but dont do anything with it. */
475 if (dev_get_drvdata(&func->card->dev)) { 472 if (func->num == 1)
476 brcmf_dbg(ERROR, "card private drvdata occupied\n"); 473 return 0;
477 return -ENXIO; 474
478 } 475 /* Ignore anything but func 2 */
479 bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); 476 if (func->num != 2)
480 if (!bus_if) 477 return -ENODEV;
481 return -ENOMEM; 478
482 sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); 479 bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
483 if (!sdiodev) { 480 if (!bus_if)
484 kfree(bus_if); 481 return -ENOMEM;
485 return -ENOMEM; 482 sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
486 } 483 if (!sdiodev) {
487 sdiodev->func[0] = func; 484 kfree(bus_if);
488 sdiodev->func[1] = func; 485 return -ENOMEM;
489 sdiodev->bus_if = bus_if;
490 bus_if->bus_priv.sdio = sdiodev;
491 bus_if->type = SDIO_BUS;
492 bus_if->align = BRCMF_SDALIGN;
493 dev_set_drvdata(&func->card->dev, sdiodev);
494
495 atomic_set(&sdiodev->suspend, false);
496 init_waitqueue_head(&sdiodev->request_byte_wait);
497 init_waitqueue_head(&sdiodev->request_word_wait);
498 init_waitqueue_head(&sdiodev->request_chain_wait);
499 init_waitqueue_head(&sdiodev->request_buffer_wait);
500 } 486 }
501 487
502 if (func->num == 2) { 488 sdiodev->func[0] = func->card->sdio_func[0];
503 sdiodev = dev_get_drvdata(&func->card->dev); 489 sdiodev->func[1] = func->card->sdio_func[0];
504 if ((!sdiodev) || (sdiodev->func[1]->card != func->card)) 490 sdiodev->func[2] = func;
505 return -ENODEV;
506
507 ret = brcmf_sdio_getintrcfg(sdiodev);
508 if (ret)
509 return ret;
510 sdiodev->func[2] = func;
511 491
512 bus_if = sdiodev->bus_if; 492 sdiodev->bus_if = bus_if;
513 sdiodev->dev = &func->dev; 493 bus_if->bus_priv.sdio = sdiodev;
514 dev_set_drvdata(&func->dev, bus_if); 494 bus_if->align = BRCMF_SDALIGN;
495 dev_set_drvdata(&func->dev, bus_if);
496 dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
497 sdiodev->dev = &sdiodev->func[1]->dev;
515 498
516 brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); 499 atomic_set(&sdiodev->suspend, false);
517 ret = brcmf_sdio_probe(sdiodev); 500 init_waitqueue_head(&sdiodev->request_byte_wait);
501 init_waitqueue_head(&sdiodev->request_word_wait);
502 init_waitqueue_head(&sdiodev->request_chain_wait);
503 init_waitqueue_head(&sdiodev->request_buffer_wait);
504 err = brcmf_sdio_getintrcfg(sdiodev);
505 if (err)
506 goto fail;
507
508 brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
509 err = brcmf_sdio_probe(sdiodev);
510 if (err) {
511 brcmf_dbg(ERROR, "F2 error, probe failed %d...\n", err);
512 goto fail;
518 } 513 }
514 brcmf_dbg(TRACE, "F2 init completed...\n");
515 return 0;
519 516
520 return ret; 517fail:
518 dev_set_drvdata(&func->dev, NULL);
519 dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
520 kfree(sdiodev);
521 kfree(bus_if);
522 return err;
521} 523}
522 524
523static void brcmf_ops_sdio_remove(struct sdio_func *func) 525static void brcmf_ops_sdio_remove(struct sdio_func *func)
524{ 526{
525 struct brcmf_bus *bus_if; 527 struct brcmf_bus *bus_if;
526 struct brcmf_sdio_dev *sdiodev; 528 struct brcmf_sdio_dev *sdiodev;
529
527 brcmf_dbg(TRACE, "Enter\n"); 530 brcmf_dbg(TRACE, "Enter\n");
528 brcmf_dbg(INFO, "func->class=%x\n", func->class); 531 brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor);
529 brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor); 532 brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device);
530 brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device); 533 brcmf_dbg(TRACE, "Function: %d\n", func->num);
531 brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
532 534
533 if (func->num == 2) { 535 if (func->num != 1 && func->num != 2)
534 bus_if = dev_get_drvdata(&func->dev); 536 return;
537
538 bus_if = dev_get_drvdata(&func->dev);
539 if (bus_if) {
535 sdiodev = bus_if->bus_priv.sdio; 540 sdiodev = bus_if->bus_priv.sdio;
536 brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
537 brcmf_sdio_remove(sdiodev); 541 brcmf_sdio_remove(sdiodev);
538 dev_set_drvdata(&func->card->dev, NULL); 542
539 dev_set_drvdata(&func->dev, NULL); 543 dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
544 dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
545
540 kfree(bus_if); 546 kfree(bus_if);
541 kfree(sdiodev); 547 kfree(sdiodev);
542 } 548 }
549
550 brcmf_dbg(TRACE, "Exit\n");
543} 551}
544 552
545#ifdef CONFIG_PM_SLEEP 553#ifdef CONFIG_PM_SLEEP
546static int brcmf_sdio_suspend(struct device *dev) 554static int brcmf_sdio_suspend(struct device *dev)
547{ 555{
548 mmc_pm_flag_t sdio_flags; 556 mmc_pm_flag_t sdio_flags;
549 struct sdio_func *func = dev_to_sdio_func(dev); 557 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
550 struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); 558 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
551 int ret = 0; 559 int ret = 0;
552 560
553 brcmf_dbg(TRACE, "\n"); 561 brcmf_dbg(TRACE, "\n");
@@ -573,8 +581,8 @@ static int brcmf_sdio_suspend(struct device *dev)
573 581
574static int brcmf_sdio_resume(struct device *dev) 582static int brcmf_sdio_resume(struct device *dev)
575{ 583{
576 struct sdio_func *func = dev_to_sdio_func(dev); 584 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
577 struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); 585 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
578 586
579 brcmf_sdio_wdtmr_enable(sdiodev, true); 587 brcmf_sdio_wdtmr_enable(sdiodev, true);
580 atomic_set(&sdiodev->suspend, false); 588 atomic_set(&sdiodev->suspend, false);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 8704daa2758..24bc4e3e162 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -23,6 +23,8 @@
23 23
24#define BRCMF_VERSION_STR "4.218.248.5" 24#define BRCMF_VERSION_STR "4.218.248.5"
25 25
26#include "fweh.h"
27
26/******************************************************************************* 28/*******************************************************************************
27 * IO codes that are interpreted by dongle firmware 29 * IO codes that are interpreted by dongle firmware
28 ******************************************************************************/ 30 ******************************************************************************/
@@ -38,8 +40,11 @@
38#define BRCMF_C_GET_SSID 25 40#define BRCMF_C_GET_SSID 25
39#define BRCMF_C_SET_SSID 26 41#define BRCMF_C_SET_SSID 26
40#define BRCMF_C_GET_CHANNEL 29 42#define BRCMF_C_GET_CHANNEL 29
43#define BRCMF_C_SET_CHANNEL 30
41#define BRCMF_C_GET_SRL 31 44#define BRCMF_C_GET_SRL 31
45#define BRCMF_C_SET_SRL 32
42#define BRCMF_C_GET_LRL 33 46#define BRCMF_C_GET_LRL 33
47#define BRCMF_C_SET_LRL 34
43#define BRCMF_C_GET_RADIO 37 48#define BRCMF_C_GET_RADIO 37
44#define BRCMF_C_SET_RADIO 38 49#define BRCMF_C_SET_RADIO 38
45#define BRCMF_C_GET_PHYTYPE 39 50#define BRCMF_C_GET_PHYTYPE 39
@@ -58,6 +63,7 @@
58#define BRCMF_C_SET_COUNTRY 84 63#define BRCMF_C_SET_COUNTRY 84
59#define BRCMF_C_GET_PM 85 64#define BRCMF_C_GET_PM 85
60#define BRCMF_C_SET_PM 86 65#define BRCMF_C_SET_PM 86
66#define BRCMF_C_GET_CURR_RATESET 114
61#define BRCMF_C_GET_AP 117 67#define BRCMF_C_GET_AP 117
62#define BRCMF_C_SET_AP 118 68#define BRCMF_C_SET_AP 118
63#define BRCMF_C_GET_RSSI 127 69#define BRCMF_C_GET_RSSI 127
@@ -65,6 +71,7 @@
65#define BRCMF_C_SET_WSEC 134 71#define BRCMF_C_SET_WSEC 134
66#define BRCMF_C_GET_PHY_NOISE 135 72#define BRCMF_C_GET_PHY_NOISE 135
67#define BRCMF_C_GET_BSS_INFO 136 73#define BRCMF_C_GET_BSS_INFO 136
74#define BRCMF_C_GET_PHYLIST 180
68#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 75#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
69#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 76#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
70#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 77#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
@@ -100,29 +107,8 @@
100#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff 107#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
101#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 108#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
102 109
103#define BRCMF_SCAN_ACTION_START 1
104#define BRCMF_SCAN_ACTION_CONTINUE 2
105#define WL_SCAN_ACTION_ABORT 3
106
107#define BRCMF_ISCAN_REQ_VERSION 1
108
109/* brcmf_iscan_results status values */
110#define BRCMF_SCAN_RESULTS_SUCCESS 0
111#define BRCMF_SCAN_RESULTS_PARTIAL 1
112#define BRCMF_SCAN_RESULTS_PENDING 2
113#define BRCMF_SCAN_RESULTS_ABORTED 3
114#define BRCMF_SCAN_RESULTS_NO_MEM 4
115
116/* Indicates this key is using soft encrypt */
117#define WL_SOFT_KEY (1 << 0)
118/* primary (ie tx) key */ 110/* primary (ie tx) key */
119#define BRCMF_PRIMARY_KEY (1 << 1) 111#define BRCMF_PRIMARY_KEY (1 << 1)
120/* Reserved for backward compat */
121#define WL_KF_RES_4 (1 << 4)
122/* Reserved for backward compat */
123#define WL_KF_RES_5 (1 << 5)
124/* Indicates a group key for a IBSS PEER */
125#define WL_IBSS_PEER_GROUP_KEY (1 << 6)
126 112
127/* For supporting multiple interfaces */ 113/* For supporting multiple interfaces */
128#define BRCMF_MAX_IFS 16 114#define BRCMF_MAX_IFS 16
@@ -130,10 +116,6 @@
130#define DOT11_BSSTYPE_ANY 2 116#define DOT11_BSSTYPE_ANY 2
131#define DOT11_MAX_DEFAULT_KEYS 4 117#define DOT11_MAX_DEFAULT_KEYS 4
132 118
133#define BRCMF_EVENT_MSG_LINK 0x01
134#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
135#define BRCMF_EVENT_MSG_GROUP 0x04
136
137#define BRCMF_ESCAN_REQ_VERSION 1 119#define BRCMF_ESCAN_REQ_VERSION 1
138 120
139#define WLC_BSS_RSSI_ON_CHANNEL 0x0002 121#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
@@ -141,108 +123,6 @@
141#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ 123#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
142#define BRCMF_STA_ASSOC 0x10 /* Associated */ 124#define BRCMF_STA_ASSOC 0x10 /* Associated */
143 125
144struct brcmf_event_msg {
145 __be16 version;
146 __be16 flags;
147 __be32 event_type;
148 __be32 status;
149 __be32 reason;
150 __be32 auth_type;
151 __be32 datalen;
152 u8 addr[ETH_ALEN];
153 char ifname[IFNAMSIZ];
154 u8 ifidx;
155 u8 bsscfgidx;
156} __packed;
157
158struct brcm_ethhdr {
159 u16 subtype;
160 u16 length;
161 u8 version;
162 u8 oui[3];
163 u16 usr_subtype;
164} __packed;
165
166struct brcmf_event {
167 struct ethhdr eth;
168 struct brcm_ethhdr hdr;
169 struct brcmf_event_msg msg;
170} __packed;
171
172/* event codes sent by the dongle to this driver */
173#define BRCMF_E_SET_SSID 0
174#define BRCMF_E_JOIN 1
175#define BRCMF_E_START 2
176#define BRCMF_E_AUTH 3
177#define BRCMF_E_AUTH_IND 4
178#define BRCMF_E_DEAUTH 5
179#define BRCMF_E_DEAUTH_IND 6
180#define BRCMF_E_ASSOC 7
181#define BRCMF_E_ASSOC_IND 8
182#define BRCMF_E_REASSOC 9
183#define BRCMF_E_REASSOC_IND 10
184#define BRCMF_E_DISASSOC 11
185#define BRCMF_E_DISASSOC_IND 12
186#define BRCMF_E_QUIET_START 13
187#define BRCMF_E_QUIET_END 14
188#define BRCMF_E_BEACON_RX 15
189#define BRCMF_E_LINK 16
190#define BRCMF_E_MIC_ERROR 17
191#define BRCMF_E_NDIS_LINK 18
192#define BRCMF_E_ROAM 19
193#define BRCMF_E_TXFAIL 20
194#define BRCMF_E_PMKID_CACHE 21
195#define BRCMF_E_RETROGRADE_TSF 22
196#define BRCMF_E_PRUNE 23
197#define BRCMF_E_AUTOAUTH 24
198#define BRCMF_E_EAPOL_MSG 25
199#define BRCMF_E_SCAN_COMPLETE 26
200#define BRCMF_E_ADDTS_IND 27
201#define BRCMF_E_DELTS_IND 28
202#define BRCMF_E_BCNSENT_IND 29
203#define BRCMF_E_BCNRX_MSG 30
204#define BRCMF_E_BCNLOST_MSG 31
205#define BRCMF_E_ROAM_PREP 32
206#define BRCMF_E_PFN_NET_FOUND 33
207#define BRCMF_E_PFN_NET_LOST 34
208#define BRCMF_E_RESET_COMPLETE 35
209#define BRCMF_E_JOIN_START 36
210#define BRCMF_E_ROAM_START 37
211#define BRCMF_E_ASSOC_START 38
212#define BRCMF_E_IBSS_ASSOC 39
213#define BRCMF_E_RADIO 40
214#define BRCMF_E_PSM_WATCHDOG 41
215#define BRCMF_E_PROBREQ_MSG 44
216#define BRCMF_E_SCAN_CONFIRM_IND 45
217#define BRCMF_E_PSK_SUP 46
218#define BRCMF_E_COUNTRY_CODE_CHANGED 47
219#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48
220#define BRCMF_E_ICV_ERROR 49
221#define BRCMF_E_UNICAST_DECODE_ERROR 50
222#define BRCMF_E_MULTICAST_DECODE_ERROR 51
223#define BRCMF_E_TRACE 52
224#define BRCMF_E_IF 54
225#define BRCMF_E_RSSI 56
226#define BRCMF_E_PFN_SCAN_COMPLETE 57
227#define BRCMF_E_EXTLOG_MSG 58
228#define BRCMF_E_ACTION_FRAME 59
229#define BRCMF_E_ACTION_FRAME_COMPLETE 60
230#define BRCMF_E_PRE_ASSOC_IND 61
231#define BRCMF_E_PRE_REASSOC_IND 62
232#define BRCMF_E_CHANNEL_ADOPTED 63
233#define BRCMF_E_AP_STARTED 64
234#define BRCMF_E_DFS_AP_STOP 65
235#define BRCMF_E_DFS_AP_RESUME 66
236#define BRCMF_E_RESERVED1 67
237#define BRCMF_E_RESERVED2 68
238#define BRCMF_E_ESCAN_RESULT 69
239#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70
240#define BRCMF_E_DCS_REQUEST 73
241
242#define BRCMF_E_FIFO_CREDIT_MAP 74
243
244#define BRCMF_E_LAST 75
245
246#define BRCMF_E_STATUS_SUCCESS 0 126#define BRCMF_E_STATUS_SUCCESS 0
247#define BRCMF_E_STATUS_FAIL 1 127#define BRCMF_E_STATUS_FAIL 1
248#define BRCMF_E_STATUS_TIMEOUT 2 128#define BRCMF_E_STATUS_TIMEOUT 2
@@ -403,7 +283,7 @@ struct brcm_rateset_le {
403 /* # rates in this set */ 283 /* # rates in this set */
404 __le32 count; 284 __le32 count;
405 /* rates in 500kbps units w/hi bit set if basic */ 285 /* rates in 500kbps units w/hi bit set if basic */
406 u8 rates[WL_NUMRATES]; 286 u8 rates[BRCMF_MAXRATES_IN_SET];
407}; 287};
408 288
409struct brcmf_ssid { 289struct brcmf_ssid {
@@ -452,14 +332,6 @@ struct brcmf_scan_params_le {
452 __le16 channel_list[1]; /* list of chanspecs */ 332 __le16 channel_list[1]; /* list of chanspecs */
453}; 333};
454 334
455/* incremental scan struct */
456struct brcmf_iscan_params_le {
457 __le32 version;
458 __le16 action;
459 __le16 scan_duration;
460 struct brcmf_scan_params_le params_le;
461};
462
463struct brcmf_scan_results { 335struct brcmf_scan_results {
464 u32 buflen; 336 u32 buflen;
465 u32 version; 337 u32 version;
@@ -467,12 +339,6 @@ struct brcmf_scan_results {
467 struct brcmf_bss_info_le bss_info_le[]; 339 struct brcmf_bss_info_le bss_info_le[];
468}; 340};
469 341
470struct brcmf_scan_results_le {
471 __le32 buflen;
472 __le32 version;
473 __le32 count;
474};
475
476struct brcmf_escan_params_le { 342struct brcmf_escan_params_le {
477 __le32 version; 343 __le32 version;
478 __le16 action; 344 __le16 action;
@@ -508,23 +374,6 @@ struct brcmf_join_params {
508 struct brcmf_assoc_params_le params_le; 374 struct brcmf_assoc_params_le params_le;
509}; 375};
510 376
511/* incremental scan results struct */
512struct brcmf_iscan_results {
513 union {
514 u32 status;
515 __le32 status_le;
516 };
517 union {
518 struct brcmf_scan_results results;
519 struct brcmf_scan_results_le results_le;
520 };
521};
522
523/* size of brcmf_iscan_results not including variable length array */
524#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
525 (sizeof(struct brcmf_scan_results) + \
526 offsetof(struct brcmf_iscan_results, results))
527
528struct brcmf_wsec_key { 377struct brcmf_wsec_key {
529 u32 index; /* key index */ 378 u32 index; /* key index */
530 u32 len; /* key length */ 379 u32 len; /* key length */
@@ -661,10 +510,11 @@ struct brcmf_pub {
661 struct mutex proto_block; 510 struct mutex proto_block;
662 unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; 511 unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
663 512
664 struct work_struct setmacaddr_work;
665 struct work_struct multicast_work;
666 u8 macvalue[ETH_ALEN]; 513 u8 macvalue[ETH_ALEN];
667 atomic_t pend_8021x_cnt; 514 atomic_t pend_8021x_cnt;
515 wait_queue_head_t pend_8021x_wait;
516
517 struct brcmf_fweh_info fweh;
668#ifdef DEBUG 518#ifdef DEBUG
669 struct dentry *dbgfs_dir; 519 struct dentry *dbgfs_dir;
670#endif 520#endif
@@ -701,6 +551,8 @@ struct brcmf_if {
701 struct brcmf_cfg80211_vif *vif; 551 struct brcmf_cfg80211_vif *vif;
702 struct net_device *ndev; 552 struct net_device *ndev;
703 struct net_device_stats stats; 553 struct net_device_stats stats;
554 struct work_struct setmacaddr_work;
555 struct work_struct multicast_work;
704 int idx; 556 int idx;
705 s32 bssidx; 557 s32 bssidx;
706 u8 mac_addr[ETH_ALEN]; 558 u8 mac_addr[ETH_ALEN];
@@ -714,9 +566,6 @@ static inline s32 brcmf_ndev_bssidx(struct net_device *ndev)
714 566
715extern const struct bcmevent_name bcmevent_names[]; 567extern const struct bcmevent_name bcmevent_names[];
716 568
717extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
718 char *buf, uint len);
719
720extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); 569extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
721 570
722/* Return pointer to interface name */ 571/* Return pointer to interface name */
@@ -728,14 +577,9 @@ extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
728extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, 577extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
729 void *buf, uint len); 578 void *buf, uint len);
730 579
731extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name);
732extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx,
733 void *pktdata, struct brcmf_event_msg *,
734 void **data_ptr);
735
736extern int brcmf_net_attach(struct brcmf_if *ifp); 580extern int brcmf_net_attach(struct brcmf_if *ifp);
737extern struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, 581extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx,
738 char *name, u8 *mac_addr); 582 s32 bssidx, char *name, u8 *mac_addr);
739extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); 583extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx);
740 584
741#endif /* _BRCMF_H_ */ 585#endif /* _BRCMF_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 265580f5b27..b8f248797f6 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -45,7 +45,6 @@ struct brcmf_bus_dcmd {
45 45
46/* interface structure between common and bus layer */ 46/* interface structure between common and bus layer */
47struct brcmf_bus { 47struct brcmf_bus {
48 u8 type; /* bus type */
49 union { 48 union {
50 struct brcmf_sdio_dev *sdio; 49 struct brcmf_sdio_dev *sdio;
51 struct brcmf_usbdev *usb; 50 struct brcmf_usbdev *usb;
@@ -85,7 +84,7 @@ extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
85 struct sk_buff *pkt, int prec); 84 struct sk_buff *pkt, int prec);
86 85
87/* Receive frame for delivery to OS. Callee disposes of rxp. */ 86/* Receive frame for delivery to OS. Callee disposes of rxp. */
88extern void brcmf_rx_frame(struct device *dev, int ifidx, 87extern void brcmf_rx_frame(struct device *dev, u8 ifidx,
89 struct sk_buff_head *rxlist); 88 struct sk_buff_head *rxlist);
90static inline void brcmf_rx_packet(struct device *dev, int ifidx, 89static inline void brcmf_rx_packet(struct device *dev, int ifidx,
91 struct sk_buff *pkt) 90 struct sk_buff *pkt)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
index b9d8a5adfd4..87536d38a4c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -23,8 +23,6 @@
23 23
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/netdevice.h> 25#include <linux/netdevice.h>
26#include <linux/sched.h>
27#include <defs.h>
28 26
29#include <brcmu_utils.h> 27#include <brcmu_utils.h>
30#include <brcmu_wifi.h> 28#include <brcmu_wifi.h>
@@ -277,76 +275,6 @@ done:
277 return ret; 275 return ret;
278} 276}
279 277
280int
281brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd,
282 int len)
283{
284 struct brcmf_proto *prot = drvr->prot;
285 int ret = -1;
286
287 if (drvr->bus_if->state == BRCMF_BUS_DOWN) {
288 brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
289 return ret;
290 }
291 mutex_lock(&drvr->proto_block);
292
293 brcmf_dbg(TRACE, "Enter\n");
294
295 if (len > BRCMF_DCMD_MAXLEN)
296 goto done;
297
298 if (prot->pending == true) {
299 brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
300 dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd,
301 (unsigned long)prot->lastcmd);
302 if (dcmd->cmd == BRCMF_C_SET_VAR ||
303 dcmd->cmd == BRCMF_C_GET_VAR)
304 brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf);
305
306 goto done;
307 }
308
309 prot->pending = true;
310 prot->lastcmd = dcmd->cmd;
311 if (dcmd->set)
312 ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd,
313 dcmd->buf, len);
314 else {
315 ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd,
316 dcmd->buf, len);
317 if (ret > 0)
318 dcmd->used = ret -
319 sizeof(struct brcmf_proto_cdc_dcmd);
320 }
321
322 if (ret >= 0)
323 ret = 0;
324 else {
325 struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
326 /* len == needed when set/query fails from dongle */
327 dcmd->needed = le32_to_cpu(msg->len);
328 }
329
330 /* Intercept the wme_dp dongle cmd here */
331 if (!ret && dcmd->cmd == BRCMF_C_SET_VAR &&
332 !strcmp(dcmd->buf, "wme_dp")) {
333 int slen;
334 __le32 val = 0;
335
336 slen = strlen("wme_dp") + 1;
337 if (len >= (int)(slen + sizeof(int)))
338 memcpy(&val, (char *)dcmd->buf + slen, sizeof(int));
339 drvr->wme_dp = (u8) le32_to_cpu(val);
340 }
341
342 prot->pending = false;
343
344done:
345 mutex_unlock(&drvr->proto_block);
346
347 return ret;
348}
349
350static bool pkt_sum_needed(struct sk_buff *skb) 278static bool pkt_sum_needed(struct sk_buff *skb)
351{ 279{
352 return skb->ip_summed == CHECKSUM_PARTIAL; 280 return skb->ip_summed == CHECKSUM_PARTIAL;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 866b66995bb..eee7175f151 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -18,10 +18,7 @@
18 18
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/string.h> 20#include <linux/string.h>
21#include <linux/sched.h>
22#include <linux/netdevice.h> 21#include <linux/netdevice.h>
23#include <asm/unaligned.h>
24#include <defs.h>
25#include <brcmu_wifi.h> 22#include <brcmu_wifi.h>
26#include <brcmu_utils.h> 23#include <brcmu_utils.h>
27#include "dhd.h" 24#include "dhd.h"
@@ -30,9 +27,6 @@
30#include "dhd_dbg.h" 27#include "dhd_dbg.h"
31#include "fwil.h" 28#include "fwil.h"
32 29
33#define BRCM_OUI "\x00\x10\x18"
34#define DOT11_OUI_LEN 3
35#define BCMILCP_BCM_SUBTYPE_EVENT 1
36#define PKTFILTER_BUF_SIZE 128 30#define PKTFILTER_BUF_SIZE 128
37#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ 31#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */
38#define BRCMF_DEFAULT_BCN_TIMEOUT 3 32#define BRCMF_DEFAULT_BCN_TIMEOUT 3
@@ -40,12 +34,6 @@
40#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 34#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
41#define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" 35#define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00"
42 36
43#define MSGTRACE_VERSION 1
44
45#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter_le, u)
46#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \
47 offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern)
48
49#ifdef DEBUG 37#ifdef DEBUG
50static const char brcmf_version[] = 38static const char brcmf_version[] =
51 "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " 39 "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
@@ -55,43 +43,6 @@ static const char brcmf_version[] =
55 "Dongle Host Driver, version " BRCMF_VERSION_STR; 43 "Dongle Host Driver, version " BRCMF_VERSION_STR;
56#endif 44#endif
57 45
58/* Message trace header */
59struct msgtrace_hdr {
60 u8 version;
61 u8 spare;
62 __be16 len; /* Len of the trace */
63 __be32 seqnum; /* Sequence number of message. Useful
64 * if the messsage has been lost
65 * because of DMA error or a bus reset
66 * (ex: SDIO Func2)
67 */
68 __be32 discarded_bytes; /* Number of discarded bytes because of
69 trace overflow */
70 __be32 discarded_printf; /* Number of discarded printf
71 because of trace overflow */
72} __packed;
73
74
75uint
76brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
77{
78 uint len;
79
80 len = strlen(name) + 1;
81
82 if ((len + datalen) > buflen)
83 return 0;
84
85 strncpy(buf, name, buflen);
86
87 /* append data onto the end of the name string */
88 if (data && datalen) {
89 memcpy(&buf[len], data, datalen);
90 len += datalen;
91 }
92
93 return len;
94}
95 46
96bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, 47bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
97 struct sk_buff *pkt, int prec) 48 struct sk_buff *pkt, int prec)
@@ -143,405 +94,6 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
143 return p != NULL; 94 return p != NULL;
144} 95}
145 96
146#ifdef DEBUG
147static void
148brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
149{
150 uint i, status, reason;
151 bool group = false, flush_txq = false, link = false;
152 char *auth_str, *event_name;
153 unsigned char *buf;
154 char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
155 static struct {
156 uint event;
157 char *event_name;
158 } event_names[] = {
159 {
160 BRCMF_E_SET_SSID, "SET_SSID"}, {
161 BRCMF_E_JOIN, "JOIN"}, {
162 BRCMF_E_START, "START"}, {
163 BRCMF_E_AUTH, "AUTH"}, {
164 BRCMF_E_AUTH_IND, "AUTH_IND"}, {
165 BRCMF_E_DEAUTH, "DEAUTH"}, {
166 BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, {
167 BRCMF_E_ASSOC, "ASSOC"}, {
168 BRCMF_E_ASSOC_IND, "ASSOC_IND"}, {
169 BRCMF_E_REASSOC, "REASSOC"}, {
170 BRCMF_E_REASSOC_IND, "REASSOC_IND"}, {
171 BRCMF_E_DISASSOC, "DISASSOC"}, {
172 BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, {
173 BRCMF_E_QUIET_START, "START_QUIET"}, {
174 BRCMF_E_QUIET_END, "END_QUIET"}, {
175 BRCMF_E_BEACON_RX, "BEACON_RX"}, {
176 BRCMF_E_LINK, "LINK"}, {
177 BRCMF_E_MIC_ERROR, "MIC_ERROR"}, {
178 BRCMF_E_NDIS_LINK, "NDIS_LINK"}, {
179 BRCMF_E_ROAM, "ROAM"}, {
180 BRCMF_E_TXFAIL, "TXFAIL"}, {
181 BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, {
182 BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
183 BRCMF_E_PRUNE, "PRUNE"}, {
184 BRCMF_E_AUTOAUTH, "AUTOAUTH"}, {
185 BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, {
186 BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
187 BRCMF_E_ADDTS_IND, "ADDTS_IND"}, {
188 BRCMF_E_DELTS_IND, "DELTS_IND"}, {
189 BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, {
190 BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, {
191 BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
192 BRCMF_E_ROAM_PREP, "ROAM_PREP"}, {
193 BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
194 BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
195 BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
196 BRCMF_E_JOIN_START, "JOIN_START"}, {
197 BRCMF_E_ROAM_START, "ROAM_START"}, {
198 BRCMF_E_ASSOC_START, "ASSOC_START"}, {
199 BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
200 BRCMF_E_RADIO, "RADIO"}, {
201 BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
202 BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
203 BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
204 BRCMF_E_PSK_SUP, "PSK_SUP"}, {
205 BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
206 BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
207 BRCMF_E_ICV_ERROR, "ICV_ERROR"}, {
208 BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
209 BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
210 BRCMF_E_TRACE, "TRACE"}, {
211 BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, {
212 BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
213 BRCMF_E_IF, "IF"}, {
214 BRCMF_E_RSSI, "RSSI"}, {
215 BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
216 BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT"}
217 };
218 uint event_type, flags, auth_type, datalen;
219 static u32 seqnum_prev;
220 struct msgtrace_hdr hdr;
221 u32 nblost;
222 char *s, *p;
223
224 event_type = be32_to_cpu(event->event_type);
225 flags = be16_to_cpu(event->flags);
226 status = be32_to_cpu(event->status);
227 reason = be32_to_cpu(event->reason);
228 auth_type = be32_to_cpu(event->auth_type);
229 datalen = be32_to_cpu(event->datalen);
230 /* debug dump of event messages */
231 sprintf(eabuf, "%pM", event->addr);
232
233 event_name = "UNKNOWN";
234 for (i = 0; i < ARRAY_SIZE(event_names); i++) {
235 if (event_names[i].event == event_type)
236 event_name = event_names[i].event_name;
237 }
238
239 brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type);
240 brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
241 flags, status, reason, auth_type, eabuf);
242
243 if (flags & BRCMF_EVENT_MSG_LINK)
244 link = true;
245 if (flags & BRCMF_EVENT_MSG_GROUP)
246 group = true;
247 if (flags & BRCMF_EVENT_MSG_FLUSHTXQ)
248 flush_txq = true;
249
250 switch (event_type) {
251 case BRCMF_E_START:
252 case BRCMF_E_DEAUTH:
253 case BRCMF_E_DISASSOC:
254 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
255 break;
256
257 case BRCMF_E_ASSOC_IND:
258 case BRCMF_E_REASSOC_IND:
259 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
260 break;
261
262 case BRCMF_E_ASSOC:
263 case BRCMF_E_REASSOC:
264 if (status == BRCMF_E_STATUS_SUCCESS)
265 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n",
266 event_name, eabuf);
267 else if (status == BRCMF_E_STATUS_TIMEOUT)
268 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n",
269 event_name, eabuf);
270 else if (status == BRCMF_E_STATUS_FAIL)
271 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
272 event_name, eabuf, (int)reason);
273 else
274 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n",
275 event_name, eabuf, (int)status);
276 break;
277
278 case BRCMF_E_DEAUTH_IND:
279 case BRCMF_E_DISASSOC_IND:
280 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n",
281 event_name, eabuf, (int)reason);
282 break;
283
284 case BRCMF_E_AUTH:
285 case BRCMF_E_AUTH_IND:
286 if (auth_type == WLAN_AUTH_OPEN)
287 auth_str = "Open System";
288 else if (auth_type == WLAN_AUTH_SHARED_KEY)
289 auth_str = "Shared Key";
290 else {
291 sprintf(err_msg, "AUTH unknown: %d", (int)auth_type);
292 auth_str = err_msg;
293 }
294 if (event_type == BRCMF_E_AUTH_IND)
295 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n",
296 event_name, eabuf, auth_str);
297 else if (status == BRCMF_E_STATUS_SUCCESS)
298 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n",
299 event_name, eabuf, auth_str);
300 else if (status == BRCMF_E_STATUS_TIMEOUT)
301 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
302 event_name, eabuf, auth_str);
303 else if (status == BRCMF_E_STATUS_FAIL) {
304 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n",
305 event_name, eabuf, auth_str, (int)reason);
306 }
307
308 break;
309
310 case BRCMF_E_JOIN:
311 case BRCMF_E_ROAM:
312 case BRCMF_E_SET_SSID:
313 if (status == BRCMF_E_STATUS_SUCCESS)
314 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n",
315 event_name, eabuf);
316 else if (status == BRCMF_E_STATUS_FAIL)
317 brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name);
318 else if (status == BRCMF_E_STATUS_NO_NETWORKS)
319 brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n",
320 event_name);
321 else
322 brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n",
323 event_name, (int)status);
324 break;
325
326 case BRCMF_E_BEACON_RX:
327 if (status == BRCMF_E_STATUS_SUCCESS)
328 brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name);
329 else if (status == BRCMF_E_STATUS_FAIL)
330 brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name);
331 else
332 brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n",
333 event_name, status);
334 break;
335
336 case BRCMF_E_LINK:
337 brcmf_dbg(EVENT, "MACEVENT: %s %s\n",
338 event_name, link ? "UP" : "DOWN");
339 break;
340
341 case BRCMF_E_MIC_ERROR:
342 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
343 event_name, eabuf, group, flush_txq);
344 break;
345
346 case BRCMF_E_ICV_ERROR:
347 case BRCMF_E_UNICAST_DECODE_ERROR:
348 case BRCMF_E_MULTICAST_DECODE_ERROR:
349 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
350 break;
351
352 case BRCMF_E_TXFAIL:
353 brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf);
354 break;
355
356 case BRCMF_E_SCAN_COMPLETE:
357 case BRCMF_E_PMKID_CACHE:
358 brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
359 break;
360
361 case BRCMF_E_ESCAN_RESULT:
362 brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
363 datalen = 0;
364 break;
365
366 case BRCMF_E_PFN_NET_FOUND:
367 case BRCMF_E_PFN_NET_LOST:
368 case BRCMF_E_PFN_SCAN_COMPLETE:
369 brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name);
370 break;
371
372 case BRCMF_E_PSK_SUP:
373 case BRCMF_E_PRUNE:
374 brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n",
375 event_name, (int)status, (int)reason);
376 break;
377
378 case BRCMF_E_TRACE:
379 buf = (unsigned char *) event_data;
380 memcpy(&hdr, buf, sizeof(struct msgtrace_hdr));
381
382 if (hdr.version != MSGTRACE_VERSION) {
383 brcmf_dbg(ERROR,
384 "MACEVENT: %s [unsupported version --> brcmf"
385 " version:%d dongle version:%d]\n",
386 event_name, MSGTRACE_VERSION, hdr.version);
387 /* Reset datalen to avoid display below */
388 datalen = 0;
389 break;
390 }
391
392 /* There are 2 bytes available at the end of data */
393 *(buf + sizeof(struct msgtrace_hdr)
394 + be16_to_cpu(hdr.len)) = '\0';
395
396 if (be32_to_cpu(hdr.discarded_bytes)
397 || be32_to_cpu(hdr.discarded_printf))
398 brcmf_dbg(ERROR,
399 "WLC_E_TRACE: [Discarded traces in dongle -->"
400 " discarded_bytes %d discarded_printf %d]\n",
401 be32_to_cpu(hdr.discarded_bytes),
402 be32_to_cpu(hdr.discarded_printf));
403
404 nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1;
405 if (nblost > 0)
406 brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum "
407 " %d nblost %d\n", be32_to_cpu(hdr.seqnum),
408 nblost);
409 seqnum_prev = be32_to_cpu(hdr.seqnum);
410
411 /* Display the trace buffer. Advance from \n to \n to
412 * avoid display big
413 * printf (issue with Linux printk )
414 */
415 p = (char *)&buf[sizeof(struct msgtrace_hdr)];
416 while ((s = strstr(p, "\n")) != NULL) {
417 *s = '\0';
418 pr_debug("%s\n", p);
419 p = s + 1;
420 }
421 pr_debug("%s\n", p);
422
423 /* Reset datalen to avoid display below */
424 datalen = 0;
425 break;
426
427 case BRCMF_E_RSSI:
428 brcmf_dbg(EVENT, "MACEVENT: %s %d\n",
429 event_name, be32_to_cpu(*((__be32 *)event_data)));
430 break;
431
432 default:
433 brcmf_dbg(EVENT,
434 "MACEVENT: %s %d, MAC %s, status %d, reason %d, "
435 "auth %d\n", event_name, event_type, eabuf,
436 (int)status, (int)reason, (int)auth_type);
437 break;
438 }
439
440 /* show any appended data */
441 brcmf_dbg_hex_dump(datalen, event_data, datalen, "Received data");
442}
443#endif /* DEBUG */
444
445int
446brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
447 struct brcmf_event_msg *event, void **data_ptr)
448{
449 /* check whether packet is a BRCM event pkt */
450 struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata;
451 struct brcmf_if_event *ifevent;
452 struct brcmf_if *ifp;
453 char *event_data;
454 u32 type, status;
455 u16 flags;
456 int evlen;
457
458 if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) {
459 brcmf_dbg(ERROR, "mismatched OUI, bailing\n");
460 return -EBADE;
461 }
462
463 /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
464 if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) !=
465 BCMILCP_BCM_SUBTYPE_EVENT) {
466 brcmf_dbg(ERROR, "mismatched subtype, bailing\n");
467 return -EBADE;
468 }
469
470 *data_ptr = &pvt_data[1];
471 event_data = *data_ptr;
472
473 /* memcpy since BRCM event pkt may be unaligned. */
474 memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg));
475
476 type = get_unaligned_be32(&event->event_type);
477 flags = get_unaligned_be16(&event->flags);
478 status = get_unaligned_be32(&event->status);
479 evlen = get_unaligned_be32(&event->datalen) +
480 sizeof(struct brcmf_event);
481
482 switch (type) {
483 case BRCMF_E_IF:
484 ifevent = (struct brcmf_if_event *) event_data;
485 brcmf_dbg(TRACE, "if event\n");
486
487 if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) {
488 if (ifevent->action == BRCMF_E_IF_ADD) {
489 ifp = brcmf_add_if(drvr->dev, ifevent->ifidx,
490 ifevent->bssidx,
491 event->ifname,
492 pvt_data->eth.h_dest);
493 if (IS_ERR(ifp))
494 return PTR_ERR(ifp);
495 brcmf_net_attach(ifp);
496 } else {
497 brcmf_del_if(drvr, ifevent->ifidx);
498 }
499 } else {
500 brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n",
501 ifevent->ifidx, event->ifname);
502 }
503
504 /* send up the if event: btamp user needs it */
505 *ifidx = brcmf_ifname2idx(drvr, event->ifname);
506 break;
507
508 /* These are what external supplicant/authenticator wants */
509 case BRCMF_E_LINK:
510 case BRCMF_E_ASSOC_IND:
511 case BRCMF_E_REASSOC_IND:
512 case BRCMF_E_DISASSOC_IND:
513 case BRCMF_E_MIC_ERROR:
514 default:
515 /* Fall through: this should get _everything_ */
516
517 *ifidx = brcmf_ifname2idx(drvr, event->ifname);
518 brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n",
519 type, flags, status);
520
521 /* put it back to BRCMF_E_NDIS_LINK */
522 if (type == BRCMF_E_NDIS_LINK) {
523 u32 temp1;
524 __be32 temp2;
525
526 temp1 = get_unaligned_be32(&event->event_type);
527 brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n",
528 temp1);
529
530 temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK);
531 memcpy((void *)(&pvt_data->msg.event_type), &temp2,
532 sizeof(pvt_data->msg.event_type));
533 }
534 break;
535 }
536
537#ifdef DEBUG
538 if (BRCMF_EVENT_ON())
539 brcmf_c_show_host_event(event, event_data);
540#endif /* DEBUG */
541
542 return 0;
543}
544
545/* Convert user's input in hex pattern to byte-size mask */ 97/* Convert user's input in hex pattern to byte-size mask */
546static int brcmf_c_pattern_atoh(char *src, char *dst) 98static int brcmf_c_pattern_atoh(char *src, char *dst)
547{ 99{
@@ -686,8 +238,8 @@ static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg)
686 } 238 }
687 239
688 pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size); 240 pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size);
689 buf_len = sizeof(*pkt_filter); 241 buf_len = offsetof(struct brcmf_pkt_filter_le,
690 buf_len -= sizeof(pkt_filter->u.pattern.mask_and_pattern); 242 u.pattern.mask_and_pattern);
691 buf_len += mask_size + pattern_size; 243 buf_len += mask_size + pattern_size;
692 244
693 err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter, 245 err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
index 862d2acb7a1..7e58e8ce9ab 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -14,18 +14,12 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16#include <linux/debugfs.h> 16#include <linux/debugfs.h>
17#include <linux/if_ether.h>
18#include <linux/if.h>
19#include <linux/netdevice.h> 17#include <linux/netdevice.h>
20#include <linux/ieee80211.h>
21#include <linux/module.h> 18#include <linux/module.h>
22#include <linux/netdevice.h>
23 19
24#include <defs.h>
25#include <brcmu_wifi.h> 20#include <brcmu_wifi.h>
26#include <brcmu_utils.h> 21#include <brcmu_utils.h>
27#include "dhd.h" 22#include "dhd.h"
28#include "dhd_bus.h"
29#include "dhd_dbg.h" 23#include "dhd_dbg.h"
30 24
31static struct dentry *root_folder; 25static struct dentry *root_folder;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index eefa6c2560c..a0e18a1ceb4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -27,11 +27,11 @@
27#define BRCMF_HDRS_VAL 0x0040 27#define BRCMF_HDRS_VAL 0x0040
28#define BRCMF_BYTES_VAL 0x0080 28#define BRCMF_BYTES_VAL 0x0080
29#define BRCMF_INTR_VAL 0x0100 29#define BRCMF_INTR_VAL 0x0100
30#define BRCMF_GLOM_VAL 0x0400 30#define BRCMF_GLOM_VAL 0x0200
31#define BRCMF_EVENT_VAL 0x0800 31#define BRCMF_EVENT_VAL 0x0400
32#define BRCMF_BTA_VAL 0x1000 32#define BRCMF_BTA_VAL 0x0800
33#define BRCMF_ISCAN_VAL 0x2000 33#define BRCMF_FIL_VAL 0x1000
34#define BRCMF_FIL_VAL 0x4000 34#define BRCMF_USB_VAL 0x2000
35 35
36#if defined(DEBUG) 36#if defined(DEBUG)
37 37
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 297652339fd..b6c86b046c1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -16,27 +16,11 @@
16 16
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18 18
19#include <linux/init.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/kthread.h>
22#include <linux/slab.h>
23#include <linux/skbuff.h>
24#include <linux/netdevice.h>
25#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
26#include <linux/mmc/sdio_func.h>
27#include <linux/random.h>
28#include <linux/spinlock.h>
29#include <linux/ethtool.h>
30#include <linux/fcntl.h>
31#include <linux/fs.h>
32#include <linux/uaccess.h>
33#include <linux/hardirq.h>
34#include <linux/mutex.h>
35#include <linux/wait.h>
36#include <linux/module.h> 21#include <linux/module.h>
37#include <net/cfg80211.h> 22#include <net/cfg80211.h>
38#include <net/rtnetlink.h> 23#include <net/rtnetlink.h>
39#include <defs.h>
40#include <brcmu_utils.h> 24#include <brcmu_utils.h>
41#include <brcmu_wifi.h> 25#include <brcmu_wifi.h>
42 26
@@ -45,35 +29,19 @@
45#include "dhd_proto.h" 29#include "dhd_proto.h"
46#include "dhd_dbg.h" 30#include "dhd_dbg.h"
47#include "wl_cfg80211.h" 31#include "wl_cfg80211.h"
32#include "fwil.h"
48 33
49MODULE_AUTHOR("Broadcom Corporation"); 34MODULE_AUTHOR("Broadcom Corporation");
50MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); 35MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
51MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); 36MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards");
52MODULE_LICENSE("Dual BSD/GPL"); 37MODULE_LICENSE("Dual BSD/GPL");
53 38
39#define MAX_WAIT_FOR_8021X_TX 50 /* msecs */
54 40
55/* Error bits */ 41/* Error bits */
56int brcmf_msg_level = BRCMF_ERROR_VAL; 42int brcmf_msg_level = BRCMF_ERROR_VAL;
57module_param(brcmf_msg_level, int, 0); 43module_param(brcmf_msg_level, int, 0);
58 44
59int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name)
60{
61 int i = BRCMF_MAX_IFS;
62 struct brcmf_if *ifp;
63
64 if (name == NULL || *name == '\0')
65 return 0;
66
67 while (--i > 0) {
68 ifp = drvr->iflist[i];
69 if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ))
70 break;
71 }
72
73 brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name);
74
75 return i; /* default - the primary interface */
76}
77 45
78char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) 46char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
79{ 47{
@@ -95,38 +63,33 @@ char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
95 63
96static void _brcmf_set_multicast_list(struct work_struct *work) 64static void _brcmf_set_multicast_list(struct work_struct *work)
97{ 65{
66 struct brcmf_if *ifp;
98 struct net_device *ndev; 67 struct net_device *ndev;
99 struct netdev_hw_addr *ha; 68 struct netdev_hw_addr *ha;
100 u32 dcmd_value, cnt; 69 u32 cmd_value, cnt;
101 __le32 cnt_le; 70 __le32 cnt_le;
102 __le32 dcmd_le_value;
103
104 struct brcmf_dcmd dcmd;
105 char *buf, *bufp; 71 char *buf, *bufp;
106 uint buflen; 72 u32 buflen;
107 int ret; 73 s32 err;
108 74
109 struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, 75 brcmf_dbg(TRACE, "enter\n");
110 multicast_work);
111 76
112 ndev = drvr->iflist[0]->ndev; 77 ifp = container_of(work, struct brcmf_if, multicast_work);
113 cnt = netdev_mc_count(ndev); 78 ndev = ifp->ndev;
114 79
115 /* Determine initial value of allmulti flag */ 80 /* Determine initial value of allmulti flag */
116 dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false; 81 cmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;
117 82
118 /* Send down the multicast list first. */ 83 /* Send down the multicast list first. */
119 84 cnt = netdev_mc_count(ndev);
120 buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN); 85 buflen = sizeof(cnt) + (cnt * ETH_ALEN);
121 bufp = buf = kmalloc(buflen, GFP_ATOMIC); 86 buf = kmalloc(buflen, GFP_ATOMIC);
122 if (!bufp) 87 if (!buf)
123 return; 88 return;
124 89 bufp = buf;
125 strcpy(bufp, "mcast_list");
126 bufp += strlen("mcast_list") + 1;
127 90
128 cnt_le = cpu_to_le32(cnt); 91 cnt_le = cpu_to_le32(cnt);
129 memcpy(bufp, &cnt_le, sizeof(cnt)); 92 memcpy(bufp, &cnt_le, sizeof(cnt_le));
130 bufp += sizeof(cnt_le); 93 bufp += sizeof(cnt_le);
131 94
132 netdev_for_each_mc_addr(ha, ndev) { 95 netdev_for_each_mc_addr(ha, ndev) {
@@ -137,129 +100,66 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
137 cnt--; 100 cnt--;
138 } 101 }
139 102
140 memset(&dcmd, 0, sizeof(dcmd)); 103 err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen);
141 dcmd.cmd = BRCMF_C_SET_VAR; 104 if (err < 0) {
142 dcmd.buf = buf; 105 brcmf_dbg(ERROR, "Setting mcast_list failed, %d\n", err);
143 dcmd.len = buflen; 106 cmd_value = cnt ? true : cmd_value;
144 dcmd.set = true;
145
146 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
147 if (ret < 0) {
148 brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n",
149 brcmf_ifname(drvr, 0), cnt);
150 dcmd_value = cnt ? true : dcmd_value;
151 } 107 }
152 108
153 kfree(buf); 109 kfree(buf);
154 110
155 /* Now send the allmulti setting. This is based on the setting in the 111 /*
112 * Now send the allmulti setting. This is based on the setting in the
156 * net_device flags, but might be modified above to be turned on if we 113 * net_device flags, but might be modified above to be turned on if we
157 * were trying to set some addresses and dongle rejected it... 114 * were trying to set some addresses and dongle rejected it...
158 */ 115 */
159 116 err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value);
160 buflen = sizeof("allmulti") + sizeof(dcmd_value); 117 if (err < 0)
161 buf = kmalloc(buflen, GFP_ATOMIC); 118 brcmf_dbg(ERROR, "Setting allmulti failed, %d\n", err);
162 if (!buf) 119
163 return; 120 /*Finally, pick up the PROMISC flag */
164 121 cmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
165 dcmd_le_value = cpu_to_le32(dcmd_value); 122 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value);
166 123 if (err < 0)
167 if (!brcmf_c_mkiovar 124 brcmf_dbg(ERROR, "Setting BRCMF_C_SET_PROMISC failed, %d\n",
168 ("allmulti", (void *)&dcmd_le_value, 125 err);
169 sizeof(dcmd_le_value), buf, buflen)) {
170 brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
171 brcmf_ifname(drvr, 0),
172 (int)sizeof(dcmd_value), buflen);
173 kfree(buf);
174 return;
175 }
176
177 memset(&dcmd, 0, sizeof(dcmd));
178 dcmd.cmd = BRCMF_C_SET_VAR;
179 dcmd.buf = buf;
180 dcmd.len = buflen;
181 dcmd.set = true;
182
183 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
184 if (ret < 0) {
185 brcmf_dbg(ERROR, "%s: set allmulti %d failed\n",
186 brcmf_ifname(drvr, 0),
187 le32_to_cpu(dcmd_le_value));
188 }
189
190 kfree(buf);
191
192 /* Finally, pick up the PROMISC flag as well, like the NIC
193 driver does */
194
195 dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
196 dcmd_le_value = cpu_to_le32(dcmd_value);
197
198 memset(&dcmd, 0, sizeof(dcmd));
199 dcmd.cmd = BRCMF_C_SET_PROMISC;
200 dcmd.buf = &dcmd_le_value;
201 dcmd.len = sizeof(dcmd_le_value);
202 dcmd.set = true;
203
204 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
205 if (ret < 0) {
206 brcmf_dbg(ERROR, "%s: set promisc %d failed\n",
207 brcmf_ifname(drvr, 0),
208 le32_to_cpu(dcmd_le_value));
209 }
210} 126}
211 127
212static void 128static void
213_brcmf_set_mac_address(struct work_struct *work) 129_brcmf_set_mac_address(struct work_struct *work)
214{ 130{
215 char buf[32]; 131 struct brcmf_if *ifp;
216 struct brcmf_dcmd dcmd; 132 s32 err;
217 int ret;
218
219 struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
220 setmacaddr_work);
221 133
222 brcmf_dbg(TRACE, "enter\n"); 134 brcmf_dbg(TRACE, "enter\n");
223 if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue,
224 ETH_ALEN, buf, 32)) {
225 brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n",
226 brcmf_ifname(drvr, 0));
227 return;
228 }
229 memset(&dcmd, 0, sizeof(dcmd));
230 dcmd.cmd = BRCMF_C_SET_VAR;
231 dcmd.buf = buf;
232 dcmd.len = 32;
233 dcmd.set = true;
234 135
235 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); 136 ifp = container_of(work, struct brcmf_if, setmacaddr_work);
236 if (ret < 0) 137 err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr,
237 brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n", 138 ETH_ALEN);
238 brcmf_ifname(drvr, 0)); 139 if (err < 0) {
239 else 140 brcmf_dbg(ERROR, "Setting cur_etheraddr failed, %d\n", err);
240 memcpy(drvr->iflist[0]->ndev->dev_addr, 141 } else {
241 drvr->macvalue, ETH_ALEN); 142 brcmf_dbg(TRACE, "MAC address updated to %pM\n",
242 143 ifp->mac_addr);
243 return; 144 memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
145 }
244} 146}
245 147
246static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) 148static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
247{ 149{
248 struct brcmf_if *ifp = netdev_priv(ndev); 150 struct brcmf_if *ifp = netdev_priv(ndev);
249 struct brcmf_pub *drvr = ifp->drvr;
250 struct sockaddr *sa = (struct sockaddr *)addr; 151 struct sockaddr *sa = (struct sockaddr *)addr;
251 152
252 memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN); 153 memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN);
253 schedule_work(&drvr->setmacaddr_work); 154 schedule_work(&ifp->setmacaddr_work);
254 return 0; 155 return 0;
255} 156}
256 157
257static void brcmf_netdev_set_multicast_list(struct net_device *ndev) 158static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
258{ 159{
259 struct brcmf_if *ifp = netdev_priv(ndev); 160 struct brcmf_if *ifp = netdev_priv(ndev);
260 struct brcmf_pub *drvr = ifp->drvr;
261 161
262 schedule_work(&drvr->multicast_work); 162 schedule_work(&ifp->multicast_work);
263} 163}
264 164
265static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) 165static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
@@ -272,7 +172,7 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
272 172
273 /* Reject if down */ 173 /* Reject if down */
274 if (!drvr->bus_if->drvr_up || 174 if (!drvr->bus_if->drvr_up ||
275 (drvr->bus_if->state == BRCMF_BUS_DOWN)) { 175 (drvr->bus_if->state != BRCMF_BUS_DATA)) {
276 brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n", 176 brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n",
277 drvr->bus_if->drvr_up, 177 drvr->bus_if->drvr_up,
278 drvr->bus_if->state); 178 drvr->bus_if->state);
@@ -350,32 +250,13 @@ void brcmf_txflowblock(struct device *dev, bool state)
350 } 250 }
351} 251}
352 252
353static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx, 253void brcmf_rx_frame(struct device *dev, u8 ifidx,
354 void *pktdata, struct brcmf_event_msg *event,
355 void **data)
356{
357 int bcmerror = 0;
358
359 bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data);
360 if (bcmerror != 0)
361 return bcmerror;
362
363 if (drvr->iflist[*ifidx]->ndev)
364 brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev,
365 event, *data);
366
367 return bcmerror;
368}
369
370void brcmf_rx_frame(struct device *dev, int ifidx,
371 struct sk_buff_head *skb_list) 254 struct sk_buff_head *skb_list)
372{ 255{
373 unsigned char *eth; 256 unsigned char *eth;
374 uint len; 257 uint len;
375 void *data;
376 struct sk_buff *skb, *pnext; 258 struct sk_buff *skb, *pnext;
377 struct brcmf_if *ifp; 259 struct brcmf_if *ifp;
378 struct brcmf_event_msg event;
379 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 260 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
380 struct brcmf_pub *drvr = bus_if->drvr; 261 struct brcmf_pub *drvr = bus_if->drvr;
381 262
@@ -422,10 +303,7 @@ void brcmf_rx_frame(struct device *dev, int ifidx,
422 skb_pull(skb, ETH_HLEN); 303 skb_pull(skb, ETH_HLEN);
423 304
424 /* Process special event packets and then discard them */ 305 /* Process special event packets and then discard them */
425 if (ntohs(skb->protocol) == ETH_P_LINK_CTL) 306 brcmf_fweh_process_skb(drvr, skb, &ifidx);
426 brcmf_host_event(drvr, &ifidx,
427 skb_mac_header(skb),
428 &event, &data);
429 307
430 if (drvr->iflist[ifidx]) { 308 if (drvr->iflist[ifidx]) {
431 ifp = drvr->iflist[ifidx]; 309 ifp = drvr->iflist[ifidx];
@@ -461,9 +339,11 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
461 eh = (struct ethhdr *)(txp->data); 339 eh = (struct ethhdr *)(txp->data);
462 type = ntohs(eh->h_proto); 340 type = ntohs(eh->h_proto);
463 341
464 if (type == ETH_P_PAE) 342 if (type == ETH_P_PAE) {
465 atomic_dec(&drvr->pend_8021x_cnt); 343 atomic_dec(&drvr->pend_8021x_cnt);
466 344 if (waitqueue_active(&drvr->pend_8021x_wait))
345 wake_up(&drvr->pend_8021x_wait);
346 }
467} 347}
468 348
469static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) 349static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
@@ -487,83 +367,26 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
487 return &ifp->stats; 367 return &ifp->stats;
488} 368}
489 369
490/* Retrieve current toe component enables, which are kept 370/*
491 as a bitmap in toe_ol iovar */ 371 * Set current toe component enables in toe_ol iovar,
492static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol) 372 * and set toe global enable iovar
493{ 373 */
494 struct brcmf_dcmd dcmd; 374static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol)
495 __le32 toe_le;
496 char buf[32];
497 int ret;
498
499 memset(&dcmd, 0, sizeof(dcmd));
500
501 dcmd.cmd = BRCMF_C_GET_VAR;
502 dcmd.buf = buf;
503 dcmd.len = (uint) sizeof(buf);
504 dcmd.set = false;
505
506 strcpy(buf, "toe_ol");
507 ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
508 if (ret < 0) {
509 /* Check for older dongle image that doesn't support toe_ol */
510 if (ret == -EIO) {
511 brcmf_dbg(ERROR, "%s: toe not supported by device\n",
512 brcmf_ifname(drvr, ifidx));
513 return -EOPNOTSUPP;
514 }
515
516 brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n",
517 brcmf_ifname(drvr, ifidx), ret);
518 return ret;
519 }
520
521 memcpy(&toe_le, buf, sizeof(u32));
522 *toe_ol = le32_to_cpu(toe_le);
523 return 0;
524}
525
526/* Set current toe component enables in toe_ol iovar,
527 and set toe global enable iovar */
528static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol)
529{ 375{
530 struct brcmf_dcmd dcmd; 376 s32 err;
531 char buf[32];
532 int ret;
533 __le32 toe_le = cpu_to_le32(toe_ol);
534
535 memset(&dcmd, 0, sizeof(dcmd));
536 377
537 dcmd.cmd = BRCMF_C_SET_VAR; 378 err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
538 dcmd.buf = buf; 379 if (err < 0) {
539 dcmd.len = (uint) sizeof(buf); 380 brcmf_dbg(ERROR, "Setting toe_ol failed, %d\n", err);
540 dcmd.set = true; 381 return err;
541
542 /* Set toe_ol as requested */
543 strcpy(buf, "toe_ol");
544 memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32));
545
546 ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
547 if (ret < 0) {
548 brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n",
549 brcmf_ifname(drvr, ifidx), ret);
550 return ret;
551 } 382 }
552 383
553 /* Enable toe globally only if any components are enabled. */ 384 err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
554 toe_le = cpu_to_le32(toe_ol != 0); 385 if (err < 0)
386 brcmf_dbg(ERROR, "Setting toe failed, %d\n", err);
555 387
556 strcpy(buf, "toe"); 388 return err;
557 memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32));
558 389
559 ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
560 if (ret < 0) {
561 brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n",
562 brcmf_ifname(drvr, ifidx), ret);
563 return ret;
564 }
565
566 return 0;
567} 390}
568 391
569static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, 392static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
@@ -581,8 +404,9 @@ static const struct ethtool_ops brcmf_ethtool_ops = {
581 .get_drvinfo = brcmf_ethtool_get_drvinfo, 404 .get_drvinfo = brcmf_ethtool_get_drvinfo,
582}; 405};
583 406
584static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) 407static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
585{ 408{
409 struct brcmf_pub *drvr = ifp->drvr;
586 struct ethtool_drvinfo info; 410 struct ethtool_drvinfo info;
587 char drvname[sizeof(info.driver)]; 411 char drvname[sizeof(info.driver)];
588 u32 cmd; 412 u32 cmd;
@@ -633,7 +457,7 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
633 /* Get toe offload components from dongle */ 457 /* Get toe offload components from dongle */
634 case ETHTOOL_GRXCSUM: 458 case ETHTOOL_GRXCSUM:
635 case ETHTOOL_GTXCSUM: 459 case ETHTOOL_GTXCSUM:
636 ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); 460 ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
637 if (ret < 0) 461 if (ret < 0)
638 return ret; 462 return ret;
639 463
@@ -654,7 +478,7 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
654 return -EFAULT; 478 return -EFAULT;
655 479
656 /* Read the current settings, update and write back */ 480 /* Read the current settings, update and write back */
657 ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); 481 ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
658 if (ret < 0) 482 if (ret < 0)
659 return ret; 483 return ret;
660 484
@@ -666,18 +490,16 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
666 else 490 else
667 toe_cmpnt &= ~csum_dir; 491 toe_cmpnt &= ~csum_dir;
668 492
669 ret = brcmf_toe_set(drvr, 0, toe_cmpnt); 493 ret = brcmf_toe_set(ifp, toe_cmpnt);
670 if (ret < 0) 494 if (ret < 0)
671 return ret; 495 return ret;
672 496
673 /* If setting TX checksum mode, tell Linux the new mode */ 497 /* If setting TX checksum mode, tell Linux the new mode */
674 if (cmd == ETHTOOL_STXCSUM) { 498 if (cmd == ETHTOOL_STXCSUM) {
675 if (edata.data) 499 if (edata.data)
676 drvr->iflist[0]->ndev->features |= 500 ifp->ndev->features |= NETIF_F_IP_CSUM;
677 NETIF_F_IP_CSUM;
678 else 501 else
679 drvr->iflist[0]->ndev->features &= 502 ifp->ndev->features &= ~NETIF_F_IP_CSUM;
680 ~NETIF_F_IP_CSUM;
681 } 503 }
682 504
683 break; 505 break;
@@ -701,7 +523,7 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
701 return -1; 523 return -1;
702 524
703 if (cmd == SIOCETHTOOL) 525 if (cmd == SIOCETHTOOL)
704 return brcmf_ethtool(drvr, ifr->ifr_data); 526 return brcmf_ethtool(ifp, ifr->ifr_data);
705 527
706 return -EOPNOTSUPP; 528 return -EOPNOTSUPP;
707} 529}
@@ -712,10 +534,12 @@ static int brcmf_netdev_stop(struct net_device *ndev)
712 struct brcmf_pub *drvr = ifp->drvr; 534 struct brcmf_pub *drvr = ifp->drvr;
713 535
714 brcmf_dbg(TRACE, "Enter\n"); 536 brcmf_dbg(TRACE, "Enter\n");
715 brcmf_cfg80211_down(drvr->config); 537
716 if (drvr->bus_if->drvr_up == 0) 538 if (drvr->bus_if->drvr_up == 0)
717 return 0; 539 return 0;
718 540
541 brcmf_cfg80211_down(ndev);
542
719 /* Set state and stop OS transmissions */ 543 /* Set state and stop OS transmissions */
720 drvr->bus_if->drvr_up = false; 544 drvr->bus_if->drvr_up = false;
721 netif_stop_queue(ndev); 545 netif_stop_queue(ndev);
@@ -730,38 +554,35 @@ static int brcmf_netdev_open(struct net_device *ndev)
730 struct brcmf_bus *bus_if = drvr->bus_if; 554 struct brcmf_bus *bus_if = drvr->bus_if;
731 u32 toe_ol; 555 u32 toe_ol;
732 s32 ret = 0; 556 s32 ret = 0;
733 uint up = 0;
734 557
735 brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); 558 brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
736 559
737 if (ifp->idx == 0) { /* do it only for primary eth0 */ 560 /* If bus is not ready, can't continue */
738 /* If bus is not ready, can't continue */ 561 if (bus_if->state != BRCMF_BUS_DATA) {
739 if (bus_if->state != BRCMF_BUS_DATA) { 562 brcmf_dbg(ERROR, "failed bus is not ready\n");
740 brcmf_dbg(ERROR, "failed bus is not ready\n"); 563 return -EAGAIN;
741 return -EAGAIN; 564 }
742 }
743 565
744 atomic_set(&drvr->pend_8021x_cnt, 0); 566 atomic_set(&drvr->pend_8021x_cnt, 0);
745 567
746 memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); 568 memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
747 569
748 /* Get current TOE mode from dongle */ 570 /* Get current TOE mode from dongle */
749 if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0 571 if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
750 && (toe_ol & TOE_TX_CSUM_OL) != 0) 572 && (toe_ol & TOE_TX_CSUM_OL) != 0)
751 drvr->iflist[ifp->idx]->ndev->features |= 573 drvr->iflist[ifp->idx]->ndev->features |=
752 NETIF_F_IP_CSUM; 574 NETIF_F_IP_CSUM;
753 else 575 else
754 drvr->iflist[ifp->idx]->ndev->features &= 576 drvr->iflist[ifp->idx]->ndev->features &=
755 ~NETIF_F_IP_CSUM; 577 ~NETIF_F_IP_CSUM;
756 }
757 578
758 /* make sure RF is ready for work */ 579 /* make sure RF is ready for work */
759 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up)); 580 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
760 581
761 /* Allow transmit calls */ 582 /* Allow transmit calls */
762 netif_start_queue(ndev); 583 netif_start_queue(ndev);
763 drvr->bus_if->drvr_up = true; 584 drvr->bus_if->drvr_up = true;
764 if (brcmf_cfg80211_up(drvr->config)) { 585 if (brcmf_cfg80211_up(ndev)) {
765 brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); 586 brcmf_dbg(ERROR, "failed to bring up cfg80211\n");
766 return -1; 587 return -1;
767 } 588 }
@@ -779,39 +600,38 @@ static const struct net_device_ops brcmf_netdev_ops_pri = {
779 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list 600 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
780}; 601};
781 602
603static const struct net_device_ops brcmf_netdev_ops_virt = {
604 .ndo_open = brcmf_cfg80211_up,
605 .ndo_stop = brcmf_cfg80211_down,
606 .ndo_get_stats = brcmf_netdev_get_stats,
607 .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
608 .ndo_start_xmit = brcmf_netdev_start_xmit,
609 .ndo_set_mac_address = brcmf_netdev_set_mac_address,
610 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
611};
612
782int brcmf_net_attach(struct brcmf_if *ifp) 613int brcmf_net_attach(struct brcmf_if *ifp)
783{ 614{
784 struct brcmf_pub *drvr = ifp->drvr; 615 struct brcmf_pub *drvr = ifp->drvr;
785 struct net_device *ndev; 616 struct net_device *ndev;
786 u8 temp_addr[ETH_ALEN];
787
788 brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
789 617
790 ndev = drvr->iflist[ifp->idx]->ndev; 618 brcmf_dbg(TRACE, "ifidx %d mac %pM\n", ifp->idx, ifp->mac_addr);
791 ndev->netdev_ops = &brcmf_netdev_ops_pri; 619 ndev = ifp->ndev;
792 620
793 /* 621 /* set appropriate operations */
794 * determine mac address to use 622 if (!ifp->idx)
795 */ 623 ndev->netdev_ops = &brcmf_netdev_ops_pri;
796 if (is_valid_ether_addr(ifp->mac_addr))
797 memcpy(temp_addr, ifp->mac_addr, ETH_ALEN);
798 else 624 else
799 memcpy(temp_addr, drvr->mac, ETH_ALEN); 625 ndev->netdev_ops = &brcmf_netdev_ops_virt;
800
801 if (ifp->idx == 1) {
802 brcmf_dbg(TRACE, "ACCESS POINT MAC:\n");
803 /* ACCESSPOINT INTERFACE CASE */
804 temp_addr[0] |= 0X02; /* set bit 2 ,
805 - Locally Administered address */
806 626
807 }
808 ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; 627 ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
809 ndev->ethtool_ops = &brcmf_ethtool_ops; 628 ndev->ethtool_ops = &brcmf_ethtool_ops;
810 629
811 drvr->rxsz = ndev->mtu + ndev->hard_header_len + 630 drvr->rxsz = ndev->mtu + ndev->hard_header_len +
812 drvr->hdrlen; 631 drvr->hdrlen;
813 632
814 memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); 633 /* set the mac address */
634 memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
815 635
816 if (register_netdev(ndev) != 0) { 636 if (register_netdev(ndev) != 0) {
817 brcmf_dbg(ERROR, "couldn't register the net device\n"); 637 brcmf_dbg(ERROR, "couldn't register the net device\n");
@@ -824,17 +644,15 @@ int brcmf_net_attach(struct brcmf_if *ifp)
824 644
825fail: 645fail:
826 ndev->netdev_ops = NULL; 646 ndev->netdev_ops = NULL;
827 free_netdev(ndev);
828 return -EBADE; 647 return -EBADE;
829} 648}
830 649
831struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, 650struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx,
832 char *name, u8 *mac_addr) 651 char *name, u8 *addr_mask)
833{ 652{
834 struct brcmf_if *ifp; 653 struct brcmf_if *ifp;
835 struct net_device *ndev; 654 struct net_device *ndev;
836 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 655 int i;
837 struct brcmf_pub *drvr = bus_if->drvr;
838 656
839 brcmf_dbg(TRACE, "idx %d\n", ifidx); 657 brcmf_dbg(TRACE, "idx %d\n", ifidx);
840 658
@@ -844,12 +662,17 @@ struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx,
844 * in case we missed the BRCMF_E_IF_DEL event. 662 * in case we missed the BRCMF_E_IF_DEL event.
845 */ 663 */
846 if (ifp) { 664 if (ifp) {
847 brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", 665 brcmf_dbg(ERROR, "ERROR: netdev:%s already exists\n",
848 ifp->ndev->name); 666 ifp->ndev->name);
849 netif_stop_queue(ifp->ndev); 667 if (ifidx) {
850 unregister_netdev(ifp->ndev); 668 netif_stop_queue(ifp->ndev);
851 free_netdev(ifp->ndev); 669 unregister_netdev(ifp->ndev);
852 drvr->iflist[ifidx] = NULL; 670 free_netdev(ifp->ndev);
671 drvr->iflist[ifidx] = NULL;
672 } else {
673 brcmf_dbg(ERROR, "ignore IF event\n");
674 return ERR_PTR(-EINVAL);
675 }
853 } 676 }
854 677
855 /* Allocate netdev, including space for private structure */ 678 /* Allocate netdev, including space for private structure */
@@ -865,11 +688,16 @@ struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx,
865 drvr->iflist[ifidx] = ifp; 688 drvr->iflist[ifidx] = ifp;
866 ifp->idx = ifidx; 689 ifp->idx = ifidx;
867 ifp->bssidx = bssidx; 690 ifp->bssidx = bssidx;
868 if (mac_addr != NULL)
869 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
870 691
871 brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", 692 INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
872 current->pid, ifp->ndev->name); 693 INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
694
695 if (addr_mask != NULL)
696 for (i = 0; i < ETH_ALEN; i++)
697 ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i];
698
699 brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
700 current->pid, ifp->ndev->name, ifp->mac_addr);
873 701
874 return ifp; 702 return ifp;
875} 703}
@@ -896,6 +724,9 @@ void brcmf_del_if(struct brcmf_pub *drvr, int ifidx)
896 netif_stop_queue(ifp->ndev); 724 netif_stop_queue(ifp->ndev);
897 } 725 }
898 726
727 cancel_work_sync(&ifp->setmacaddr_work);
728 cancel_work_sync(&ifp->multicast_work);
729
899 unregister_netdev(ifp->ndev); 730 unregister_netdev(ifp->ndev);
900 drvr->iflist[ifidx] = NULL; 731 drvr->iflist[ifidx] = NULL;
901 if (ifidx == 0) 732 if (ifidx == 0)
@@ -934,11 +765,13 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
934 goto fail; 765 goto fail;
935 } 766 }
936 767
937 INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address); 768 /* attach firmware event handler */
938 INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list); 769 brcmf_fweh_attach(drvr);
939 770
940 INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); 771 INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
941 772
773 init_waitqueue_head(&drvr->pend_8021x_wait);
774
942 return ret; 775 return ret;
943 776
944fail: 777fail:
@@ -964,7 +797,7 @@ int brcmf_bus_start(struct device *dev)
964 } 797 }
965 798
966 /* add primary networking interface */ 799 /* add primary networking interface */
967 ifp = brcmf_add_if(dev, 0, 0, "wlan%d", NULL); 800 ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
968 if (IS_ERR(ifp)) 801 if (IS_ERR(ifp))
969 return PTR_ERR(ifp); 802 return PTR_ERR(ifp);
970 803
@@ -974,15 +807,25 @@ int brcmf_bus_start(struct device *dev)
974 /* Bus is ready, do any initialization */ 807 /* Bus is ready, do any initialization */
975 ret = brcmf_c_preinit_dcmds(ifp); 808 ret = brcmf_c_preinit_dcmds(ifp);
976 if (ret < 0) 809 if (ret < 0)
977 return ret; 810 goto fail;
978 811
979 drvr->config = brcmf_cfg80211_attach(drvr); 812 drvr->config = brcmf_cfg80211_attach(drvr);
980 if (drvr->config == NULL) 813 if (drvr->config == NULL) {
981 return -ENOMEM; 814 ret = -ENOMEM;
815 goto fail;
816 }
817
818 ret = brcmf_fweh_activate_events(ifp);
819 if (ret < 0)
820 goto fail;
982 821
983 ret = brcmf_net_attach(ifp); 822 ret = brcmf_net_attach(ifp);
823fail:
984 if (ret < 0) { 824 if (ret < 0) {
985 brcmf_dbg(ERROR, "brcmf_net_attach failed"); 825 brcmf_dbg(ERROR, "failed: %d\n", ret);
826 if (drvr->config)
827 brcmf_cfg80211_detach(drvr->config);
828 free_netdev(drvr->iflist[0]->ndev);
986 drvr->iflist[0] = NULL; 829 drvr->iflist[0] = NULL;
987 return ret; 830 return ret;
988 } 831 }
@@ -1011,6 +854,11 @@ void brcmf_detach(struct device *dev)
1011 854
1012 brcmf_dbg(TRACE, "Enter\n"); 855 brcmf_dbg(TRACE, "Enter\n");
1013 856
857 if (drvr == NULL)
858 return;
859
860 /* stop firmware event handling */
861 brcmf_fweh_detach(drvr);
1014 862
1015 /* make sure primary interface removed last */ 863 /* make sure primary interface removed last */
1016 for (i = BRCMF_MAX_IFS-1; i > -1; i--) 864 for (i = BRCMF_MAX_IFS-1; i > -1; i--)
@@ -1020,8 +868,6 @@ void brcmf_detach(struct device *dev)
1020 brcmf_bus_detach(drvr); 868 brcmf_bus_detach(drvr);
1021 869
1022 if (drvr->prot) { 870 if (drvr->prot) {
1023 cancel_work_sync(&drvr->setmacaddr_work);
1024 cancel_work_sync(&drvr->multicast_work);
1025 brcmf_proto_detach(drvr); 871 brcmf_proto_detach(drvr);
1026 } 872 }
1027 873
@@ -1035,26 +881,19 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr)
1035 return atomic_read(&drvr->pend_8021x_cnt); 881 return atomic_read(&drvr->pend_8021x_cnt);
1036} 882}
1037 883
1038#define MAX_WAIT_FOR_8021X_TX 10
1039
1040int brcmf_netdev_wait_pend8021x(struct net_device *ndev) 884int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
1041{ 885{
1042 struct brcmf_if *ifp = netdev_priv(ndev); 886 struct brcmf_if *ifp = netdev_priv(ndev);
1043 struct brcmf_pub *drvr = ifp->drvr; 887 struct brcmf_pub *drvr = ifp->drvr;
1044 int timeout = 10 * HZ / 1000; 888 int err;
1045 int ntimes = MAX_WAIT_FOR_8021X_TX; 889
1046 int pend = brcmf_get_pend_8021x_cnt(drvr); 890 err = wait_event_timeout(drvr->pend_8021x_wait,
1047 891 !brcmf_get_pend_8021x_cnt(drvr),
1048 while (ntimes && pend) { 892 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));
1049 if (pend) { 893
1050 set_current_state(TASK_INTERRUPTIBLE); 894 WARN_ON(!err);
1051 schedule_timeout(timeout); 895
1052 set_current_state(TASK_RUNNING); 896 return !err;
1053 ntimes--;
1054 }
1055 pend = brcmf_get_pend_8021x_cnt(drvr);
1056 }
1057 return pend;
1058} 897}
1059 898
1060static void brcmf_driver_init(struct work_struct *work) 899static void brcmf_driver_init(struct work_struct *work)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
index 7fe6779b90c..48fa7030219 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
@@ -36,14 +36,7 @@ extern void brcmf_proto_stop(struct brcmf_pub *drvr);
36extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, 36extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
37 struct sk_buff *txp); 37 struct sk_buff *txp);
38 38
39/* Use protocol to issue command to dongle */
40extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx,
41 struct brcmf_dcmd *dcmd, int len);
42
43/* Sets dongle media info (drv_version, mac address). */ 39/* Sets dongle media info (drv_version, mac address). */
44extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); 40extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
45 41
46extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx,
47 uint cmd, void *buf, uint len);
48
49#endif /* _BRCMF_PROTO_H_ */ 42#endif /* _BRCMF_PROTO_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 415f2be3637..45725454714 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -533,9 +533,11 @@ struct brcmf_sdio {
533 u8 *rxbuf; /* Buffer for receiving control packets */ 533 u8 *rxbuf; /* Buffer for receiving control packets */
534 uint rxblen; /* Allocated length of rxbuf */ 534 uint rxblen; /* Allocated length of rxbuf */
535 u8 *rxctl; /* Aligned pointer into rxbuf */ 535 u8 *rxctl; /* Aligned pointer into rxbuf */
536 u8 *rxctl_orig; /* pointer for freeing rxctl */
536 u8 *databuf; /* Buffer for receiving big glom packet */ 537 u8 *databuf; /* Buffer for receiving big glom packet */
537 u8 *dataptr; /* Aligned pointer into databuf */ 538 u8 *dataptr; /* Aligned pointer into databuf */
538 uint rxlen; /* Length of valid data in buffer */ 539 uint rxlen; /* Length of valid data in buffer */
540 spinlock_t rxctl_lock; /* protection lock for ctrl frame resources */
539 541
540 u8 sdpcm_ver; /* Bus protocol reported by dongle */ 542 u8 sdpcm_ver; /* Bus protocol reported by dongle */
541 543
@@ -582,8 +584,6 @@ struct brcmf_sdio {
582 struct list_head dpc_tsklst; 584 struct list_head dpc_tsklst;
583 spinlock_t dpc_tl_lock; 585 spinlock_t dpc_tl_lock;
584 586
585 struct semaphore sdsem;
586
587 const struct firmware *firmware; 587 const struct firmware *firmware;
588 u32 fw_ptr; 588 u32 fw_ptr;
589 589
@@ -1037,9 +1037,9 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
1037 } 1037 }
1038} 1038}
1039 1039
1040static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, 1040static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1041 struct brcmf_sdio_read *rd, 1041 struct brcmf_sdio_read *rd,
1042 enum brcmf_sdio_frmtype type) 1042 enum brcmf_sdio_frmtype type)
1043{ 1043{
1044 u16 len, checksum; 1044 u16 len, checksum;
1045 u8 rx_seq, fc, tx_seq_max; 1045 u8 rx_seq, fc, tx_seq_max;
@@ -1054,26 +1054,26 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1054 /* All zero means no more to read */ 1054 /* All zero means no more to read */
1055 if (!(len | checksum)) { 1055 if (!(len | checksum)) {
1056 bus->rxpending = false; 1056 bus->rxpending = false;
1057 return false; 1057 return -ENODATA;
1058 } 1058 }
1059 if ((u16)(~(len ^ checksum))) { 1059 if ((u16)(~(len ^ checksum))) {
1060 brcmf_dbg(ERROR, "HW header checksum error\n"); 1060 brcmf_dbg(ERROR, "HW header checksum error\n");
1061 bus->sdcnt.rx_badhdr++; 1061 bus->sdcnt.rx_badhdr++;
1062 brcmf_sdbrcm_rxfail(bus, false, false); 1062 brcmf_sdbrcm_rxfail(bus, false, false);
1063 return false; 1063 return -EIO;
1064 } 1064 }
1065 if (len < SDPCM_HDRLEN) { 1065 if (len < SDPCM_HDRLEN) {
1066 brcmf_dbg(ERROR, "HW header length error\n"); 1066 brcmf_dbg(ERROR, "HW header length error\n");
1067 return false; 1067 return -EPROTO;
1068 } 1068 }
1069 if (type == BRCMF_SDIO_FT_SUPER && 1069 if (type == BRCMF_SDIO_FT_SUPER &&
1070 (roundup(len, bus->blocksize) != rd->len)) { 1070 (roundup(len, bus->blocksize) != rd->len)) {
1071 brcmf_dbg(ERROR, "HW superframe header length error\n"); 1071 brcmf_dbg(ERROR, "HW superframe header length error\n");
1072 return false; 1072 return -EPROTO;
1073 } 1073 }
1074 if (type == BRCMF_SDIO_FT_SUB && len > rd->len) { 1074 if (type == BRCMF_SDIO_FT_SUB && len > rd->len) {
1075 brcmf_dbg(ERROR, "HW subframe header length error\n"); 1075 brcmf_dbg(ERROR, "HW subframe header length error\n");
1076 return false; 1076 return -EPROTO;
1077 } 1077 }
1078 rd->len = len; 1078 rd->len = len;
1079 1079
@@ -1091,7 +1091,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1091 SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) { 1091 SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) {
1092 brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n"); 1092 brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n");
1093 rd->len = 0; 1093 rd->len = 0;
1094 return false; 1094 return -EINVAL;
1095 } 1095 }
1096 rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]); 1096 rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]);
1097 rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]); 1097 rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]);
@@ -1102,18 +1102,18 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1102 bus->sdcnt.rx_toolong++; 1102 bus->sdcnt.rx_toolong++;
1103 brcmf_sdbrcm_rxfail(bus, false, false); 1103 brcmf_sdbrcm_rxfail(bus, false, false);
1104 rd->len = 0; 1104 rd->len = 0;
1105 return false; 1105 return -EPROTO;
1106 } 1106 }
1107 if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) { 1107 if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) {
1108 brcmf_dbg(ERROR, "Wrong channel for superframe\n"); 1108 brcmf_dbg(ERROR, "Wrong channel for superframe\n");
1109 rd->len = 0; 1109 rd->len = 0;
1110 return false; 1110 return -EINVAL;
1111 } 1111 }
1112 if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL && 1112 if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL &&
1113 rd->channel != SDPCM_EVENT_CHANNEL) { 1113 rd->channel != SDPCM_EVENT_CHANNEL) {
1114 brcmf_dbg(ERROR, "Wrong channel for subframe\n"); 1114 brcmf_dbg(ERROR, "Wrong channel for subframe\n");
1115 rd->len = 0; 1115 rd->len = 0;
1116 return false; 1116 return -EINVAL;
1117 } 1117 }
1118 rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]); 1118 rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]);
1119 if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { 1119 if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) {
@@ -1121,7 +1121,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1121 bus->sdcnt.rx_badhdr++; 1121 bus->sdcnt.rx_badhdr++;
1122 brcmf_sdbrcm_rxfail(bus, false, false); 1122 brcmf_sdbrcm_rxfail(bus, false, false);
1123 rd->len = 0; 1123 rd->len = 0;
1124 return false; 1124 return -ENXIO;
1125 } 1125 }
1126 if (rd->seq_num != rx_seq) { 1126 if (rd->seq_num != rx_seq) {
1127 brcmf_dbg(ERROR, "seq %d: sequence number error, expect %d\n", 1127 brcmf_dbg(ERROR, "seq %d: sequence number error, expect %d\n",
@@ -1131,7 +1131,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1131 } 1131 }
1132 /* no need to check the reset for subframe */ 1132 /* no need to check the reset for subframe */
1133 if (type == BRCMF_SDIO_FT_SUB) 1133 if (type == BRCMF_SDIO_FT_SUB)
1134 return true; 1134 return 0;
1135 rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; 1135 rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
1136 if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) { 1136 if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) {
1137 /* only warm for NON glom packet */ 1137 /* only warm for NON glom packet */
@@ -1155,7 +1155,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1155 } 1155 }
1156 bus->tx_max = tx_seq_max; 1156 bus->tx_max = tx_seq_max;
1157 1157
1158 return true; 1158 return 0;
1159} 1159}
1160 1160
1161static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) 1161static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
@@ -1272,6 +1272,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1272 * read directly into the chained packet, or allocate a large 1272 * read directly into the chained packet, or allocate a large
1273 * packet and and copy into the chain. 1273 * packet and and copy into the chain.
1274 */ 1274 */
1275 sdio_claim_host(bus->sdiodev->func[1]);
1275 if (usechain) { 1276 if (usechain) {
1276 errcode = brcmf_sdcard_recv_chain(bus->sdiodev, 1277 errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
1277 bus->sdiodev->sbwad, 1278 bus->sdiodev->sbwad,
@@ -1293,6 +1294,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1293 dlen); 1294 dlen);
1294 errcode = -1; 1295 errcode = -1;
1295 } 1296 }
1297 sdio_release_host(bus->sdiodev->func[1]);
1296 bus->sdcnt.f2rxdata++; 1298 bus->sdcnt.f2rxdata++;
1297 1299
1298 /* On failure, kill the superframe, allow a couple retries */ 1300 /* On failure, kill the superframe, allow a couple retries */
@@ -1301,6 +1303,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1301 dlen, errcode); 1303 dlen, errcode);
1302 bus->sdiodev->bus_if->dstats.rx_errors++; 1304 bus->sdiodev->bus_if->dstats.rx_errors++;
1303 1305
1306 sdio_claim_host(bus->sdiodev->func[1]);
1304 if (bus->glomerr++ < 3) { 1307 if (bus->glomerr++ < 3) {
1305 brcmf_sdbrcm_rxfail(bus, true, true); 1308 brcmf_sdbrcm_rxfail(bus, true, true);
1306 } else { 1309 } else {
@@ -1309,6 +1312,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1309 bus->sdcnt.rxglomfail++; 1312 bus->sdcnt.rxglomfail++;
1310 brcmf_sdbrcm_free_glom(bus); 1313 brcmf_sdbrcm_free_glom(bus);
1311 } 1314 }
1315 sdio_release_host(bus->sdiodev->func[1]);
1312 return 0; 1316 return 0;
1313 } 1317 }
1314 1318
@@ -1318,8 +1322,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1318 1322
1319 rd_new.seq_num = rxseq; 1323 rd_new.seq_num = rxseq;
1320 rd_new.len = dlen; 1324 rd_new.len = dlen;
1321 errcode = -!brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, 1325 sdio_claim_host(bus->sdiodev->func[1]);
1322 BRCMF_SDIO_FT_SUPER); 1326 errcode = brcmf_sdio_hdparser(bus, pfirst->data, &rd_new,
1327 BRCMF_SDIO_FT_SUPER);
1328 sdio_release_host(bus->sdiodev->func[1]);
1323 bus->cur_read.len = rd_new.len_nxtfrm << 4; 1329 bus->cur_read.len = rd_new.len_nxtfrm << 4;
1324 1330
1325 /* Remove superframe header, remember offset */ 1331 /* Remove superframe header, remember offset */
@@ -1335,9 +1341,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1335 1341
1336 rd_new.len = pnext->len; 1342 rd_new.len = pnext->len;
1337 rd_new.seq_num = rxseq++; 1343 rd_new.seq_num = rxseq++;
1338 errcode = -!brcmf_sdio_hdparser(bus, pnext->data, 1344 sdio_claim_host(bus->sdiodev->func[1]);
1339 &rd_new, 1345 errcode = brcmf_sdio_hdparser(bus, pnext->data, &rd_new,
1340 BRCMF_SDIO_FT_SUB); 1346 BRCMF_SDIO_FT_SUB);
1347 sdio_release_host(bus->sdiodev->func[1]);
1341 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), 1348 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
1342 pnext->data, 32, "subframe:\n"); 1349 pnext->data, 32, "subframe:\n");
1343 1350
@@ -1347,6 +1354,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1347 if (errcode) { 1354 if (errcode) {
1348 /* Terminate frame on error, request 1355 /* Terminate frame on error, request
1349 a couple retries */ 1356 a couple retries */
1357 sdio_claim_host(bus->sdiodev->func[1]);
1350 if (bus->glomerr++ < 3) { 1358 if (bus->glomerr++ < 3) {
1351 /* Restore superframe header space */ 1359 /* Restore superframe header space */
1352 skb_push(pfirst, sfdoff); 1360 skb_push(pfirst, sfdoff);
@@ -1357,6 +1365,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1357 bus->sdcnt.rxglomfail++; 1365 bus->sdcnt.rxglomfail++;
1358 brcmf_sdbrcm_free_glom(bus); 1366 brcmf_sdbrcm_free_glom(bus);
1359 } 1367 }
1368 sdio_release_host(bus->sdiodev->func[1]);
1360 bus->cur_read.len = 0; 1369 bus->cur_read.len = 0;
1361 return 0; 1370 return 0;
1362 } 1371 }
@@ -1397,11 +1406,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1397 pfirst->prev); 1406 pfirst->prev);
1398 } 1407 }
1399 /* sent any remaining packets up */ 1408 /* sent any remaining packets up */
1400 if (bus->glom.qlen) { 1409 if (bus->glom.qlen)
1401 up(&bus->sdsem);
1402 brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); 1410 brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom);
1403 down(&bus->sdsem);
1404 }
1405 1411
1406 bus->sdcnt.rxglomframes++; 1412 bus->sdcnt.rxglomframes++;
1407 bus->sdcnt.rxglompkts += bus->glom.qlen; 1413 bus->sdcnt.rxglompkts += bus->glom.qlen;
@@ -1442,21 +1448,24 @@ static void
1442brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) 1448brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1443{ 1449{
1444 uint rdlen, pad; 1450 uint rdlen, pad;
1445 1451 u8 *buf = NULL, *rbuf;
1446 int sdret; 1452 int sdret;
1447 1453
1448 brcmf_dbg(TRACE, "Enter\n"); 1454 brcmf_dbg(TRACE, "Enter\n");
1449 1455
1450 /* Set rxctl for frame (w/optional alignment) */ 1456 if (bus->rxblen)
1451 bus->rxctl = bus->rxbuf; 1457 buf = vzalloc(bus->rxblen);
1452 bus->rxctl += BRCMF_FIRSTREAD; 1458 if (!buf) {
1453 pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN); 1459 brcmf_dbg(ERROR, "no memory for control frame\n");
1460 goto done;
1461 }
1462 rbuf = bus->rxbuf;
1463 pad = ((unsigned long)rbuf % BRCMF_SDALIGN);
1454 if (pad) 1464 if (pad)
1455 bus->rxctl += (BRCMF_SDALIGN - pad); 1465 rbuf += (BRCMF_SDALIGN - pad);
1456 bus->rxctl -= BRCMF_FIRSTREAD;
1457 1466
1458 /* Copy the already-read portion over */ 1467 /* Copy the already-read portion over */
1459 memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD); 1468 memcpy(buf, hdr, BRCMF_FIRSTREAD);
1460 if (len <= BRCMF_FIRSTREAD) 1469 if (len <= BRCMF_FIRSTREAD)
1461 goto gotpkt; 1470 goto gotpkt;
1462 1471
@@ -1493,11 +1502,11 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1493 goto done; 1502 goto done;
1494 } 1503 }
1495 1504
1496 /* Read remainder of frame body into the rxctl buffer */ 1505 /* Read remain of frame body */
1497 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, 1506 sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
1498 bus->sdiodev->sbwad, 1507 bus->sdiodev->sbwad,
1499 SDIO_FUNC_2, 1508 SDIO_FUNC_2,
1500 F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen); 1509 F2SYNC, rbuf, rdlen);
1501 bus->sdcnt.f2rxdata++; 1510 bus->sdcnt.f2rxdata++;
1502 1511
1503 /* Control frame failures need retransmission */ 1512 /* Control frame failures need retransmission */
@@ -1507,16 +1516,26 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1507 bus->sdcnt.rxc_errors++; 1516 bus->sdcnt.rxc_errors++;
1508 brcmf_sdbrcm_rxfail(bus, true, true); 1517 brcmf_sdbrcm_rxfail(bus, true, true);
1509 goto done; 1518 goto done;
1510 } 1519 } else
1520 memcpy(buf + BRCMF_FIRSTREAD, rbuf, rdlen);
1511 1521
1512gotpkt: 1522gotpkt:
1513 1523
1514 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), 1524 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
1515 bus->rxctl, len, "RxCtrl:\n"); 1525 buf, len, "RxCtrl:\n");
1516 1526
1517 /* Point to valid data and indicate its length */ 1527 /* Point to valid data and indicate its length */
1518 bus->rxctl += doff; 1528 spin_lock_bh(&bus->rxctl_lock);
1529 if (bus->rxctl) {
1530 brcmf_dbg(ERROR, "last control frame is being processed.\n");
1531 spin_unlock_bh(&bus->rxctl_lock);
1532 vfree(buf);
1533 goto done;
1534 }
1535 bus->rxctl = buf + doff;
1536 bus->rxctl_orig = buf;
1519 bus->rxlen = len - doff; 1537 bus->rxlen = len - doff;
1538 spin_unlock_bh(&bus->rxctl_lock);
1520 1539
1521done: 1540done:
1522 /* Awake any waiters */ 1541 /* Awake any waiters */
@@ -1571,6 +1590,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1571 1590
1572 rd->len_left = rd->len; 1591 rd->len_left = rd->len;
1573 /* read header first for unknow frame length */ 1592 /* read header first for unknow frame length */
1593 sdio_claim_host(bus->sdiodev->func[1]);
1574 if (!rd->len) { 1594 if (!rd->len) {
1575 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, 1595 sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
1576 bus->sdiodev->sbwad, 1596 bus->sdiodev->sbwad,
@@ -1583,6 +1603,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1583 sdret); 1603 sdret);
1584 bus->sdcnt.rx_hdrfail++; 1604 bus->sdcnt.rx_hdrfail++;
1585 brcmf_sdbrcm_rxfail(bus, true, true); 1605 brcmf_sdbrcm_rxfail(bus, true, true);
1606 sdio_release_host(bus->sdiodev->func[1]);
1586 continue; 1607 continue;
1587 } 1608 }
1588 1609
@@ -1590,8 +1611,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1590 bus->rxhdr, SDPCM_HDRLEN, 1611 bus->rxhdr, SDPCM_HDRLEN,
1591 "RxHdr:\n"); 1612 "RxHdr:\n");
1592 1613
1593 if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd, 1614 if (brcmf_sdio_hdparser(bus, bus->rxhdr, rd,
1594 BRCMF_SDIO_FT_NORMAL)) { 1615 BRCMF_SDIO_FT_NORMAL)) {
1616 sdio_release_host(bus->sdiodev->func[1]);
1595 if (!bus->rxpending) 1617 if (!bus->rxpending)
1596 break; 1618 break;
1597 else 1619 else
@@ -1607,6 +1629,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1607 rd->len_nxtfrm = 0; 1629 rd->len_nxtfrm = 0;
1608 /* treat all packet as event if we don't know */ 1630 /* treat all packet as event if we don't know */
1609 rd->channel = SDPCM_EVENT_CHANNEL; 1631 rd->channel = SDPCM_EVENT_CHANNEL;
1632 sdio_release_host(bus->sdiodev->func[1]);
1610 continue; 1633 continue;
1611 } 1634 }
1612 rd->len_left = rd->len > BRCMF_FIRSTREAD ? 1635 rd->len_left = rd->len > BRCMF_FIRSTREAD ?
@@ -1624,6 +1647,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1624 bus->sdiodev->bus_if->dstats.rx_dropped++; 1647 bus->sdiodev->bus_if->dstats.rx_dropped++;
1625 brcmf_sdbrcm_rxfail(bus, false, 1648 brcmf_sdbrcm_rxfail(bus, false,
1626 RETRYCHAN(rd->channel)); 1649 RETRYCHAN(rd->channel));
1650 sdio_release_host(bus->sdiodev->func[1]);
1627 continue; 1651 continue;
1628 } 1652 }
1629 skb_pull(pkt, head_read); 1653 skb_pull(pkt, head_read);
@@ -1632,14 +1656,17 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1632 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1656 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
1633 SDIO_FUNC_2, F2SYNC, pkt); 1657 SDIO_FUNC_2, F2SYNC, pkt);
1634 bus->sdcnt.f2rxdata++; 1658 bus->sdcnt.f2rxdata++;
1659 sdio_release_host(bus->sdiodev->func[1]);
1635 1660
1636 if (sdret < 0) { 1661 if (sdret < 0) {
1637 brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n", 1662 brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n",
1638 rd->len, rd->channel, sdret); 1663 rd->len, rd->channel, sdret);
1639 brcmu_pkt_buf_free_skb(pkt); 1664 brcmu_pkt_buf_free_skb(pkt);
1640 bus->sdiodev->bus_if->dstats.rx_errors++; 1665 bus->sdiodev->bus_if->dstats.rx_errors++;
1666 sdio_claim_host(bus->sdiodev->func[1]);
1641 brcmf_sdbrcm_rxfail(bus, true, 1667 brcmf_sdbrcm_rxfail(bus, true,
1642 RETRYCHAN(rd->channel)); 1668 RETRYCHAN(rd->channel));
1669 sdio_release_host(bus->sdiodev->func[1]);
1643 continue; 1670 continue;
1644 } 1671 }
1645 1672
@@ -1650,8 +1677,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1650 } else { 1677 } else {
1651 memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); 1678 memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN);
1652 rd_new.seq_num = rd->seq_num; 1679 rd_new.seq_num = rd->seq_num;
1653 if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, 1680 sdio_claim_host(bus->sdiodev->func[1]);
1654 BRCMF_SDIO_FT_NORMAL)) { 1681 if (brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new,
1682 BRCMF_SDIO_FT_NORMAL)) {
1655 rd->len = 0; 1683 rd->len = 0;
1656 brcmu_pkt_buf_free_skb(pkt); 1684 brcmu_pkt_buf_free_skb(pkt);
1657 } 1685 }
@@ -1662,9 +1690,11 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1662 roundup(rd_new.len, 16) >> 4); 1690 roundup(rd_new.len, 16) >> 4);
1663 rd->len = 0; 1691 rd->len = 0;
1664 brcmf_sdbrcm_rxfail(bus, true, true); 1692 brcmf_sdbrcm_rxfail(bus, true, true);
1693 sdio_release_host(bus->sdiodev->func[1]);
1665 brcmu_pkt_buf_free_skb(pkt); 1694 brcmu_pkt_buf_free_skb(pkt);
1666 continue; 1695 continue;
1667 } 1696 }
1697 sdio_release_host(bus->sdiodev->func[1]);
1668 rd->len_nxtfrm = rd_new.len_nxtfrm; 1698 rd->len_nxtfrm = rd_new.len_nxtfrm;
1669 rd->channel = rd_new.channel; 1699 rd->channel = rd_new.channel;
1670 rd->dat_offset = rd_new.dat_offset; 1700 rd->dat_offset = rd_new.dat_offset;
@@ -1680,7 +1710,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1680 rd_new.seq_num); 1710 rd_new.seq_num);
1681 /* Force retry w/normal header read */ 1711 /* Force retry w/normal header read */
1682 rd->len = 0; 1712 rd->len = 0;
1713 sdio_claim_host(bus->sdiodev->func[1]);
1683 brcmf_sdbrcm_rxfail(bus, false, true); 1714 brcmf_sdbrcm_rxfail(bus, false, true);
1715 sdio_release_host(bus->sdiodev->func[1]);
1684 brcmu_pkt_buf_free_skb(pkt); 1716 brcmu_pkt_buf_free_skb(pkt);
1685 continue; 1717 continue;
1686 } 1718 }
@@ -1703,7 +1735,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1703 } else { 1735 } else {
1704 brcmf_dbg(ERROR, "%s: glom superframe w/o " 1736 brcmf_dbg(ERROR, "%s: glom superframe w/o "
1705 "descriptor!\n", __func__); 1737 "descriptor!\n", __func__);
1738 sdio_claim_host(bus->sdiodev->func[1]);
1706 brcmf_sdbrcm_rxfail(bus, false, false); 1739 brcmf_sdbrcm_rxfail(bus, false, false);
1740 sdio_release_host(bus->sdiodev->func[1]);
1707 } 1741 }
1708 /* prepare the descriptor for the next read */ 1742 /* prepare the descriptor for the next read */
1709 rd->len = rd->len_nxtfrm << 4; 1743 rd->len = rd->len_nxtfrm << 4;
@@ -1734,10 +1768,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1734 continue; 1768 continue;
1735 } 1769 }
1736 1770
1737 /* Unlock during rx call */
1738 up(&bus->sdsem);
1739 brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); 1771 brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt);
1740 down(&bus->sdsem);
1741 } 1772 }
1742 1773
1743 rxcount = maxframes - rxleft; 1774 rxcount = maxframes - rxleft;
@@ -1755,15 +1786,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1755} 1786}
1756 1787
1757static void 1788static void
1758brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar)
1759{
1760 up(&bus->sdsem);
1761 wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2);
1762 down(&bus->sdsem);
1763 return;
1764}
1765
1766static void
1767brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) 1789brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
1768{ 1790{
1769 if (waitqueue_active(&bus->ctrl_wait)) 1791 if (waitqueue_active(&bus->ctrl_wait))
@@ -1864,6 +1886,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1864 if (len & (ALIGNMENT - 1)) 1886 if (len & (ALIGNMENT - 1))
1865 len = roundup(len, ALIGNMENT); 1887 len = roundup(len, ALIGNMENT);
1866 1888
1889 sdio_claim_host(bus->sdiodev->func[1]);
1867 ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1890 ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
1868 SDIO_FUNC_2, F2SYNC, pkt); 1891 SDIO_FUNC_2, F2SYNC, pkt);
1869 bus->sdcnt.f2txdata++; 1892 bus->sdcnt.f2txdata++;
@@ -1891,15 +1914,14 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1891 } 1914 }
1892 1915
1893 } 1916 }
1917 sdio_release_host(bus->sdiodev->func[1]);
1894 if (ret == 0) 1918 if (ret == 0)
1895 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; 1919 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
1896 1920
1897done: 1921done:
1898 /* restore pkt buffer pointer before calling tx complete routine */ 1922 /* restore pkt buffer pointer before calling tx complete routine */
1899 skb_pull(pkt, SDPCM_HDRLEN + pad); 1923 skb_pull(pkt, SDPCM_HDRLEN + pad);
1900 up(&bus->sdsem);
1901 brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); 1924 brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0);
1902 down(&bus->sdsem);
1903 1925
1904 if (free_pkt) 1926 if (free_pkt)
1905 brcmu_pkt_buf_free_skb(pkt); 1927 brcmu_pkt_buf_free_skb(pkt);
@@ -1940,9 +1962,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
1940 /* In poll mode, need to check for other events */ 1962 /* In poll mode, need to check for other events */
1941 if (!bus->intr && cnt) { 1963 if (!bus->intr && cnt) {
1942 /* Check device status, signal pending interrupt */ 1964 /* Check device status, signal pending interrupt */
1965 sdio_claim_host(bus->sdiodev->func[1]);
1943 ret = r_sdreg32(bus, &intstatus, 1966 ret = r_sdreg32(bus, &intstatus,
1944 offsetof(struct sdpcmd_regs, 1967 offsetof(struct sdpcmd_regs,
1945 intstatus)); 1968 intstatus));
1969 sdio_release_host(bus->sdiodev->func[1]);
1946 bus->sdcnt.f2txdata++; 1970 bus->sdcnt.f2txdata++;
1947 if (ret != 0) 1971 if (ret != 0)
1948 break; 1972 break;
@@ -1979,7 +2003,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
1979 bus->watchdog_tsk = NULL; 2003 bus->watchdog_tsk = NULL;
1980 } 2004 }
1981 2005
1982 down(&bus->sdsem); 2006 sdio_claim_host(bus->sdiodev->func[1]);
1983 2007
1984 /* Enable clock for device interrupts */ 2008 /* Enable clock for device interrupts */
1985 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 2009 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
@@ -2013,6 +2037,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
2013 2037
2014 /* Turn off the backplane clock (only) */ 2038 /* Turn off the backplane clock (only) */
2015 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); 2039 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
2040 sdio_release_host(bus->sdiodev->func[1]);
2016 2041
2017 /* Clear the data packet queues */ 2042 /* Clear the data packet queues */
2018 brcmu_pktq_flush(&bus->txq, true, NULL, NULL); 2043 brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
@@ -2023,14 +2048,14 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
2023 brcmf_sdbrcm_free_glom(bus); 2048 brcmf_sdbrcm_free_glom(bus);
2024 2049
2025 /* Clear rx control and wake any waiters */ 2050 /* Clear rx control and wake any waiters */
2051 spin_lock_bh(&bus->rxctl_lock);
2026 bus->rxlen = 0; 2052 bus->rxlen = 0;
2053 spin_unlock_bh(&bus->rxctl_lock);
2027 brcmf_sdbrcm_dcmd_resp_wake(bus); 2054 brcmf_sdbrcm_dcmd_resp_wake(bus);
2028 2055
2029 /* Reset some F2 state stuff */ 2056 /* Reset some F2 state stuff */
2030 bus->rxskip = false; 2057 bus->rxskip = false;
2031 bus->tx_seq = bus->rx_seq = 0; 2058 bus->tx_seq = bus->rx_seq = 0;
2032
2033 up(&bus->sdsem);
2034} 2059}
2035 2060
2036#ifdef CONFIG_BRCMFMAC_SDIO_OOB 2061#ifdef CONFIG_BRCMFMAC_SDIO_OOB
@@ -2114,7 +2139,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2114 2139
2115 brcmf_dbg(TRACE, "Enter\n"); 2140 brcmf_dbg(TRACE, "Enter\n");
2116 2141
2117 down(&bus->sdsem); 2142 sdio_claim_host(bus->sdiodev->func[1]);
2118 2143
2119 /* If waiting for HTAVAIL, check status */ 2144 /* If waiting for HTAVAIL, check status */
2120 if (bus->clkstate == CLK_PENDING) { 2145 if (bus->clkstate == CLK_PENDING) {
@@ -2168,9 +2193,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2168 /* Pending interrupt indicates new device status */ 2193 /* Pending interrupt indicates new device status */
2169 if (atomic_read(&bus->ipend) > 0) { 2194 if (atomic_read(&bus->ipend) > 0) {
2170 atomic_set(&bus->ipend, 0); 2195 atomic_set(&bus->ipend, 0);
2171 sdio_claim_host(bus->sdiodev->func[1]);
2172 err = brcmf_sdio_intr_rstatus(bus); 2196 err = brcmf_sdio_intr_rstatus(bus);
2173 sdio_release_host(bus->sdiodev->func[1]);
2174 } 2197 }
2175 2198
2176 /* Start with leftover status bits */ 2199 /* Start with leftover status bits */
@@ -2199,6 +2222,8 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2199 intstatus |= brcmf_sdbrcm_hostmail(bus); 2222 intstatus |= brcmf_sdbrcm_hostmail(bus);
2200 } 2223 }
2201 2224
2225 sdio_release_host(bus->sdiodev->func[1]);
2226
2202 /* Generally don't ask for these, can get CRC errors... */ 2227 /* Generally don't ask for these, can get CRC errors... */
2203 if (intstatus & I_WR_OOSYNC) { 2228 if (intstatus & I_WR_OOSYNC) {
2204 brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n"); 2229 brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n");
@@ -2245,6 +2270,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2245 (bus->clkstate == CLK_AVAIL)) { 2270 (bus->clkstate == CLK_AVAIL)) {
2246 int i; 2271 int i;
2247 2272
2273 sdio_claim_host(bus->sdiodev->func[1]);
2248 err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, 2274 err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
2249 SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, 2275 SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf,
2250 (u32) bus->ctrl_frame_len); 2276 (u32) bus->ctrl_frame_len);
@@ -2278,6 +2304,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2278 } else { 2304 } else {
2279 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; 2305 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
2280 } 2306 }
2307 sdio_release_host(bus->sdiodev->func[1]);
2281 bus->ctrl_frame_stat = false; 2308 bus->ctrl_frame_stat = false;
2282 brcmf_sdbrcm_wait_event_wakeup(bus); 2309 brcmf_sdbrcm_wait_event_wakeup(bus);
2283 } 2310 }
@@ -2307,10 +2334,10 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2307 if ((bus->clkstate != CLK_PENDING) 2334 if ((bus->clkstate != CLK_PENDING)
2308 && bus->idletime == BRCMF_IDLE_IMMEDIATE) { 2335 && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
2309 bus->activity = false; 2336 bus->activity = false;
2337 sdio_claim_host(bus->sdiodev->func[1]);
2310 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); 2338 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
2339 sdio_release_host(bus->sdiodev->func[1]);
2311 } 2340 }
2312
2313 up(&bus->sdsem);
2314} 2341}
2315 2342
2316static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) 2343static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
@@ -2601,11 +2628,10 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2601 2628
2602 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ 2629 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
2603 2630
2604 /* Need to lock here to protect txseq and SDIO tx calls */
2605 down(&bus->sdsem);
2606
2607 /* Make sure backplane clock is on */ 2631 /* Make sure backplane clock is on */
2632 sdio_claim_host(bus->sdiodev->func[1]);
2608 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 2633 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
2634 sdio_release_host(bus->sdiodev->func[1]);
2609 2635
2610 /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ 2636 /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
2611 *(__le16 *) frame = cpu_to_le16((u16) msglen); 2637 *(__le16 *) frame = cpu_to_le16((u16) msglen);
@@ -2628,7 +2654,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2628 bus->ctrl_frame_buf = frame; 2654 bus->ctrl_frame_buf = frame;
2629 bus->ctrl_frame_len = len; 2655 bus->ctrl_frame_len = len;
2630 2656
2631 brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat); 2657 wait_event_interruptible_timeout(bus->ctrl_wait,
2658 !bus->ctrl_frame_stat,
2659 msecs_to_jiffies(2000));
2632 2660
2633 if (!bus->ctrl_frame_stat) { 2661 if (!bus->ctrl_frame_stat) {
2634 brcmf_dbg(INFO, "ctrl_frame_stat == false\n"); 2662 brcmf_dbg(INFO, "ctrl_frame_stat == false\n");
@@ -2647,7 +2675,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2647 frame, min_t(u16, len, 16), "TxHdr:\n"); 2675 frame, min_t(u16, len, 16), "TxHdr:\n");
2648 2676
2649 do { 2677 do {
2678 sdio_claim_host(bus->sdiodev->func[1]);
2650 ret = brcmf_tx_frame(bus, frame, len); 2679 ret = brcmf_tx_frame(bus, frame, len);
2680 sdio_release_host(bus->sdiodev->func[1]);
2651 } while (ret < 0 && retries++ < TXRETRIES); 2681 } while (ret < 0 && retries++ < TXRETRIES);
2652 } 2682 }
2653 2683
@@ -2657,13 +2687,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2657 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); 2687 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2658 2688
2659 bus->activity = false; 2689 bus->activity = false;
2690 sdio_claim_host(bus->sdiodev->func[1]);
2660 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); 2691 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
2692 sdio_release_host(bus->sdiodev->func[1]);
2661 } else { 2693 } else {
2662 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); 2694 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2663 } 2695 }
2664 2696
2665 up(&bus->sdsem);
2666
2667 if (ret) 2697 if (ret)
2668 bus->sdcnt.tx_ctlerrs++; 2698 bus->sdcnt.tx_ctlerrs++;
2669 else 2699 else
@@ -2693,8 +2723,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2693 * Read last word in socram to determine 2723 * Read last word in socram to determine
2694 * address of sdpcm_shared structure 2724 * address of sdpcm_shared structure
2695 */ 2725 */
2726 sdio_claim_host(bus->sdiodev->func[1]);
2696 rv = brcmf_sdbrcm_membytes(bus, false, shaddr, 2727 rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
2697 (u8 *)&addr_le, 4); 2728 (u8 *)&addr_le, 4);
2729 sdio_claim_host(bus->sdiodev->func[1]);
2698 if (rv < 0) 2730 if (rv < 0)
2699 return rv; 2731 return rv;
2700 2732
@@ -2713,8 +2745,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2713 } 2745 }
2714 2746
2715 /* Read hndrte_shared structure */ 2747 /* Read hndrte_shared structure */
2748 sdio_claim_host(bus->sdiodev->func[1]);
2716 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, 2749 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le,
2717 sizeof(struct sdpcm_shared_le)); 2750 sizeof(struct sdpcm_shared_le));
2751 sdio_release_host(bus->sdiodev->func[1]);
2718 if (rv < 0) 2752 if (rv < 0)
2719 return rv; 2753 return rv;
2720 2754
@@ -2817,12 +2851,14 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
2817 if ((sh->flags & SDPCM_SHARED_TRAP) == 0) 2851 if ((sh->flags & SDPCM_SHARED_TRAP) == 0)
2818 return 0; 2852 return 0;
2819 2853
2854 sdio_claim_host(bus->sdiodev->func[1]);
2820 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, 2855 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
2821 sizeof(struct brcmf_trap_info)); 2856 sizeof(struct brcmf_trap_info));
2822 if (error < 0) 2857 if (error < 0)
2823 return error; 2858 return error;
2824 2859
2825 nbytes = brcmf_sdio_dump_console(bus, sh, data, count); 2860 nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
2861 sdio_release_host(bus->sdiodev->func[1]);
2826 if (nbytes < 0) 2862 if (nbytes < 0)
2827 return nbytes; 2863 return nbytes;
2828 2864
@@ -2868,6 +2904,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
2868 return 0; 2904 return 0;
2869 } 2905 }
2870 2906
2907 sdio_claim_host(bus->sdiodev->func[1]);
2871 if (sh->assert_file_addr != 0) { 2908 if (sh->assert_file_addr != 0) {
2872 error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, 2909 error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr,
2873 (u8 *)file, 80); 2910 (u8 *)file, 80);
@@ -2880,6 +2917,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
2880 if (error < 0) 2917 if (error < 0)
2881 return error; 2918 return error;
2882 } 2919 }
2920 sdio_release_host(bus->sdiodev->func[1]);
2883 2921
2884 res = scnprintf(buf, sizeof(buf), 2922 res = scnprintf(buf, sizeof(buf),
2885 "dongle assert: %s:%d: assert(%s)\n", 2923 "dongle assert: %s:%d: assert(%s)\n",
@@ -2892,9 +2930,7 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus)
2892 int error; 2930 int error;
2893 struct sdpcm_shared sh; 2931 struct sdpcm_shared sh;
2894 2932
2895 down(&bus->sdsem);
2896 error = brcmf_sdio_readshared(bus, &sh); 2933 error = brcmf_sdio_readshared(bus, &sh);
2897 up(&bus->sdsem);
2898 2934
2899 if (error < 0) 2935 if (error < 0)
2900 return error; 2936 return error;
@@ -2921,7 +2957,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data,
2921 if (pos != 0) 2957 if (pos != 0)
2922 return 0; 2958 return 0;
2923 2959
2924 down(&bus->sdsem);
2925 error = brcmf_sdio_readshared(bus, &sh); 2960 error = brcmf_sdio_readshared(bus, &sh);
2926 if (error < 0) 2961 if (error < 0)
2927 goto done; 2962 goto done;
@@ -2938,7 +2973,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data,
2938 error += nbytes; 2973 error += nbytes;
2939 *ppos += error; 2974 *ppos += error;
2940done: 2975done:
2941 up(&bus->sdsem);
2942 return error; 2976 return error;
2943} 2977}
2944 2978
@@ -2989,6 +3023,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
2989 int timeleft; 3023 int timeleft;
2990 uint rxlen = 0; 3024 uint rxlen = 0;
2991 bool pending; 3025 bool pending;
3026 u8 *buf;
2992 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 3027 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2993 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 3028 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
2994 struct brcmf_sdio *bus = sdiodev->bus; 3029 struct brcmf_sdio *bus = sdiodev->bus;
@@ -2998,11 +3033,15 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
2998 /* Wait until control frame is available */ 3033 /* Wait until control frame is available */
2999 timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending); 3034 timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending);
3000 3035
3001 down(&bus->sdsem); 3036 spin_lock_bh(&bus->rxctl_lock);
3002 rxlen = bus->rxlen; 3037 rxlen = bus->rxlen;
3003 memcpy(msg, bus->rxctl, min(msglen, rxlen)); 3038 memcpy(msg, bus->rxctl, min(msglen, rxlen));
3039 bus->rxctl = NULL;
3040 buf = bus->rxctl_orig;
3041 bus->rxctl_orig = NULL;
3004 bus->rxlen = 0; 3042 bus->rxlen = 0;
3005 up(&bus->sdsem); 3043 spin_unlock_bh(&bus->rxctl_lock);
3044 vfree(buf);
3006 3045
3007 if (rxlen) { 3046 if (rxlen) {
3008 brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n", 3047 brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n",
@@ -3338,13 +3377,16 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
3338{ 3377{
3339 bool ret; 3378 bool ret;
3340 3379
3341 /* Download the firmware */ 3380 sdio_claim_host(bus->sdiodev->func[1]);
3381
3342 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 3382 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3343 3383
3344 ret = _brcmf_sdbrcm_download_firmware(bus) == 0; 3384 ret = _brcmf_sdbrcm_download_firmware(bus) == 0;
3345 3385
3346 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); 3386 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
3347 3387
3388 sdio_release_host(bus->sdiodev->func[1]);
3389
3348 return ret; 3390 return ret;
3349} 3391}
3350 3392
@@ -3373,7 +3415,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3373 bus->sdcnt.tickcnt = 0; 3415 bus->sdcnt.tickcnt = 0;
3374 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); 3416 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
3375 3417
3376 down(&bus->sdsem); 3418 sdio_claim_host(bus->sdiodev->func[1]);
3377 3419
3378 /* Make sure backplane clock is on, needed to generate F2 interrupt */ 3420 /* Make sure backplane clock is on, needed to generate F2 interrupt */
3379 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 3421 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
@@ -3442,7 +3484,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3442 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); 3484 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3443 3485
3444exit: 3486exit:
3445 up(&bus->sdsem); 3487 sdio_release_host(bus->sdiodev->func[1]);
3446 3488
3447 return ret; 3489 return ret;
3448} 3490}
@@ -3489,8 +3531,6 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3489 3531
3490 brcmf_dbg(TIMER, "Enter\n"); 3532 brcmf_dbg(TIMER, "Enter\n");
3491 3533
3492 down(&bus->sdsem);
3493
3494 /* Poll period: check device if appropriate. */ 3534 /* Poll period: check device if appropriate. */
3495 if (bus->poll && (++bus->polltick >= bus->pollrate)) { 3535 if (bus->poll && (++bus->polltick >= bus->pollrate)) {
3496 u32 intstatus = 0; 3536 u32 intstatus = 0;
@@ -3507,9 +3547,11 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3507 u8 devpend; 3547 u8 devpend;
3508 spin_unlock_irqrestore(&bus->dpc_tl_lock, 3548 spin_unlock_irqrestore(&bus->dpc_tl_lock,
3509 flags); 3549 flags);
3550 sdio_claim_host(bus->sdiodev->func[1]);
3510 devpend = brcmf_sdio_regrb(bus->sdiodev, 3551 devpend = brcmf_sdio_regrb(bus->sdiodev,
3511 SDIO_CCCR_INTx, 3552 SDIO_CCCR_INTx,
3512 NULL); 3553 NULL);
3554 sdio_release_host(bus->sdiodev->func[1]);
3513 intstatus = 3555 intstatus =
3514 devpend & (INTR_STATUS_FUNC1 | 3556 devpend & (INTR_STATUS_FUNC1 |
3515 INTR_STATUS_FUNC2); 3557 INTR_STATUS_FUNC2);
@@ -3534,16 +3576,18 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3534 } 3576 }
3535#ifdef DEBUG 3577#ifdef DEBUG
3536 /* Poll for console output periodically */ 3578 /* Poll for console output periodically */
3537 if (bus_if->state == BRCMF_BUS_DATA && 3579 if (bus_if && bus_if->state == BRCMF_BUS_DATA &&
3538 bus->console_interval != 0) { 3580 bus->console_interval != 0) {
3539 bus->console.count += BRCMF_WD_POLL_MS; 3581 bus->console.count += BRCMF_WD_POLL_MS;
3540 if (bus->console.count >= bus->console_interval) { 3582 if (bus->console.count >= bus->console_interval) {
3541 bus->console.count -= bus->console_interval; 3583 bus->console.count -= bus->console_interval;
3584 sdio_claim_host(bus->sdiodev->func[1]);
3542 /* Make sure backplane clock is on */ 3585 /* Make sure backplane clock is on */
3543 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 3586 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3544 if (brcmf_sdbrcm_readconsole(bus) < 0) 3587 if (brcmf_sdbrcm_readconsole(bus) < 0)
3545 /* stop on error */ 3588 /* stop on error */
3546 bus->console_interval = 0; 3589 bus->console_interval = 0;
3590 sdio_release_host(bus->sdiodev->func[1]);
3547 } 3591 }
3548 } 3592 }
3549#endif /* DEBUG */ 3593#endif /* DEBUG */
@@ -3556,13 +3600,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3556 bus->activity = false; 3600 bus->activity = false;
3557 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); 3601 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
3558 } else { 3602 } else {
3603 sdio_claim_host(bus->sdiodev->func[1]);
3559 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); 3604 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3605 sdio_release_host(bus->sdiodev->func[1]);
3560 } 3606 }
3561 } 3607 }
3562 } 3608 }
3563 3609
3564 up(&bus->sdsem);
3565
3566 return (atomic_read(&bus->ipend) > 0); 3610 return (atomic_read(&bus->ipend) > 0);
3567} 3611}
3568 3612
@@ -3657,6 +3701,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3657 3701
3658 bus->alp_only = true; 3702 bus->alp_only = true;
3659 3703
3704 sdio_claim_host(bus->sdiodev->func[1]);
3705
3660 pr_debug("F1 signature read @0x18000000=0x%4x\n", 3706 pr_debug("F1 signature read @0x18000000=0x%4x\n",
3661 brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); 3707 brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
3662 3708
@@ -3704,6 +3750,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3704 reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); 3750 reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL);
3705 brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); 3751 brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL);
3706 3752
3753 sdio_release_host(bus->sdiodev->func[1]);
3754
3707 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); 3755 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
3708 3756
3709 /* Locate an appropriately-aligned portion of hdrbuf */ 3757 /* Locate an appropriately-aligned portion of hdrbuf */
@@ -3719,6 +3767,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3719 return true; 3767 return true;
3720 3768
3721fail: 3769fail:
3770 sdio_release_host(bus->sdiodev->func[1]);
3722 return false; 3771 return false;
3723} 3772}
3724 3773
@@ -3726,6 +3775,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
3726{ 3775{
3727 brcmf_dbg(TRACE, "Enter\n"); 3776 brcmf_dbg(TRACE, "Enter\n");
3728 3777
3778 sdio_claim_host(bus->sdiodev->func[1]);
3779
3729 /* Disable F2 to clear any intermediate frame state on the dongle */ 3780 /* Disable F2 to clear any intermediate frame state on the dongle */
3730 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, 3781 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx,
3731 SDIO_FUNC_ENABLE_1, NULL); 3782 SDIO_FUNC_ENABLE_1, NULL);
@@ -3736,6 +3787,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
3736 /* Done with backplane-dependent accesses, can drop clock... */ 3787 /* Done with backplane-dependent accesses, can drop clock... */
3737 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); 3788 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
3738 3789
3790 sdio_release_host(bus->sdiodev->func[1]);
3791
3739 /* ...and initialize clock/power states */ 3792 /* ...and initialize clock/power states */
3740 bus->clkstate = CLK_SDONLY; 3793 bus->clkstate = CLK_SDONLY;
3741 bus->idletime = BRCMF_IDLE_INTERVAL; 3794 bus->idletime = BRCMF_IDLE_INTERVAL;
@@ -3791,8 +3844,10 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus)
3791 brcmf_dbg(TRACE, "Enter\n"); 3844 brcmf_dbg(TRACE, "Enter\n");
3792 3845
3793 if (bus->ci) { 3846 if (bus->ci) {
3847 sdio_claim_host(bus->sdiodev->func[1]);
3794 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 3848 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3795 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); 3849 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3850 sdio_release_host(bus->sdiodev->func[1]);
3796 brcmf_sdio_chip_detach(&bus->ci); 3851 brcmf_sdio_chip_detach(&bus->ci);
3797 if (bus->vars && bus->varsz) 3852 if (bus->vars && bus->varsz)
3798 kfree(bus->vars); 3853 kfree(bus->vars);
@@ -3812,7 +3867,8 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
3812 brcmf_sdio_intr_unregister(bus->sdiodev); 3867 brcmf_sdio_intr_unregister(bus->sdiodev);
3813 3868
3814 cancel_work_sync(&bus->datawork); 3869 cancel_work_sync(&bus->datawork);
3815 destroy_workqueue(bus->brcmf_wq); 3870 if (bus->brcmf_wq)
3871 destroy_workqueue(bus->brcmf_wq);
3816 3872
3817 if (bus->sdiodev->bus_if->drvr) { 3873 if (bus->sdiodev->bus_if->drvr) {
3818 brcmf_detach(bus->sdiodev->dev); 3874 brcmf_detach(bus->sdiodev->dev);
@@ -3854,31 +3910,29 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3854 bus->txminmax = BRCMF_TXMINMAX; 3910 bus->txminmax = BRCMF_TXMINMAX;
3855 bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; 3911 bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
3856 3912
3913 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
3914 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq");
3915 if (bus->brcmf_wq == NULL) {
3916 brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n");
3917 goto fail;
3918 }
3919
3857 /* attempt to attach to the dongle */ 3920 /* attempt to attach to the dongle */
3858 if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { 3921 if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) {
3859 brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); 3922 brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n");
3860 goto fail; 3923 goto fail;
3861 } 3924 }
3862 3925
3926 spin_lock_init(&bus->rxctl_lock);
3863 spin_lock_init(&bus->txqlock); 3927 spin_lock_init(&bus->txqlock);
3864 init_waitqueue_head(&bus->ctrl_wait); 3928 init_waitqueue_head(&bus->ctrl_wait);
3865 init_waitqueue_head(&bus->dcmd_resp_wait); 3929 init_waitqueue_head(&bus->dcmd_resp_wait);
3866 3930
3867 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq");
3868 if (bus->brcmf_wq == NULL) {
3869 brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n");
3870 goto fail;
3871 }
3872 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
3873
3874 /* Set up the watchdog timer */ 3931 /* Set up the watchdog timer */
3875 init_timer(&bus->timer); 3932 init_timer(&bus->timer);
3876 bus->timer.data = (unsigned long)bus; 3933 bus->timer.data = (unsigned long)bus;
3877 bus->timer.function = brcmf_sdbrcm_watchdog; 3934 bus->timer.function = brcmf_sdbrcm_watchdog;
3878 3935
3879 /* Initialize thread based operation and lock */
3880 sema_init(&bus->sdsem, 1);
3881
3882 /* Initialize watchdog thread */ 3936 /* Initialize watchdog thread */
3883 init_completion(&bus->watchdog_wait); 3937 init_completion(&bus->watchdog_wait);
3884 bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, 3938 bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,
@@ -3941,10 +3995,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3941 /* if firmware path present try to download and bring up bus */ 3995 /* if firmware path present try to download and bring up bus */
3942 ret = brcmf_bus_start(bus->sdiodev->dev); 3996 ret = brcmf_bus_start(bus->sdiodev->dev);
3943 if (ret != 0) { 3997 if (ret != 0) {
3944 if (ret == -ENOLINK) { 3998 brcmf_dbg(ERROR, "dongle is not responding\n");
3945 brcmf_dbg(ERROR, "dongle is not responding\n"); 3999 goto fail;
3946 goto fail;
3947 }
3948 } 4000 }
3949 4001
3950 return bus; 4002 return bus;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
new file mode 100644
index 00000000000..fa8fc443341
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -0,0 +1,509 @@
1/*
2 * Copyright (c) 2012 Broadcom Corporation
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 ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/netdevice.h>
17
18#include "brcmu_wifi.h"
19#include "brcmu_utils.h"
20
21#include "dhd.h"
22#include "dhd_dbg.h"
23#include "fweh.h"
24#include "fwil.h"
25
26/**
27 * struct brcm_ethhdr - broadcom specific ether header.
28 *
29 * @subtype: subtype for this packet.
30 * @length: TODO: length of appended data.
31 * @version: version indication.
32 * @oui: OUI of this packet.
33 * @usr_subtype: subtype for this OUI.
34 */
35struct brcm_ethhdr {
36 __be16 subtype;
37 __be16 length;
38 u8 version;
39 u8 oui[3];
40 __be16 usr_subtype;
41} __packed;
42
43struct brcmf_event_msg_be {
44 __be16 version;
45 __be16 flags;
46 __be32 event_type;
47 __be32 status;
48 __be32 reason;
49 __be32 auth_type;
50 __be32 datalen;
51 u8 addr[ETH_ALEN];
52 char ifname[IFNAMSIZ];
53 u8 ifidx;
54 u8 bsscfgidx;
55} __packed;
56
57/**
58 * struct brcmf_event - contents of broadcom event packet.
59 *
60 * @eth: standard ether header.
61 * @hdr: broadcom specific ether header.
62 * @msg: common part of the actual event message.
63 */
64struct brcmf_event {
65 struct ethhdr eth;
66 struct brcm_ethhdr hdr;
67 struct brcmf_event_msg_be msg;
68} __packed;
69
70/**
71 * struct brcmf_fweh_queue_item - event item on event queue.
72 *
73 * @q: list element for queuing.
74 * @code: event code.
75 * @ifidx: interface index related to this event.
76 * @ifaddr: ethernet address for interface.
77 * @emsg: common parameters of the firmware event message.
78 * @data: event specific data part of the firmware event.
79 */
80struct brcmf_fweh_queue_item {
81 struct list_head q;
82 enum brcmf_fweh_event_code code;
83 u8 ifidx;
84 u8 ifaddr[ETH_ALEN];
85 struct brcmf_event_msg_be emsg;
86 u8 data[0];
87};
88
89/**
90 * struct brcmf_fweh_event_name - code, name mapping entry.
91 */
92struct brcmf_fweh_event_name {
93 enum brcmf_fweh_event_code code;
94 const char *name;
95};
96
97#ifdef DEBUG
98/* array for mapping code to event name */
99static struct brcmf_fweh_event_name fweh_event_names[] = {
100 { BRCMF_E_SET_SSID, "SET_SSID" },
101 { BRCMF_E_JOIN, "JOIN" },
102 { BRCMF_E_START, "START" },
103 { BRCMF_E_AUTH, "AUTH" },
104 { BRCMF_E_AUTH_IND, "AUTH_IND" },
105 { BRCMF_E_DEAUTH, "DEAUTH" },
106 { BRCMF_E_DEAUTH_IND, "DEAUTH_IND" },
107 { BRCMF_E_ASSOC, "ASSOC" },
108 { BRCMF_E_ASSOC_IND, "ASSOC_IND" },
109 { BRCMF_E_REASSOC, "REASSOC" },
110 { BRCMF_E_REASSOC_IND, "REASSOC_IND" },
111 { BRCMF_E_DISASSOC, "DISASSOC" },
112 { BRCMF_E_DISASSOC_IND, "DISASSOC_IND" },
113 { BRCMF_E_QUIET_START, "START_QUIET" },
114 { BRCMF_E_QUIET_END, "END_QUIET" },
115 { BRCMF_E_BEACON_RX, "BEACON_RX" },
116 { BRCMF_E_LINK, "LINK" },
117 { BRCMF_E_MIC_ERROR, "MIC_ERROR" },
118 { BRCMF_E_NDIS_LINK, "NDIS_LINK" },
119 { BRCMF_E_ROAM, "ROAM" },
120 { BRCMF_E_TXFAIL, "TXFAIL" },
121 { BRCMF_E_PMKID_CACHE, "PMKID_CACHE" },
122 { BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF" },
123 { BRCMF_E_PRUNE, "PRUNE" },
124 { BRCMF_E_AUTOAUTH, "AUTOAUTH" },
125 { BRCMF_E_EAPOL_MSG, "EAPOL_MSG" },
126 { BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE" },
127 { BRCMF_E_ADDTS_IND, "ADDTS_IND" },
128 { BRCMF_E_DELTS_IND, "DELTS_IND" },
129 { BRCMF_E_BCNSENT_IND, "BCNSENT_IND" },
130 { BRCMF_E_BCNRX_MSG, "BCNRX_MSG" },
131 { BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG" },
132 { BRCMF_E_ROAM_PREP, "ROAM_PREP" },
133 { BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND" },
134 { BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST" },
135 { BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE" },
136 { BRCMF_E_JOIN_START, "JOIN_START" },
137 { BRCMF_E_ROAM_START, "ROAM_START" },
138 { BRCMF_E_ASSOC_START, "ASSOC_START" },
139 { BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC" },
140 { BRCMF_E_RADIO, "RADIO" },
141 { BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG" },
142 { BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG" },
143 { BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND" },
144 { BRCMF_E_PSK_SUP, "PSK_SUP" },
145 { BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED" },
146 { BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME" },
147 { BRCMF_E_ICV_ERROR, "ICV_ERROR" },
148 { BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR" },
149 { BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR" },
150 { BRCMF_E_TRACE, "TRACE" },
151 { BRCMF_E_IF, "IF" },
152 { BRCMF_E_RSSI, "RSSI" },
153 { BRCMF_E_PFN_SCAN_COMPLETE, "PFN_SCAN_COMPLETE" },
154 { BRCMF_E_EXTLOG_MSG, "EXTLOG_MSG" },
155 { BRCMF_E_ACTION_FRAME, "ACTION_FRAME" },
156 { BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION_FRAME_COMPLETE" },
157 { BRCMF_E_PRE_ASSOC_IND, "PRE_ASSOC_IND" },
158 { BRCMF_E_PRE_REASSOC_IND, "PRE_REASSOC_IND" },
159 { BRCMF_E_CHANNEL_ADOPTED, "CHANNEL_ADOPTED" },
160 { BRCMF_E_AP_STARTED, "AP_STARTED" },
161 { BRCMF_E_DFS_AP_STOP, "DFS_AP_STOP" },
162 { BRCMF_E_DFS_AP_RESUME, "DFS_AP_RESUME" },
163 { BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT" },
164 { BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE, "ACTION_FRM_OFF_CHAN_CMPLT" },
165 { BRCMF_E_DCS_REQUEST, "DCS_REQUEST" },
166 { BRCMF_E_FIFO_CREDIT_MAP, "FIFO_CREDIT_MAP"}
167};
168
169/**
170 * brcmf_fweh_event_name() - returns name for given event code.
171 *
172 * @code: code to lookup.
173 */
174static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code)
175{
176 int i;
177 for (i = 0; i < ARRAY_SIZE(fweh_event_names); i++) {
178 if (fweh_event_names[i].code == code)
179 return fweh_event_names[i].name;
180 }
181 return "unknown";
182}
183#else
184static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code)
185{
186 return "nodebug";
187}
188#endif
189
190/**
191 * brcmf_fweh_queue_event() - create and queue event.
192 *
193 * @fweh: firmware event handling info.
194 * @event: event queue entry.
195 */
196static void brcmf_fweh_queue_event(struct brcmf_fweh_info *fweh,
197 struct brcmf_fweh_queue_item *event)
198{
199 ulong flags;
200
201 spin_lock_irqsave(&fweh->evt_q_lock, flags);
202 list_add_tail(&event->q, &fweh->event_q);
203 spin_unlock_irqrestore(&fweh->evt_q_lock, flags);
204 schedule_work(&fweh->event_work);
205}
206
207static int brcmf_fweh_call_event_handler(struct brcmf_if *ifp,
208 enum brcmf_fweh_event_code code,
209 struct brcmf_event_msg *emsg,
210 void *data)
211{
212 struct brcmf_fweh_info *fweh;
213 int err = -EINVAL;
214
215 if (ifp) {
216 fweh = &ifp->drvr->fweh;
217
218 /* handle the event if valid interface and handler */
219 if (ifp->ndev && fweh->evt_handler[code])
220 err = fweh->evt_handler[code](ifp, emsg, data);
221 else
222 brcmf_dbg(ERROR, "unhandled event %d ignored\n", code);
223 } else {
224 brcmf_dbg(ERROR, "no interface object\n");
225 }
226 return err;
227}
228
229/**
230 * brcmf_fweh_handle_if_event() - handle IF event.
231 *
232 * @drvr: driver information object.
233 * @item: queue entry.
234 * @ifpp: interface object (may change upon ADD action).
235 */
236static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
237 struct brcmf_event_msg *emsg,
238 void *data)
239{
240 struct brcmf_if_event *ifevent = data;
241 struct brcmf_if *ifp;
242 int err = 0;
243
244 brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u\n",
245 ifevent->action, ifevent->ifidx,
246 ifevent->bssidx, ifevent->flags);
247
248 if (ifevent->ifidx >= BRCMF_MAX_IFS) {
249 brcmf_dbg(ERROR, "invalid interface index: %u\n",
250 ifevent->ifidx);
251 return;
252 }
253
254 ifp = drvr->iflist[ifevent->ifidx];
255
256 if (ifevent->action == BRCMF_E_IF_ADD) {
257 brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname,
258 emsg->addr);
259 ifp = brcmf_add_if(drvr, ifevent->ifidx, ifevent->bssidx,
260 emsg->ifname, emsg->addr);
261 if (IS_ERR(ifp))
262 return;
263
264 if (!drvr->fweh.evt_handler[BRCMF_E_IF])
265 err = brcmf_net_attach(ifp);
266 }
267
268 err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
269
270 if (ifevent->action == BRCMF_E_IF_DEL)
271 brcmf_del_if(drvr, ifevent->ifidx);
272}
273
274/**
275 * brcmf_fweh_dequeue_event() - get event from the queue.
276 *
277 * @fweh: firmware event handling info.
278 */
279static struct brcmf_fweh_queue_item *
280brcmf_fweh_dequeue_event(struct brcmf_fweh_info *fweh)
281{
282 struct brcmf_fweh_queue_item *event = NULL;
283 ulong flags;
284
285 spin_lock_irqsave(&fweh->evt_q_lock, flags);
286 if (!list_empty(&fweh->event_q)) {
287 event = list_first_entry(&fweh->event_q,
288 struct brcmf_fweh_queue_item, q);
289 list_del(&event->q);
290 }
291 spin_unlock_irqrestore(&fweh->evt_q_lock, flags);
292
293 return event;
294}
295
296/**
297 * brcmf_fweh_event_worker() - firmware event worker.
298 *
299 * @work: worker object.
300 */
301static void brcmf_fweh_event_worker(struct work_struct *work)
302{
303 struct brcmf_pub *drvr;
304 struct brcmf_if *ifp;
305 struct brcmf_fweh_info *fweh;
306 struct brcmf_fweh_queue_item *event;
307 int err = 0;
308 struct brcmf_event_msg_be *emsg_be;
309 struct brcmf_event_msg emsg;
310
311 fweh = container_of(work, struct brcmf_fweh_info, event_work);
312 drvr = container_of(fweh, struct brcmf_pub, fweh);
313
314 while ((event = brcmf_fweh_dequeue_event(fweh))) {
315 ifp = drvr->iflist[event->ifidx];
316
317 brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM:\n",
318 brcmf_fweh_event_name(event->code), event->code,
319 event->emsg.ifidx, event->emsg.bsscfgidx,
320 event->emsg.addr);
321
322 /* convert event message */
323 emsg_be = &event->emsg;
324 emsg.version = be16_to_cpu(emsg_be->version);
325 emsg.flags = be16_to_cpu(emsg_be->flags);
326 emsg.event_code = event->code;
327 emsg.status = be32_to_cpu(emsg_be->status);
328 emsg.reason = be32_to_cpu(emsg_be->reason);
329 emsg.auth_type = be32_to_cpu(emsg_be->auth_type);
330 emsg.datalen = be32_to_cpu(emsg_be->datalen);
331 memcpy(emsg.addr, emsg_be->addr, ETH_ALEN);
332 memcpy(emsg.ifname, emsg_be->ifname, sizeof(emsg.ifname));
333 emsg.ifidx = emsg_be->ifidx;
334 emsg.bsscfgidx = emsg_be->bsscfgidx;
335
336 brcmf_dbg(EVENT, " version %u flags %u status %u reason %u\n",
337 emsg.version, emsg.flags, emsg.status, emsg.reason);
338 brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data,
339 min_t(u32, emsg.datalen, 64),
340 "appended:");
341
342 /* special handling of interface event */
343 if (event->code == BRCMF_E_IF) {
344 brcmf_fweh_handle_if_event(drvr, &emsg, event->data);
345 goto event_free;
346 }
347
348 err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg,
349 event->data);
350 if (err) {
351 brcmf_dbg(ERROR, "event handler failed (%d)\n",
352 event->code);
353 err = 0;
354 }
355event_free:
356 kfree(event);
357 }
358}
359
360/**
361 * brcmf_fweh_attach() - initialize firmware event handling.
362 *
363 * @drvr: driver information object.
364 */
365void brcmf_fweh_attach(struct brcmf_pub *drvr)
366{
367 struct brcmf_fweh_info *fweh = &drvr->fweh;
368 INIT_WORK(&fweh->event_work, brcmf_fweh_event_worker);
369 spin_lock_init(&fweh->evt_q_lock);
370 INIT_LIST_HEAD(&fweh->event_q);
371}
372
373/**
374 * brcmf_fweh_detach() - cleanup firmware event handling.
375 *
376 * @drvr: driver information object.
377 */
378void brcmf_fweh_detach(struct brcmf_pub *drvr)
379{
380 struct brcmf_fweh_info *fweh = &drvr->fweh;
381 struct brcmf_if *ifp = drvr->iflist[0];
382 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
383
384 if (ifp) {
385 /* clear all events */
386 memset(eventmask, 0, BRCMF_EVENTING_MASK_LEN);
387 (void)brcmf_fil_iovar_data_set(ifp, "event_msgs",
388 eventmask,
389 BRCMF_EVENTING_MASK_LEN);
390 }
391 /* cancel the worker */
392 cancel_work_sync(&fweh->event_work);
393 WARN_ON(!list_empty(&fweh->event_q));
394 memset(fweh->evt_handler, 0, sizeof(fweh->evt_handler));
395}
396
397/**
398 * brcmf_fweh_register() - register handler for given event code.
399 *
400 * @drvr: driver information object.
401 * @code: event code.
402 * @handler: handler for the given event code.
403 */
404int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code,
405 brcmf_fweh_handler_t handler)
406{
407 if (drvr->fweh.evt_handler[code]) {
408 brcmf_dbg(ERROR, "event code %d already registered\n", code);
409 return -ENOSPC;
410 }
411 drvr->fweh.evt_handler[code] = handler;
412 brcmf_dbg(TRACE, "event handler registered for %s\n",
413 brcmf_fweh_event_name(code));
414 return 0;
415}
416
417/**
418 * brcmf_fweh_unregister() - remove handler for given code.
419 *
420 * @drvr: driver information object.
421 * @code: event code.
422 */
423void brcmf_fweh_unregister(struct brcmf_pub *drvr,
424 enum brcmf_fweh_event_code code)
425{
426 brcmf_dbg(TRACE, "event handler cleared for %s\n",
427 brcmf_fweh_event_name(code));
428 drvr->fweh.evt_handler[code] = NULL;
429}
430
431/**
432 * brcmf_fweh_activate_events() - enables firmware events registered.
433 *
434 * @ifp: primary interface object.
435 */
436int brcmf_fweh_activate_events(struct brcmf_if *ifp)
437{
438 int i, err;
439 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
440
441 for (i = 0; i < BRCMF_E_LAST; i++) {
442 if (ifp->drvr->fweh.evt_handler[i]) {
443 brcmf_dbg(EVENT, "enable event %s\n",
444 brcmf_fweh_event_name(i));
445 setbit(eventmask, i);
446 }
447 }
448
449 /* want to handle IF event as well */
450 brcmf_dbg(EVENT, "enable event IF\n");
451 setbit(eventmask, BRCMF_E_IF);
452
453 err = brcmf_fil_iovar_data_set(ifp, "event_msgs",
454 eventmask, BRCMF_EVENTING_MASK_LEN);
455 if (err)
456 brcmf_dbg(ERROR, "Set event_msgs error (%d)\n", err);
457
458 return err;
459}
460
461/**
462 * brcmf_fweh_process_event() - process skb as firmware event.
463 *
464 * @drvr: driver information object.
465 * @event_packet: event packet to process.
466 * @ifidx: index of the firmware interface (may change).
467 *
468 * If the packet buffer contains a firmware event message it will
469 * dispatch the event to a registered handler (using worker).
470 */
471void brcmf_fweh_process_event(struct brcmf_pub *drvr,
472 struct brcmf_event *event_packet, u8 *ifidx)
473{
474 enum brcmf_fweh_event_code code;
475 struct brcmf_fweh_info *fweh = &drvr->fweh;
476 struct brcmf_fweh_queue_item *event;
477 gfp_t alloc_flag = GFP_KERNEL;
478 void *data;
479 u32 datalen;
480
481 /* get event info */
482 code = get_unaligned_be32(&event_packet->msg.event_type);
483 datalen = get_unaligned_be32(&event_packet->msg.datalen);
484 *ifidx = event_packet->msg.ifidx;
485 data = &event_packet[1];
486
487 if (code >= BRCMF_E_LAST)
488 return;
489
490 if (code != BRCMF_E_IF && !fweh->evt_handler[code])
491 return;
492
493 if (in_interrupt())
494 alloc_flag = GFP_ATOMIC;
495
496 event = kzalloc(sizeof(*event) + datalen, alloc_flag);
497 if (!event)
498 return;
499
500 event->code = code;
501 event->ifidx = *ifidx;
502
503 /* use memcpy to get aligned event message */
504 memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg));
505 memcpy(event->data, data, datalen);
506 memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN);
507
508 brcmf_fweh_queue_event(fweh, event);
509}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
new file mode 100644
index 00000000000..b39246a630d
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -0,0 +1,207 @@
1/*
2 * Copyright (c) 2012 Broadcom Corporation
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 ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17
18#ifndef FWEH_H_
19#define FWEH_H_
20
21#include <asm/unaligned.h>
22#include <linux/skbuff.h>
23#include <linux/if_ether.h>
24#include <linux/if.h>
25
26/* formward declarations */
27struct brcmf_pub;
28struct brcmf_if;
29struct brcmf_cfg80211_info;
30struct brcmf_event;
31
32/* firmware event codes sent by the dongle */
33enum brcmf_fweh_event_code {
34 BRCMF_E_SET_SSID = 0,
35 BRCMF_E_JOIN = 1,
36 BRCMF_E_START = 2,
37 BRCMF_E_AUTH = 3,
38 BRCMF_E_AUTH_IND = 4,
39 BRCMF_E_DEAUTH = 5,
40 BRCMF_E_DEAUTH_IND = 6,
41 BRCMF_E_ASSOC = 7,
42 BRCMF_E_ASSOC_IND = 8,
43 BRCMF_E_REASSOC = 9,
44 BRCMF_E_REASSOC_IND = 10,
45 BRCMF_E_DISASSOC = 11,
46 BRCMF_E_DISASSOC_IND = 12,
47 BRCMF_E_QUIET_START = 13,
48 BRCMF_E_QUIET_END = 14,
49 BRCMF_E_BEACON_RX = 15,
50 BRCMF_E_LINK = 16,
51 BRCMF_E_MIC_ERROR = 17,
52 BRCMF_E_NDIS_LINK = 18,
53 BRCMF_E_ROAM = 19,
54 BRCMF_E_TXFAIL = 20,
55 BRCMF_E_PMKID_CACHE = 21,
56 BRCMF_E_RETROGRADE_TSF = 22,
57 BRCMF_E_PRUNE = 23,
58 BRCMF_E_AUTOAUTH = 24,
59 BRCMF_E_EAPOL_MSG = 25,
60 BRCMF_E_SCAN_COMPLETE = 26,
61 BRCMF_E_ADDTS_IND = 27,
62 BRCMF_E_DELTS_IND = 28,
63 BRCMF_E_BCNSENT_IND = 29,
64 BRCMF_E_BCNRX_MSG = 30,
65 BRCMF_E_BCNLOST_MSG = 31,
66 BRCMF_E_ROAM_PREP = 32,
67 BRCMF_E_PFN_NET_FOUND = 33,
68 BRCMF_E_PFN_NET_LOST = 34,
69 BRCMF_E_RESET_COMPLETE = 35,
70 BRCMF_E_JOIN_START = 36,
71 BRCMF_E_ROAM_START = 37,
72 BRCMF_E_ASSOC_START = 38,
73 BRCMF_E_IBSS_ASSOC = 39,
74 BRCMF_E_RADIO = 40,
75 BRCMF_E_PSM_WATCHDOG = 41,
76 BRCMF_E_PROBREQ_MSG = 44,
77 BRCMF_E_SCAN_CONFIRM_IND = 45,
78 BRCMF_E_PSK_SUP = 46,
79 BRCMF_E_COUNTRY_CODE_CHANGED = 47,
80 BRCMF_E_EXCEEDED_MEDIUM_TIME = 48,
81 BRCMF_E_ICV_ERROR = 49,
82 BRCMF_E_UNICAST_DECODE_ERROR = 50,
83 BRCMF_E_MULTICAST_DECODE_ERROR = 51,
84 BRCMF_E_TRACE = 52,
85 BRCMF_E_IF = 54,
86 BRCMF_E_RSSI = 56,
87 BRCMF_E_PFN_SCAN_COMPLETE = 57,
88 BRCMF_E_EXTLOG_MSG = 58,
89 BRCMF_E_ACTION_FRAME = 59,
90 BRCMF_E_ACTION_FRAME_COMPLETE = 60,
91 BRCMF_E_PRE_ASSOC_IND = 61,
92 BRCMF_E_PRE_REASSOC_IND = 62,
93 BRCMF_E_CHANNEL_ADOPTED = 63,
94 BRCMF_E_AP_STARTED = 64,
95 BRCMF_E_DFS_AP_STOP = 65,
96 BRCMF_E_DFS_AP_RESUME = 66,
97 BRCMF_E_ESCAN_RESULT = 69,
98 BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE = 70,
99 BRCMF_E_DCS_REQUEST = 73,
100 BRCMF_E_FIFO_CREDIT_MAP = 74,
101 BRCMF_E_LAST
102};
103
104/* flags field values in struct brcmf_event_msg */
105#define BRCMF_EVENT_MSG_LINK 0x01
106#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
107#define BRCMF_EVENT_MSG_GROUP 0x04
108
109/**
110 * definitions for event packet validation.
111 */
112#define BRCMF_EVENT_OUI_OFFSET 19
113#define BRCM_OUI "\x00\x10\x18"
114#define DOT11_OUI_LEN 3
115#define BCMILCP_BCM_SUBTYPE_EVENT 1
116
117
118/**
119 * struct brcmf_event_msg - firmware event message.
120 *
121 * @version: version information.
122 * @flags: event flags.
123 * @event_code: firmware event code.
124 * @status: status information.
125 * @reason: reason code.
126 * @auth_type: authentication type.
127 * @datalen: lenght of event data buffer.
128 * @addr: ether address.
129 * @ifname: interface name.
130 * @ifidx: interface index.
131 * @bsscfgidx: bsscfg index.
132 */
133struct brcmf_event_msg {
134 u16 version;
135 u16 flags;
136 u32 event_code;
137 u32 status;
138 u32 reason;
139 s32 auth_type;
140 u32 datalen;
141 u8 addr[ETH_ALEN];
142 char ifname[IFNAMSIZ];
143 u8 ifidx;
144 u8 bsscfgidx;
145};
146
147typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
148 const struct brcmf_event_msg *evtmsg,
149 void *data);
150
151/**
152 * struct brcmf_fweh_info - firmware event handling information.
153 *
154 * @event_work: event worker.
155 * @evt_q_lock: lock for event queue protection.
156 * @event_q: event queue.
157 * @evt_handler: registered event handlers.
158 */
159struct brcmf_fweh_info {
160 struct work_struct event_work;
161 struct spinlock evt_q_lock;
162 struct list_head event_q;
163 int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp,
164 const struct brcmf_event_msg *evtmsg,
165 void *data);
166};
167
168void brcmf_fweh_attach(struct brcmf_pub *drvr);
169void brcmf_fweh_detach(struct brcmf_pub *drvr);
170int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code,
171 int (*handler)(struct brcmf_if *ifp,
172 const struct brcmf_event_msg *evtmsg,
173 void *data));
174void brcmf_fweh_unregister(struct brcmf_pub *drvr,
175 enum brcmf_fweh_event_code code);
176int brcmf_fweh_activate_events(struct brcmf_if *ifp);
177void brcmf_fweh_process_event(struct brcmf_pub *drvr,
178 struct brcmf_event *event_packet, u8 *ifidx);
179
180static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
181 struct sk_buff *skb, u8 *ifidx)
182{
183 struct brcmf_event *event_packet;
184 u8 *data;
185 u16 usr_stype;
186
187 /* only process events when protocol matches */
188 if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL))
189 return;
190
191 /* check for BRCM oui match */
192 event_packet = (struct brcmf_event *)skb_mac_header(skb);
193 data = (u8 *)event_packet;
194 data += BRCMF_EVENT_OUI_OFFSET;
195 if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN))
196 return;
197
198 /* final match on usr_subtype */
199 data += DOT11_OUI_LEN;
200 usr_stype = get_unaligned_be16(data);
201 if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT)
202 return;
203
204 brcmf_fweh_process_event(drvr, event_packet, ifidx);
205}
206
207#endif /* FWEH_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index 4b272c3d237..51a14505197 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -20,7 +20,6 @@
20 20
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/netdevice.h> 22#include <linux/netdevice.h>
23#include <defs.h>
24#include <brcmu_utils.h> 23#include <brcmu_utils.h>
25#include <brcmu_wifi.h> 24#include <brcmu_wifi.h>
26#include "dhd.h" 25#include "dhd.h"
@@ -29,13 +28,16 @@
29#include "fwil.h" 28#include "fwil.h"
30 29
31 30
31#define MAX_HEX_DUMP_LEN 64
32
33
32static s32 34static s32
33brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) 35brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
34{ 36{
35 struct brcmf_pub *drvr = ifp->drvr; 37 struct brcmf_pub *drvr = ifp->drvr;
36 s32 err; 38 s32 err;
37 39
38 if (drvr->bus_if->state == BRCMF_BUS_DOWN) { 40 if (drvr->bus_if->state != BRCMF_BUS_DATA) {
39 brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); 41 brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
40 return -EIO; 42 return -EIO;
41 } 43 }
@@ -64,7 +66,8 @@ brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len)
64 mutex_lock(&ifp->drvr->proto_block); 66 mutex_lock(&ifp->drvr->proto_block);
65 67
66 brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); 68 brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len);
67 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); 69 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
70 min_t(uint, len, MAX_HEX_DUMP_LEN), "data");
68 71
69 err = brcmf_fil_cmd_data(ifp, cmd, data, len, true); 72 err = brcmf_fil_cmd_data(ifp, cmd, data, len, true);
70 mutex_unlock(&ifp->drvr->proto_block); 73 mutex_unlock(&ifp->drvr->proto_block);
@@ -81,7 +84,8 @@ brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len)
81 err = brcmf_fil_cmd_data(ifp, cmd, data, len, false); 84 err = brcmf_fil_cmd_data(ifp, cmd, data, len, false);
82 85
83 brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); 86 brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len);
84 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); 87 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
88 min_t(uint, len, MAX_HEX_DUMP_LEN), "data");
85 89
86 mutex_unlock(&ifp->drvr->proto_block); 90 mutex_unlock(&ifp->drvr->proto_block);
87 91
@@ -147,7 +151,8 @@ brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data,
147 mutex_lock(&drvr->proto_block); 151 mutex_lock(&drvr->proto_block);
148 152
149 brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); 153 brcmf_dbg(FIL, "name=%s, len=%d\n", name, len);
150 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); 154 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
155 min_t(uint, len, MAX_HEX_DUMP_LEN), "data");
151 156
152 buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, 157 buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf,
153 sizeof(drvr->proto_buf)); 158 sizeof(drvr->proto_buf));
@@ -186,7 +191,8 @@ brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data,
186 } 191 }
187 192
188 brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); 193 brcmf_dbg(FIL, "name=%s, len=%d\n", name, len);
189 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); 194 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
195 min_t(uint, len, MAX_HEX_DUMP_LEN), "data");
190 196
191 mutex_unlock(&drvr->proto_block); 197 mutex_unlock(&drvr->proto_block);
192 return err; 198 return err;
@@ -268,7 +274,8 @@ brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name,
268 mutex_lock(&drvr->proto_block); 274 mutex_lock(&drvr->proto_block);
269 275
270 brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); 276 brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len);
271 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); 277 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
278 min_t(uint, len, MAX_HEX_DUMP_LEN), "data");
272 279
273 buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, 280 buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len,
274 drvr->proto_buf, sizeof(drvr->proto_buf)); 281 drvr->proto_buf, sizeof(drvr->proto_buf));
@@ -294,7 +301,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name,
294 301
295 mutex_lock(&drvr->proto_block); 302 mutex_lock(&drvr->proto_block);
296 303
297 buflen = brcmf_create_bsscfg(ifp->bssidx, name, NULL, len, 304 buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len,
298 drvr->proto_buf, sizeof(drvr->proto_buf)); 305 drvr->proto_buf, sizeof(drvr->proto_buf));
299 if (buflen) { 306 if (buflen) {
300 err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf, 307 err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf,
@@ -306,7 +313,8 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name,
306 brcmf_dbg(ERROR, "Creating bsscfg failed\n"); 313 brcmf_dbg(ERROR, "Creating bsscfg failed\n");
307 } 314 }
308 brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); 315 brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len);
309 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); 316 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
317 min_t(uint, len, MAX_HEX_DUMP_LEN), "data");
310 318
311 mutex_unlock(&drvr->proto_block); 319 mutex_unlock(&drvr->proto_block);
312 return err; 320 return err;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 484a6e4f23a..39a5baa92f2 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -14,24 +14,12 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/init.h>
18#include <linux/kernel.h> 17#include <linux/kernel.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/kthread.h>
21#include <linux/slab.h>
22#include <linux/skbuff.h>
23#include <linux/netdevice.h>
24#include <linux/spinlock.h>
25#include <linux/ethtool.h>
26#include <linux/fcntl.h>
27#include <linux/fs.h>
28#include <linux/uaccess.h>
29#include <linux/firmware.h> 19#include <linux/firmware.h>
30#include <linux/usb.h> 20#include <linux/usb.h>
31#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
32#include <net/cfg80211.h>
33 22
34#include <defs.h>
35#include <brcmu_utils.h> 23#include <brcmu_utils.h>
36#include <brcmu_wifi.h> 24#include <brcmu_wifi.h>
37#include <dhd_bus.h> 25#include <dhd_bus.h>
@@ -42,13 +30,11 @@
42 30
43#define IOCTL_RESP_TIMEOUT 2000 31#define IOCTL_RESP_TIMEOUT 2000
44 32
45#define BRCMF_USB_DLIMAGE_SPINWAIT 100 /* in unit of ms */ 33#define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */
46#define BRCMF_USB_DLIMAGE_LIMIT 500 /* spinwait limit (ms) */ 34#define BRCMF_USB_RESET_GETVER_LOOP_CNT 10
47 35
48#define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle 36#define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle
49 has boot up */ 37 has boot up */
50#define BRCMF_USB_RESETCFG_SPINWAIT 1 /* wait after resetcfg (ms) */
51
52#define BRCMF_USB_NRXQ 50 38#define BRCMF_USB_NRXQ 50
53#define BRCMF_USB_NTXQ 50 39#define BRCMF_USB_NTXQ 50
54 40
@@ -69,16 +55,6 @@
69#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" 55#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin"
70#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" 56#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin"
71 57
72enum usbdev_suspend_state {
73 USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow
74 suspend */
75 USBOS_SUSPEND_STATE_SUSPEND_PENDING, /* Device is idle, can be
76 * suspended. Wating PM to
77 * suspend the device
78 */
79 USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */
80};
81
82struct brcmf_usb_image { 58struct brcmf_usb_image {
83 struct list_head list; 59 struct list_head list;
84 s8 *fwname; 60 s8 *fwname;
@@ -99,10 +75,8 @@ struct brcmf_usbdev_info {
99 struct list_head rx_postq; 75 struct list_head rx_postq;
100 struct list_head tx_freeq; 76 struct list_head tx_freeq;
101 struct list_head tx_postq; 77 struct list_head tx_postq;
102 enum usbdev_suspend_state suspend_state;
103 uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; 78 uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
104 79
105 bool activity;
106 int rx_low_watermark; 80 int rx_low_watermark;
107 int tx_low_watermark; 81 int tx_low_watermark;
108 int tx_high_watermark; 82 int tx_high_watermark;
@@ -170,6 +144,7 @@ static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
170static void 144static void
171brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status) 145brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status)
172{ 146{
147 brcmf_dbg(USB, "Enter, status=%d\n", status);
173 148
174 if (unlikely(devinfo == NULL)) 149 if (unlikely(devinfo == NULL))
175 return; 150 return;
@@ -197,6 +172,7 @@ brcmf_usb_ctlread_complete(struct urb *urb)
197 struct brcmf_usbdev_info *devinfo = 172 struct brcmf_usbdev_info *devinfo =
198 (struct brcmf_usbdev_info *)urb->context; 173 (struct brcmf_usbdev_info *)urb->context;
199 174
175 brcmf_dbg(USB, "Enter\n");
200 devinfo->ctl_urb_actual_length = urb->actual_length; 176 devinfo->ctl_urb_actual_length = urb->actual_length;
201 brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ, 177 brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ,
202 urb->status); 178 urb->status);
@@ -208,33 +184,22 @@ brcmf_usb_ctlwrite_complete(struct urb *urb)
208 struct brcmf_usbdev_info *devinfo = 184 struct brcmf_usbdev_info *devinfo =
209 (struct brcmf_usbdev_info *)urb->context; 185 (struct brcmf_usbdev_info *)urb->context;
210 186
187 brcmf_dbg(USB, "Enter\n");
211 brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE, 188 brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE,
212 urb->status); 189 urb->status);
213} 190}
214 191
215static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state)
216{
217 return 0;
218}
219
220static int 192static int
221brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) 193brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
222{ 194{
223 int ret; 195 int ret;
224 u16 size; 196 u16 size;
225 197
198 brcmf_dbg(USB, "Enter\n");
226 if (devinfo == NULL || buf == NULL || 199 if (devinfo == NULL || buf == NULL ||
227 len == 0 || devinfo->ctl_urb == NULL) 200 len == 0 || devinfo->ctl_urb == NULL)
228 return -EINVAL; 201 return -EINVAL;
229 202
230 /* If the USB/HSIC bus in sleep state, wake it up */
231 if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED)
232 if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
233 brcmf_dbg(ERROR, "Could not Resume the bus!\n");
234 return -EIO;
235 }
236
237 devinfo->activity = true;
238 size = len; 203 size = len;
239 devinfo->ctl_write.wLength = cpu_to_le16p(&size); 204 devinfo->ctl_write.wLength = cpu_to_le16p(&size);
240 devinfo->ctl_urb->transfer_buffer_length = size; 205 devinfo->ctl_urb->transfer_buffer_length = size;
@@ -262,6 +227,7 @@ brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
262 int ret; 227 int ret;
263 u16 size; 228 u16 size;
264 229
230 brcmf_dbg(USB, "Enter\n");
265 if ((devinfo == NULL) || (buf == NULL) || (len == 0) 231 if ((devinfo == NULL) || (buf == NULL) || (len == 0)
266 || (devinfo->ctl_urb == NULL)) 232 || (devinfo->ctl_urb == NULL))
267 return -EINVAL; 233 return -EINVAL;
@@ -295,10 +261,9 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
295 int timeout = 0; 261 int timeout = 0;
296 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 262 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
297 263
298 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { 264 brcmf_dbg(USB, "Enter\n");
299 /* TODO: handle suspend/resume */ 265 if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP)
300 return -EIO; 266 return -EIO;
301 }
302 267
303 if (test_and_set_bit(0, &devinfo->ctl_op)) 268 if (test_and_set_bit(0, &devinfo->ctl_op))
304 return -EIO; 269 return -EIO;
@@ -325,10 +290,10 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
325 int timeout = 0; 290 int timeout = 0;
326 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 291 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
327 292
328 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { 293 brcmf_dbg(USB, "Enter\n");
329 /* TODO: handle suspend/resume */ 294 if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP)
330 return -EIO; 295 return -EIO;
331 } 296
332 if (test_and_set_bit(0, &devinfo->ctl_op)) 297 if (test_and_set_bit(0, &devinfo->ctl_op))
333 return -EIO; 298 return -EIO;
334 299
@@ -453,6 +418,8 @@ static void brcmf_usb_tx_complete(struct urb *urb)
453 struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; 418 struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
454 struct brcmf_usbdev_info *devinfo = req->devinfo; 419 struct brcmf_usbdev_info *devinfo = req->devinfo;
455 420
421 brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status,
422 req->skb);
456 brcmf_usb_del_fromq(devinfo, req); 423 brcmf_usb_del_fromq(devinfo, req);
457 if (urb->status == 0) 424 if (urb->status == 0)
458 devinfo->bus_pub.bus->dstats.tx_packets++; 425 devinfo->bus_pub.bus->dstats.tx_packets++;
@@ -478,6 +445,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
478 struct sk_buff *skb; 445 struct sk_buff *skb;
479 int ifidx = 0; 446 int ifidx = 0;
480 447
448 brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);
481 brcmf_usb_del_fromq(devinfo, req); 449 brcmf_usb_del_fromq(devinfo, req);
482 skb = req->skb; 450 skb = req->skb;
483 req->skb = NULL; 451 req->skb = NULL;
@@ -491,7 +459,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
491 return; 459 return;
492 } 460 }
493 461
494 if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) { 462 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {
495 skb_put(skb, urb->actual_length); 463 skb_put(skb, urb->actual_length);
496 if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { 464 if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
497 brcmf_dbg(ERROR, "rx protocol error\n"); 465 brcmf_dbg(ERROR, "rx protocol error\n");
@@ -544,8 +512,8 @@ static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo)
544{ 512{
545 struct brcmf_usbreq *req; 513 struct brcmf_usbreq *req;
546 514
547 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { 515 if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) {
548 brcmf_dbg(ERROR, "bus is not up\n"); 516 brcmf_dbg(ERROR, "bus is not up=%d\n", devinfo->bus_pub.state);
549 return; 517 return;
550 } 518 }
551 while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL) 519 while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL)
@@ -558,29 +526,24 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
558 struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus; 526 struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus;
559 int old_state; 527 int old_state;
560 528
529 brcmf_dbg(USB, "Enter, current state=%d, new state=%d\n",
530 devinfo->bus_pub.state, state);
561 531
562 if (devinfo->bus_pub.state == state) 532 if (devinfo->bus_pub.state == state)
563 return; 533 return;
564 534
565 old_state = devinfo->bus_pub.state; 535 old_state = devinfo->bus_pub.state;
566 brcmf_dbg(TRACE, "dbus state change from %d to to %d\n", 536 devinfo->bus_pub.state = state;
567 old_state, state);
568
569 /* Don't update state if it's PnP firmware re-download */
570 if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */
571 devinfo->bus_pub.state = state;
572
573 if ((old_state == BCMFMAC_USB_STATE_SLEEP)
574 && (state == BCMFMAC_USB_STATE_UP)) {
575 brcmf_usb_rx_fill_all(devinfo);
576 }
577 537
578 /* update state of upper layer */ 538 /* update state of upper layer */
579 if (state == BCMFMAC_USB_STATE_DOWN) { 539 if (state == BRCMFMAC_USB_STATE_DOWN) {
580 brcmf_dbg(INFO, "DBUS is down\n"); 540 brcmf_dbg(USB, "DBUS is down\n");
581 bcmf_bus->state = BRCMF_BUS_DOWN; 541 bcmf_bus->state = BRCMF_BUS_DOWN;
542 } else if (state == BRCMFMAC_USB_STATE_UP) {
543 brcmf_dbg(USB, "DBUS is up\n");
544 bcmf_bus->state = BRCMF_BUS_DATA;
582 } else { 545 } else {
583 brcmf_dbg(INFO, "DBUS current state=%d\n", state); 546 brcmf_dbg(USB, "DBUS current state=%d\n", state);
584 } 547 }
585} 548}
586 549
@@ -589,30 +552,32 @@ brcmf_usb_intr_complete(struct urb *urb)
589{ 552{
590 struct brcmf_usbdev_info *devinfo = 553 struct brcmf_usbdev_info *devinfo =
591 (struct brcmf_usbdev_info *)urb->context; 554 (struct brcmf_usbdev_info *)urb->context;
592 bool killed; 555 int err;
556
557 brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);
593 558
594 if (devinfo == NULL) 559 if (devinfo == NULL)
595 return; 560 return;
596 561
597 if (unlikely(urb->status)) { 562 if (unlikely(urb->status)) {
598 if (devinfo->suspend_state == 563 if (urb->status == -ENOENT ||
599 USBOS_SUSPEND_STATE_SUSPEND_PENDING) 564 urb->status == -ESHUTDOWN ||
600 killed = true; 565 urb->status == -ENODEV) {
601 566 brcmf_usb_state_change(devinfo,
602 if ((urb->status == -ENOENT && (!killed)) 567 BRCMFMAC_USB_STATE_DOWN);
603 || urb->status == -ESHUTDOWN ||
604 urb->status == -ENODEV) {
605 brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN);
606 } 568 }
607 } 569 }
608 570
609 if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) { 571 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) {
610 brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n"); 572 brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n");
611 return; 573 return;
612 } 574 }
613 575
614 if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) 576 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {
615 usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); 577 err = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
578 if (err)
579 brcmf_dbg(ERROR, "usb_submit_urb, err=%d\n", err);
580 }
616} 581}
617 582
618static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) 583static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
@@ -621,10 +586,9 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
621 struct brcmf_usbreq *req; 586 struct brcmf_usbreq *req;
622 int ret; 587 int ret;
623 588
624 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { 589 brcmf_dbg(USB, "Enter, skb=%p\n", skb);
625 /* TODO: handle suspend/resume */ 590 if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP)
626 return -EIO; 591 return -EIO;
627 }
628 592
629 req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq, 593 req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq,
630 &devinfo->tx_freecount); 594 &devinfo->tx_freecount);
@@ -664,25 +628,16 @@ static int brcmf_usb_up(struct device *dev)
664{ 628{
665 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 629 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
666 u16 ifnum; 630 u16 ifnum;
631 int ret;
667 632
668 if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) 633 brcmf_dbg(USB, "Enter\n");
634 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP)
669 return 0; 635 return 0;
670 636
671 /* If the USB/HSIC bus in sleep state, wake it up */
672 if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) {
673 if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
674 brcmf_dbg(ERROR, "Could not Resume the bus!\n");
675 return -EIO;
676 }
677 }
678 devinfo->activity = true;
679
680 /* Success, indicate devinfo is fully up */ 637 /* Success, indicate devinfo is fully up */
681 brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP); 638 brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_UP);
682 639
683 if (devinfo->intr_urb) { 640 if (devinfo->intr_urb) {
684 int ret;
685
686 usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev, 641 usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev,
687 devinfo->intr_pipe, 642 devinfo->intr_pipe,
688 &devinfo->intr, 643 &devinfo->intr,
@@ -727,14 +682,14 @@ static void brcmf_usb_down(struct device *dev)
727{ 682{
728 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 683 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
729 684
685 brcmf_dbg(USB, "Enter\n");
730 if (devinfo == NULL) 686 if (devinfo == NULL)
731 return; 687 return;
732 688
733 brcmf_dbg(TRACE, "enter\n"); 689 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN)
734 if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN)
735 return; 690 return;
736 691
737 brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); 692 brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN);
738 if (devinfo->intr_urb) 693 if (devinfo->intr_urb)
739 usb_kill_urb(devinfo->intr_urb); 694 usb_kill_urb(devinfo->intr_urb);
740 695
@@ -808,27 +763,25 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo)
808 struct bootrom_id_le id; 763 struct bootrom_id_le id;
809 u32 chipid, chiprev; 764 u32 chipid, chiprev;
810 765
811 brcmf_dbg(TRACE, "enter\n"); 766 brcmf_dbg(USB, "Enter\n");
812 767
813 if (devinfo == NULL) 768 if (devinfo == NULL)
814 return false; 769 return false;
815 770
816 /* Check if firmware downloaded already by querying runtime ID */ 771 /* Check if firmware downloaded already by querying runtime ID */
817 id.chip = cpu_to_le32(0xDEAD); 772 id.chip = cpu_to_le32(0xDEAD);
818 brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, 773 brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id));
819 sizeof(struct bootrom_id_le));
820 774
821 chipid = le32_to_cpu(id.chip); 775 chipid = le32_to_cpu(id.chip);
822 chiprev = le32_to_cpu(id.chiprev); 776 chiprev = le32_to_cpu(id.chiprev);
823 777
824 if ((chipid & 0x4300) == 0x4300) 778 if ((chipid & 0x4300) == 0x4300)
825 brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev); 779 brcmf_dbg(USB, "chip %x rev 0x%x\n", chipid, chiprev);
826 else 780 else
827 brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev); 781 brcmf_dbg(USB, "chip %d rev 0x%x\n", chipid, chiprev);
828 if (chipid == BRCMF_POSTBOOT_ID) { 782 if (chipid == BRCMF_POSTBOOT_ID) {
829 brcmf_dbg(INFO, "firmware already downloaded\n"); 783 brcmf_dbg(USB, "firmware already downloaded\n");
830 brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, 784 brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, sizeof(id));
831 sizeof(struct bootrom_id_le));
832 return false; 785 return false;
833 } else { 786 } else {
834 devinfo->bus_pub.devid = chipid; 787 devinfo->bus_pub.devid = chipid;
@@ -841,38 +794,29 @@ static int
841brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) 794brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
842{ 795{
843 struct bootrom_id_le id; 796 struct bootrom_id_le id;
844 u16 wait = 0, wait_time; 797 u32 loop_cnt;
845 798
846 brcmf_dbg(TRACE, "enter\n"); 799 brcmf_dbg(USB, "Enter\n");
847
848 if (devinfo == NULL)
849 return -EINVAL;
850 800
851 /* Give dongle chance to boot */ 801 loop_cnt = 0;
852 wait_time = BRCMF_USB_DLIMAGE_SPINWAIT; 802 do {
853 while (wait < BRCMF_USB_DLIMAGE_LIMIT) { 803 mdelay(BRCMF_USB_RESET_GETVER_SPINWAIT);
854 mdelay(wait_time); 804 loop_cnt++;
855 wait += wait_time;
856 id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ 805 id.chip = cpu_to_le32(0xDEAD); /* Get the ID */
857 brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, 806 brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id));
858 sizeof(struct bootrom_id_le));
859 if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) 807 if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID))
860 break; 808 break;
861 } 809 } while (loop_cnt < BRCMF_USB_RESET_GETVER_LOOP_CNT);
862 810
863 if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) { 811 if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) {
864 brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n", 812 brcmf_dbg(USB, "postboot chip 0x%x/rev 0x%x\n",
865 wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev)); 813 le32_to_cpu(id.chip), le32_to_cpu(id.chiprev));
866
867 brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
868 sizeof(struct bootrom_id_le));
869 814
870 /* XXX this wait may not be necessary */ 815 brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, sizeof(id));
871 mdelay(BRCMF_USB_RESETCFG_SPINWAIT);
872 return 0; 816 return 0;
873 } else { 817 } else {
874 brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n", 818 brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n",
875 wait); 819 BRCMF_USB_RESET_GETVER_SPINWAIT * loop_cnt);
876 return -EINVAL; 820 return -EINVAL;
877 } 821 }
878} 822}
@@ -911,7 +855,8 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
911 struct rdl_state_le state; 855 struct rdl_state_le state;
912 u32 rdlstate, rdlbytes; 856 u32 rdlstate, rdlbytes;
913 int err = 0; 857 int err = 0;
914 brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen); 858
859 brcmf_dbg(USB, "Enter, fw %p, len %d\n", fw, fwlen);
915 860
916 bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC); 861 bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC);
917 if (bulkchunk == NULL) { 862 if (bulkchunk == NULL) {
@@ -986,7 +931,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
986 931
987fail: 932fail:
988 kfree(bulkchunk); 933 kfree(bulkchunk);
989 brcmf_dbg(TRACE, "err=%d\n", err); 934 brcmf_dbg(USB, "Exit, err=%d\n", err);
990 return err; 935 return err;
991} 936}
992 937
@@ -994,7 +939,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len)
994{ 939{
995 int err; 940 int err;
996 941
997 brcmf_dbg(TRACE, "enter\n"); 942 brcmf_dbg(USB, "Enter\n");
998 943
999 if (devinfo == NULL) 944 if (devinfo == NULL)
1000 return -EINVAL; 945 return -EINVAL;
@@ -1004,10 +949,10 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len)
1004 949
1005 err = brcmf_usb_dl_writeimage(devinfo, fw, len); 950 err = brcmf_usb_dl_writeimage(devinfo, fw, len);
1006 if (err == 0) 951 if (err == 0)
1007 devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE; 952 devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DL_DONE;
1008 else 953 else
1009 devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING; 954 devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DL_FAIL;
1010 brcmf_dbg(TRACE, "exit: err=%d\n", err); 955 brcmf_dbg(USB, "Exit, err=%d\n", err);
1011 956
1012 return err; 957 return err;
1013} 958}
@@ -1016,7 +961,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
1016{ 961{
1017 struct rdl_state_le state; 962 struct rdl_state_le state;
1018 963
1019 brcmf_dbg(TRACE, "enter\n"); 964 brcmf_dbg(USB, "Enter\n");
1020 if (!devinfo) 965 if (!devinfo)
1021 return -EINVAL; 966 return -EINVAL;
1022 967
@@ -1039,7 +984,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
1039 brcmf_dbg(ERROR, "Dongle not runnable\n"); 984 brcmf_dbg(ERROR, "Dongle not runnable\n");
1040 return -EINVAL; 985 return -EINVAL;
1041 } 986 }
1042 brcmf_dbg(TRACE, "exit\n"); 987 brcmf_dbg(USB, "Exit\n");
1043 return 0; 988 return 0;
1044} 989}
1045 990
@@ -1066,7 +1011,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
1066 int devid, chiprev; 1011 int devid, chiprev;
1067 int err; 1012 int err;
1068 1013
1069 brcmf_dbg(TRACE, "enter\n"); 1014 brcmf_dbg(USB, "Enter\n");
1070 if (devinfo == NULL) 1015 if (devinfo == NULL)
1071 return -ENODEV; 1016 return -ENODEV;
1072 1017
@@ -1094,7 +1039,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
1094 1039
1095static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo) 1040static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo)
1096{ 1041{
1097 brcmf_dbg(TRACE, "devinfo %p\n", devinfo); 1042 brcmf_dbg(USB, "Enter, devinfo %p\n", devinfo);
1098 1043
1099 /* free the URBS */ 1044 /* free the URBS */
1100 brcmf_usb_free_q(&devinfo->rx_freeq, false); 1045 brcmf_usb_free_q(&devinfo->rx_freeq, false);
@@ -1129,6 +1074,7 @@ static int check_file(const u8 *headers)
1129 struct trx_header_le *trx; 1074 struct trx_header_le *trx;
1130 int actual_len = -1; 1075 int actual_len = -1;
1131 1076
1077 brcmf_dbg(USB, "Enter\n");
1132 /* Extract trx header */ 1078 /* Extract trx header */
1133 trx = (struct trx_header_le *) headers; 1079 trx = (struct trx_header_le *) headers;
1134 if (trx->magic != cpu_to_le32(TRX_MAGIC)) 1080 if (trx->magic != cpu_to_le32(TRX_MAGIC))
@@ -1150,6 +1096,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
1150 struct brcmf_usb_image *fw_image; 1096 struct brcmf_usb_image *fw_image;
1151 int err; 1097 int err;
1152 1098
1099 brcmf_dbg(USB, "Enter\n");
1153 switch (devinfo->bus_pub.devid) { 1100 switch (devinfo->bus_pub.devid) {
1154 case 43143: 1101 case 43143:
1155 fwname = BRCMF_USB_43143_FW_NAME; 1102 fwname = BRCMF_USB_43143_FW_NAME;
@@ -1166,7 +1113,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
1166 return -EINVAL; 1113 return -EINVAL;
1167 break; 1114 break;
1168 } 1115 }
1169 1116 brcmf_dbg(USB, "Loading FW %s\n", fwname);
1170 list_for_each_entry(fw_image, &fw_image_list, list) { 1117 list_for_each_entry(fw_image, &fw_image_list, list) {
1171 if (fw_image->fwname == fwname) { 1118 if (fw_image->fwname == fwname) {
1172 devinfo->image = fw_image->image; 1119 devinfo->image = fw_image->image;
@@ -1211,10 +1158,13 @@ static
1211struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, 1158struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
1212 int nrxq, int ntxq) 1159 int nrxq, int ntxq)
1213{ 1160{
1161 brcmf_dbg(USB, "Enter\n");
1162
1214 devinfo->bus_pub.nrxq = nrxq; 1163 devinfo->bus_pub.nrxq = nrxq;
1215 devinfo->rx_low_watermark = nrxq / 2; 1164 devinfo->rx_low_watermark = nrxq / 2;
1216 devinfo->bus_pub.devinfo = devinfo; 1165 devinfo->bus_pub.devinfo = devinfo;
1217 devinfo->bus_pub.ntxq = ntxq; 1166 devinfo->bus_pub.ntxq = ntxq;
1167 devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DOWN;
1218 1168
1219 /* flow control when too many tx urbs posted */ 1169 /* flow control when too many tx urbs posted */
1220 devinfo->tx_low_watermark = ntxq / 4; 1170 devinfo->tx_low_watermark = ntxq / 4;
@@ -1263,7 +1213,7 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
1263 if (!brcmf_usb_dlneeded(devinfo)) 1213 if (!brcmf_usb_dlneeded(devinfo))
1264 return &devinfo->bus_pub; 1214 return &devinfo->bus_pub;
1265 1215
1266 brcmf_dbg(TRACE, "start fw downloading\n"); 1216 brcmf_dbg(USB, "Start fw downloading\n");
1267 if (brcmf_usb_get_fw(devinfo)) 1217 if (brcmf_usb_get_fw(devinfo))
1268 goto error; 1218 goto error;
1269 1219
@@ -1278,14 +1228,14 @@ error:
1278 return NULL; 1228 return NULL;
1279} 1229}
1280 1230
1281static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, 1231static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1282 const char *desc, u32 bustype, u32 hdrlen)
1283{ 1232{
1284 struct brcmf_bus *bus = NULL; 1233 struct brcmf_bus *bus = NULL;
1285 struct brcmf_usbdev *bus_pub = NULL; 1234 struct brcmf_usbdev *bus_pub = NULL;
1286 int ret; 1235 int ret;
1287 struct device *dev = devinfo->dev; 1236 struct device *dev = devinfo->dev;
1288 1237
1238 brcmf_dbg(USB, "Enter\n");
1289 bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); 1239 bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
1290 if (!bus_pub) 1240 if (!bus_pub)
1291 return -ENODEV; 1241 return -ENODEV;
@@ -1302,14 +1252,13 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,
1302 bus->brcmf_bus_stop = brcmf_usb_down; 1252 bus->brcmf_bus_stop = brcmf_usb_down;
1303 bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt; 1253 bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt;
1304 bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt; 1254 bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt;
1305 bus->type = bustype;
1306 bus->bus_priv.usb = bus_pub; 1255 bus->bus_priv.usb = bus_pub;
1307 dev_set_drvdata(dev, bus); 1256 dev_set_drvdata(dev, bus);
1308 1257
1309 /* Attach to the common driver interface */ 1258 /* Attach to the common driver interface */
1310 ret = brcmf_attach(hdrlen, dev); 1259 ret = brcmf_attach(0, dev);
1311 if (ret) { 1260 if (ret) {
1312 brcmf_dbg(ERROR, "dhd_attach failed\n"); 1261 brcmf_dbg(ERROR, "brcmf_attach failed\n");
1313 goto fail; 1262 goto fail;
1314 } 1263 }
1315 1264
@@ -1333,7 +1282,7 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
1333{ 1282{
1334 if (!devinfo) 1283 if (!devinfo)
1335 return; 1284 return;
1336 brcmf_dbg(TRACE, "enter: bus_pub %p\n", devinfo); 1285 brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo);
1337 1286
1338 brcmf_detach(devinfo->dev); 1287 brcmf_detach(devinfo->dev);
1339 kfree(devinfo->bus_pub.bus); 1288 kfree(devinfo->bus_pub.bus);
@@ -1351,7 +1300,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1351 u8 endpoint_num; 1300 u8 endpoint_num;
1352 struct brcmf_usbdev_info *devinfo; 1301 struct brcmf_usbdev_info *devinfo;
1353 1302
1354 brcmf_dbg(TRACE, "enter\n"); 1303 brcmf_dbg(USB, "Enter\n");
1355 1304
1356 devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC); 1305 devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC);
1357 if (devinfo == NULL) 1306 if (devinfo == NULL)
@@ -1452,11 +1401,11 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1452 devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; 1401 devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
1453 1402
1454 if (usb->speed == USB_SPEED_HIGH) 1403 if (usb->speed == USB_SPEED_HIGH)
1455 brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n"); 1404 brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n");
1456 else 1405 else
1457 brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n"); 1406 brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n");
1458 1407
1459 ret = brcmf_usb_probe_cb(devinfo, "", USB_BUS, 0); 1408 ret = brcmf_usb_probe_cb(devinfo);
1460 if (ret) 1409 if (ret)
1461 goto fail; 1410 goto fail;
1462 1411
@@ -1476,40 +1425,55 @@ brcmf_usb_disconnect(struct usb_interface *intf)
1476{ 1425{
1477 struct brcmf_usbdev_info *devinfo; 1426 struct brcmf_usbdev_info *devinfo;
1478 1427
1479 brcmf_dbg(TRACE, "enter\n"); 1428 brcmf_dbg(USB, "Enter\n");
1480 devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf); 1429 devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);
1481 brcmf_usb_disconnect_cb(devinfo); 1430 brcmf_usb_disconnect_cb(devinfo);
1482 kfree(devinfo); 1431 kfree(devinfo);
1432 brcmf_dbg(USB, "Exit\n");
1483} 1433}
1484 1434
1485/* 1435/*
1486 * only need to signal the bus being down and update the suspend state. 1436 * only need to signal the bus being down and update the state.
1487 */ 1437 */
1488static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) 1438static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
1489{ 1439{
1490 struct usb_device *usb = interface_to_usbdev(intf); 1440 struct usb_device *usb = interface_to_usbdev(intf);
1491 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); 1441 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
1492 1442
1493 brcmf_dbg(TRACE, "enter\n"); 1443 brcmf_dbg(USB, "Enter\n");
1494 devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN; 1444 devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP;
1495 devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED; 1445 brcmf_detach(&usb->dev);
1496 return 0; 1446 return 0;
1497} 1447}
1498 1448
1499/* 1449/*
1500 * mark suspend state active and crank up the bus. 1450 * (re-) start the bus.
1501 */ 1451 */
1502static int brcmf_usb_resume(struct usb_interface *intf) 1452static int brcmf_usb_resume(struct usb_interface *intf)
1503{ 1453{
1504 struct usb_device *usb = interface_to_usbdev(intf); 1454 struct usb_device *usb = interface_to_usbdev(intf);
1505 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); 1455 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
1506 1456
1507 brcmf_dbg(TRACE, "enter\n"); 1457 brcmf_dbg(USB, "Enter\n");
1508 devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE; 1458 if (!brcmf_attach(0, devinfo->dev))
1509 brcmf_bus_start(&usb->dev); 1459 return brcmf_bus_start(&usb->dev);
1460
1510 return 0; 1461 return 0;
1511} 1462}
1512 1463
1464static int brcmf_usb_reset_resume(struct usb_interface *intf)
1465{
1466 struct usb_device *usb = interface_to_usbdev(intf);
1467 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
1468
1469 brcmf_dbg(USB, "Enter\n");
1470
1471 if (!brcmf_usb_fw_download(devinfo))
1472 return brcmf_usb_resume(intf);
1473
1474 return -EIO;
1475}
1476
1513#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c 1477#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c
1514#define BRCMF_USB_DEVICE_ID_43143 0xbd1e 1478#define BRCMF_USB_DEVICE_ID_43143 0xbd1e
1515#define BRCMF_USB_DEVICE_ID_43236 0xbd17 1479#define BRCMF_USB_DEVICE_ID_43236 0xbd17
@@ -1529,7 +1493,6 @@ MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME);
1529MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); 1493MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
1530MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME); 1494MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME);
1531 1495
1532/* TODO: suspend and resume entries */
1533static struct usb_driver brcmf_usbdrvr = { 1496static struct usb_driver brcmf_usbdrvr = {
1534 .name = KBUILD_MODNAME, 1497 .name = KBUILD_MODNAME,
1535 .probe = brcmf_usb_probe, 1498 .probe = brcmf_usb_probe,
@@ -1537,6 +1500,7 @@ static struct usb_driver brcmf_usbdrvr = {
1537 .id_table = brcmf_usb_devid_table, 1500 .id_table = brcmf_usb_devid_table,
1538 .suspend = brcmf_usb_suspend, 1501 .suspend = brcmf_usb_suspend,
1539 .resume = brcmf_usb_resume, 1502 .resume = brcmf_usb_resume,
1503 .reset_resume = brcmf_usb_reset_resume,
1540 .supports_autosuspend = 1, 1504 .supports_autosuspend = 1,
1541 .disable_hub_initiated_lpm = 1, 1505 .disable_hub_initiated_lpm = 1,
1542}; 1506};
@@ -1554,12 +1518,14 @@ static void brcmf_release_fw(struct list_head *q)
1554 1518
1555void brcmf_usb_exit(void) 1519void brcmf_usb_exit(void)
1556{ 1520{
1521 brcmf_dbg(USB, "Enter\n");
1557 usb_deregister(&brcmf_usbdrvr); 1522 usb_deregister(&brcmf_usbdrvr);
1558 brcmf_release_fw(&fw_image_list); 1523 brcmf_release_fw(&fw_image_list);
1559} 1524}
1560 1525
1561void brcmf_usb_init(void) 1526void brcmf_usb_init(void)
1562{ 1527{
1528 brcmf_dbg(USB, "Enter\n");
1563 INIT_LIST_HEAD(&fw_image_list); 1529 INIT_LIST_HEAD(&fw_image_list);
1564 usb_register(&brcmf_usbdrvr); 1530 usb_register(&brcmf_usbdrvr);
1565} 1531}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h
index acfa5e89872..f483a8c9945 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h
@@ -17,19 +17,11 @@
17#define BRCMFMAC_USB_H 17#define BRCMFMAC_USB_H
18 18
19enum brcmf_usb_state { 19enum brcmf_usb_state {
20 BCMFMAC_USB_STATE_DL_PENDING, 20 BRCMFMAC_USB_STATE_DOWN,
21 BCMFMAC_USB_STATE_DL_DONE, 21 BRCMFMAC_USB_STATE_DL_FAIL,
22 BCMFMAC_USB_STATE_UP, 22 BRCMFMAC_USB_STATE_DL_DONE,
23 BCMFMAC_USB_STATE_DOWN, 23 BRCMFMAC_USB_STATE_UP,
24 BCMFMAC_USB_STATE_PNP_FWDL, 24 BRCMFMAC_USB_STATE_SLEEP
25 BCMFMAC_USB_STATE_DISCONNECT,
26 BCMFMAC_USB_STATE_SLEEP
27};
28
29enum brcmf_usb_pnp_state {
30 BCMFMAC_USB_PNP_DISCONNECT,
31 BCMFMAC_USB_PNP_SLEEP,
32 BCMFMAC_USB_PNP_RESUME,
33}; 25};
34 26
35struct brcmf_stats { 27struct brcmf_stats {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 6d554249394..2044fdb5555 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -19,14 +19,7 @@
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 20
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/if_arp.h>
23#include <linux/sched.h>
24#include <linux/kthread.h>
25#include <linux/netdevice.h>
26#include <linux/bitops.h>
27#include <linux/etherdevice.h> 22#include <linux/etherdevice.h>
28#include <linux/ieee80211.h>
29#include <linux/uaccess.h>
30#include <net/cfg80211.h> 23#include <net/cfg80211.h>
31#include <net/netlink.h> 24#include <net/netlink.h>
32 25
@@ -486,13 +479,6 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
486 479
487 if (ap) { 480 if (ap) {
488 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); 481 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
489 if (!cfg->ap_info)
490 cfg->ap_info = kzalloc(sizeof(*cfg->ap_info),
491 GFP_KERNEL);
492 if (!cfg->ap_info) {
493 err = -ENOMEM;
494 goto done;
495 }
496 WL_INFO("IF Type = AP\n"); 482 WL_INFO("IF Type = AP\n");
497 } else { 483 } else {
498 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), 484 err = brcmf_fil_cmd_int_set(netdev_priv(ndev),
@@ -529,185 +515,6 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc)
529 } 515 }
530} 516}
531 517
532static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
533 struct brcmf_ssid *ssid)
534{
535 memset(params_le->bssid, 0xFF, ETH_ALEN);
536 params_le->bss_type = DOT11_BSSTYPE_ANY;
537 params_le->scan_type = 0;
538 params_le->channel_num = 0;
539 params_le->nprobes = cpu_to_le32(-1);
540 params_le->active_time = cpu_to_le32(-1);
541 params_le->passive_time = cpu_to_le32(-1);
542 params_le->home_time = cpu_to_le32(-1);
543 if (ssid && ssid->SSID_len) {
544 params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len);
545 memcpy(&params_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
546 }
547}
548
549static s32
550brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
551 struct brcmf_ssid *ssid, u16 action)
552{
553 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
554 offsetof(struct brcmf_iscan_params_le, params_le);
555 struct brcmf_iscan_params_le *params;
556 s32 err = 0;
557
558 if (ssid && ssid->SSID_len)
559 params_size += sizeof(struct brcmf_ssid);
560 params = kzalloc(params_size, GFP_KERNEL);
561 if (!params)
562 return -ENOMEM;
563 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
564
565 brcmf_iscan_prep(&params->params_le, ssid);
566
567 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
568 params->action = cpu_to_le16(action);
569 params->scan_duration = cpu_to_le16(0);
570
571 err = brcmf_fil_iovar_data_set(netdev_priv(iscan->ndev), "iscan",
572 params, params_size);
573 if (err) {
574 if (err == -EBUSY)
575 WL_INFO("system busy : iscan canceled\n");
576 else
577 WL_ERR("error (%d)\n", err);
578 }
579
580 kfree(params);
581 return err;
582}
583
584static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg)
585{
586 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
587 struct net_device *ndev = cfg_to_ndev(cfg);
588 struct brcmf_ssid ssid;
589 u32 passive_scan;
590 s32 err = 0;
591
592 /* Broadcast scan by default */
593 memset(&ssid, 0, sizeof(ssid));
594
595 iscan->state = WL_ISCAN_STATE_SCANING;
596
597 passive_scan = cfg->active_scan ? 0 : 1;
598 err = brcmf_fil_cmd_int_set(netdev_priv(ndev),
599 BRCMF_C_SET_PASSIVE_SCAN, passive_scan);
600 if (err) {
601 WL_ERR("error (%d)\n", err);
602 return err;
603 }
604 brcmf_set_mpc(ndev, 0);
605 cfg->iscan_kickstart = true;
606 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
607 if (err) {
608 brcmf_set_mpc(ndev, 1);
609 cfg->iscan_kickstart = false;
610 return err;
611 }
612 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
613 iscan->timer_on = 1;
614 return err;
615}
616
617static s32
618brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
619 struct cfg80211_scan_request *request,
620 struct cfg80211_ssid *this_ssid)
621{
622 struct brcmf_if *ifp = netdev_priv(ndev);
623 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
624 struct cfg80211_ssid *ssids;
625 struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
626 u32 passive_scan;
627 bool iscan_req;
628 bool spec_scan;
629 s32 err = 0;
630 u32 SSID_len;
631
632 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
633 WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
634 return -EAGAIN;
635 }
636 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
637 WL_ERR("Scanning being aborted: status (%lu)\n",
638 cfg->scan_status);
639 return -EAGAIN;
640 }
641 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
642 WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state);
643 return -EAGAIN;
644 }
645
646 iscan_req = false;
647 spec_scan = false;
648 if (request) {
649 /* scan bss */
650 ssids = request->ssids;
651 if (cfg->iscan_on && (!ssids || !ssids->ssid_len))
652 iscan_req = true;
653 } else {
654 /* scan in ibss */
655 /* we don't do iscan in ibss */
656 ssids = this_ssid;
657 }
658
659 cfg->scan_request = request;
660 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
661 if (iscan_req) {
662 err = brcmf_do_iscan(cfg);
663 if (!err)
664 return err;
665 else
666 goto scan_out;
667 } else {
668 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
669 ssids->ssid, ssids->ssid_len);
670 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
671 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
672 sr->ssid_le.SSID_len = cpu_to_le32(0);
673 if (SSID_len) {
674 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
675 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
676 spec_scan = true;
677 } else {
678 WL_SCAN("Broadcast scan\n");
679 }
680
681 passive_scan = cfg->active_scan ? 0 : 1;
682 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
683 passive_scan);
684 if (err) {
685 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
686 goto scan_out;
687 }
688 brcmf_set_mpc(ndev, 0);
689 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
690 &sr->ssid_le, sizeof(sr->ssid_le));
691 if (err) {
692 if (err == -EBUSY)
693 WL_INFO("system busy : scan for \"%s\" "
694 "canceled\n", sr->ssid_le.SSID);
695 else
696 WL_ERR("WLC_SCAN error (%d)\n", err);
697
698 brcmf_set_mpc(ndev, 1);
699 goto scan_out;
700 }
701 }
702
703 return 0;
704
705scan_out:
706 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
707 cfg->scan_request = NULL;
708 return err;
709}
710
711static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, 518static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
712 struct cfg80211_scan_request *request) 519 struct cfg80211_scan_request *request)
713{ 520{
@@ -931,7 +738,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
931 struct brcmf_if *ifp = netdev_priv(ndev); 738 struct brcmf_if *ifp = netdev_priv(ndev);
932 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); 739 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
933 struct cfg80211_ssid *ssids; 740 struct cfg80211_ssid *ssids;
934 struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; 741 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
935 u32 passive_scan; 742 u32 passive_scan;
936 bool escan_req; 743 bool escan_req;
937 bool spec_scan; 744 bool spec_scan;
@@ -973,9 +780,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
973 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 780 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
974 if (escan_req) { 781 if (escan_req) {
975 err = brcmf_do_escan(cfg, wiphy, ndev, request); 782 err = brcmf_do_escan(cfg, wiphy, ndev, request);
976 if (!err) 783 if (err)
977 return err;
978 else
979 goto scan_out; 784 goto scan_out;
980 } else { 785 } else {
981 WL_SCAN("ssid \"%s\", ssid_len (%d)\n", 786 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
@@ -1027,7 +832,6 @@ static s32
1027brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) 832brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1028{ 833{
1029 struct net_device *ndev = request->wdev->netdev; 834 struct net_device *ndev = request->wdev->netdev;
1030 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1031 s32 err = 0; 835 s32 err = 0;
1032 836
1033 WL_TRACE("Enter\n"); 837 WL_TRACE("Enter\n");
@@ -1036,10 +840,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1036 struct brcmf_cfg80211_vif, wdev))) 840 struct brcmf_cfg80211_vif, wdev)))
1037 return -EIO; 841 return -EIO;
1038 842
1039 if (cfg->iscan_on) 843 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
1040 err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
1041 else if (cfg->escan_on)
1042 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
1043 844
1044 if (err) 845 if (err)
1045 WL_ERR("scan error (%d)\n", err); 846 WL_ERR("scan error (%d)\n", err);
@@ -1075,7 +876,7 @@ static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1075static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) 876static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1076{ 877{
1077 s32 err = 0; 878 s32 err = 0;
1078 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL); 879 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1079 880
1080 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry); 881 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1081 if (err) { 882 if (err) {
@@ -1212,8 +1013,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1212 else 1013 else
1213 WL_CONN("No BSSID specified\n"); 1014 WL_CONN("No BSSID specified\n");
1214 1015
1215 if (params->channel) 1016 if (params->chandef.chan)
1216 WL_CONN("channel: %d\n", params->channel->center_freq); 1017 WL_CONN("channel: %d\n", params->chandef.chan->center_freq);
1217 else 1018 else
1218 WL_CONN("no channel specified\n"); 1019 WL_CONN("no channel specified\n");
1219 1020
@@ -1258,7 +1059,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1258 else 1059 else
1259 bcnprd = 100; 1060 bcnprd = 100;
1260 1061
1261 err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_BCNPRD, bcnprd); 1062 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1262 if (err) { 1063 if (err) {
1263 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); 1064 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1264 goto done; 1065 goto done;
@@ -1286,12 +1087,12 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1286 } 1087 }
1287 1088
1288 /* Channel */ 1089 /* Channel */
1289 if (params->channel) { 1090 if (params->chandef.chan) {
1290 u32 target_channel; 1091 u32 target_channel;
1291 1092
1292 cfg->channel = 1093 cfg->channel =
1293 ieee80211_frequency_to_channel( 1094 ieee80211_frequency_to_channel(
1294 params->channel->center_freq); 1095 params->chandef.chan->center_freq);
1295 if (params->channel_fixed) { 1096 if (params->channel_fixed) {
1296 /* adding chanspec */ 1097 /* adding chanspec */
1297 brcmf_ch_to_chanspec(cfg->channel, 1098 brcmf_ch_to_chanspec(cfg->channel,
@@ -1300,7 +1101,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1300 1101
1301 /* set channel for starter */ 1102 /* set channel for starter */
1302 target_channel = cfg->channel; 1103 target_channel = cfg->channel;
1303 err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_CHANNEL, 1104 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1304 target_channel); 1105 target_channel);
1305 if (err) { 1106 if (err) {
1306 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); 1107 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
@@ -1721,7 +1522,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1721} 1522}
1722 1523
1723static s32 1524static s32
1724brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, 1525brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1725 enum nl80211_tx_power_setting type, s32 mbm) 1526 enum nl80211_tx_power_setting type, s32 mbm)
1726{ 1527{
1727 1528
@@ -1770,7 +1571,9 @@ done:
1770 return err; 1571 return err;
1771} 1572}
1772 1573
1773static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) 1574static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1575 struct wireless_dev *wdev,
1576 s32 *dbm)
1774{ 1577{
1775 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 1578 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1776 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); 1579 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
@@ -2014,6 +1817,12 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2014 if (!check_vif_up(ifp->vif)) 1817 if (!check_vif_up(ifp->vif))
2015 return -EIO; 1818 return -EIO;
2016 1819
1820 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
1821 /* we ignore this key index in this case */
1822 WL_ERR("invalid key index (%d)\n", key_idx);
1823 return -EINVAL;
1824 }
1825
2017 memset(&key, 0, sizeof(key)); 1826 memset(&key, 0, sizeof(key));
2018 1827
2019 key.index = (u32) key_idx; 1828 key.index = (u32) key_idx;
@@ -2024,15 +1833,6 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2024 1833
2025 /* Set the new key/index */ 1834 /* Set the new key/index */
2026 err = send_key_to_dongle(ndev, &key); 1835 err = send_key_to_dongle(ndev, &key);
2027 if (err) {
2028 if (err == -EINVAL) {
2029 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
2030 /* we ignore this key index in this case */
2031 WL_ERR("invalid key index (%d)\n", key_idx);
2032 }
2033 /* Ignore this error, may happen during DISASSOC */
2034 err = -EAGAIN;
2035 }
2036 1836
2037 WL_TRACE("Exit\n"); 1837 WL_TRACE("Exit\n");
2038 return err; 1838 return err;
@@ -2239,7 +2039,7 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
2239 2039
2240 /* addr param is always NULL. ignore it */ 2040 /* addr param is always NULL. ignore it */
2241 /* Get current rateset */ 2041 /* Get current rateset */
2242 err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_CURR_RATESET, 2042 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET,
2243 &rateset_le, sizeof(rateset_le)); 2043 &rateset_le, sizeof(rateset_le));
2244 if (err) { 2044 if (err) {
2245 WL_ERR("could not get current rateset (%d)\n", err); 2045 WL_ERR("could not get current rateset (%d)\n", err);
@@ -2354,13 +2154,14 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2354 int i; 2154 int i;
2355 2155
2356 bss_list = cfg->bss_list; 2156 bss_list = cfg->bss_list;
2357 if (bss_list->version != BRCMF_BSS_INFO_VERSION) { 2157 if (bss_list->count != 0 &&
2158 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2358 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", 2159 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2359 bss_list->version); 2160 bss_list->version);
2360 return -EOPNOTSUPP; 2161 return -EOPNOTSUPP;
2361 } 2162 }
2362 WL_SCAN("scanned AP count (%d)\n", bss_list->count); 2163 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2363 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { 2164 for (i = 0; i < bss_list->count; i++) {
2364 bi = next_bss_le(bss_list, bi); 2165 bi = next_bss_le(bss_list, bi);
2365 err = brcmf_inform_single_bss(cfg, bi); 2166 err = brcmf_inform_single_bss(cfg, bi);
2366 if (err) 2167 if (err)
@@ -2582,33 +2383,10 @@ update_bss_info_out:
2582 2383
2583static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) 2384static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2584{ 2385{
2585 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2586 struct escan_info *escan = &cfg->escan_info; 2386 struct escan_info *escan = &cfg->escan_info;
2587 struct brcmf_ssid ssid;
2588 2387
2589 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); 2388 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2590 if (cfg->iscan_on) { 2389 if (cfg->scan_request) {
2591 iscan->state = WL_ISCAN_STATE_IDLE;
2592
2593 if (iscan->timer_on) {
2594 del_timer_sync(&iscan->timer);
2595 iscan->timer_on = 0;
2596 }
2597
2598 cancel_work_sync(&iscan->work);
2599
2600 /* Abort iscan running in FW */
2601 memset(&ssid, 0, sizeof(ssid));
2602 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2603
2604 if (cfg->scan_request) {
2605 /* Indidate scan abort to cfg80211 layer */
2606 WL_INFO("Terminating scan in progress\n");
2607 cfg80211_scan_done(cfg->scan_request, true);
2608 cfg->scan_request = NULL;
2609 }
2610 }
2611 if (cfg->escan_on && cfg->scan_request) {
2612 escan->escan_state = WL_ESCAN_STATE_IDLE; 2390 escan->escan_state = WL_ESCAN_STATE_IDLE;
2613 brcmf_notify_escan_complete(cfg, escan->ndev, true, true); 2391 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2614 } 2392 }
@@ -2616,198 +2394,6 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2616 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); 2394 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2617} 2395}
2618 2396
2619static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2620 bool aborted)
2621{
2622 struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2623 struct net_device *ndev = cfg_to_ndev(cfg);
2624
2625 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2626 WL_ERR("Scan complete while device not scanning\n");
2627 return;
2628 }
2629 if (cfg->scan_request) {
2630 WL_SCAN("ISCAN Completed scan: %s\n",
2631 aborted ? "Aborted" : "Done");
2632 cfg80211_scan_done(cfg->scan_request, aborted);
2633 brcmf_set_mpc(ndev, 1);
2634 cfg->scan_request = NULL;
2635 }
2636 cfg->iscan_kickstart = false;
2637}
2638
2639static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2640{
2641 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2642 WL_SCAN("wake up iscan\n");
2643 schedule_work(&iscan->work);
2644 return 0;
2645 }
2646
2647 return -EIO;
2648}
2649
2650static s32
2651brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2652 struct brcmf_scan_results **bss_list)
2653{
2654 struct brcmf_scan_results *results;
2655 struct brcmf_scan_results_le *results_le;
2656 struct brcmf_iscan_results *list_buf;
2657 s32 err = 0;
2658
2659 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2660 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2661 results = &list_buf->results;
2662 results_le = &list_buf->results_le;
2663 results_le->buflen = cpu_to_le32(sizeof(iscan->scan_buf));
2664 results_le->version = 0;
2665 results_le->count = 0;
2666
2667 err = brcmf_fil_iovar_data_get(netdev_priv(iscan->ndev), "iscanresults",
2668 iscan->scan_buf,
2669 sizeof(iscan->scan_buf));
2670 if (err) {
2671 WL_ERR("error (%d)\n", err);
2672 return err;
2673 }
2674 results->buflen = le32_to_cpu(results_le->buflen);
2675 results->version = le32_to_cpu(results_le->version);
2676 results->count = le32_to_cpu(results_le->count);
2677 WL_SCAN("results->count = %d\n", results_le->count);
2678 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2679 *status = le32_to_cpu(list_buf->status_le);
2680 WL_SCAN("status = %d\n", *status);
2681 *bss_list = results;
2682
2683 return err;
2684}
2685
2686static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg)
2687{
2688 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2689 s32 err = 0;
2690
2691 iscan->state = WL_ISCAN_STATE_IDLE;
2692 brcmf_inform_bss(cfg);
2693 brcmf_notify_iscan_complete(iscan, false);
2694
2695 return err;
2696}
2697
2698static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg)
2699{
2700 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2701 s32 err = 0;
2702
2703 /* Reschedule the timer */
2704 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2705 iscan->timer_on = 1;
2706
2707 return err;
2708}
2709
2710static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg)
2711{
2712 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2713 s32 err = 0;
2714
2715 brcmf_inform_bss(cfg);
2716 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2717 /* Reschedule the timer */
2718 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2719 iscan->timer_on = 1;
2720
2721 return err;
2722}
2723
2724static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg)
2725{
2726 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2727 s32 err = 0;
2728
2729 iscan->state = WL_ISCAN_STATE_IDLE;
2730 brcmf_notify_iscan_complete(iscan, true);
2731
2732 return err;
2733}
2734
2735static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2736{
2737 struct brcmf_cfg80211_iscan_ctrl *iscan =
2738 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2739 work);
2740 struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2741 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2742 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2743
2744 if (iscan->timer_on) {
2745 del_timer_sync(&iscan->timer);
2746 iscan->timer_on = 0;
2747 }
2748
2749 if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) {
2750 status = BRCMF_SCAN_RESULTS_ABORTED;
2751 WL_ERR("Abort iscan\n");
2752 }
2753
2754 el->handler[status](cfg);
2755}
2756
2757static void brcmf_iscan_timer(unsigned long data)
2758{
2759 struct brcmf_cfg80211_iscan_ctrl *iscan =
2760 (struct brcmf_cfg80211_iscan_ctrl *)data;
2761
2762 if (iscan) {
2763 iscan->timer_on = 0;
2764 WL_SCAN("timer expired\n");
2765 brcmf_wakeup_iscan(iscan);
2766 }
2767}
2768
2769static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg)
2770{
2771 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2772
2773 if (cfg->iscan_on) {
2774 iscan->state = WL_ISCAN_STATE_IDLE;
2775 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2776 }
2777
2778 return 0;
2779}
2780
2781static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2782{
2783 memset(el, 0, sizeof(*el));
2784 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2785 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2786 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2787 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2788 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2789}
2790
2791static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg)
2792{
2793 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2794 int err = 0;
2795
2796 if (cfg->iscan_on) {
2797 iscan->ndev = cfg_to_ndev(cfg);
2798 brcmf_init_iscan_eloop(&iscan->el);
2799 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2800 init_timer(&iscan->timer);
2801 iscan->timer.data = (unsigned long) iscan;
2802 iscan->timer.function = brcmf_iscan_timer;
2803 err = brcmf_invoke_iscan(cfg);
2804 if (!err)
2805 iscan->data = cfg;
2806 }
2807
2808 return err;
2809}
2810
2811static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work) 2397static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2812{ 2398{
2813 struct brcmf_cfg80211_info *cfg = 2399 struct brcmf_cfg80211_info *cfg =
@@ -2825,8 +2411,7 @@ static void brcmf_escan_timeout(unsigned long data)
2825 2411
2826 if (cfg->scan_request) { 2412 if (cfg->scan_request) {
2827 WL_ERR("timer expired\n"); 2413 WL_ERR("timer expired\n");
2828 if (cfg->escan_on) 2414 schedule_work(&cfg->escan_timeout_work);
2829 schedule_work(&cfg->escan_timeout_work);
2830 } 2415 }
2831} 2416}
2832 2417
@@ -2863,10 +2448,11 @@ brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2863} 2448}
2864 2449
2865static s32 2450static s32
2866brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg, 2451brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2867 struct net_device *ndev,
2868 const struct brcmf_event_msg *e, void *data) 2452 const struct brcmf_event_msg *e, void *data)
2869{ 2453{
2454 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2455 struct net_device *ndev = ifp->ndev;
2870 s32 status; 2456 s32 status;
2871 s32 err = 0; 2457 s32 err = 0;
2872 struct brcmf_escan_result_le *escan_result_le; 2458 struct brcmf_escan_result_le *escan_result_le;
@@ -2877,13 +2463,11 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg,
2877 u32 i; 2463 u32 i;
2878 bool aborted; 2464 bool aborted;
2879 2465
2880 status = be32_to_cpu(e->status); 2466 status = e->status;
2881 2467
2882 if (!ndev || !cfg->escan_on || 2468 if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2883 !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { 2469 WL_ERR("scan not ready ndev %p drv_status %x\n", ndev,
2884 WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n", 2470 !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2885 ndev, cfg->escan_on,
2886 !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2887 return -EPERM; 2471 return -EPERM;
2888 } 2472 }
2889 2473
@@ -2960,18 +2544,15 @@ exit:
2960 2544
2961static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg) 2545static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2962{ 2546{
2963 2547 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2964 if (cfg->escan_on) { 2548 brcmf_cfg80211_escan_handler);
2965 cfg->el.handler[BRCMF_E_ESCAN_RESULT] = 2549 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2966 brcmf_cfg80211_escan_handler; 2550 /* Init scan_timeout timer */
2967 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; 2551 init_timer(&cfg->escan_timeout);
2968 /* Init scan_timeout timer */ 2552 cfg->escan_timeout.data = (unsigned long) cfg;
2969 init_timer(&cfg->escan_timeout); 2553 cfg->escan_timeout.function = brcmf_escan_timeout;
2970 cfg->escan_timeout.data = (unsigned long) cfg; 2554 INIT_WORK(&cfg->escan_timeout_work,
2971 cfg->escan_timeout.function = brcmf_escan_timeout; 2555 brcmf_cfg80211_escan_timeout_worker);
2972 INIT_WORK(&cfg->escan_timeout_work,
2973 brcmf_cfg80211_escan_timeout_worker);
2974 }
2975} 2556}
2976 2557
2977static __always_inline void brcmf_delay(u32 ms) 2558static __always_inline void brcmf_delay(u32 ms)
@@ -2986,20 +2567,8 @@ static __always_inline void brcmf_delay(u32 ms)
2986 2567
2987static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) 2568static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2988{ 2569{
2989 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2990 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
2991
2992 /*
2993 * Check for BRCMF_VIF_STATUS_READY before any function call which
2994 * could result is bus access. Don't block the resume for
2995 * any driver error conditions
2996 */
2997 WL_TRACE("Enter\n"); 2570 WL_TRACE("Enter\n");
2998 2571
2999 if (check_vif_up(ifp->vif))
3000 brcmf_invoke_iscan(cfg);
3001
3002 WL_TRACE("Exit\n");
3003 return 0; 2572 return 0;
3004} 2573}
3005 2574
@@ -3198,10 +2767,11 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3198 * cfg80211_scan_request one out of the received PNO event. 2767 * cfg80211_scan_request one out of the received PNO event.
3199 */ 2768 */
3200static s32 2769static s32
3201brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg, 2770brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3202 struct net_device *ndev,
3203 const struct brcmf_event_msg *e, void *data) 2771 const struct brcmf_event_msg *e, void *data)
3204{ 2772{
2773 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2774 struct net_device *ndev = ifp->ndev;
3205 struct brcmf_pno_net_info_le *netinfo, *netinfo_start; 2775 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3206 struct cfg80211_scan_request *request = NULL; 2776 struct cfg80211_scan_request *request = NULL;
3207 struct cfg80211_ssid *ssid = NULL; 2777 struct cfg80211_ssid *ssid = NULL;
@@ -3216,7 +2786,7 @@ brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg,
3216 2786
3217 WL_SCAN("Enter\n"); 2787 WL_SCAN("Enter\n");
3218 2788
3219 if (e->event_type == cpu_to_be32(BRCMF_E_PFN_NET_LOST)) { 2789 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3220 WL_SCAN("PFN NET LOST event. Do Nothing\n"); 2790 WL_SCAN("PFN NET LOST event. Do Nothing\n");
3221 return 0; 2791 return 0;
3222 } 2792 }
@@ -3309,7 +2879,6 @@ out_err:
3309 return err; 2879 return err;
3310} 2880}
3311 2881
3312#ifndef CONFIG_BRCMISCAN
3313static int brcmf_dev_pno_clean(struct net_device *ndev) 2882static int brcmf_dev_pno_clean(struct net_device *ndev)
3314{ 2883{
3315 int ret; 2884 int ret;
@@ -3446,7 +3015,6 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3446 brcmf_notify_escan_complete(cfg, ndev, true, true); 3015 brcmf_notify_escan_complete(cfg, ndev, true, true);
3447 return 0; 3016 return 0;
3448} 3017}
3449#endif /* CONFIG_BRCMISCAN */
3450 3018
3451#ifdef CONFIG_NL80211_TESTMODE 3019#ifdef CONFIG_NL80211_TESTMODE
3452static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) 3020static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
@@ -3512,7 +3080,7 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3512 3080
3513static s32 3081static s32
3514brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, 3082brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3515 bool is_rsn_ie, s32 bssidx) 3083 bool is_rsn_ie)
3516{ 3084{
3517 struct brcmf_if *ifp = netdev_priv(ndev); 3085 struct brcmf_if *ifp = netdev_priv(ndev);
3518 u32 auth = 0; /* d11 open authentication */ 3086 u32 auth = 0; /* d11 open authentication */
@@ -3689,7 +3257,7 @@ exit:
3689} 3257}
3690 3258
3691static s32 3259static s32
3692brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len, 3260brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3693 struct parsed_vndr_ies *vndr_ies) 3261 struct parsed_vndr_ies *vndr_ies)
3694{ 3262{
3695 s32 err = 0; 3263 s32 err = 0;
@@ -3768,13 +3336,12 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3768 return ie_len + VNDR_IE_HDR_SIZE; 3336 return ie_len + VNDR_IE_HDR_SIZE;
3769} 3337}
3770 3338
3771static s32 3339static
3772brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, 3340s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3773 struct net_device *ndev, s32 pktflag, 3341 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3774 u8 *vndr_ie_buf, u32 vndr_ie_len)
3775{ 3342{
3776 struct brcmf_if *ifp = netdev_priv(ndev); 3343 struct brcmf_if *ifp;
3777 struct vif_saved_ie *saved_ie = &ifp->vif->saved_ie; 3344 struct vif_saved_ie *saved_ie;
3778 s32 err = 0; 3345 s32 err = 0;
3779 u8 *iovar_ie_buf; 3346 u8 *iovar_ie_buf;
3780 u8 *curr_ie_buf; 3347 u8 *curr_ie_buf;
@@ -3791,8 +3358,12 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
3791 u8 *ptr; 3358 u8 *ptr;
3792 int remained_buf_len; 3359 int remained_buf_len;
3793 3360
3794 WL_TRACE("bssidx %d, pktflag : 0x%02X\n", 3361 if (!vif)
3795 brcmf_ndev_bssidx(ndev), pktflag); 3362 return -ENODEV;
3363 ifp = vif->ifp;
3364 saved_ie = &vif->saved_ie;
3365
3366 WL_TRACE("bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3796 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); 3367 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3797 if (!iovar_ie_buf) 3368 if (!iovar_ie_buf)
3798 return -ENOMEM; 3369 return -ENOMEM;
@@ -3932,13 +3503,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3932 struct brcmf_tlv *rsn_ie; 3503 struct brcmf_tlv *rsn_ie;
3933 struct brcmf_vs_tlv *wpa_ie; 3504 struct brcmf_vs_tlv *wpa_ie;
3934 struct brcmf_join_params join_params; 3505 struct brcmf_join_params join_params;
3935 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3936 s32 bssidx = 0; 3506 s32 bssidx = 0;
3937 3507
3938 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", 3508 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3939 settings->channel_type, settings->beacon_interval, 3509 cfg80211_get_chandef_type(&settings->chandef),
3510 settings->beacon_interval,
3940 settings->dtim_period); 3511 settings->dtim_period);
3941 WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n", 3512 WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3942 settings->ssid, settings->ssid_len, settings->auth_type, 3513 settings->ssid, settings->ssid_len, settings->auth_type,
3943 settings->inactivity_timeout); 3514 settings->inactivity_timeout);
3944 3515
@@ -3990,55 +3561,39 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3990 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail, 3561 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3991 settings->beacon.tail_len); 3562 settings->beacon.tail_len);
3992 3563
3993 kfree(cfg->ap_info->rsn_ie);
3994 cfg->ap_info->rsn_ie = NULL;
3995 kfree(cfg->ap_info->wpa_ie);
3996 cfg->ap_info->wpa_ie = NULL;
3997
3998 if ((wpa_ie != NULL || rsn_ie != NULL)) { 3564 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3999 WL_TRACE("WPA(2) IE is found\n"); 3565 WL_TRACE("WPA(2) IE is found\n");
4000 if (wpa_ie != NULL) { 3566 if (wpa_ie != NULL) {
4001 /* WPA IE */ 3567 /* WPA IE */
4002 err = brcmf_configure_wpaie(ndev, wpa_ie, false, 3568 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
4003 bssidx);
4004 if (err < 0) 3569 if (err < 0)
4005 goto exit; 3570 goto exit;
4006 cfg->ap_info->wpa_ie = kmemdup(wpa_ie,
4007 wpa_ie->len +
4008 TLV_HDR_LEN,
4009 GFP_KERNEL);
4010 } else { 3571 } else {
4011 /* RSN IE */ 3572 /* RSN IE */
4012 err = brcmf_configure_wpaie(ndev, 3573 err = brcmf_configure_wpaie(ndev,
4013 (struct brcmf_vs_tlv *)rsn_ie, true, bssidx); 3574 (struct brcmf_vs_tlv *)rsn_ie, true);
4014 if (err < 0) 3575 if (err < 0)
4015 goto exit; 3576 goto exit;
4016 cfg->ap_info->rsn_ie = kmemdup(rsn_ie,
4017 rsn_ie->len +
4018 TLV_HDR_LEN,
4019 GFP_KERNEL);
4020 } 3577 }
4021 cfg->ap_info->security_mode = true;
4022 } else { 3578 } else {
4023 WL_TRACE("No WPA(2) IEs found\n"); 3579 WL_TRACE("No WPA(2) IEs found\n");
4024 brcmf_configure_opensecurity(ndev, bssidx); 3580 brcmf_configure_opensecurity(ndev, bssidx);
4025 cfg->ap_info->security_mode = false;
4026 } 3581 }
4027 /* Set Beacon IEs to FW */ 3582 /* Set Beacon IEs to FW */
4028 err = brcmf_set_management_ie(cfg, ndev, 3583 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
4029 VNDR_IE_BEACON_FLAG, 3584 VNDR_IE_BEACON_FLAG,
4030 (u8 *)settings->beacon.tail, 3585 settings->beacon.tail,
4031 settings->beacon.tail_len); 3586 settings->beacon.tail_len);
4032 if (err) 3587 if (err)
4033 WL_ERR("Set Beacon IE Failed\n"); 3588 WL_ERR("Set Beacon IE Failed\n");
4034 else 3589 else
4035 WL_TRACE("Applied Vndr IEs for Beacon\n"); 3590 WL_TRACE("Applied Vndr IEs for Beacon\n");
4036 3591
4037 /* Set Probe Response IEs to FW */ 3592 /* Set Probe Response IEs to FW */
4038 err = brcmf_set_management_ie(cfg, ndev, 3593 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
4039 VNDR_IE_PRBRSP_FLAG, 3594 VNDR_IE_PRBRSP_FLAG,
4040 (u8 *)settings->beacon.proberesp_ies, 3595 settings->beacon.proberesp_ies,
4041 settings->beacon.proberesp_ies_len); 3596 settings->beacon.proberesp_ies_len);
4042 if (err) 3597 if (err)
4043 WL_ERR("Set Probe Resp IE Failed\n"); 3598 WL_ERR("Set Probe Resp IE Failed\n");
4044 else 3599 else
@@ -4169,11 +3724,8 @@ static struct cfg80211_ops wl_cfg80211_ops = {
4169 .start_ap = brcmf_cfg80211_start_ap, 3724 .start_ap = brcmf_cfg80211_start_ap,
4170 .stop_ap = brcmf_cfg80211_stop_ap, 3725 .stop_ap = brcmf_cfg80211_stop_ap,
4171 .del_station = brcmf_cfg80211_del_station, 3726 .del_station = brcmf_cfg80211_del_station,
4172#ifndef CONFIG_BRCMISCAN
4173 /* scheduled scan need e-scan, which is mutual exclusive with i-scan */
4174 .sched_scan_start = brcmf_cfg80211_sched_scan_start, 3727 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4175 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, 3728 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4176#endif
4177#ifdef CONFIG_NL80211_TESTMODE 3729#ifdef CONFIG_NL80211_TESTMODE
4178 .testmode_cmd = brcmf_cfg80211_testmode 3730 .testmode_cmd = brcmf_cfg80211_testmode
4179#endif 3731#endif
@@ -4197,13 +3749,11 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
4197 3749
4198static void brcmf_wiphy_pno_params(struct wiphy *wiphy) 3750static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4199{ 3751{
4200#ifndef CONFIG_BRCMISCAN
4201 /* scheduled scan settings */ 3752 /* scheduled scan settings */
4202 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; 3753 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4203 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; 3754 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4204 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; 3755 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4205 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 3756 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4206#endif
4207} 3757}
4208 3758
4209static struct wiphy *brcmf_setup_wiphy(struct device *phydev) 3759static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
@@ -4302,8 +3852,8 @@ static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4302static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, 3852static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg,
4303 const struct brcmf_event_msg *e) 3853 const struct brcmf_event_msg *e)
4304{ 3854{
4305 u32 event = be32_to_cpu(e->event_type); 3855 u32 event = e->event_code;
4306 u32 status = be32_to_cpu(e->status); 3856 u32 status = e->status;
4307 3857
4308 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { 3858 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4309 WL_CONN("Processing set ssid\n"); 3859 WL_CONN("Processing set ssid\n");
@@ -4317,8 +3867,8 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg,
4317static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, 3867static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg,
4318 const struct brcmf_event_msg *e) 3868 const struct brcmf_event_msg *e)
4319{ 3869{
4320 u32 event = be32_to_cpu(e->event_type); 3870 u32 event = e->event_code;
4321 u16 flags = be16_to_cpu(e->flags); 3871 u16 flags = e->flags;
4322 3872
4323 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { 3873 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4324 WL_CONN("Processing link down\n"); 3874 WL_CONN("Processing link down\n");
@@ -4330,13 +3880,12 @@ static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg,
4330static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg, 3880static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4331 const struct brcmf_event_msg *e) 3881 const struct brcmf_event_msg *e)
4332{ 3882{
4333 u32 event = be32_to_cpu(e->event_type); 3883 u32 event = e->event_code;
4334 u32 status = be32_to_cpu(e->status); 3884 u32 status = e->status;
4335 3885
4336 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) { 3886 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4337 WL_CONN("Processing Link %s & no network found\n", 3887 WL_CONN("Processing Link %s & no network found\n",
4338 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ? 3888 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4339 "up" : "down");
4340 return true; 3889 return true;
4341 } 3890 }
4342 3891
@@ -4524,9 +4073,9 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4524 const struct brcmf_event_msg *e, void *data) 4073 const struct brcmf_event_msg *e, void *data)
4525{ 4074{
4526 s32 err = 0; 4075 s32 err = 0;
4527 u32 event = be32_to_cpu(e->event_type); 4076 u32 event = e->event_code;
4528 u32 reason = be32_to_cpu(e->reason); 4077 u32 reason = e->reason;
4529 u32 len = be32_to_cpu(e->datalen); 4078 u32 len = e->datalen;
4530 static int generation; 4079 static int generation;
4531 4080
4532 struct station_info sinfo; 4081 struct station_info sinfo;
@@ -4558,11 +4107,11 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4558} 4107}
4559 4108
4560static s32 4109static s32
4561brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg, 4110brcmf_notify_connect_status(struct brcmf_if *ifp,
4562 struct net_device *ndev,
4563 const struct brcmf_event_msg *e, void *data) 4111 const struct brcmf_event_msg *e, void *data)
4564{ 4112{
4565 struct brcmf_if *ifp = netdev_priv(ndev); 4113 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4114 struct net_device *ndev = ifp->ndev;
4566 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; 4115 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4567 s32 err = 0; 4116 s32 err = 0;
4568 4117
@@ -4610,31 +4159,29 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
4610} 4159}
4611 4160
4612static s32 4161static s32
4613brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg, 4162brcmf_notify_roaming_status(struct brcmf_if *ifp,
4614 struct net_device *ndev,
4615 const struct brcmf_event_msg *e, void *data) 4163 const struct brcmf_event_msg *e, void *data)
4616{ 4164{
4617 struct brcmf_if *ifp = netdev_priv(ndev); 4165 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4618 s32 err = 0; 4166 s32 err = 0;
4619 u32 event = be32_to_cpu(e->event_type); 4167 u32 event = e->event_code;
4620 u32 status = be32_to_cpu(e->status); 4168 u32 status = e->status;
4621 4169
4622 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { 4170 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4623 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) 4171 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4624 brcmf_bss_roaming_done(cfg, ndev, e); 4172 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4625 else 4173 else
4626 brcmf_bss_connect_done(cfg, ndev, e, true); 4174 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4627 } 4175 }
4628 4176
4629 return err; 4177 return err;
4630} 4178}
4631 4179
4632static s32 4180static s32
4633brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg, 4181brcmf_notify_mic_status(struct brcmf_if *ifp,
4634 struct net_device *ndev,
4635 const struct brcmf_event_msg *e, void *data) 4182 const struct brcmf_event_msg *e, void *data)
4636{ 4183{
4637 u16 flags = be16_to_cpu(e->flags); 4184 u16 flags = e->flags;
4638 enum nl80211_key_type key_type; 4185 enum nl80211_key_type key_type;
4639 4186
4640 if (flags & BRCMF_EVENT_MSG_GROUP) 4187 if (flags & BRCMF_EVENT_MSG_GROUP)
@@ -4642,84 +4189,12 @@ brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg,
4642 else 4189 else
4643 key_type = NL80211_KEYTYPE_PAIRWISE; 4190 key_type = NL80211_KEYTYPE_PAIRWISE;
4644 4191
4645 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1, 4192 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4646 NULL, GFP_KERNEL); 4193 NULL, GFP_KERNEL);
4647 4194
4648 return 0; 4195 return 0;
4649} 4196}
4650 4197
4651static s32
4652brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
4653 struct net_device *ndev,
4654 const struct brcmf_event_msg *e, void *data)
4655{
4656 struct brcmf_if *ifp = netdev_priv(ndev);
4657 struct brcmf_channel_info_le channel_inform_le;
4658 struct brcmf_scan_results_le *bss_list_le;
4659 u32 len = WL_SCAN_BUF_MAX;
4660 s32 err = 0;
4661 bool scan_abort = false;
4662 u32 scan_channel;
4663
4664 WL_TRACE("Enter\n");
4665
4666 if (cfg->iscan_on && cfg->iscan_kickstart) {
4667 WL_TRACE("Exit\n");
4668 return brcmf_wakeup_iscan(cfg_to_iscan(cfg));
4669 }
4670
4671 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
4672 WL_ERR("Scan complete while device not scanning\n");
4673 scan_abort = true;
4674 err = -EINVAL;
4675 goto scan_done_out;
4676 }
4677
4678 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL,
4679 &channel_inform_le,
4680 sizeof(channel_inform_le));
4681 if (err) {
4682 WL_ERR("scan busy (%d)\n", err);
4683 scan_abort = true;
4684 goto scan_done_out;
4685 }
4686 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
4687 if (scan_channel)
4688 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
4689 cfg->bss_list = cfg->scan_results;
4690 bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list;
4691
4692 memset(cfg->scan_results, 0, len);
4693 bss_list_le->buflen = cpu_to_le32(len);
4694 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_SCAN_RESULTS,
4695 cfg->scan_results, len);
4696 if (err) {
4697 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
4698 err = -EINVAL;
4699 scan_abort = true;
4700 goto scan_done_out;
4701 }
4702 cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
4703 cfg->scan_results->version = le32_to_cpu(bss_list_le->version);
4704 cfg->scan_results->count = le32_to_cpu(bss_list_le->count);
4705
4706 err = brcmf_inform_bss(cfg);
4707 if (err)
4708 scan_abort = true;
4709
4710scan_done_out:
4711 if (cfg->scan_request) {
4712 WL_SCAN("calling cfg80211_scan_done\n");
4713 cfg80211_scan_done(cfg->scan_request, scan_abort);
4714 brcmf_set_mpc(ndev, 1);
4715 cfg->scan_request = NULL;
4716 }
4717
4718 WL_TRACE("Exit\n");
4719
4720 return err;
4721}
4722
4723static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) 4198static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4724{ 4199{
4725 conf->mode = (u32)-1; 4200 conf->mode = (u32)-1;
@@ -4730,77 +4205,53 @@ static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4730 conf->tx_power = -1; 4205 conf->tx_power = -1;
4731} 4206}
4732 4207
4733static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el) 4208static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4734{ 4209{
4735 memset(el, 0, sizeof(*el)); 4210 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4736 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status; 4211 brcmf_notify_connect_status);
4737 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status; 4212 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4738 el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status; 4213 brcmf_notify_connect_status);
4739 el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status; 4214 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4740 el->handler[BRCMF_E_DISASSOC_IND] = brcmf_notify_connect_status; 4215 brcmf_notify_connect_status);
4741 el->handler[BRCMF_E_ASSOC_IND] = brcmf_notify_connect_status; 4216 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4742 el->handler[BRCMF_E_REASSOC_IND] = brcmf_notify_connect_status; 4217 brcmf_notify_connect_status);
4743 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status; 4218 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4744 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status; 4219 brcmf_notify_connect_status);
4745 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status; 4220 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4746 el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results; 4221 brcmf_notify_connect_status);
4222 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4223 brcmf_notify_roaming_status);
4224 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4225 brcmf_notify_mic_status);
4226 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4227 brcmf_notify_connect_status);
4228 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4229 brcmf_notify_sched_scan_results);
4747} 4230}
4748 4231
4749static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) 4232static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4750{ 4233{
4751 kfree(cfg->scan_results);
4752 cfg->scan_results = NULL;
4753 kfree(cfg->bss_info);
4754 cfg->bss_info = NULL;
4755 kfree(cfg->conf); 4234 kfree(cfg->conf);
4756 cfg->conf = NULL; 4235 cfg->conf = NULL;
4757 kfree(cfg->scan_req_int);
4758 cfg->scan_req_int = NULL;
4759 kfree(cfg->escan_ioctl_buf); 4236 kfree(cfg->escan_ioctl_buf);
4760 cfg->escan_ioctl_buf = NULL; 4237 cfg->escan_ioctl_buf = NULL;
4761 kfree(cfg->dcmd_buf);
4762 cfg->dcmd_buf = NULL;
4763 kfree(cfg->extra_buf); 4238 kfree(cfg->extra_buf);
4764 cfg->extra_buf = NULL; 4239 cfg->extra_buf = NULL;
4765 kfree(cfg->iscan);
4766 cfg->iscan = NULL;
4767 kfree(cfg->pmk_list); 4240 kfree(cfg->pmk_list);
4768 cfg->pmk_list = NULL; 4241 cfg->pmk_list = NULL;
4769 if (cfg->ap_info) {
4770 kfree(cfg->ap_info->wpa_ie);
4771 kfree(cfg->ap_info->rsn_ie);
4772 kfree(cfg->ap_info);
4773 cfg->ap_info = NULL;
4774 }
4775} 4242}
4776 4243
4777static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) 4244static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4778{ 4245{
4779 cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
4780 if (!cfg->scan_results)
4781 goto init_priv_mem_out;
4782 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); 4246 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4783 if (!cfg->conf) 4247 if (!cfg->conf)
4784 goto init_priv_mem_out; 4248 goto init_priv_mem_out;
4785 cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4786 if (!cfg->bss_info)
4787 goto init_priv_mem_out;
4788 cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int),
4789 GFP_KERNEL);
4790 if (!cfg->scan_req_int)
4791 goto init_priv_mem_out;
4792 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); 4249 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4793 if (!cfg->escan_ioctl_buf) 4250 if (!cfg->escan_ioctl_buf)
4794 goto init_priv_mem_out; 4251 goto init_priv_mem_out;
4795 cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
4796 if (!cfg->dcmd_buf)
4797 goto init_priv_mem_out;
4798 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); 4252 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4799 if (!cfg->extra_buf) 4253 if (!cfg->extra_buf)
4800 goto init_priv_mem_out; 4254 goto init_priv_mem_out;
4801 cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL);
4802 if (!cfg->iscan)
4803 goto init_priv_mem_out;
4804 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL); 4255 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4805 if (!cfg->pmk_list) 4256 if (!cfg->pmk_list)
4806 goto init_priv_mem_out; 4257 goto init_priv_mem_out;
@@ -4813,149 +4264,22 @@ init_priv_mem_out:
4813 return -ENOMEM; 4264 return -ENOMEM;
4814} 4265}
4815 4266
4816/*
4817* retrieve first queued event from head
4818*/
4819
4820static struct brcmf_cfg80211_event_q *brcmf_deq_event(
4821 struct brcmf_cfg80211_info *cfg)
4822{
4823 struct brcmf_cfg80211_event_q *e = NULL;
4824
4825 spin_lock_irq(&cfg->evt_q_lock);
4826 if (!list_empty(&cfg->evt_q_list)) {
4827 e = list_first_entry(&cfg->evt_q_list,
4828 struct brcmf_cfg80211_event_q, evt_q_list);
4829 list_del(&e->evt_q_list);
4830 }
4831 spin_unlock_irq(&cfg->evt_q_lock);
4832
4833 return e;
4834}
4835
4836/*
4837* push event to tail of the queue
4838*
4839* remark: this function may not sleep as it is called in atomic context.
4840*/
4841
4842static s32
4843brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event,
4844 const struct brcmf_event_msg *msg, void *data)
4845{
4846 struct brcmf_cfg80211_event_q *e;
4847 s32 err = 0;
4848 ulong flags;
4849 u32 data_len;
4850 u32 total_len;
4851
4852 total_len = sizeof(struct brcmf_cfg80211_event_q);
4853 if (data)
4854 data_len = be32_to_cpu(msg->datalen);
4855 else
4856 data_len = 0;
4857 total_len += data_len;
4858 e = kzalloc(total_len, GFP_ATOMIC);
4859 if (!e)
4860 return -ENOMEM;
4861
4862 e->etype = event;
4863 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
4864 if (data)
4865 memcpy(&e->edata, data, data_len);
4866
4867 spin_lock_irqsave(&cfg->evt_q_lock, flags);
4868 list_add_tail(&e->evt_q_list, &cfg->evt_q_list);
4869 spin_unlock_irqrestore(&cfg->evt_q_lock, flags);
4870
4871 return err;
4872}
4873
4874static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
4875{
4876 kfree(e);
4877}
4878
4879static void brcmf_cfg80211_event_handler(struct work_struct *work)
4880{
4881 struct brcmf_cfg80211_info *cfg =
4882 container_of(work, struct brcmf_cfg80211_info,
4883 event_work);
4884 struct brcmf_cfg80211_event_q *e;
4885
4886 e = brcmf_deq_event(cfg);
4887 if (unlikely(!e)) {
4888 WL_ERR("event queue empty...\n");
4889 return;
4890 }
4891
4892 do {
4893 WL_INFO("event type (%d)\n", e->etype);
4894 if (cfg->el.handler[e->etype])
4895 cfg->el.handler[e->etype](cfg,
4896 cfg_to_ndev(cfg),
4897 &e->emsg, e->edata);
4898 else
4899 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
4900 brcmf_put_event(e);
4901 } while ((e = brcmf_deq_event(cfg)));
4902
4903}
4904
4905static void brcmf_init_eq(struct brcmf_cfg80211_info *cfg)
4906{
4907 spin_lock_init(&cfg->evt_q_lock);
4908 INIT_LIST_HEAD(&cfg->evt_q_list);
4909}
4910
4911static void brcmf_flush_eq(struct brcmf_cfg80211_info *cfg)
4912{
4913 struct brcmf_cfg80211_event_q *e;
4914
4915 spin_lock_irq(&cfg->evt_q_lock);
4916 while (!list_empty(&cfg->evt_q_list)) {
4917 e = list_first_entry(&cfg->evt_q_list,
4918 struct brcmf_cfg80211_event_q, evt_q_list);
4919 list_del(&e->evt_q_list);
4920 kfree(e);
4921 }
4922 spin_unlock_irq(&cfg->evt_q_lock);
4923}
4924
4925static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) 4267static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4926{ 4268{
4927 s32 err = 0; 4269 s32 err = 0;
4928 4270
4929 cfg->scan_request = NULL; 4271 cfg->scan_request = NULL;
4930 cfg->pwr_save = true; 4272 cfg->pwr_save = true;
4931#ifdef CONFIG_BRCMISCAN
4932 cfg->iscan_on = true; /* iscan on & off switch.
4933 we enable iscan per default */
4934 cfg->escan_on = false; /* escan on & off switch.
4935 we disable escan per default */
4936#else
4937 cfg->iscan_on = false; /* iscan on & off switch.
4938 we disable iscan per default */
4939 cfg->escan_on = true; /* escan on & off switch.
4940 we enable escan per default */
4941#endif
4942 cfg->roam_on = true; /* roam on & off switch. 4273 cfg->roam_on = true; /* roam on & off switch.
4943 we enable roam per default */ 4274 we enable roam per default */
4944
4945 cfg->iscan_kickstart = false;
4946 cfg->active_scan = true; /* we do active scan for 4275 cfg->active_scan = true; /* we do active scan for
4947 specific scan per default */ 4276 specific scan per default */
4948 cfg->dongle_up = false; /* dongle is not up yet */ 4277 cfg->dongle_up = false; /* dongle is not up yet */
4949 brcmf_init_eq(cfg);
4950 err = brcmf_init_priv_mem(cfg); 4278 err = brcmf_init_priv_mem(cfg);
4951 if (err) 4279 if (err)
4952 return err; 4280 return err;
4953 INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler); 4281 brcmf_register_event_handlers(cfg);
4954 brcmf_init_eloop_handler(&cfg->el);
4955 mutex_init(&cfg->usr_sync); 4282 mutex_init(&cfg->usr_sync);
4956 err = brcmf_init_iscan(cfg);
4957 if (err)
4958 return err;
4959 brcmf_init_escan(cfg); 4283 brcmf_init_escan(cfg);
4960 brcmf_init_conf(cfg->conf); 4284 brcmf_init_conf(cfg->conf);
4961 brcmf_link_down(cfg); 4285 brcmf_link_down(cfg);
@@ -4965,9 +4289,7 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4965 4289
4966static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) 4290static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4967{ 4291{
4968 cancel_work_sync(&cfg->event_work);
4969 cfg->dongle_up = false; /* dongle down */ 4292 cfg->dongle_up = false; /* dongle down */
4970 brcmf_flush_eq(cfg);
4971 brcmf_link_down(cfg); 4293 brcmf_link_down(cfg);
4972 brcmf_abort_scanning(cfg); 4294 brcmf_abort_scanning(cfg);
4973 brcmf_deinit_priv_mem(cfg); 4295 brcmf_deinit_priv_mem(cfg);
@@ -5029,66 +4351,6 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5029 } 4351 }
5030} 4352}
5031 4353
5032void
5033brcmf_cfg80211_event(struct net_device *ndev,
5034 const struct brcmf_event_msg *e, void *data)
5035{
5036 u32 event_type = be32_to_cpu(e->event_type);
5037 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
5038
5039 if (!brcmf_enq_event(cfg, event_type, e, data))
5040 schedule_work(&cfg->event_work);
5041}
5042
5043static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
5044{
5045 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
5046 s32 err = 0;
5047
5048 WL_TRACE("Enter\n");
5049
5050 /* Setup event_msgs */
5051 err = brcmf_fil_iovar_data_get(netdev_priv(ndev), "event_msgs",
5052 eventmask, BRCMF_EVENTING_MASK_LEN);
5053 if (err) {
5054 WL_ERR("Get event_msgs error (%d)\n", err);
5055 goto dongle_eventmsg_out;
5056 }
5057
5058 setbit(eventmask, BRCMF_E_SET_SSID);
5059 setbit(eventmask, BRCMF_E_ROAM);
5060 setbit(eventmask, BRCMF_E_PRUNE);
5061 setbit(eventmask, BRCMF_E_AUTH);
5062 setbit(eventmask, BRCMF_E_REASSOC);
5063 setbit(eventmask, BRCMF_E_REASSOC_IND);
5064 setbit(eventmask, BRCMF_E_DEAUTH_IND);
5065 setbit(eventmask, BRCMF_E_DISASSOC_IND);
5066 setbit(eventmask, BRCMF_E_DISASSOC);
5067 setbit(eventmask, BRCMF_E_JOIN);
5068 setbit(eventmask, BRCMF_E_ASSOC_IND);
5069 setbit(eventmask, BRCMF_E_PSK_SUP);
5070 setbit(eventmask, BRCMF_E_LINK);
5071 setbit(eventmask, BRCMF_E_NDIS_LINK);
5072 setbit(eventmask, BRCMF_E_MIC_ERROR);
5073 setbit(eventmask, BRCMF_E_PMKID_CACHE);
5074 setbit(eventmask, BRCMF_E_TXFAIL);
5075 setbit(eventmask, BRCMF_E_JOIN_START);
5076 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
5077 setbit(eventmask, BRCMF_E_ESCAN_RESULT);
5078 setbit(eventmask, BRCMF_E_PFN_NET_FOUND);
5079
5080 err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "event_msgs",
5081 eventmask, BRCMF_EVENTING_MASK_LEN);
5082 if (err) {
5083 WL_ERR("Set event_msgs error (%d)\n", err);
5084 goto dongle_eventmsg_out;
5085 }
5086
5087dongle_eventmsg_out:
5088 WL_TRACE("Exit\n");
5089 return err;
5090}
5091
5092static s32 4354static s32
5093brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) 4355brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
5094{ 4356{
@@ -5190,7 +4452,7 @@ static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5190 s8 phy; 4452 s8 phy;
5191 s32 err = 0; 4453 s32 err = 0;
5192 4454
5193 err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_PHYLIST, 4455 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5194 &phy_list, sizeof(phy_list)); 4456 &phy_list, sizeof(phy_list));
5195 if (err) { 4457 if (err) {
5196 WL_ERR("error (%d)\n", err); 4458 WL_ERR("error (%d)\n", err);
@@ -5228,10 +4490,6 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5228 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, 4490 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
5229 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); 4491 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5230 4492
5231 err = brcmf_dongle_eventmsg(ndev);
5232 if (err)
5233 goto default_conf_out;
5234
5235 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; 4493 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5236 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, 4494 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM,
5237 power_mode); 4495 power_mode);
@@ -5262,26 +4520,18 @@ default_conf_out:
5262 4520
5263} 4521}
5264 4522
5265static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) 4523static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5266{ 4524{
5267 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5268 s32 err = 0;
5269
5270 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); 4525 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4526 if (ifp->idx)
4527 return 0;
5271 4528
5272 err = brcmf_config_dongle(cfg); 4529 return brcmf_config_dongle(ifp->drvr->config);
5273 if (err)
5274 return err;
5275
5276 brcmf_invoke_iscan(cfg);
5277
5278 return err;
5279} 4530}
5280 4531
5281static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) 4532static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5282{ 4533{
5283 struct net_device *ndev = cfg_to_ndev(cfg); 4534 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5284 struct brcmf_if *ifp = netdev_priv(ndev);
5285 4535
5286 /* 4536 /*
5287 * While going down, if associated with AP disassociate 4537 * While going down, if associated with AP disassociate
@@ -5306,23 +4556,27 @@ static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
5306 return 0; 4556 return 0;
5307} 4557}
5308 4558
5309s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) 4559s32 brcmf_cfg80211_up(struct net_device *ndev)
5310{ 4560{
4561 struct brcmf_if *ifp = netdev_priv(ndev);
4562 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5311 s32 err = 0; 4563 s32 err = 0;
5312 4564
5313 mutex_lock(&cfg->usr_sync); 4565 mutex_lock(&cfg->usr_sync);
5314 err = __brcmf_cfg80211_up(cfg); 4566 err = __brcmf_cfg80211_up(ifp);
5315 mutex_unlock(&cfg->usr_sync); 4567 mutex_unlock(&cfg->usr_sync);
5316 4568
5317 return err; 4569 return err;
5318} 4570}
5319 4571
5320s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) 4572s32 brcmf_cfg80211_down(struct net_device *ndev)
5321{ 4573{
4574 struct brcmf_if *ifp = netdev_priv(ndev);
4575 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5322 s32 err = 0; 4576 s32 err = 0;
5323 4577
5324 mutex_lock(&cfg->usr_sync); 4578 mutex_lock(&cfg->usr_sync);
5325 err = __brcmf_cfg80211_down(cfg); 4579 err = __brcmf_cfg80211_down(ifp);
5326 mutex_unlock(&cfg->usr_sync); 4580 mutex_unlock(&cfg->usr_sync);
5327 4581
5328 return err; 4582 return err;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index 1dd96f148ef..e2ef8519ea8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -84,31 +84,12 @@ do { \
84#define WL_CONN(fmt, args...) 84#define WL_CONN(fmt, args...)
85#endif /* (defined DEBUG) */ 85#endif /* (defined DEBUG) */
86 86
87#define WL_NUM_SCAN_MAX 1 87#define WL_NUM_SCAN_MAX 10
88#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used 88#define WL_NUM_PMKIDS_MAX MAXPMKID
89 * for 2.6.33 kernel
90 * or later
91 */
92#define WL_SCAN_BUF_MAX (1024 * 8)
93#define WL_TLV_INFO_MAX 1024 89#define WL_TLV_INFO_MAX 1024
94#define WL_BSS_INFO_MAX 2048 90#define WL_BSS_INFO_MAX 2048
95#define WL_ASSOC_INFO_MAX 512 /* 91#define WL_ASSOC_INFO_MAX 512 /* assoc related fil max buf */
96 * needs to grab assoc info from dongle to 92#define WL_EXTRA_BUF_MAX 2048
97 * report it to cfg80211 through "connect"
98 * event
99 */
100#define WL_DCMD_LEN_MAX 1024
101#define WL_EXTRA_BUF_MAX 2048
102#define WL_ISCAN_BUF_MAX 2048 /*
103 * the buf length can be BRCMF_DCMD_MAXLEN
104 * to reduce iteration
105 */
106#define WL_ISCAN_TIMER_INTERVAL_MS 3000
107#define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1)
108#define WL_AP_MAX 256 /* virtually unlimitted as long
109 * as kernel memory allows
110 */
111
112#define WL_ROAM_TRIGGER_LEVEL -75 93#define WL_ROAM_TRIGGER_LEVEL -75
113#define WL_ROAM_DELTA 20 94#define WL_ROAM_DELTA 20
114#define WL_BEACON_TIMEOUT 3 95#define WL_BEACON_TIMEOUT 3
@@ -145,12 +126,6 @@ enum wl_mode {
145 WL_MODE_AP 126 WL_MODE_AP
146}; 127};
147 128
148/* dongle iscan state */
149enum wl_iscan_state {
150 WL_ISCAN_STATE_IDLE,
151 WL_ISCAN_STATE_SCANING
152};
153
154/* dongle configuration */ 129/* dongle configuration */
155struct brcmf_cfg80211_conf { 130struct brcmf_cfg80211_conf {
156 u32 mode; /* adhoc , infrastructure or ap */ 131 u32 mode; /* adhoc , infrastructure or ap */
@@ -162,17 +137,6 @@ struct brcmf_cfg80211_conf {
162 struct ieee80211_channel channel; 137 struct ieee80211_channel channel;
163}; 138};
164 139
165/* forward declaration */
166struct brcmf_cfg80211_info;
167
168/* cfg80211 main event loop */
169struct brcmf_cfg80211_event_loop {
170 s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_info *cfg,
171 struct net_device *ndev,
172 const struct brcmf_event_msg *e,
173 void *data);
174};
175
176/* basic structure of scan request */ 140/* basic structure of scan request */
177struct brcmf_cfg80211_scan_req { 141struct brcmf_cfg80211_scan_req {
178 struct brcmf_ssid_le ssid_le; 142 struct brcmf_ssid_le ssid_le;
@@ -184,14 +148,6 @@ struct brcmf_cfg80211_ie {
184 u8 buf[WL_TLV_INFO_MAX]; 148 u8 buf[WL_TLV_INFO_MAX];
185}; 149};
186 150
187/* event queue for cfg80211 main event */
188struct brcmf_cfg80211_event_q {
189 struct list_head evt_q_list;
190 u32 etype;
191 struct brcmf_event_msg emsg;
192 s8 edata[1];
193};
194
195/* security information with currently associated ap */ 151/* security information with currently associated ap */
196struct brcmf_cfg80211_security { 152struct brcmf_cfg80211_security {
197 u32 wpa_versions; 153 u32 wpa_versions;
@@ -270,26 +226,6 @@ struct brcmf_cfg80211_vif {
270 struct list_head list; 226 struct list_head list;
271}; 227};
272 228
273/* dongle iscan event loop */
274struct brcmf_cfg80211_iscan_eloop {
275 s32 (*handler[WL_SCAN_ERSULTS_LAST])
276 (struct brcmf_cfg80211_info *cfg);
277};
278
279/* dongle iscan controller */
280struct brcmf_cfg80211_iscan_ctrl {
281 struct net_device *ndev;
282 struct timer_list timer;
283 u32 timer_ms;
284 u32 timer_on;
285 s32 state;
286 struct work_struct work;
287 struct brcmf_cfg80211_iscan_eloop el;
288 void *data;
289 s8 dcmd_buf[BRCMF_DCMD_SMLEN];
290 s8 scan_buf[WL_ISCAN_BUF_MAX];
291};
292
293/* association inform */ 229/* association inform */
294struct brcmf_cfg80211_connect_info { 230struct brcmf_cfg80211_connect_info {
295 u8 *req_ie; 231 u8 *req_ie;
@@ -323,17 +259,6 @@ struct escan_info {
323 struct net_device *ndev; 259 struct net_device *ndev;
324}; 260};
325 261
326/* Structure to hold WPS, WPA IEs for a AP */
327struct ap_info {
328 u8 probe_res_ie[IE_MAX_LEN];
329 u8 beacon_ie[IE_MAX_LEN];
330 u32 probe_res_ie_len;
331 u32 beacon_ie_len;
332 u8 *wpa_ie;
333 u8 *rsn_ie;
334 bool security_mode;
335};
336
337/** 262/**
338 * struct brcmf_pno_param_le - PNO scan configuration parameters 263 * struct brcmf_pno_param_le - PNO scan configuration parameters
339 * 264 *
@@ -421,24 +346,16 @@ struct brcmf_pno_scanresults_le {
421 * @wiphy: wiphy object for cfg80211 interface. 346 * @wiphy: wiphy object for cfg80211 interface.
422 * @conf: dongle configuration. 347 * @conf: dongle configuration.
423 * @scan_request: cfg80211 scan request object. 348 * @scan_request: cfg80211 scan request object.
424 * @el: main event loop.
425 * @evt_q_list: used for event queue.
426 * @evt_q_lock: for event queue synchronization.
427 * @usr_sync: mainly for dongle up/down synchronization. 349 * @usr_sync: mainly for dongle up/down synchronization.
428 * @bss_list: bss_list holding scanned ap information. 350 * @bss_list: bss_list holding scanned ap information.
429 * @scan_results: results of the last scan.
430 * @scan_req_int: internal scan request object. 351 * @scan_req_int: internal scan request object.
431 * @bss_info: bss information for cfg80211 layer. 352 * @bss_info: bss information for cfg80211 layer.
432 * @ie: information element object for internal purpose. 353 * @ie: information element object for internal purpose.
433 * @iscan: iscan controller information.
434 * @conn_info: association info. 354 * @conn_info: association info.
435 * @pmk_list: wpa2 pmk list. 355 * @pmk_list: wpa2 pmk list.
436 * @event_work: event handler work struct.
437 * @scan_status: scan activity on the dongle. 356 * @scan_status: scan activity on the dongle.
438 * @pub: common driver information. 357 * @pub: common driver information.
439 * @channel: current channel. 358 * @channel: current channel.
440 * @iscan_on: iscan on/off switch.
441 * @iscan_kickstart: indicate iscan already started.
442 * @active_scan: current scan mode. 359 * @active_scan: current scan mode.
443 * @sched_escan: e-scan for scheduled scan support running. 360 * @sched_escan: e-scan for scheduled scan support running.
444 * @ibss_starter: indicates this sta is ibss starter. 361 * @ibss_starter: indicates this sta is ibss starter.
@@ -450,12 +367,10 @@ struct brcmf_pno_scanresults_le {
450 * @dcmd_buf: dcmd buffer. 367 * @dcmd_buf: dcmd buffer.
451 * @extra_buf: mainly to grab assoc information. 368 * @extra_buf: mainly to grab assoc information.
452 * @debugfsdir: debugfs folder for this device. 369 * @debugfsdir: debugfs folder for this device.
453 * @escan_on: escan on/off switch.
454 * @escan_info: escan information. 370 * @escan_info: escan information.
455 * @escan_timeout: Timer for catch scan timeout. 371 * @escan_timeout: Timer for catch scan timeout.
456 * @escan_timeout_work: scan timeout worker. 372 * @escan_timeout_work: scan timeout worker.
457 * @escan_ioctl_buf: dongle command buffer for escan commands. 373 * @escan_ioctl_buf: dongle command buffer for escan commands.
458 * @ap_info: host ap information.
459 * @vif_list: linked list of vif instances. 374 * @vif_list: linked list of vif instances.
460 * @vif_cnt: number of vif instances. 375 * @vif_cnt: number of vif instances.
461 */ 376 */
@@ -463,24 +378,16 @@ struct brcmf_cfg80211_info {
463 struct wiphy *wiphy; 378 struct wiphy *wiphy;
464 struct brcmf_cfg80211_conf *conf; 379 struct brcmf_cfg80211_conf *conf;
465 struct cfg80211_scan_request *scan_request; 380 struct cfg80211_scan_request *scan_request;
466 struct brcmf_cfg80211_event_loop el;
467 struct list_head evt_q_list;
468 spinlock_t evt_q_lock;
469 struct mutex usr_sync; 381 struct mutex usr_sync;
470 struct brcmf_scan_results *bss_list; 382 struct brcmf_scan_results *bss_list;
471 struct brcmf_scan_results *scan_results; 383 struct brcmf_cfg80211_scan_req scan_req_int;
472 struct brcmf_cfg80211_scan_req *scan_req_int;
473 struct wl_cfg80211_bss_info *bss_info; 384 struct wl_cfg80211_bss_info *bss_info;
474 struct brcmf_cfg80211_ie ie; 385 struct brcmf_cfg80211_ie ie;
475 struct brcmf_cfg80211_iscan_ctrl *iscan;
476 struct brcmf_cfg80211_connect_info conn_info; 386 struct brcmf_cfg80211_connect_info conn_info;
477 struct brcmf_cfg80211_pmk_list *pmk_list; 387 struct brcmf_cfg80211_pmk_list *pmk_list;
478 struct work_struct event_work;
479 unsigned long scan_status; 388 unsigned long scan_status;
480 struct brcmf_pub *pub; 389 struct brcmf_pub *pub;
481 u32 channel; 390 u32 channel;
482 bool iscan_on;
483 bool iscan_kickstart;
484 bool active_scan; 391 bool active_scan;
485 bool sched_escan; 392 bool sched_escan;
486 bool ibss_starter; 393 bool ibss_starter;
@@ -492,12 +399,10 @@ struct brcmf_cfg80211_info {
492 u8 *dcmd_buf; 399 u8 *dcmd_buf;
493 u8 *extra_buf; 400 u8 *extra_buf;
494 struct dentry *debugfsdir; 401 struct dentry *debugfsdir;
495 bool escan_on;
496 struct escan_info escan_info; 402 struct escan_info escan_info;
497 struct timer_list escan_timeout; 403 struct timer_list escan_timeout;
498 struct work_struct escan_timeout_work; 404 struct work_struct escan_timeout_work;
499 u8 *escan_ioctl_buf; 405 u8 *escan_ioctl_buf;
500 struct ap_info *ap_info;
501 struct list_head vif_list; 406 struct list_head vif_list;
502 u8 vif_cnt; 407 u8 vif_cnt;
503}; 408};
@@ -536,8 +441,11 @@ static inline struct brcmf_cfg80211_profile *ndev_to_prof(struct net_device *nd)
536 return &ifp->vif->profile; 441 return &ifp->vif->profile;
537} 442}
538 443
539#define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data)) 444static inline struct brcmf_cfg80211_vif *ndev_to_vif(struct net_device *ndev)
540#define cfg_to_iscan(w) (w->iscan) 445{
446 struct brcmf_if *ifp = netdev_priv(ndev);
447 return ifp->vif;
448}
541 449
542static inline struct 450static inline struct
543brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) 451brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg)
@@ -547,11 +455,7 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg)
547 455
548struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr); 456struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr);
549void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); 457void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
550 458s32 brcmf_cfg80211_up(struct net_device *ndev);
551/* event handler from dongle */ 459s32 brcmf_cfg80211_down(struct net_device *ndev);
552void brcmf_cfg80211_event(struct net_device *ndev,
553 const struct brcmf_event_msg *e, void *data);
554s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg);
555s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg);
556 460
557#endif /* _wl_cfg80211_h_ */ 461#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
index e227c4c68ef..d3d4151c3ed 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
@@ -40,7 +40,8 @@ BRCMSMAC_OFILES := \
40 phy/phytbl_n.o \ 40 phy/phytbl_n.o \
41 phy/phy_qmath.o \ 41 phy/phy_qmath.o \
42 dma.o \ 42 dma.o \
43 brcms_trace_events.o 43 brcms_trace_events.o \
44 debug.o
44 45
45MODULEPFX := brcmsmac 46MODULEPFX := brcmsmac
46 47
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index be5bcfb9153..1de94f30564 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -21,6 +21,8 @@
21#include "antsel.h" 21#include "antsel.h"
22#include "main.h" 22#include "main.h"
23#include "ampdu.h" 23#include "ampdu.h"
24#include "debug.h"
25#include "brcms_trace_events.h"
24 26
25/* max number of mpdus in an ampdu */ 27/* max number of mpdus in an ampdu */
26#define AMPDU_MAX_MPDU 32 28#define AMPDU_MAX_MPDU 32
@@ -40,8 +42,6 @@
40#define AMPDU_DEF_RETRY_LIMIT 5 42#define AMPDU_DEF_RETRY_LIMIT 5
41/* default tx retry limit at reg rate */ 43/* default tx retry limit at reg rate */
42#define AMPDU_DEF_RR_RETRY_LIMIT 2 44#define AMPDU_DEF_RR_RETRY_LIMIT 2
43/* default weight of ampdu in txfifo */
44#define AMPDU_DEF_TXPKT_WEIGHT 2
45/* default ffpld reserved bytes */ 45/* default ffpld reserved bytes */
46#define AMPDU_DEF_FFPLD_RSVD 2048 46#define AMPDU_DEF_FFPLD_RSVD 2048
47/* # of inis to be freed on detach */ 47/* # of inis to be freed on detach */
@@ -114,7 +114,6 @@ struct brcms_fifo_info {
114 * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec 114 * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec
115 * max_pdu: max pdus allowed in ampdu 115 * max_pdu: max pdus allowed in ampdu
116 * dur: max duration of an ampdu (in msec) 116 * dur: max duration of an ampdu (in msec)
117 * txpkt_weight: weight of ampdu in txfifo; reduces rate lag
118 * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes 117 * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes
119 * ffpld_rsvd: number of bytes to reserve for preload 118 * ffpld_rsvd: number of bytes to reserve for preload
120 * max_txlen: max size of ampdu per mcs, bw and sgi 119 * max_txlen: max size of ampdu per mcs, bw and sgi
@@ -136,7 +135,6 @@ struct ampdu_info {
136 u8 mpdu_density; 135 u8 mpdu_density;
137 s8 max_pdu; 136 s8 max_pdu;
138 u8 dur; 137 u8 dur;
139 u8 txpkt_weight;
140 u8 rx_factor; 138 u8 rx_factor;
141 u32 ffpld_rsvd; 139 u32 ffpld_rsvd;
142 u32 max_txlen[MCS_TABLE_SIZE][2][2]; 140 u32 max_txlen[MCS_TABLE_SIZE][2][2];
@@ -183,18 +181,19 @@ static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
183static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on) 181static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
184{ 182{
185 struct brcms_c_info *wlc = ampdu->wlc; 183 struct brcms_c_info *wlc = ampdu->wlc;
184 struct bcma_device *core = wlc->hw->d11core;
186 185
187 wlc->pub->_ampdu = false; 186 wlc->pub->_ampdu = false;
188 187
189 if (on) { 188 if (on) {
190 if (!(wlc->pub->_n_enab & SUPPORT_11N)) { 189 if (!(wlc->pub->_n_enab & SUPPORT_11N)) {
191 wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not " 190 brcms_err(core, "wl%d: driver not nmode enabled\n",
192 "nmode enabled\n", wlc->pub->unit); 191 wlc->pub->unit);
193 return -ENOTSUPP; 192 return -ENOTSUPP;
194 } 193 }
195 if (!brcms_c_ampdu_cap(ampdu)) { 194 if (!brcms_c_ampdu_cap(ampdu)) {
196 wiphy_err(ampdu->wlc->wiphy, "wl%d: device not " 195 brcms_err(core, "wl%d: device not ampdu capable\n",
197 "ampdu capable\n", wlc->pub->unit); 196 wlc->pub->unit);
198 return -ENOTSUPP; 197 return -ENOTSUPP;
199 } 198 }
200 wlc->pub->_ampdu = on; 199 wlc->pub->_ampdu = on;
@@ -247,7 +246,6 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
247 ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; 246 ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
248 ampdu->max_pdu = AUTO; 247 ampdu->max_pdu = AUTO;
249 ampdu->dur = AMPDU_MAX_DUR; 248 ampdu->dur = AMPDU_MAX_DUR;
250 ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;
251 249
252 ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; 250 ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
253 /* 251 /*
@@ -374,7 +372,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
374 offsetof(struct macstat, txfunfl[fid])); 372 offsetof(struct macstat, txfunfl[fid]));
375 new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); 373 new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
376 if (new_txunfl == 0) { 374 if (new_txunfl == 0) {
377 BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n"); 375 brcms_dbg_ht(wlc->hw->d11core,
376 "TX status FRAG set but no tx underflows\n");
378 return -1; 377 return -1;
379 } 378 }
380 fifo->prev_txfunfl = cur_txunfl; 379 fifo->prev_txfunfl = cur_txunfl;
@@ -396,8 +395,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
396 if (fifo->accum_txfunfl < 10) 395 if (fifo->accum_txfunfl < 10)
397 return 0; 396 return 0;
398 397
399 BCMMSG(wlc->wiphy, "ampdu_count %d tx_underflows %d\n", 398 brcms_dbg_ht(wlc->hw->d11core, "ampdu_count %d tx_underflows %d\n",
400 current_ampdu_cnt, fifo->accum_txfunfl); 399 current_ampdu_cnt, fifo->accum_txfunfl);
401 400
402 /* 401 /*
403 compute the current ratio of tx unfl per ampdu. 402 compute the current ratio of tx unfl per ampdu.
@@ -450,9 +449,10 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
450 (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) 449 (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
451 / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; 450 / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
452 451
453 BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; " 452 brcms_dbg_ht(wlc->hw->d11core,
454 "pre-load size %d\n", 453 "DMA estimated transfer rate %d; "
455 fifo->dmaxferrate, fifo->ampdu_pld_size); 454 "pre-load size %d\n",
455 fifo->dmaxferrate, fifo->ampdu_pld_size);
456 } else { 456 } else {
457 457
458 /* decrease ampdu size */ 458 /* decrease ampdu size */
@@ -486,7 +486,7 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
486 scb_ampdu = &scb->scb_ampdu; 486 scb_ampdu = &scb->scb_ampdu;
487 487
488 if (!ampdu->ini_enable[tid]) { 488 if (!ampdu->ini_enable[tid]) {
489 wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n", 489 brcms_err(wlc->hw->d11core, "%s: Rejecting tid %d\n",
490 __func__, tid); 490 __func__, tid);
491 return; 491 return;
492 } 492 }
@@ -498,378 +498,324 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
498 scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes; 498 scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
499} 499}
500 500
501int 501void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session,
502brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, 502 struct brcms_c_info *wlc)
503 struct sk_buff **pdu, int prec)
504{ 503{
505 struct brcms_c_info *wlc; 504 session->wlc = wlc;
506 struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; 505 skb_queue_head_init(&session->skb_list);
507 u8 tid, ndelim; 506 session->max_ampdu_len = 0; /* determined from first MPDU */
508 int err = 0; 507 session->max_ampdu_frames = 0; /* determined from first MPDU */
509 u8 preamble_type = BRCMS_GF_PREAMBLE; 508 session->ampdu_len = 0;
510 u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; 509 session->dma_len = 0;
511 u8 rts_preamble_type = BRCMS_LONG_PREAMBLE; 510}
512 u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
513 511
514 bool rr = true, fbr = false; 512/*
515 uint i, count = 0, fifo, seg_cnt = 0; 513 * Preps the given packet for AMPDU based on the session data. If the
516 u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0; 514 * frame cannot be accomodated in the current session, -ENOSPC is
517 u32 ampdu_len, max_ampdu_bytes = 0; 515 * returned.
518 struct d11txh *txh = NULL; 516 */
517int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session,
518 struct sk_buff *p)
519{
520 struct brcms_c_info *wlc = session->wlc;
521 struct ampdu_info *ampdu = wlc->ampdu;
522 struct scb *scb = &wlc->pri_scb;
523 struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
524 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
525 struct ieee80211_tx_rate *txrate = tx_info->status.rates;
526 struct d11txh *txh = (struct d11txh *)p->data;
527 unsigned ampdu_frames;
528 u8 ndelim, tid;
519 u8 *plcp; 529 u8 *plcp;
520 struct ieee80211_hdr *h; 530 uint len;
521 struct scb *scb; 531 u16 mcl;
522 struct scb_ampdu *scb_ampdu;
523 struct scb_ampdu_tid_ini *ini;
524 u8 mcs = 0;
525 bool use_rts = false, use_cts = false;
526 u32 rspec = 0, rspec_fallback = 0;
527 u32 rts_rspec = 0, rts_rspec_fallback = 0;
528 u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
529 struct ieee80211_rts *rts;
530 u8 rr_retry_limit;
531 struct brcms_fifo_info *f;
532 bool fbr_iscck; 532 bool fbr_iscck;
533 struct ieee80211_tx_info *tx_info; 533 bool rr;
534 u16 qlen;
535 struct wiphy *wiphy;
536
537 wlc = ampdu->wlc;
538 wiphy = wlc->wiphy;
539 p = *pdu;
540
541 tid = (u8) (p->priority);
542 534
543 f = ampdu->fifo_tb + prio2fifo[tid]; 535 ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
536 plcp = (u8 *)(txh + 1);
537 fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03);
538 len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) :
539 BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
540 len = roundup(len, 4) + (ndelim + 1) * AMPDU_DELIMITER_LEN;
544 541
545 scb = &wlc->pri_scb; 542 ampdu_frames = skb_queue_len(&session->skb_list);
546 scb_ampdu = &scb->scb_ampdu; 543 if (ampdu_frames != 0) {
547 ini = &scb_ampdu->ini[tid]; 544 struct sk_buff *first;
548 545
549 /* Let pressure continue to build ... */ 546 if (ampdu_frames + 1 > session->max_ampdu_frames ||
550 qlen = pktq_plen(&qi->q, prec); 547 session->ampdu_len + len > session->max_ampdu_len)
551 if (ini->tx_in_transit > 0 && 548 return -ENOSPC;
552 qlen < min(scb_ampdu->max_pdu, ini->ba_wsize))
553 /* Collect multiple MPDU's to be sent in the next AMPDU */
554 return -EBUSY;
555 549
556 /* at this point we intend to transmit an AMPDU */ 550 /*
557 rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; 551 * We aren't really out of space if the new frame is of
558 ampdu_len = 0; 552 * a different priority, but we want the same behaviour
559 dma_len = 0; 553 * so return -ENOSPC anyway.
560 while (p) { 554 *
561 struct ieee80211_tx_rate *txrate; 555 * XXX: The old AMPDU code did this, but is it really
562 556 * necessary?
563 tx_info = IEEE80211_SKB_CB(p); 557 */
564 txrate = tx_info->status.rates; 558 first = skb_peek(&session->skb_list);
559 if (p->priority != first->priority)
560 return -ENOSPC;
561 }
565 562
566 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { 563 /*
567 err = brcms_c_prep_pdu(wlc, p, &fifo); 564 * Now that we're sure this frame can be accomodated, update the
568 } else { 565 * session information.
569 wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__); 566 */
570 *pdu = NULL; 567 session->ampdu_len += len;
571 err = 0; 568 session->dma_len += p->len;
572 break;
573 }
574 569
575 if (err) { 570 tid = (u8)p->priority;
576 if (err == -EBUSY) {
577 wiphy_err(wiphy, "wl%d: sendampdu: "
578 "prep_xdu retry; seq 0x%x\n",
579 wlc->pub->unit, seq);
580 *pdu = p;
581 break;
582 }
583 571
584 /* error in the packet; reject it */ 572 /* Handle retry limits */
585 wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu " 573 if (txrate[0].count <= ampdu->rr_retry_limit_tid[tid]) {
586 "rejected; seq 0x%x\n", wlc->pub->unit, seq); 574 txrate[0].count++;
587 *pdu = NULL; 575 rr = true;
588 break; 576 } else {
589 } 577 txrate[1].count++;
578 rr = false;
579 }
590 580
591 /* pkt is good to be aggregated */ 581 if (ampdu_frames == 0) {
592 txh = (struct d11txh *) p->data; 582 u8 plcp0, plcp3, is40, sgi, mcs;
593 plcp = (u8 *) (txh + 1); 583 uint fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
594 h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); 584 struct brcms_fifo_info *f = &ampdu->fifo_tb[fifo];
595 seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
596 index = TX_SEQ_TO_INDEX(seq);
597 585
598 /* check mcl fields and test whether it can be agg'd */ 586 if (rr) {
599 mcl = le16_to_cpu(txh->MacTxControlLow); 587 plcp0 = plcp[0];
600 mcl &= ~TXC_AMPDU_MASK; 588 plcp3 = plcp[3];
601 fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
602 txh->PreloadSize = 0; /* always default to 0 */
603
604 /* Handle retry limits */
605 if (txrate[0].count <= rr_retry_limit) {
606 txrate[0].count++;
607 rr = true;
608 fbr = false;
609 } else { 589 } else {
610 fbr = true; 590 plcp0 = txh->FragPLCPFallback[0];
611 rr = false; 591 plcp3 = txh->FragPLCPFallback[3];
612 txrate[1].count++;
613 }
614
615 /* extract the length info */
616 len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
617 : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
618
619 /* retrieve null delimiter count */
620 ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
621 seg_cnt += 1;
622 592
623 BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
624 wlc->pub->unit, count, len);
625
626 /*
627 * aggregateable mpdu. For ucode/hw agg,
628 * test whether need to break or change the epoch
629 */
630 if (count == 0) {
631 mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
632 /* refill the bits since might be a retx mpdu */
633 mcl |= TXC_STARTMSDU;
634 rts = (struct ieee80211_rts *)&txh->rts_frame;
635
636 if (ieee80211_is_rts(rts->frame_control)) {
637 mcl |= TXC_SENDRTS;
638 use_rts = true;
639 }
640 if (ieee80211_is_cts(rts->frame_control)) {
641 mcl |= TXC_SENDCTS;
642 use_cts = true;
643 }
644 } else {
645 mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
646 mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
647 } 593 }
648 594
649 len = roundup(len, 4); 595 /* Limit AMPDU size based on MCS */
650 ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); 596 is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
597 sgi = plcp3_issgi(plcp3) ? 1 : 0;
598 mcs = plcp0 & ~MIMO_PLCP_40MHZ;
599 session->max_ampdu_len = min(scb_ampdu->max_rx_ampdu_bytes,
600 ampdu->max_txlen[mcs][is40][sgi]);
651 601
652 dma_len += (u16) p->len; 602 session->max_ampdu_frames = scb_ampdu->max_pdu;
603 if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
604 session->max_ampdu_frames =
605 min_t(u16, f->mcs2ampdu_table[mcs],
606 session->max_ampdu_frames);
607 }
608 }
653 609
654 BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" 610 /*
655 " seg_cnt %d null delim %d\n", 611 * Treat all frames as "middle" frames of AMPDU here. First and
656 wlc->pub->unit, ampdu_len, seg_cnt, ndelim); 612 * last frames must be fixed up after all MPDUs have been prepped.
613 */
614 mcl = le16_to_cpu(txh->MacTxControlLow);
615 mcl &= ~TXC_AMPDU_MASK;
616 mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
617 mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
618 txh->MacTxControlLow = cpu_to_le16(mcl);
619 txh->PreloadSize = 0; /* always default to 0 */
657 620
658 txh->MacTxControlLow = cpu_to_le16(mcl); 621 skb_queue_tail(&session->skb_list, p);
659 622
660 /* this packet is added */ 623 return 0;
661 pkt[count++] = p; 624}
662 625
663 /* patch the first MPDU */ 626void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session)
664 if (count == 1) { 627{
665 u8 plcp0, plcp3, is40, sgi; 628 struct brcms_c_info *wlc = session->wlc;
629 struct ampdu_info *ampdu = wlc->ampdu;
630 struct sk_buff *first, *last;
631 struct d11txh *txh;
632 struct ieee80211_tx_info *tx_info;
633 struct ieee80211_tx_rate *txrate;
634 u8 ndelim;
635 u8 *plcp;
636 uint len;
637 uint fifo;
638 struct brcms_fifo_info *f;
639 u16 mcl;
640 bool fbr;
641 bool fbr_iscck;
642 struct ieee80211_rts *rts;
643 bool use_rts = false, use_cts = false;
644 u16 dma_len = session->dma_len;
645 u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
646 u32 rspec = 0, rspec_fallback = 0;
647 u32 rts_rspec = 0, rts_rspec_fallback = 0;
648 u8 plcp0, plcp3, is40, sgi, mcs;
649 u16 mch;
650 u8 preamble_type = BRCMS_GF_PREAMBLE;
651 u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
652 u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
653 u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
666 654
667 if (rr) { 655 if (skb_queue_empty(&session->skb_list))
668 plcp0 = plcp[0]; 656 return;
669 plcp3 = plcp[3];
670 } else {
671 plcp0 = txh->FragPLCPFallback[0];
672 plcp3 = txh->FragPLCPFallback[3];
673 657
674 } 658 first = skb_peek(&session->skb_list);
675 is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; 659 last = skb_peek_tail(&session->skb_list);
676 sgi = plcp3_issgi(plcp3) ? 1 : 0; 660
677 mcs = plcp0 & ~MIMO_PLCP_40MHZ; 661 /* Need to fix up last MPDU first to adjust AMPDU length */
678 max_ampdu_bytes = 662 txh = (struct d11txh *)last->data;
679 min(scb_ampdu->max_rx_ampdu_bytes, 663 fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
680 ampdu->max_txlen[mcs][is40][sgi]); 664 f = &ampdu->fifo_tb[fifo];
681 665
682 if (is40) 666 mcl = le16_to_cpu(txh->MacTxControlLow);
683 mimo_ctlchbw = 667 mcl &= ~TXC_AMPDU_MASK;
684 CHSPEC_SB_UPPER(wlc_phy_chanspec_get( 668 mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
685 wlc->band->pi)) 669 txh->MacTxControlLow = cpu_to_le16(mcl);
686 ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; 670
687 671 /* remove the null delimiter after last mpdu */
688 /* rebuild the rspec and rspec_fallback */ 672 ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
689 rspec = RSPEC_MIMORATE; 673 txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
690 rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; 674 session->ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
691 if (plcp[0] & MIMO_PLCP_40MHZ) 675
692 rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); 676 /* remove the pad len from last mpdu */
693 677 fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
694 if (fbr_iscck) /* CCK */ 678 len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) :
695 rspec_fallback = cck_rspec(cck_phy2mac_rate 679 BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
696 (txh->FragPLCPFallback[0])); 680 session->ampdu_len -= roundup(len, 4) - len;
697 else { /* MIMO */ 681
698 rspec_fallback = RSPEC_MIMORATE; 682 /* Now fix up the first MPDU */
699 rspec_fallback |= 683 tx_info = IEEE80211_SKB_CB(first);
700 txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; 684 txrate = tx_info->status.rates;
701 if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) 685 txh = (struct d11txh *)first->data;
702 rspec_fallback |= 686 plcp = (u8 *)(txh + 1);
703 (PHY_TXC1_BW_40MHZ << 687 rts = (struct ieee80211_rts *)&txh->rts_frame;
704 RSPEC_BW_SHIFT); 688
705 } 689 mcl = le16_to_cpu(txh->MacTxControlLow);
690 /* If only one MPDU leave it marked as last */
691 if (first != last) {
692 mcl &= ~TXC_AMPDU_MASK;
693 mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
694 }
695 mcl |= TXC_STARTMSDU;
696 if (ieee80211_is_rts(rts->frame_control)) {
697 mcl |= TXC_SENDRTS;
698 use_rts = true;
699 }
700 if (ieee80211_is_cts(rts->frame_control)) {
701 mcl |= TXC_SENDCTS;
702 use_cts = true;
703 }
704 txh->MacTxControlLow = cpu_to_le16(mcl);
706 705
707 if (use_rts || use_cts) { 706 fbr = txrate[1].count > 0;
708 rts_rspec = 707 if (!fbr) {
709 brcms_c_rspec_to_rts_rspec(wlc, 708 plcp0 = plcp[0];
710 rspec, false, mimo_ctlchbw); 709 plcp3 = plcp[3];
711 rts_rspec_fallback = 710 } else {
712 brcms_c_rspec_to_rts_rspec(wlc, 711 plcp0 = txh->FragPLCPFallback[0];
713 rspec_fallback, false, mimo_ctlchbw); 712 plcp3 = txh->FragPLCPFallback[3];
714 } 713 }
715 } 714 is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
715 sgi = plcp3_issgi(plcp3) ? 1 : 0;
716 mcs = plcp0 & ~MIMO_PLCP_40MHZ;
717
718 if (is40) {
719 if (CHSPEC_SB_UPPER(wlc_phy_chanspec_get(wlc->band->pi)))
720 mimo_ctlchbw = PHY_TXC1_BW_20MHZ_UP;
721 else
722 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
723 }
716 724
717 /* if (first mpdu for host agg) */ 725 /* rebuild the rspec and rspec_fallback */
718 /* test whether to add more */ 726 rspec = RSPEC_MIMORATE;
719 if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) && 727 rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
720 (count == f->mcs2ampdu_table[mcs])) { 728 if (plcp[0] & MIMO_PLCP_40MHZ)
721 BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping" 729 rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
722 " ampdu at %d for mcs %d\n",
723 wlc->pub->unit, count, mcs);
724 break;
725 }
726 730
727 if (count == scb_ampdu->max_pdu) 731 fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03);
728 break; 732 if (fbr_iscck) {
733 rspec_fallback =
734 cck_rspec(cck_phy2mac_rate(txh->FragPLCPFallback[0]));
735 } else {
736 rspec_fallback = RSPEC_MIMORATE;
737 rspec_fallback |= txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
738 if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
739 rspec_fallback |= PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT;
740 }
729 741
730 /* 742 if (use_rts || use_cts) {
731 * check to see if the next pkt is 743 rts_rspec =
732 * a candidate for aggregation 744 brcms_c_rspec_to_rts_rspec(wlc, rspec,
733 */ 745 false, mimo_ctlchbw);
734 p = pktq_ppeek(&qi->q, prec); 746 rts_rspec_fallback =
735 if (p) { 747 brcms_c_rspec_to_rts_rspec(wlc, rspec_fallback,
736 tx_info = IEEE80211_SKB_CB(p); 748 false, mimo_ctlchbw);
737 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && 749 }
738 ((u8) (p->priority) == tid)) {
739 plen = p->len + AMPDU_MAX_MPDU_OVERHEAD;
740 plen = max(scb_ampdu->min_len, plen);
741 750
742 if ((plen + ampdu_len) > max_ampdu_bytes) { 751 BRCMS_SET_MIMO_PLCP_LEN(plcp, session->ampdu_len);
743 p = NULL; 752 /* mark plcp to indicate ampdu */
744 continue; 753 BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
745 }
746 754
747 /* 755 /* reset the mixed mode header durations */
748 * check if there are enough 756 if (txh->MModeLen) {
749 * descriptors available 757 u16 mmodelen = brcms_c_calc_lsig_len(wlc, rspec,
750 */ 758 session->ampdu_len);
751 if (*wlc->core->txavail[fifo] <= seg_cnt + 1) { 759 txh->MModeLen = cpu_to_le16(mmodelen);
752 wiphy_err(wiphy, "%s: No fifo space " 760 preamble_type = BRCMS_MM_PREAMBLE;
753 "!!\n", __func__); 761 }
754 p = NULL; 762 if (txh->MModeFbrLen) {
755 continue; 763 u16 mmfbrlen = brcms_c_calc_lsig_len(wlc, rspec_fallback,
756 } 764 session->ampdu_len);
757 /* next packet fit for aggregation so dequeue */ 765 txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
758 p = brcmu_pktq_pdeq(&qi->q, prec); 766 fbr_preamble_type = BRCMS_MM_PREAMBLE;
759 } else { 767 }
760 p = NULL;
761 }
762 }
763 } /* end while(p) */
764 768
765 ini->tx_in_transit += count; 769 /* set the preload length */
770 if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
771 dma_len = min(dma_len, f->ampdu_pld_size);
772 txh->PreloadSize = cpu_to_le16(dma_len);
773 } else {
774 txh->PreloadSize = 0;
775 }
766 776
767 if (count) { 777 mch = le16_to_cpu(txh->MacTxControlHigh);
768 /* patch up the last txh */
769 txh = (struct d11txh *) pkt[count - 1]->data;
770 mcl = le16_to_cpu(txh->MacTxControlLow);
771 mcl &= ~TXC_AMPDU_MASK;
772 mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
773 txh->MacTxControlLow = cpu_to_le16(mcl);
774
775 /* remove the null delimiter after last mpdu */
776 ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
777 txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
778 ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
779
780 /* remove the pad len from last mpdu */
781 fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
782 len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
783 : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
784 ampdu_len -= roundup(len, 4) - len;
785
786 /* patch up the first txh & plcp */
787 txh = (struct d11txh *) pkt[0]->data;
788 plcp = (u8 *) (txh + 1);
789 778
790 BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len); 779 /* update RTS dur fields */
791 /* mark plcp to indicate ampdu */ 780 if (use_rts || use_cts) {
792 BRCMS_SET_MIMO_PLCP_AMPDU(plcp); 781 u16 durid;
782 if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
783 TXC_PREAMBLE_RTS_MAIN_SHORT)
784 rts_preamble_type = BRCMS_SHORT_PREAMBLE;
793 785
794 /* reset the mixed mode header durations */ 786 if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
795 if (txh->MModeLen) { 787 TXC_PREAMBLE_RTS_FB_SHORT)
796 u16 mmodelen = 788 rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
797 brcms_c_calc_lsig_len(wlc, rspec, ampdu_len);
798 txh->MModeLen = cpu_to_le16(mmodelen);
799 preamble_type = BRCMS_MM_PREAMBLE;
800 }
801 if (txh->MModeFbrLen) {
802 u16 mmfbrlen =
803 brcms_c_calc_lsig_len(wlc, rspec_fallback,
804 ampdu_len);
805 txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
806 fbr_preamble_type = BRCMS_MM_PREAMBLE;
807 }
808 789
809 /* set the preload length */ 790 durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
810 if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
811 dma_len = min(dma_len, f->ampdu_pld_size);
812 txh->PreloadSize = cpu_to_le16(dma_len);
813 } else
814 txh->PreloadSize = 0;
815
816 mch = le16_to_cpu(txh->MacTxControlHigh);
817
818 /* update RTS dur fields */
819 if (use_rts || use_cts) {
820 u16 durid;
821 rts = (struct ieee80211_rts *)&txh->rts_frame;
822 if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
823 TXC_PREAMBLE_RTS_MAIN_SHORT)
824 rts_preamble_type = BRCMS_SHORT_PREAMBLE;
825
826 if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
827 TXC_PREAMBLE_RTS_FB_SHORT)
828 rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
829
830 durid =
831 brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
832 rspec, rts_preamble_type, 791 rspec, rts_preamble_type,
833 preamble_type, ampdu_len, 792 preamble_type,
834 true); 793 session->ampdu_len, true);
835 rts->duration = cpu_to_le16(durid); 794 rts->duration = cpu_to_le16(durid);
836 durid = brcms_c_compute_rtscts_dur(wlc, use_cts, 795 durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
837 rts_rspec_fallback, 796 rts_rspec_fallback,
838 rspec_fallback, 797 rspec_fallback,
839 rts_fbr_preamble_type, 798 rts_fbr_preamble_type,
840 fbr_preamble_type, 799 fbr_preamble_type,
841 ampdu_len, true); 800 session->ampdu_len, true);
842 txh->RTSDurFallback = cpu_to_le16(durid); 801 txh->RTSDurFallback = cpu_to_le16(durid);
843 /* set TxFesTimeNormal */ 802 /* set TxFesTimeNormal */
844 txh->TxFesTimeNormal = rts->duration; 803 txh->TxFesTimeNormal = rts->duration;
845 /* set fallback rate version of TxFesTimeNormal */ 804 /* set fallback rate version of TxFesTimeNormal */
846 txh->TxFesTimeFallback = txh->RTSDurFallback; 805 txh->TxFesTimeFallback = txh->RTSDurFallback;
847 } 806 }
848
849 /* set flag and plcp for fallback rate */
850 if (fbr) {
851 mch |= TXC_AMPDU_FBR;
852 txh->MacTxControlHigh = cpu_to_le16(mch);
853 BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
854 BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
855 }
856
857 BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
858 wlc->pub->unit, count, ampdu_len);
859
860 /* inform rate_sel if it this is a rate probe pkt */
861 frameid = le16_to_cpu(txh->TxFrameID);
862 if (frameid & TXFID_RATE_PROBE_MASK)
863 wiphy_err(wiphy, "%s: XXX what to do with "
864 "TXFID_RATE_PROBE_MASK!?\n", __func__);
865
866 for (i = 0; i < count; i++)
867 brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1),
868 ampdu->txpkt_weight);
869 807
808 /* set flag and plcp for fallback rate */
809 if (fbr) {
810 mch |= TXC_AMPDU_FBR;
811 txh->MacTxControlHigh = cpu_to_le16(mch);
812 BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
813 BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
870 } 814 }
871 /* endif (count) */ 815
872 return err; 816 brcms_dbg_ht(wlc->hw->d11core, "wl%d: count %d ampdu_len %d\n",
817 wlc->pub->unit, skb_queue_len(&session->skb_list),
818 session->ampdu_len);
873} 819}
874 820
875static void 821static void
@@ -909,7 +855,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
909 u8 antselid = 0; 855 u8 antselid = 0;
910 u8 retry_limit, rr_retry_limit; 856 u8 retry_limit, rr_retry_limit;
911 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); 857 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
912 struct wiphy *wiphy = wlc->wiphy;
913 858
914#ifdef DEBUG 859#ifdef DEBUG
915 u8 hole[AMPDU_MAX_MPDU]; 860 u8 hole[AMPDU_MAX_MPDU];
@@ -955,13 +900,14 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
955 if (supr_status) { 900 if (supr_status) {
956 update_rate = false; 901 update_rate = false;
957 if (supr_status == TX_STATUS_SUPR_BADCH) { 902 if (supr_status == TX_STATUS_SUPR_BADCH) {
958 wiphy_err(wiphy, 903 brcms_err(wlc->hw->d11core,
959 "%s: Pkt tx suppressed, illegal channel possibly %d\n", 904 "%s: Pkt tx suppressed, illegal channel possibly %d\n",
960 __func__, CHSPEC_CHANNEL( 905 __func__, CHSPEC_CHANNEL(
961 wlc->default_bss->chanspec)); 906 wlc->default_bss->chanspec));
962 } else { 907 } else {
963 if (supr_status != TX_STATUS_SUPR_FRAG) 908 if (supr_status != TX_STATUS_SUPR_FRAG)
964 wiphy_err(wiphy, "%s: supr_status 0x%x\n", 909 brcms_err(wlc->hw->d11core,
910 "%s: supr_status 0x%x\n",
965 __func__, supr_status); 911 __func__, supr_status);
966 } 912 }
967 /* no need to retry for badch; will fail again */ 913 /* no need to retry for badch; will fail again */
@@ -977,20 +923,14 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
977 * if there were underflows, but pre-loading 923 * if there were underflows, but pre-loading
978 * is not active, notify rate adaptation. 924 * is not active, notify rate adaptation.
979 */ 925 */
980 if (brcms_c_ffpld_check_txfunfl(wlc, 926 if (brcms_c_ffpld_check_txfunfl(wlc, queue) > 0)
981 prio2fifo[tid]) > 0)
982 tx_error = true; 927 tx_error = true;
983 } 928 }
984 } else if (txs->phyerr) { 929 } else if (txs->phyerr) {
985 update_rate = false; 930 update_rate = false;
986 wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n", 931 brcms_err(wlc->hw->d11core,
932 "%s: ampdu tx phy error (0x%x)\n",
987 __func__, txs->phyerr); 933 __func__, txs->phyerr);
988
989 if (brcm_msg_level & LOG_ERROR_VAL) {
990 brcmu_prpkt("txpkt (AMPDU)", p);
991 brcms_c_print_txdesc((struct d11txh *) p->data);
992 }
993 brcms_c_print_txstatus(txs);
994 } 934 }
995 } 935 }
996 936
@@ -1003,6 +943,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
1003 h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); 943 h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
1004 seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; 944 seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
1005 945
946 trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh));
947
1006 if (tot_mpdu == 0) { 948 if (tot_mpdu == 0) {
1007 mcs = plcp[0] & MIMO_PLCP_MCS_MASK; 949 mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
1008 mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel); 950 mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
@@ -1012,10 +954,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
1012 ack_recd = false; 954 ack_recd = false;
1013 if (ba_recd) { 955 if (ba_recd) {
1014 bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); 956 bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
1015 BCMMSG(wiphy, 957 brcms_dbg_ht(wlc->hw->d11core,
1016 "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", 958 "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
1017 tid, seq, start_seq, bindex, 959 tid, seq, start_seq, bindex,
1018 isset(bitmap, bindex), index); 960 isset(bitmap, bindex), index);
1019 /* if acked then clear bit and free packet */ 961 /* if acked then clear bit and free packet */
1020 if ((bindex < AMPDU_TX_BA_MAX_WSIZE) 962 if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
1021 && isset(bitmap, bindex)) { 963 && isset(bitmap, bindex)) {
@@ -1046,14 +988,16 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
1046 /* either retransmit or send bar if ack not recd */ 988 /* either retransmit or send bar if ack not recd */
1047 if (!ack_recd) { 989 if (!ack_recd) {
1048 if (retry && (ini->txretry[index] < (int)retry_limit)) { 990 if (retry && (ini->txretry[index] < (int)retry_limit)) {
991 int ret;
1049 ini->txretry[index]++; 992 ini->txretry[index]++;
1050 ini->tx_in_transit--; 993 ini->tx_in_transit--;
994 ret = brcms_c_txfifo(wlc, queue, p);
1051 /* 995 /*
1052 * Use high prededence for retransmit to 996 * We shouldn't be out of space in the DMA
1053 * give some punch 997 * ring here since we're reinserting a frame
998 * that was just pulled out.
1054 */ 999 */
1055 brcms_c_txq_enq(wlc, scb, p, 1000 WARN_ONCE(ret, "queue %d out of txds\n", queue);
1056 BRCMS_PRIO_TO_HI_PREC(tid));
1057 } else { 1001 } else {
1058 /* Retry timeout */ 1002 /* Retry timeout */
1059 ini->tx_in_transit--; 1003 ini->tx_in_transit--;
@@ -1064,9 +1008,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
1064 IEEE80211_TX_STAT_AMPDU_NO_BACK; 1008 IEEE80211_TX_STAT_AMPDU_NO_BACK;
1065 skb_pull(p, D11_PHY_HDR_LEN); 1009 skb_pull(p, D11_PHY_HDR_LEN);
1066 skb_pull(p, D11_TXH_LEN); 1010 skb_pull(p, D11_TXH_LEN);
1067 BCMMSG(wiphy, 1011 brcms_dbg_ht(wlc->hw->d11core,
1068 "BA Timeout, seq %d, in_transit %d\n", 1012 "BA Timeout, seq %d, in_transit %d\n",
1069 seq, ini->tx_in_transit); 1013 seq, ini->tx_in_transit);
1070 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, 1014 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1071 p); 1015 p);
1072 } 1016 }
@@ -1080,12 +1024,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
1080 1024
1081 p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); 1025 p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
1082 } 1026 }
1083 brcms_c_send_q(wlc);
1084 1027
1085 /* update rate state */ 1028 /* update rate state */
1086 antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel); 1029 antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
1087
1088 brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
1089} 1030}
1090 1031
1091void 1032void
@@ -1133,6 +1074,8 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
1133 while (p) { 1074 while (p) {
1134 tx_info = IEEE80211_SKB_CB(p); 1075 tx_info = IEEE80211_SKB_CB(p);
1135 txh = (struct d11txh *) p->data; 1076 txh = (struct d11txh *) p->data;
1077 trace_brcms_txdesc(&wlc->hw->d11core->dev, txh,
1078 sizeof(*txh));
1136 mcl = le16_to_cpu(txh->MacTxControlLow); 1079 mcl = le16_to_cpu(txh->MacTxControlLow);
1137 brcmu_pkt_buf_free_skb(p); 1080 brcmu_pkt_buf_free_skb(p);
1138 /* break out if last packet of ampdu */ 1081 /* break out if last packet of ampdu */
@@ -1142,7 +1085,6 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
1142 p = dma_getnexttxp(wlc->hw->di[queue], 1085 p = dma_getnexttxp(wlc->hw->di[queue],
1143 DMA_RANGE_TRANSMITTED); 1086 DMA_RANGE_TRANSMITTED);
1144 } 1087 }
1145 brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
1146 } 1088 }
1147} 1089}
1148 1090
@@ -1182,23 +1124,6 @@ void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
1182} 1124}
1183 1125
1184/* 1126/*
1185 * callback function that helps flushing ampdu packets from a priority queue
1186 */
1187static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
1188{
1189 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
1190 struct cb_del_ampdu_pars *ampdu_pars =
1191 (struct cb_del_ampdu_pars *)arg_a;
1192 bool rc;
1193
1194 rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
1195 rc = rc && (tx_info->rate_driver_data[0] == NULL || ampdu_pars->sta == NULL ||
1196 tx_info->rate_driver_data[0] == ampdu_pars->sta);
1197 rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
1198 return rc;
1199}
1200
1201/*
1202 * callback function that helps invalidating ampdu packets in a DMA queue 1127 * callback function that helps invalidating ampdu packets in a DMA queue
1203 */ 1128 */
1204static void dma_cb_fn_ampdu(void *txi, void *arg_a) 1129static void dma_cb_fn_ampdu(void *txi, void *arg_a)
@@ -1218,15 +1143,5 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a)
1218void brcms_c_ampdu_flush(struct brcms_c_info *wlc, 1143void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
1219 struct ieee80211_sta *sta, u16 tid) 1144 struct ieee80211_sta *sta, u16 tid)
1220{ 1145{
1221 struct brcms_txq_info *qi = wlc->pkt_queue;
1222 struct pktq *pq = &qi->q;
1223 int prec;
1224 struct cb_del_ampdu_pars ampdu_pars;
1225
1226 ampdu_pars.sta = sta;
1227 ampdu_pars.tid = tid;
1228 for (prec = 0; prec < pq->num_prec; prec++)
1229 brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
1230 (void *)&ampdu_pars);
1231 brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); 1146 brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
1232} 1147}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
index 421f4ba7c63..73d01e58610 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
@@ -17,11 +17,34 @@
17#ifndef _BRCM_AMPDU_H_ 17#ifndef _BRCM_AMPDU_H_
18#define _BRCM_AMPDU_H_ 18#define _BRCM_AMPDU_H_
19 19
20/*
21 * Data structure representing an in-progress session for accumulating
22 * frames for AMPDU.
23 *
24 * wlc: pointer to common driver data
25 * skb_list: queue of skb's for AMPDU
26 * max_ampdu_len: maximum length for this AMPDU
27 * max_ampdu_frames: maximum number of frames for this AMPDU
28 * ampdu_len: total number of bytes accumulated for this AMPDU
29 * dma_len: DMA length of this AMPDU
30 */
31struct brcms_ampdu_session {
32 struct brcms_c_info *wlc;
33 struct sk_buff_head skb_list;
34 unsigned max_ampdu_len;
35 u16 max_ampdu_frames;
36 u16 ampdu_len;
37 u16 dma_len;
38};
39
40extern void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session,
41 struct brcms_c_info *wlc);
42extern int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session,
43 struct sk_buff *p);
44extern void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session);
45
20extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); 46extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
21extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu); 47extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
22extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
23 struct brcms_txq_info *qi,
24 struct sk_buff **aggp, int prec);
25extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, 48extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
26 struct sk_buff *p, struct tx_status *txs); 49 struct sk_buff *p, struct tx_status *txs);
27extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); 50extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
index 55e12c32791..54c61691959 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
@@ -21,6 +21,7 @@
21#include "main.h" 21#include "main.h"
22#include "phy_shim.h" 22#include "phy_shim.h"
23#include "antsel.h" 23#include "antsel.h"
24#include "debug.h"
24 25
25#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ 26#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */
26#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ 27#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */
@@ -137,7 +138,8 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
137 asi->antsel_avail = false; 138 asi->antsel_avail = false;
138 } else { 139 } else {
139 asi->antsel_avail = false; 140 asi->antsel_avail = false;
140 wiphy_err(wlc->wiphy, "antsel_attach: 2o3 " 141 brcms_err(wlc->hw->d11core,
142 "antsel_attach: 2o3 "
141 "board cfg invalid\n"); 143 "board cfg invalid\n");
142 } 144 }
143 145
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
index 27dd73eef56..871781e6a71 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
@@ -14,22 +14,29 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#undef TRACE_SYSTEM
18#define TRACE_SYSTEM brcmsmac
19
20#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ) 17#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ)
21 18
22#define __TRACE_BRCMSMAC_H 19#define __TRACE_BRCMSMAC_H
23 20
21#include <linux/types.h>
22#include <linux/device.h>
24#include <linux/tracepoint.h> 23#include <linux/tracepoint.h>
25#include "mac80211_if.h" 24#include "mac80211_if.h"
26 25
27#ifndef CONFIG_BRCMDBG 26#ifndef CONFIG_BRCM_TRACING
28#undef TRACE_EVENT 27#undef TRACE_EVENT
29#define TRACE_EVENT(name, proto, ...) \ 28#define TRACE_EVENT(name, proto, ...) \
30static inline void trace_ ## name(proto) {} 29static inline void trace_ ## name(proto) {}
30#undef DECLARE_EVENT_CLASS
31#define DECLARE_EVENT_CLASS(...)
32#undef DEFINE_EVENT
33#define DEFINE_EVENT(evt_class, name, proto, ...) \
34static inline void trace_ ## name(proto) {}
31#endif 35#endif
32 36
37#undef TRACE_SYSTEM
38#define TRACE_SYSTEM brcmsmac
39
33/* 40/*
34 * We define a tracepoint, its arguments, its printk format and its 41 * We define a tracepoint, its arguments, its printk format and its
35 * 'fast binary record' layout. 42 * 'fast binary record' layout.
@@ -78,9 +85,165 @@ TRACE_EVENT(brcms_dpc,
78 ) 85 )
79); 86);
80 87
88TRACE_EVENT(brcms_macintstatus,
89 TP_PROTO(const struct device *dev, int in_isr, u32 macintstatus,
90 u32 mask),
91 TP_ARGS(dev, in_isr, macintstatus, mask),
92 TP_STRUCT__entry(
93 __string(dev, dev_name(dev))
94 __field(int, in_isr)
95 __field(u32, macintstatus)
96 __field(u32, mask)
97 ),
98 TP_fast_assign(
99 __assign_str(dev, dev_name(dev));
100 __entry->in_isr = in_isr;
101 __entry->macintstatus = macintstatus;
102 __entry->mask = mask;
103 ),
104 TP_printk("[%s] in_isr=%d macintstatus=%#x mask=%#x", __get_str(dev),
105 __entry->in_isr, __entry->macintstatus, __entry->mask)
106);
107
108#undef TRACE_SYSTEM
109#define TRACE_SYSTEM brcmsmac_tx
110
111TRACE_EVENT(brcms_txdesc,
112 TP_PROTO(const struct device *dev,
113 void *txh, size_t txh_len),
114 TP_ARGS(dev, txh, txh_len),
115 TP_STRUCT__entry(
116 __string(dev, dev_name(dev))
117 __dynamic_array(u8, txh, txh_len)
118 ),
119 TP_fast_assign(
120 __assign_str(dev, dev_name(dev));
121 memcpy(__get_dynamic_array(txh), txh, txh_len);
122 ),
123 TP_printk("[%s] txdesc", __get_str(dev))
124);
125
126TRACE_EVENT(brcms_txstatus,
127 TP_PROTO(const struct device *dev, u16 framelen, u16 frameid,
128 u16 status, u16 lasttxtime, u16 sequence, u16 phyerr,
129 u16 ackphyrxsh),
130 TP_ARGS(dev, framelen, frameid, status, lasttxtime, sequence, phyerr,
131 ackphyrxsh),
132 TP_STRUCT__entry(
133 __string(dev, dev_name(dev))
134 __field(u16, framelen)
135 __field(u16, frameid)
136 __field(u16, status)
137 __field(u16, lasttxtime)
138 __field(u16, sequence)
139 __field(u16, phyerr)
140 __field(u16, ackphyrxsh)
141 ),
142 TP_fast_assign(
143 __assign_str(dev, dev_name(dev));
144 __entry->framelen = framelen;
145 __entry->frameid = frameid;
146 __entry->status = status;
147 __entry->lasttxtime = lasttxtime;
148 __entry->sequence = sequence;
149 __entry->phyerr = phyerr;
150 __entry->ackphyrxsh = ackphyrxsh;
151 ),
152 TP_printk("[%s] FrameId %#04x TxStatus %#04x LastTxTime %#04x "
153 "Seq %#04x PHYTxStatus %#04x RxAck %#04x",
154 __get_str(dev), __entry->frameid, __entry->status,
155 __entry->lasttxtime, __entry->sequence, __entry->phyerr,
156 __entry->ackphyrxsh)
157);
158
159TRACE_EVENT(brcms_ampdu_session,
160 TP_PROTO(const struct device *dev, unsigned max_ampdu_len,
161 u16 max_ampdu_frames, u16 ampdu_len, u16 ampdu_frames,
162 u16 dma_len),
163 TP_ARGS(dev, max_ampdu_len, max_ampdu_frames, ampdu_len, ampdu_frames,
164 dma_len),
165 TP_STRUCT__entry(
166 __string(dev, dev_name(dev))
167 __field(unsigned, max_ampdu_len)
168 __field(u16, max_ampdu_frames)
169 __field(u16, ampdu_len)
170 __field(u16, ampdu_frames)
171 __field(u16, dma_len)
172 ),
173 TP_fast_assign(
174 __assign_str(dev, dev_name(dev));
175 __entry->max_ampdu_len = max_ampdu_len;
176 __entry->max_ampdu_frames = max_ampdu_frames;
177 __entry->ampdu_len = ampdu_len;
178 __entry->ampdu_frames = ampdu_frames;
179 __entry->dma_len = dma_len;
180 ),
181 TP_printk("[%s] ampdu session max_len=%u max_frames=%u len=%u frames=%u dma_len=%u",
182 __get_str(dev), __entry->max_ampdu_len,
183 __entry->max_ampdu_frames, __entry->ampdu_len,
184 __entry->ampdu_frames, __entry->dma_len)
185);
186
187#undef TRACE_SYSTEM
188#define TRACE_SYSTEM brcmsmac_msg
189
190#define MAX_MSG_LEN 100
191
192DECLARE_EVENT_CLASS(brcms_msg_event,
193 TP_PROTO(struct va_format *vaf),
194 TP_ARGS(vaf),
195 TP_STRUCT__entry(
196 __dynamic_array(char, msg, MAX_MSG_LEN)
197 ),
198 TP_fast_assign(
199 WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
200 MAX_MSG_LEN, vaf->fmt,
201 *vaf->va) >= MAX_MSG_LEN);
202 ),
203 TP_printk("%s", __get_str(msg))
204);
205
206DEFINE_EVENT(brcms_msg_event, brcms_info,
207 TP_PROTO(struct va_format *vaf),
208 TP_ARGS(vaf)
209);
210
211DEFINE_EVENT(brcms_msg_event, brcms_warn,
212 TP_PROTO(struct va_format *vaf),
213 TP_ARGS(vaf)
214);
215
216DEFINE_EVENT(brcms_msg_event, brcms_err,
217 TP_PROTO(struct va_format *vaf),
218 TP_ARGS(vaf)
219);
220
221DEFINE_EVENT(brcms_msg_event, brcms_crit,
222 TP_PROTO(struct va_format *vaf),
223 TP_ARGS(vaf)
224);
225
226TRACE_EVENT(brcms_dbg,
227 TP_PROTO(u32 level, const char *func, struct va_format *vaf),
228 TP_ARGS(level, func, vaf),
229 TP_STRUCT__entry(
230 __field(u32, level)
231 __string(func, func)
232 __dynamic_array(char, msg, MAX_MSG_LEN)
233 ),
234 TP_fast_assign(
235 __entry->level = level;
236 __assign_str(func, func);
237 WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
238 MAX_MSG_LEN, vaf->fmt,
239 *vaf->va) >= MAX_MSG_LEN);
240 ),
241 TP_printk("%s: %s", __get_str(func), __get_str(msg))
242);
243
81#endif /* __TRACE_BRCMSMAC_H */ 244#endif /* __TRACE_BRCMSMAC_H */
82 245
83#ifdef CONFIG_BRCMDBG 246#ifdef CONFIG_BRCM_TRACING
84 247
85#undef TRACE_INCLUDE_PATH 248#undef TRACE_INCLUDE_PATH
86#define TRACE_INCLUDE_PATH . 249#define TRACE_INCLUDE_PATH .
@@ -89,4 +252,4 @@ TRACE_EVENT(brcms_dpc,
89 252
90#include <trace/define_trace.h> 253#include <trace/define_trace.h>
91 254
92#endif /* CONFIG_BRCMDBG */ 255#endif /* CONFIG_BRCM_TRACING */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
index 64a48f06d68..a90b72202ec 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
@@ -26,6 +26,7 @@
26#include "stf.h" 26#include "stf.h"
27#include "channel.h" 27#include "channel.h"
28#include "mac80211_if.h" 28#include "mac80211_if.h"
29#include "debug.h"
29 30
30/* QDB() macro takes a dB value and converts to a quarter dB value */ 31/* QDB() macro takes a dB value and converts to a quarter dB value */
31#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) 32#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
@@ -336,8 +337,6 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
336 const char *ccode = sprom->alpha2; 337 const char *ccode = sprom->alpha2;
337 int ccode_len = sizeof(sprom->alpha2); 338 int ccode_len = sizeof(sprom->alpha2);
338 339
339 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
340
341 wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); 340 wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
342 if (wlc_cm == NULL) 341 if (wlc_cm == NULL)
343 return NULL; 342 return NULL;
@@ -615,8 +614,8 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec)
615 614
616 /* check the chanspec */ 615 /* check the chanspec */
617 if (brcms_c_chspec_malformed(chspec)) { 616 if (brcms_c_chspec_malformed(chspec)) {
618 wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n", 617 brcms_err(wlc->hw->d11core, "wl%d: malformed chanspec 0x%x\n",
619 wlc->pub->unit, chspec); 618 wlc->pub->unit, chspec);
620 return false; 619 return false;
621 } 620 }
622 621
@@ -738,7 +737,8 @@ static int brcms_reg_notifier(struct wiphy *wiphy,
738 mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); 737 mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
739 } else { 738 } else {
740 mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); 739 mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
741 wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\"\n", 740 brcms_err(wlc->hw->d11core,
741 "wl%d: %s: no valid channel for \"%s\"\n",
742 wlc->pub->unit, __func__, request->alpha2); 742 wlc->pub->unit, __func__, request->alpha2);
743 } 743 }
744 744
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/brcm80211/brcmsmac/debug.c
new file mode 100644
index 00000000000..6ba4136c7cf
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.c
@@ -0,0 +1,44 @@
1#include <linux/net.h>
2#include "types.h"
3#include "debug.h"
4#include "brcms_trace_events.h"
5
6#define __brcms_fn(fn) \
7void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \
8{ \
9 struct va_format vaf = { \
10 .fmt = fmt, \
11 }; \
12 va_list args; \
13 \
14 va_start(args, fmt); \
15 vaf.va = &args; \
16 dev_ ##fn(dev, "%pV", &vaf); \
17 trace_brcms_ ##fn(&vaf); \
18 va_end(args); \
19}
20
21__brcms_fn(info)
22__brcms_fn(warn)
23__brcms_fn(err)
24__brcms_fn(crit)
25
26#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING)
27void __brcms_dbg(struct device *dev, u32 level, const char *func,
28 const char *fmt, ...)
29{
30 struct va_format vaf = {
31 .fmt = fmt,
32 };
33 va_list args;
34
35 va_start(args, fmt);
36 vaf.va = &args;
37#ifdef CONFIG_BRCMDBG
38 if ((brcm_msg_level & level) && net_ratelimit())
39 dev_err(dev, "%s %pV", func, &vaf);
40#endif
41 trace_brcms_dbg(level, func, &vaf);
42 va_end(args);
43}
44#endif
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
new file mode 100644
index 00000000000..f77066bda9d
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
@@ -0,0 +1,52 @@
1#ifndef _BRCMS_DEBUG_H_
2#define _BRCMS_DEBUG_H_
3
4#include <linux/device.h>
5#include <linux/bcma/bcma.h>
6#include <net/cfg80211.h>
7#include <net/mac80211.h>
8#include "main.h"
9#include "mac80211_if.h"
10
11__printf(2, 3)
12void __brcms_info(struct device *dev, const char *fmt, ...);
13__printf(2, 3)
14void __brcms_warn(struct device *dev, const char *fmt, ...);
15__printf(2, 3)
16void __brcms_err(struct device *dev, const char *fmt, ...);
17__printf(2, 3)
18void __brcms_crit(struct device *dev, const char *fmt, ...);
19
20#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING)
21__printf(4, 5)
22void __brcms_dbg(struct device *dev, u32 level, const char *func,
23 const char *fmt, ...);
24#else
25static inline __printf(4, 5)
26void __brcms_dbg(struct device *dev, u32 level, const char *func,
27 const char *fmt, ...)
28{
29}
30#endif
31
32/*
33 * Debug macros cannot be used when wlc is uninitialized. Generally
34 * this means any code that could run before brcms_c_attach() has
35 * returned successfully probably shouldn't use the following macros.
36 */
37
38#define brcms_dbg(core, l, f, a...) __brcms_dbg(&(core)->dev, l, __func__, f, ##a)
39#define brcms_info(core, f, a...) __brcms_info(&(core)->dev, f, ##a)
40#define brcms_warn(core, f, a...) __brcms_warn(&(core)->dev, f, ##a)
41#define brcms_err(core, f, a...) __brcms_err(&(core)->dev, f, ##a)
42#define brcms_crit(core, f, a...) __brcms_crit(&(core)->dev, f, ##a)
43
44#define brcms_dbg_info(core, f, a...) brcms_dbg(core, BRCM_DL_INFO, f, ##a)
45#define brcms_dbg_mac80211(core, f, a...) brcms_dbg(core, BRCM_DL_MAC80211, f, ##a)
46#define brcms_dbg_rx(core, f, a...) brcms_dbg(core, BRCM_DL_RX, f, ##a)
47#define brcms_dbg_tx(core, f, a...) brcms_dbg(core, BRCM_DL_TX, f, ##a)
48#define brcms_dbg_int(core, f, a...) brcms_dbg(core, BRCM_DL_INT, f, ##a)
49#define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a)
50#define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a)
51
52#endif /* _BRCMS_DEBUG_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index 5e53305bd9a..511e45775c3 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -14,17 +14,22 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19#include <linux/slab.h> 17#include <linux/slab.h>
20#include <linux/delay.h> 18#include <linux/delay.h>
21#include <linux/pci.h> 19#include <linux/pci.h>
20#include <net/cfg80211.h>
21#include <net/mac80211.h>
22 22
23#include <brcmu_utils.h> 23#include <brcmu_utils.h>
24#include <aiutils.h> 24#include <aiutils.h>
25#include "types.h" 25#include "types.h"
26#include "main.h"
26#include "dma.h" 27#include "dma.h"
27#include "soc.h" 28#include "soc.h"
29#include "scb.h"
30#include "ampdu.h"
31#include "debug.h"
32#include "brcms_trace_events.h"
28 33
29/* 34/*
30 * dma register field offset calculation 35 * dma register field offset calculation
@@ -176,28 +181,6 @@
176 181
177#define BCMEXTRAHDROOM 172 182#define BCMEXTRAHDROOM 172
178 183
179/* debug/trace */
180#ifdef DEBUG
181#define DMA_ERROR(fmt, ...) \
182do { \
183 if (*di->msg_level & 1) \
184 pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
185} while (0)
186#define DMA_TRACE(fmt, ...) \
187do { \
188 if (*di->msg_level & 2) \
189 pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
190} while (0)
191#else
192#define DMA_ERROR(fmt, ...) \
193 no_printk(fmt, ##__VA_ARGS__)
194#define DMA_TRACE(fmt, ...) \
195 no_printk(fmt, ##__VA_ARGS__)
196#endif /* DEBUG */
197
198#define DMA_NONE(fmt, ...) \
199 no_printk(fmt, ##__VA_ARGS__)
200
201#define MAXNAMEL 8 /* 8 char names */ 184#define MAXNAMEL 8 /* 8 char names */
202 185
203/* macros to convert between byte offsets and indexes */ 186/* macros to convert between byte offsets and indexes */
@@ -224,12 +207,14 @@ struct dma64desc {
224/* dma engine software state */ 207/* dma engine software state */
225struct dma_info { 208struct dma_info {
226 struct dma_pub dma; /* exported structure */ 209 struct dma_pub dma; /* exported structure */
227 uint *msg_level; /* message level pointer */
228 char name[MAXNAMEL]; /* callers name for diag msgs */ 210 char name[MAXNAMEL]; /* callers name for diag msgs */
229 211
230 struct bcma_device *core; 212 struct bcma_device *core;
231 struct device *dmadev; 213 struct device *dmadev;
232 214
215 /* session information for AMPDU */
216 struct brcms_ampdu_session ampdu_session;
217
233 bool dma64; /* this dma engine is operating in 64-bit mode */ 218 bool dma64; /* this dma engine is operating in 64-bit mode */
234 bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ 219 bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
235 220
@@ -298,12 +283,6 @@ struct dma_info {
298 bool aligndesc_4k; 283 bool aligndesc_4k;
299}; 284};
300 285
301/*
302 * default dma message level (if input msg_level
303 * pointer is null in dma_attach())
304 */
305static uint dma_msg_level;
306
307/* Check for odd number of 1's */ 286/* Check for odd number of 1's */
308static u32 parity32(__le32 data) 287static u32 parity32(__le32 data)
309{ 288{
@@ -353,7 +332,7 @@ static uint prevtxd(struct dma_info *di, uint i)
353 332
354static uint nextrxd(struct dma_info *di, uint i) 333static uint nextrxd(struct dma_info *di, uint i)
355{ 334{
356 return txd(di, i + 1); 335 return rxd(di, i + 1);
357} 336}
358 337
359static uint ntxdactive(struct dma_info *di, uint h, uint t) 338static uint ntxdactive(struct dma_info *di, uint h, uint t)
@@ -371,7 +350,7 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
371 uint dmactrlflags; 350 uint dmactrlflags;
372 351
373 if (di == NULL) { 352 if (di == NULL) {
374 DMA_ERROR("NULL dma handle\n"); 353 brcms_dbg_dma(di->core, "NULL dma handle\n");
375 return 0; 354 return 0;
376 } 355 }
377 356
@@ -423,13 +402,15 @@ static bool _dma_isaddrext(struct dma_info *di)
423 /* not all tx or rx channel are available */ 402 /* not all tx or rx channel are available */
424 if (di->d64txregbase != 0) { 403 if (di->d64txregbase != 0) {
425 if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control))) 404 if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control)))
426 DMA_ERROR("%s: DMA64 tx doesn't have AE set\n", 405 brcms_dbg_dma(di->core,
427 di->name); 406 "%s: DMA64 tx doesn't have AE set\n",
407 di->name);
428 return true; 408 return true;
429 } else if (di->d64rxregbase != 0) { 409 } else if (di->d64rxregbase != 0) {
430 if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control))) 410 if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control)))
431 DMA_ERROR("%s: DMA64 rx doesn't have AE set\n", 411 brcms_dbg_dma(di->core,
432 di->name); 412 "%s: DMA64 rx doesn't have AE set\n",
413 di->name);
433 return true; 414 return true;
434 } 415 }
435 416
@@ -530,8 +511,9 @@ static bool dma64_alloc(struct dma_info *di, uint direction)
530 va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, 511 va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
531 &alloced, &di->txdpaorig); 512 &alloced, &di->txdpaorig);
532 if (va == NULL) { 513 if (va == NULL) {
533 DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n", 514 brcms_dbg_dma(di->core,
534 di->name); 515 "%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
516 di->name);
535 return false; 517 return false;
536 } 518 }
537 align = (1 << align_bits); 519 align = (1 << align_bits);
@@ -544,8 +526,9 @@ static bool dma64_alloc(struct dma_info *di, uint direction)
544 va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, 526 va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
545 &alloced, &di->rxdpaorig); 527 &alloced, &di->rxdpaorig);
546 if (va == NULL) { 528 if (va == NULL) {
547 DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n", 529 brcms_dbg_dma(di->core,
548 di->name); 530 "%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
531 di->name);
549 return false; 532 return false;
550 } 533 }
551 align = (1 << align_bits); 534 align = (1 << align_bits);
@@ -564,12 +547,13 @@ static bool _dma_alloc(struct dma_info *di, uint direction)
564 return dma64_alloc(di, direction); 547 return dma64_alloc(di, direction);
565} 548}
566 549
567struct dma_pub *dma_attach(char *name, struct si_pub *sih, 550struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
568 struct bcma_device *core,
569 uint txregbase, uint rxregbase, uint ntxd, uint nrxd, 551 uint txregbase, uint rxregbase, uint ntxd, uint nrxd,
570 uint rxbufsize, int rxextheadroom, 552 uint rxbufsize, int rxextheadroom,
571 uint nrxpost, uint rxoffset, uint *msg_level) 553 uint nrxpost, uint rxoffset)
572{ 554{
555 struct si_pub *sih = wlc->hw->sih;
556 struct bcma_device *core = wlc->hw->d11core;
573 struct dma_info *di; 557 struct dma_info *di;
574 u8 rev = core->id.rev; 558 u8 rev = core->id.rev;
575 uint size; 559 uint size;
@@ -580,9 +564,6 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
580 if (di == NULL) 564 if (di == NULL)
581 return NULL; 565 return NULL;
582 566
583 di->msg_level = msg_level ? msg_level : &dma_msg_level;
584
585
586 di->dma64 = 567 di->dma64 =
587 ((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64); 568 ((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64);
588 569
@@ -598,11 +579,11 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
598 */ 579 */
599 _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); 580 _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0);
600 581
601 DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d " 582 brcms_dbg_dma(di->core, "%s: %s flags 0x%x ntxd %d nrxd %d "
602 "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " 583 "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
603 "txregbase %u rxregbase %u\n", name, "DMA64", 584 "txregbase %u rxregbase %u\n", name, "DMA64",
604 di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, 585 di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
605 rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase); 586 rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase);
606 587
607 /* make a private copy of our callers name */ 588 /* make a private copy of our callers name */
608 strncpy(di->name, name, MAXNAMEL); 589 strncpy(di->name, name, MAXNAMEL);
@@ -664,8 +645,8 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
664 di->dmadesc_align = 4; /* 16 byte alignment */ 645 di->dmadesc_align = 4; /* 16 byte alignment */
665 } 646 }
666 647
667 DMA_NONE("DMA descriptor align_needed %d, align %d\n", 648 brcms_dbg_dma(di->core, "DMA descriptor align_needed %d, align %d\n",
668 di->aligndesc_4k, di->dmadesc_align); 649 di->aligndesc_4k, di->dmadesc_align);
669 650
670 /* allocate tx packet pointer vector */ 651 /* allocate tx packet pointer vector */
671 if (ntxd) { 652 if (ntxd) {
@@ -703,21 +684,27 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
703 684
704 if ((di->ddoffsetlow != 0) && !di->addrext) { 685 if ((di->ddoffsetlow != 0) && !di->addrext) {
705 if (di->txdpa > SI_PCI_DMA_SZ) { 686 if (di->txdpa > SI_PCI_DMA_SZ) {
706 DMA_ERROR("%s: txdpa 0x%x: addrext not supported\n", 687 brcms_dbg_dma(di->core,
707 di->name, (u32)di->txdpa); 688 "%s: txdpa 0x%x: addrext not supported\n",
689 di->name, (u32)di->txdpa);
708 goto fail; 690 goto fail;
709 } 691 }
710 if (di->rxdpa > SI_PCI_DMA_SZ) { 692 if (di->rxdpa > SI_PCI_DMA_SZ) {
711 DMA_ERROR("%s: rxdpa 0x%x: addrext not supported\n", 693 brcms_dbg_dma(di->core,
712 di->name, (u32)di->rxdpa); 694 "%s: rxdpa 0x%x: addrext not supported\n",
695 di->name, (u32)di->rxdpa);
713 goto fail; 696 goto fail;
714 } 697 }
715 } 698 }
716 699
717 DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n", 700 /* Initialize AMPDU session */
718 di->ddoffsetlow, di->ddoffsethigh, 701 brcms_c_ampdu_reset_session(&di->ampdu_session, wlc);
719 di->dataoffsetlow, di->dataoffsethigh, 702
720 di->addrext); 703 brcms_dbg_dma(di->core,
704 "ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n",
705 di->ddoffsetlow, di->ddoffsethigh,
706 di->dataoffsetlow, di->dataoffsethigh,
707 di->addrext);
721 708
722 return (struct dma_pub *) di; 709 return (struct dma_pub *) di;
723 710
@@ -763,7 +750,7 @@ void dma_detach(struct dma_pub *pub)
763{ 750{
764 struct dma_info *di = (struct dma_info *)pub; 751 struct dma_info *di = (struct dma_info *)pub;
765 752
766 DMA_TRACE("%s:\n", di->name); 753 brcms_dbg_dma(di->core, "%s:\n", di->name);
767 754
768 /* free dma descriptor rings */ 755 /* free dma descriptor rings */
769 if (di->txd64) 756 if (di->txd64)
@@ -839,7 +826,7 @@ static void _dma_rxenable(struct dma_info *di)
839 uint dmactrlflags = di->dma.dmactrlflags; 826 uint dmactrlflags = di->dma.dmactrlflags;
840 u32 control; 827 u32 control;
841 828
842 DMA_TRACE("%s:\n", di->name); 829 brcms_dbg_dma(di->core, "%s:\n", di->name);
843 830
844 control = D64_RC_RE | (bcma_read32(di->core, 831 control = D64_RC_RE | (bcma_read32(di->core,
845 DMA64RXREGOFFS(di, control)) & 832 DMA64RXREGOFFS(di, control)) &
@@ -859,7 +846,7 @@ void dma_rxinit(struct dma_pub *pub)
859{ 846{
860 struct dma_info *di = (struct dma_info *)pub; 847 struct dma_info *di = (struct dma_info *)pub;
861 848
862 DMA_TRACE("%s:\n", di->name); 849 brcms_dbg_dma(di->core, "%s:\n", di->name);
863 850
864 if (di->nrxd == 0) 851 if (di->nrxd == 0)
865 return; 852 return;
@@ -954,7 +941,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
954 return 0; 941 return 0;
955 942
956 len = le16_to_cpu(*(__le16 *) (p->data)); 943 len = le16_to_cpu(*(__le16 *) (p->data));
957 DMA_TRACE("%s: dma_rx len %d\n", di->name, len); 944 brcms_dbg_dma(di->core, "%s: dma_rx len %d\n", di->name, len);
958 dma_spin_for_len(len, p); 945 dma_spin_for_len(len, p);
959 946
960 /* set actual length */ 947 /* set actual length */
@@ -981,14 +968,15 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
981 DMA64RXREGOFFS(di, status0)) & 968 DMA64RXREGOFFS(di, status0)) &
982 D64_RS0_CD_MASK) - di->rcvptrbase) & 969 D64_RS0_CD_MASK) - di->rcvptrbase) &
983 D64_RS0_CD_MASK, struct dma64desc); 970 D64_RS0_CD_MASK, struct dma64desc);
984 DMA_ERROR("rxin %d rxout %d, hw_curr %d\n", 971 brcms_dbg_dma(di->core,
985 di->rxin, di->rxout, cur); 972 "rxin %d rxout %d, hw_curr %d\n",
973 di->rxin, di->rxout, cur);
986 } 974 }
987#endif /* DEBUG */ 975#endif /* DEBUG */
988 976
989 if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { 977 if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
990 DMA_ERROR("%s: bad frame length (%d)\n", 978 brcms_dbg_dma(di->core, "%s: bad frame length (%d)\n",
991 di->name, len); 979 di->name, len);
992 skb_queue_walk_safe(&dma_frames, p, next) { 980 skb_queue_walk_safe(&dma_frames, p, next) {
993 skb_unlink(p, &dma_frames); 981 skb_unlink(p, &dma_frames);
994 brcmu_pkt_buf_free_skb(p); 982 brcmu_pkt_buf_free_skb(p);
@@ -1005,7 +993,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
1005 993
1006static bool dma64_rxidle(struct dma_info *di) 994static bool dma64_rxidle(struct dma_info *di)
1007{ 995{
1008 DMA_TRACE("%s:\n", di->name); 996 brcms_dbg_dma(di->core, "%s:\n", di->name);
1009 997
1010 if (di->nrxd == 0) 998 if (di->nrxd == 0)
1011 return true; 999 return true;
@@ -1016,6 +1004,17 @@ static bool dma64_rxidle(struct dma_info *di)
1016 D64_RS0_CD_MASK)); 1004 D64_RS0_CD_MASK));
1017} 1005}
1018 1006
1007static bool dma64_txidle(struct dma_info *di)
1008{
1009 if (di->ntxd == 0)
1010 return true;
1011
1012 return ((bcma_read32(di->core,
1013 DMA64TXREGOFFS(di, status0)) & D64_XS0_CD_MASK) ==
1014 (bcma_read32(di->core, DMA64TXREGOFFS(di, ptr)) &
1015 D64_XS0_CD_MASK));
1016}
1017
1019/* 1018/*
1020 * post receive buffers 1019 * post receive buffers
1021 * return false is refill failed completely and ring is empty this will stall 1020 * return false is refill failed completely and ring is empty this will stall
@@ -1047,7 +1046,7 @@ bool dma_rxfill(struct dma_pub *pub)
1047 1046
1048 n = di->nrxpost - nrxdactive(di, rxin, rxout); 1047 n = di->nrxpost - nrxdactive(di, rxin, rxout);
1049 1048
1050 DMA_TRACE("%s: post %d\n", di->name, n); 1049 brcms_dbg_dma(di->core, "%s: post %d\n", di->name, n);
1051 1050
1052 if (di->rxbufsize > BCMEXTRAHDROOM) 1051 if (di->rxbufsize > BCMEXTRAHDROOM)
1053 extra_offset = di->rxextrahdrroom; 1052 extra_offset = di->rxextrahdrroom;
@@ -1060,9 +1059,11 @@ bool dma_rxfill(struct dma_pub *pub)
1060 p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); 1059 p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset);
1061 1060
1062 if (p == NULL) { 1061 if (p == NULL) {
1063 DMA_ERROR("%s: out of rxbufs\n", di->name); 1062 brcms_dbg_dma(di->core, "%s: out of rxbufs\n",
1063 di->name);
1064 if (i == 0 && dma64_rxidle(di)) { 1064 if (i == 0 && dma64_rxidle(di)) {
1065 DMA_ERROR("%s: ring is empty !\n", di->name); 1065 brcms_dbg_dma(di->core, "%s: ring is empty !\n",
1066 di->name);
1066 ring_empty = true; 1067 ring_empty = true;
1067 } 1068 }
1068 di->dma.rxnobuf++; 1069 di->dma.rxnobuf++;
@@ -1107,7 +1108,7 @@ void dma_rxreclaim(struct dma_pub *pub)
1107 struct dma_info *di = (struct dma_info *)pub; 1108 struct dma_info *di = (struct dma_info *)pub;
1108 struct sk_buff *p; 1109 struct sk_buff *p;
1109 1110
1110 DMA_TRACE("%s:\n", di->name); 1111 brcms_dbg_dma(di->core, "%s:\n", di->name);
1111 1112
1112 while ((p = _dma_getnextrxp(di, true))) 1113 while ((p = _dma_getnextrxp(di, true)))
1113 brcmu_pkt_buf_free_skb(p); 1114 brcmu_pkt_buf_free_skb(p);
@@ -1138,7 +1139,7 @@ void dma_txinit(struct dma_pub *pub)
1138 struct dma_info *di = (struct dma_info *)pub; 1139 struct dma_info *di = (struct dma_info *)pub;
1139 u32 control = D64_XC_XE; 1140 u32 control = D64_XC_XE;
1140 1141
1141 DMA_TRACE("%s:\n", di->name); 1142 brcms_dbg_dma(di->core, "%s:\n", di->name);
1142 1143
1143 if (di->ntxd == 0) 1144 if (di->ntxd == 0)
1144 return; 1145 return;
@@ -1170,7 +1171,7 @@ void dma_txsuspend(struct dma_pub *pub)
1170{ 1171{
1171 struct dma_info *di = (struct dma_info *)pub; 1172 struct dma_info *di = (struct dma_info *)pub;
1172 1173
1173 DMA_TRACE("%s:\n", di->name); 1174 brcms_dbg_dma(di->core, "%s:\n", di->name);
1174 1175
1175 if (di->ntxd == 0) 1176 if (di->ntxd == 0)
1176 return; 1177 return;
@@ -1182,7 +1183,7 @@ void dma_txresume(struct dma_pub *pub)
1182{ 1183{
1183 struct dma_info *di = (struct dma_info *)pub; 1184 struct dma_info *di = (struct dma_info *)pub;
1184 1185
1185 DMA_TRACE("%s:\n", di->name); 1186 brcms_dbg_dma(di->core, "%s:\n", di->name);
1186 1187
1187 if (di->ntxd == 0) 1188 if (di->ntxd == 0)
1188 return; 1189 return;
@@ -1205,11 +1206,11 @@ void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
1205 struct dma_info *di = (struct dma_info *)pub; 1206 struct dma_info *di = (struct dma_info *)pub;
1206 struct sk_buff *p; 1207 struct sk_buff *p;
1207 1208
1208 DMA_TRACE("%s: %s\n", 1209 brcms_dbg_dma(di->core, "%s: %s\n",
1209 di->name, 1210 di->name,
1210 range == DMA_RANGE_ALL ? "all" : 1211 range == DMA_RANGE_ALL ? "all" :
1211 range == DMA_RANGE_TRANSMITTED ? "transmitted" : 1212 range == DMA_RANGE_TRANSMITTED ? "transmitted" :
1212 "transferred"); 1213 "transferred");
1213 1214
1214 if (di->txin == di->txout) 1215 if (di->txin == di->txout)
1215 return; 1216 return;
@@ -1264,39 +1265,25 @@ bool dma_rxreset(struct dma_pub *pub)
1264 return status == D64_RS0_RS_DISABLED; 1265 return status == D64_RS0_RS_DISABLED;
1265} 1266}
1266 1267
1267/* 1268static void dma_txenq(struct dma_info *di, struct sk_buff *p)
1268 * !! tx entry routine
1269 * WARNING: call must check the return value for error.
1270 * the error(toss frames) could be fatal and cause many subsequent hard
1271 * to debug problems
1272 */
1273int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)
1274{ 1269{
1275 struct dma_info *di = (struct dma_info *)pub;
1276 unsigned char *data; 1270 unsigned char *data;
1277 uint len; 1271 uint len;
1278 u16 txout; 1272 u16 txout;
1279 u32 flags = 0; 1273 u32 flags = 0;
1280 dma_addr_t pa; 1274 dma_addr_t pa;
1281 1275
1282 DMA_TRACE("%s:\n", di->name);
1283
1284 txout = di->txout; 1276 txout = di->txout;
1285 1277
1278 if (WARN_ON(nexttxd(di, txout) == di->txin))
1279 return;
1280
1286 /* 1281 /*
1287 * obtain and initialize transmit descriptor entry. 1282 * obtain and initialize transmit descriptor entry.
1288 */ 1283 */
1289 data = p->data; 1284 data = p->data;
1290 len = p->len; 1285 len = p->len;
1291 1286
1292 /* no use to transmit a zero length packet */
1293 if (len == 0)
1294 return 0;
1295
1296 /* return nonzero if out of tx descriptors */
1297 if (nexttxd(di, txout) == di->txin)
1298 goto outoftxd;
1299
1300 /* get physical address of buffer start */ 1287 /* get physical address of buffer start */
1301 pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE); 1288 pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE);
1302 1289
@@ -1318,23 +1305,147 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)
1318 1305
1319 /* bump the tx descriptor index */ 1306 /* bump the tx descriptor index */
1320 di->txout = txout; 1307 di->txout = txout;
1308}
1321 1309
1322 /* kick the chip */ 1310static void ampdu_finalize(struct dma_info *di)
1323 if (commit) 1311{
1324 bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), 1312 struct brcms_ampdu_session *session = &di->ampdu_session;
1325 di->xmtptrbase + I2B(txout, struct dma64desc)); 1313 struct sk_buff *p;
1314
1315 trace_brcms_ampdu_session(&session->wlc->hw->d11core->dev,
1316 session->max_ampdu_len,
1317 session->max_ampdu_frames,
1318 session->ampdu_len,
1319 skb_queue_len(&session->skb_list),
1320 session->dma_len);
1321
1322 if (WARN_ON(skb_queue_empty(&session->skb_list)))
1323 return;
1324
1325 brcms_c_ampdu_finalize(session);
1326
1327 while (!skb_queue_empty(&session->skb_list)) {
1328 p = skb_dequeue(&session->skb_list);
1329 dma_txenq(di, p);
1330 }
1331
1332 bcma_write32(di->core, DMA64TXREGOFFS(di, ptr),
1333 di->xmtptrbase + I2B(di->txout, struct dma64desc));
1334 brcms_c_ampdu_reset_session(session, session->wlc);
1335}
1336
1337static void prep_ampdu_frame(struct dma_info *di, struct sk_buff *p)
1338{
1339 struct brcms_ampdu_session *session = &di->ampdu_session;
1340 int ret;
1341
1342 ret = brcms_c_ampdu_add_frame(session, p);
1343 if (ret == -ENOSPC) {
1344 /*
1345 * AMPDU cannot accomodate this frame. Close out the in-
1346 * progress AMPDU session and start a new one.
1347 */
1348 ampdu_finalize(di);
1349 ret = brcms_c_ampdu_add_frame(session, p);
1350 }
1351
1352 WARN_ON(ret);
1353}
1354
1355/* Update count of available tx descriptors based on current DMA state */
1356static void dma_update_txavail(struct dma_info *di)
1357{
1358 /*
1359 * Available space is number of descriptors less the number of
1360 * active descriptors and the number of queued AMPDU frames.
1361 */
1362 di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) -
1363 skb_queue_len(&di->ampdu_session.skb_list) - 1;
1364}
1365
1366/*
1367 * !! tx entry routine
1368 * WARNING: call must check the return value for error.
1369 * the error(toss frames) could be fatal and cause many subsequent hard
1370 * to debug problems
1371 */
1372int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
1373 struct sk_buff *p)
1374{
1375 struct dma_info *di = (struct dma_info *)pub;
1376 struct brcms_ampdu_session *session = &di->ampdu_session;
1377 struct ieee80211_tx_info *tx_info;
1378 bool is_ampdu;
1379
1380 /* no use to transmit a zero length packet */
1381 if (p->len == 0)
1382 return 0;
1383
1384 /* return nonzero if out of tx descriptors */
1385 if (di->dma.txavail == 0 || nexttxd(di, di->txout) == di->txin)
1386 goto outoftxd;
1387
1388 tx_info = IEEE80211_SKB_CB(p);
1389 is_ampdu = tx_info->flags & IEEE80211_TX_CTL_AMPDU;
1390 if (is_ampdu)
1391 prep_ampdu_frame(di, p);
1392 else
1393 dma_txenq(di, p);
1326 1394
1327 /* tx flow control */ 1395 /* tx flow control */
1328 di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1; 1396 dma_update_txavail(di);
1397
1398 /* kick the chip */
1399 if (is_ampdu) {
1400 /*
1401 * Start sending data if we've got a full AMPDU, there's
1402 * no more space in the DMA ring, or the ring isn't
1403 * currently transmitting.
1404 */
1405 if (skb_queue_len(&session->skb_list) == session->max_ampdu_frames ||
1406 di->dma.txavail == 0 || dma64_txidle(di))
1407 ampdu_finalize(di);
1408 } else {
1409 bcma_write32(di->core, DMA64TXREGOFFS(di, ptr),
1410 di->xmtptrbase + I2B(di->txout, struct dma64desc));
1411 }
1329 1412
1330 return 0; 1413 return 0;
1331 1414
1332 outoftxd: 1415 outoftxd:
1333 DMA_ERROR("%s: out of txds !!!\n", di->name); 1416 brcms_dbg_dma(di->core, "%s: out of txds !!!\n", di->name);
1334 brcmu_pkt_buf_free_skb(p); 1417 brcmu_pkt_buf_free_skb(p);
1335 di->dma.txavail = 0; 1418 di->dma.txavail = 0;
1336 di->dma.txnobuf++; 1419 di->dma.txnobuf++;
1337 return -1; 1420 return -ENOSPC;
1421}
1422
1423void dma_txflush(struct dma_pub *pub)
1424{
1425 struct dma_info *di = (struct dma_info *)pub;
1426 struct brcms_ampdu_session *session = &di->ampdu_session;
1427
1428 if (!skb_queue_empty(&session->skb_list))
1429 ampdu_finalize(di);
1430}
1431
1432int dma_txpending(struct dma_pub *pub)
1433{
1434 struct dma_info *di = (struct dma_info *)pub;
1435 return ntxdactive(di, di->txin, di->txout);
1436}
1437
1438/*
1439 * If we have an active AMPDU session and are not transmitting,
1440 * this function will force tx to start.
1441 */
1442void dma_kick_tx(struct dma_pub *pub)
1443{
1444 struct dma_info *di = (struct dma_info *)pub;
1445 struct brcms_ampdu_session *session = &di->ampdu_session;
1446
1447 if (!skb_queue_empty(&session->skb_list) && dma64_txidle(di))
1448 ampdu_finalize(di);
1338} 1449}
1339 1450
1340/* 1451/*
@@ -1354,11 +1465,11 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
1354 u16 active_desc; 1465 u16 active_desc;
1355 struct sk_buff *txp; 1466 struct sk_buff *txp;
1356 1467
1357 DMA_TRACE("%s: %s\n", 1468 brcms_dbg_dma(di->core, "%s: %s\n",
1358 di->name, 1469 di->name,
1359 range == DMA_RANGE_ALL ? "all" : 1470 range == DMA_RANGE_ALL ? "all" :
1360 range == DMA_RANGE_TRANSMITTED ? "transmitted" : 1471 range == DMA_RANGE_TRANSMITTED ? "transmitted" :
1361 "transferred"); 1472 "transferred");
1362 1473
1363 if (di->ntxd == 0) 1474 if (di->ntxd == 0)
1364 return NULL; 1475 return NULL;
@@ -1412,13 +1523,13 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
1412 di->txin = i; 1523 di->txin = i;
1413 1524
1414 /* tx flow control */ 1525 /* tx flow control */
1415 di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1; 1526 dma_update_txavail(di);
1416 1527
1417 return txp; 1528 return txp;
1418 1529
1419 bogus: 1530 bogus:
1420 DMA_NONE("bogus curr: start %d end %d txout %d\n", 1531 brcms_dbg_dma(di->core, "bogus curr: start %d end %d txout %d\n",
1421 start, end, di->txout); 1532 start, end, di->txout);
1422 return NULL; 1533 return NULL;
1423} 1534}
1424 1535
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
index cc269ee5c49..ff5b80b0904 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
@@ -74,12 +74,11 @@ struct dma_pub {
74 uint txnobuf; /* tx out of dma descriptors */ 74 uint txnobuf; /* tx out of dma descriptors */
75}; 75};
76 76
77extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, 77extern struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
78 struct bcma_device *d11core,
79 uint txregbase, uint rxregbase, 78 uint txregbase, uint rxregbase,
80 uint ntxd, uint nrxd, 79 uint ntxd, uint nrxd,
81 uint rxbufsize, int rxextheadroom, 80 uint rxbufsize, int rxextheadroom,
82 uint nrxpost, uint rxoffset, uint *msg_level); 81 uint nrxpost, uint rxoffset);
83 82
84void dma_rxinit(struct dma_pub *pub); 83void dma_rxinit(struct dma_pub *pub);
85int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list); 84int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list);
@@ -87,7 +86,11 @@ bool dma_rxfill(struct dma_pub *pub);
87bool dma_rxreset(struct dma_pub *pub); 86bool dma_rxreset(struct dma_pub *pub);
88bool dma_txreset(struct dma_pub *pub); 87bool dma_txreset(struct dma_pub *pub);
89void dma_txinit(struct dma_pub *pub); 88void dma_txinit(struct dma_pub *pub);
90int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit); 89int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
90 struct sk_buff *p0);
91void dma_txflush(struct dma_pub *pub);
92int dma_txpending(struct dma_pub *pub);
93void dma_kick_tx(struct dma_pub *pub);
91void dma_txsuspend(struct dma_pub *pub); 94void dma_txsuspend(struct dma_pub *pub);
92bool dma_txsuspended(struct dma_pub *pub); 95bool dma_txsuspended(struct dma_pub *pub);
93void dma_txresume(struct dma_pub *pub); 96void dma_txresume(struct dma_pub *pub);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index a744ea5a955..1710ccba8ba 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -33,6 +33,7 @@
33#include "ucode_loader.h" 33#include "ucode_loader.h"
34#include "mac80211_if.h" 34#include "mac80211_if.h"
35#include "main.h" 35#include "main.h"
36#include "debug.h"
36 37
37#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ 38#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */
38 39
@@ -98,10 +99,14 @@ static struct bcma_device_id brcms_coreid_table[] = {
98}; 99};
99MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); 100MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
100 101
101#ifdef DEBUG 102#if defined(CONFIG_BRCMDBG)
102static int msglevel = 0xdeadbeef; 103/*
103module_param(msglevel, int, 0); 104 * Module parameter for setting the debug message level. Available
104#endif /* DEBUG */ 105 * flags are specified by the BRCM_DL_* macros in
106 * drivers/net/wireless/brcm80211/include/defs.h.
107 */
108module_param_named(debug, brcm_msg_level, uint, S_IRUGO | S_IWUSR);
109#endif
105 110
106static struct ieee80211_channel brcms_2ghz_chantable[] = { 111static struct ieee80211_channel brcms_2ghz_chantable[] = {
107 CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), 112 CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
@@ -276,7 +281,7 @@ static void brcms_ops_tx(struct ieee80211_hw *hw,
276 281
277 spin_lock_bh(&wl->lock); 282 spin_lock_bh(&wl->lock);
278 if (!wl->pub->up) { 283 if (!wl->pub->up) {
279 wiphy_err(wl->wiphy, "ops->tx called while down\n"); 284 brcms_err(wl->wlc->hw->d11core, "ops->tx called while down\n");
280 kfree_skb(skb); 285 kfree_skb(skb);
281 goto done; 286 goto done;
282 } 287 }
@@ -313,8 +318,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
313 spin_unlock_bh(&wl->lock); 318 spin_unlock_bh(&wl->lock);
314 319
315 if (err != 0) 320 if (err != 0)
316 wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, 321 brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n",
317 err); 322 __func__, err);
318 return err; 323 return err;
319} 324}
320 325
@@ -332,7 +337,7 @@ static void brcms_ops_stop(struct ieee80211_hw *hw)
332 status = brcms_c_chipmatch(wl->wlc->hw->d11core); 337 status = brcms_c_chipmatch(wl->wlc->hw->d11core);
333 spin_unlock_bh(&wl->lock); 338 spin_unlock_bh(&wl->lock);
334 if (!status) { 339 if (!status) {
335 wiphy_err(wl->wiphy, 340 brcms_err(wl->wlc->hw->d11core,
336 "wl: brcms_ops_stop: chipmatch failed\n"); 341 "wl: brcms_ops_stop: chipmatch failed\n");
337 return; 342 return;
338 } 343 }
@@ -350,8 +355,9 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
350 355
351 /* Just STA for now */ 356 /* Just STA for now */
352 if (vif->type != NL80211_IFTYPE_STATION) { 357 if (vif->type != NL80211_IFTYPE_STATION) {
353 wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" 358 brcms_err(wl->wlc->hw->d11core,
354 " STA for now\n", __func__, vif->type); 359 "%s: Attempt to add type %d, only STA for now\n",
360 __func__, vif->type);
355 return -EOPNOTSUPP; 361 return -EOPNOTSUPP;
356 } 362 }
357 363
@@ -370,9 +376,9 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
370{ 376{
371 struct ieee80211_conf *conf = &hw->conf; 377 struct ieee80211_conf *conf = &hw->conf;
372 struct brcms_info *wl = hw->priv; 378 struct brcms_info *wl = hw->priv;
379 struct bcma_device *core = wl->wlc->hw->d11core;
373 int err = 0; 380 int err = 0;
374 int new_int; 381 int new_int;
375 struct wiphy *wiphy = hw->wiphy;
376 382
377 spin_lock_bh(&wl->lock); 383 spin_lock_bh(&wl->lock);
378 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { 384 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
@@ -380,25 +386,26 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
380 conf->listen_interval); 386 conf->listen_interval);
381 } 387 }
382 if (changed & IEEE80211_CONF_CHANGE_MONITOR) 388 if (changed & IEEE80211_CONF_CHANGE_MONITOR)
383 wiphy_dbg(wiphy, "%s: change monitor mode: %s\n", 389 brcms_dbg_info(core, "%s: change monitor mode: %s\n",
384 __func__, conf->flags & IEEE80211_CONF_MONITOR ? 390 __func__, conf->flags & IEEE80211_CONF_MONITOR ?
385 "true" : "false"); 391 "true" : "false");
386 if (changed & IEEE80211_CONF_CHANGE_PS) 392 if (changed & IEEE80211_CONF_CHANGE_PS)
387 wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n", 393 brcms_err(core, "%s: change power-save mode: %s (implement)\n",
388 __func__, conf->flags & IEEE80211_CONF_PS ? 394 __func__, conf->flags & IEEE80211_CONF_PS ?
389 "true" : "false"); 395 "true" : "false");
390 396
391 if (changed & IEEE80211_CONF_CHANGE_POWER) { 397 if (changed & IEEE80211_CONF_CHANGE_POWER) {
392 err = brcms_c_set_tx_power(wl->wlc, conf->power_level); 398 err = brcms_c_set_tx_power(wl->wlc, conf->power_level);
393 if (err < 0) { 399 if (err < 0) {
394 wiphy_err(wiphy, "%s: Error setting power_level\n", 400 brcms_err(core, "%s: Error setting power_level\n",
395 __func__); 401 __func__);
396 goto config_out; 402 goto config_out;
397 } 403 }
398 new_int = brcms_c_get_tx_power(wl->wlc); 404 new_int = brcms_c_get_tx_power(wl->wlc);
399 if (new_int != conf->power_level) 405 if (new_int != conf->power_level)
400 wiphy_err(wiphy, "%s: Power level req != actual, %d %d" 406 brcms_err(core,
401 "\n", __func__, conf->power_level, 407 "%s: Power level req != actual, %d %d\n",
408 __func__, conf->power_level,
402 new_int); 409 new_int);
403 } 410 }
404 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 411 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
@@ -425,13 +432,13 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
425 struct ieee80211_bss_conf *info, u32 changed) 432 struct ieee80211_bss_conf *info, u32 changed)
426{ 433{
427 struct brcms_info *wl = hw->priv; 434 struct brcms_info *wl = hw->priv;
428 struct wiphy *wiphy = hw->wiphy; 435 struct bcma_device *core = wl->wlc->hw->d11core;
429 436
430 if (changed & BSS_CHANGED_ASSOC) { 437 if (changed & BSS_CHANGED_ASSOC) {
431 /* association status changed (associated/disassociated) 438 /* association status changed (associated/disassociated)
432 * also implies a change in the AID. 439 * also implies a change in the AID.
433 */ 440 */
434 wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME, 441 brcms_err(core, "%s: %s: %sassociated\n", KBUILD_MODNAME,
435 __func__, info->assoc ? "" : "dis"); 442 __func__, info->assoc ? "" : "dis");
436 spin_lock_bh(&wl->lock); 443 spin_lock_bh(&wl->lock);
437 brcms_c_associate_upd(wl->wlc, info->assoc); 444 brcms_c_associate_upd(wl->wlc, info->assoc);
@@ -491,7 +498,7 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
491 error = brcms_c_set_rateset(wl->wlc, &rs); 498 error = brcms_c_set_rateset(wl->wlc, &rs);
492 spin_unlock_bh(&wl->lock); 499 spin_unlock_bh(&wl->lock);
493 if (error) 500 if (error)
494 wiphy_err(wiphy, "changing basic rates failed: %d\n", 501 brcms_err(core, "changing basic rates failed: %d\n",
495 error); 502 error);
496 } 503 }
497 if (changed & BSS_CHANGED_BEACON_INT) { 504 if (changed & BSS_CHANGED_BEACON_INT) {
@@ -508,30 +515,30 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
508 } 515 }
509 if (changed & BSS_CHANGED_BEACON) 516 if (changed & BSS_CHANGED_BEACON)
510 /* Beacon data changed, retrieve new beacon (beaconing modes) */ 517 /* Beacon data changed, retrieve new beacon (beaconing modes) */
511 wiphy_err(wiphy, "%s: beacon changed\n", __func__); 518 brcms_err(core, "%s: beacon changed\n", __func__);
512 519
513 if (changed & BSS_CHANGED_BEACON_ENABLED) { 520 if (changed & BSS_CHANGED_BEACON_ENABLED) {
514 /* Beaconing should be enabled/disabled (beaconing modes) */ 521 /* Beaconing should be enabled/disabled (beaconing modes) */
515 wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__, 522 brcms_err(core, "%s: Beacon enabled: %s\n", __func__,
516 info->enable_beacon ? "true" : "false"); 523 info->enable_beacon ? "true" : "false");
517 } 524 }
518 525
519 if (changed & BSS_CHANGED_CQM) { 526 if (changed & BSS_CHANGED_CQM) {
520 /* Connection quality monitor config changed */ 527 /* Connection quality monitor config changed */
521 wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d " 528 brcms_err(core, "%s: cqm change: threshold %d, hys %d "
522 " (implement)\n", __func__, info->cqm_rssi_thold, 529 " (implement)\n", __func__, info->cqm_rssi_thold,
523 info->cqm_rssi_hyst); 530 info->cqm_rssi_hyst);
524 } 531 }
525 532
526 if (changed & BSS_CHANGED_IBSS) { 533 if (changed & BSS_CHANGED_IBSS) {
527 /* IBSS join status changed */ 534 /* IBSS join status changed */
528 wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__, 535 brcms_err(core, "%s: IBSS joined: %s (implement)\n",
529 info->ibss_joined ? "true" : "false"); 536 __func__, info->ibss_joined ? "true" : "false");
530 } 537 }
531 538
532 if (changed & BSS_CHANGED_ARP_FILTER) { 539 if (changed & BSS_CHANGED_ARP_FILTER) {
533 /* Hardware ARP filter address list or state changed */ 540 /* Hardware ARP filter address list or state changed */
534 wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d" 541 brcms_err(core, "%s: arp filtering: enabled %s, count %d"
535 " (implement)\n", __func__, info->arp_filter_enabled ? 542 " (implement)\n", __func__, info->arp_filter_enabled ?
536 "true" : "false", info->arp_addr_cnt); 543 "true" : "false", info->arp_addr_cnt);
537 } 544 }
@@ -541,8 +548,8 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
541 * QoS for this association was enabled/disabled. 548 * QoS for this association was enabled/disabled.
542 * Note that it is only ever disabled for station mode. 549 * Note that it is only ever disabled for station mode.
543 */ 550 */
544 wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__, 551 brcms_err(core, "%s: qos enabled: %s (implement)\n",
545 info->qos ? "true" : "false"); 552 __func__, info->qos ? "true" : "false");
546 } 553 }
547 return; 554 return;
548} 555}
@@ -553,25 +560,25 @@ brcms_ops_configure_filter(struct ieee80211_hw *hw,
553 unsigned int *total_flags, u64 multicast) 560 unsigned int *total_flags, u64 multicast)
554{ 561{
555 struct brcms_info *wl = hw->priv; 562 struct brcms_info *wl = hw->priv;
556 struct wiphy *wiphy = hw->wiphy; 563 struct bcma_device *core = wl->wlc->hw->d11core;
557 564
558 changed_flags &= MAC_FILTERS; 565 changed_flags &= MAC_FILTERS;
559 *total_flags &= MAC_FILTERS; 566 *total_flags &= MAC_FILTERS;
560 567
561 if (changed_flags & FIF_PROMISC_IN_BSS) 568 if (changed_flags & FIF_PROMISC_IN_BSS)
562 wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n"); 569 brcms_dbg_info(core, "FIF_PROMISC_IN_BSS\n");
563 if (changed_flags & FIF_ALLMULTI) 570 if (changed_flags & FIF_ALLMULTI)
564 wiphy_dbg(wiphy, "FIF_ALLMULTI\n"); 571 brcms_dbg_info(core, "FIF_ALLMULTI\n");
565 if (changed_flags & FIF_FCSFAIL) 572 if (changed_flags & FIF_FCSFAIL)
566 wiphy_dbg(wiphy, "FIF_FCSFAIL\n"); 573 brcms_dbg_info(core, "FIF_FCSFAIL\n");
567 if (changed_flags & FIF_CONTROL) 574 if (changed_flags & FIF_CONTROL)
568 wiphy_dbg(wiphy, "FIF_CONTROL\n"); 575 brcms_dbg_info(core, "FIF_CONTROL\n");
569 if (changed_flags & FIF_OTHER_BSS) 576 if (changed_flags & FIF_OTHER_BSS)
570 wiphy_dbg(wiphy, "FIF_OTHER_BSS\n"); 577 brcms_dbg_info(core, "FIF_OTHER_BSS\n");
571 if (changed_flags & FIF_PSPOLL) 578 if (changed_flags & FIF_PSPOLL)
572 wiphy_dbg(wiphy, "FIF_PSPOLL\n"); 579 brcms_dbg_info(core, "FIF_PSPOLL\n");
573 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) 580 if (changed_flags & FIF_BCN_PRBRESP_PROMISC)
574 wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n"); 581 brcms_dbg_info(core, "FIF_BCN_PRBRESP_PROMISC\n");
575 582
576 spin_lock_bh(&wl->lock); 583 spin_lock_bh(&wl->lock);
577 brcms_c_mac_promisc(wl->wlc, *total_flags); 584 brcms_c_mac_promisc(wl->wlc, *total_flags);
@@ -653,8 +660,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
653 status = brcms_c_aggregatable(wl->wlc, tid); 660 status = brcms_c_aggregatable(wl->wlc, tid);
654 spin_unlock_bh(&wl->lock); 661 spin_unlock_bh(&wl->lock);
655 if (!status) { 662 if (!status) {
656 wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n", 663 brcms_err(wl->wlc->hw->d11core,
657 tid); 664 "START: tid %d is not agg\'able\n", tid);
658 return -EINVAL; 665 return -EINVAL;
659 } 666 }
660 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 667 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
@@ -681,8 +688,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
681 /* Power save wakeup */ 688 /* Power save wakeup */
682 break; 689 break;
683 default: 690 default:
684 wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n", 691 brcms_err(wl->wlc->hw->d11core,
685 __func__); 692 "%s: Invalid command, ignoring\n", __func__);
686 } 693 }
687 694
688 return 0; 695 return 0;
@@ -1144,14 +1151,13 @@ static int brcms_suspend(struct bcma_device *pdev)
1144 wl->pub->hw_up = false; 1151 wl->pub->hw_up = false;
1145 spin_unlock_bh(&wl->lock); 1152 spin_unlock_bh(&wl->lock);
1146 1153
1147 pr_debug("brcms_suspend ok\n"); 1154 brcms_dbg_info(wl->wlc->hw->d11core, "brcms_suspend ok\n");
1148 1155
1149 return 0; 1156 return 0;
1150} 1157}
1151 1158
1152static int brcms_resume(struct bcma_device *pdev) 1159static int brcms_resume(struct bcma_device *pdev)
1153{ 1160{
1154 pr_debug("brcms_resume ok\n");
1155 return 0; 1161 return 0;
1156} 1162}
1157 1163
@@ -1184,10 +1190,6 @@ static DECLARE_WORK(brcms_driver_work, brcms_driver_init);
1184 1190
1185static int __init brcms_module_init(void) 1191static int __init brcms_module_init(void)
1186{ 1192{
1187#ifdef DEBUG
1188 if (msglevel != 0xdeadbeef)
1189 brcm_msg_level = msglevel;
1190#endif
1191 if (!schedule_work(&brcms_driver_work)) 1193 if (!schedule_work(&brcms_driver_work))
1192 return -EBUSY; 1194 return -EBUSY;
1193 1195
@@ -1216,7 +1218,7 @@ module_exit(brcms_module_exit);
1216void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, 1218void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
1217 bool state, int prio) 1219 bool state, int prio)
1218{ 1220{
1219 wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__); 1221 brcms_err(wl->wlc->hw->d11core, "Shouldn't be here %s\n", __func__);
1220} 1222}
1221 1223
1222/* 1224/*
@@ -1224,7 +1226,8 @@ void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
1224 */ 1226 */
1225void brcms_init(struct brcms_info *wl) 1227void brcms_init(struct brcms_info *wl)
1226{ 1228{
1227 BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); 1229 brcms_dbg_info(wl->wlc->hw->d11core, "Initializing wl%d\n",
1230 wl->pub->unit);
1228 brcms_reset(wl); 1231 brcms_reset(wl);
1229 brcms_c_init(wl->wlc, wl->mute_tx); 1232 brcms_c_init(wl->wlc, wl->mute_tx);
1230} 1233}
@@ -1234,7 +1237,7 @@ void brcms_init(struct brcms_info *wl)
1234 */ 1237 */
1235uint brcms_reset(struct brcms_info *wl) 1238uint brcms_reset(struct brcms_info *wl)
1236{ 1239{
1237 BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); 1240 brcms_dbg_info(wl->wlc->hw->d11core, "Resetting wl%d\n", wl->pub->unit);
1238 brcms_c_reset(wl->wlc); 1241 brcms_c_reset(wl->wlc);
1239 1242
1240 /* dpc will not be rescheduled */ 1243 /* dpc will not be rescheduled */
@@ -1248,7 +1251,7 @@ uint brcms_reset(struct brcms_info *wl)
1248 1251
1249void brcms_fatal_error(struct brcms_info *wl) 1252void brcms_fatal_error(struct brcms_info *wl)
1250{ 1253{
1251 wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n", 1254 brcms_err(wl->wlc->hw->d11core, "wl%d: fatal error, reinitializing\n",
1252 wl->wlc->pub->unit); 1255 wl->wlc->pub->unit);
1253 brcms_reset(wl); 1256 brcms_reset(wl);
1254 ieee80211_restart_hw(wl->pub->ieee_hw); 1257 ieee80211_restart_hw(wl->pub->ieee_hw);
@@ -1396,8 +1399,9 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
1396 1399
1397#ifdef DEBUG 1400#ifdef DEBUG
1398 if (t->set) 1401 if (t->set)
1399 wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n", 1402 brcms_dbg_info(t->wl->wlc->hw->d11core,
1400 __func__, t->name, periodic); 1403 "%s: Already set. Name: %s, per %d\n",
1404 __func__, t->name, periodic);
1401#endif 1405#endif
1402 t->ms = ms; 1406 t->ms = ms;
1403 t->periodic = (bool) periodic; 1407 t->periodic = (bool) periodic;
@@ -1486,8 +1490,8 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
1486 } 1490 }
1487 } 1491 }
1488 } 1492 }
1489 wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n", 1493 brcms_err(wl->wlc->hw->d11core,
1490 idx); 1494 "ERROR: ucode buf tag:%d can not be found!\n", idx);
1491 *pbuf = NULL; 1495 *pbuf = NULL;
1492fail: 1496fail:
1493 return -ENODATA; 1497 return -ENODATA;
@@ -1510,7 +1514,7 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
1510 pdata = wl->fw.fw_bin[i]->data + 1514 pdata = wl->fw.fw_bin[i]->data +
1511 le32_to_cpu(hdr->offset); 1515 le32_to_cpu(hdr->offset);
1512 if (le32_to_cpu(hdr->len) != 4) { 1516 if (le32_to_cpu(hdr->len) != 4) {
1513 wiphy_err(wl->wiphy, 1517 brcms_err(wl->wlc->hw->d11core,
1514 "ERROR: fw hdr len\n"); 1518 "ERROR: fw hdr len\n");
1515 return -ENOMSG; 1519 return -ENOMSG;
1516 } 1520 }
@@ -1519,7 +1523,8 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
1519 } 1523 }
1520 } 1524 }
1521 } 1525 }
1522 wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx); 1526 brcms_err(wl->wlc->hw->d11core,
1527 "ERROR: ucode tag:%d can not be found!\n", idx);
1523 return -ENOMSG; 1528 return -ENOMSG;
1524} 1529}
1525 1530
@@ -1560,8 +1565,8 @@ int brcms_check_firmwares(struct brcms_info *wl)
1560 sizeof(struct firmware_hdr)); 1565 sizeof(struct firmware_hdr));
1561 rc = -EBADF; 1566 rc = -EBADF;
1562 } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { 1567 } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
1563 wiphy_err(wl->wiphy, "%s: out of bounds fw file size " 1568 wiphy_err(wl->wiphy, "%s: out of bounds fw file size %zu\n",
1564 "%zu\n", __func__, fw->size); 1569 __func__, fw->size);
1565 rc = -EBADF; 1570 rc = -EBADF;
1566 } else { 1571 } else {
1567 /* check if ucode section overruns firmware image */ 1572 /* check if ucode section overruns firmware image */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 565c15abbed..2a44593f1e3 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -34,12 +34,9 @@
34#include "ucode_loader.h" 34#include "ucode_loader.h"
35#include "main.h" 35#include "main.h"
36#include "soc.h" 36#include "soc.h"
37 37#include "dma.h"
38/* 38#include "debug.h"
39 * Indication for txflowcontrol that all priority bits in 39#include "brcms_trace_events.h"
40 * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
41 */
42#define ALLPRIO -1
43 40
44/* watchdog timer, in unit of ms */ 41/* watchdog timer, in unit of ms */
45#define TIMER_INTERVAL_WATCHDOG 1000 42#define TIMER_INTERVAL_WATCHDOG 1000
@@ -126,21 +123,6 @@
126 123
127#define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ 124#define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */
128 125
129/* precedences numbers for wlc queues. These are twice as may levels as
130 * 802.1D priorities.
131 * Odd numbers are used for HI priority traffic at same precedence levels
132 * These constants are used ONLY by wlc_prio2prec_map. Do not use them
133 * elsewhere.
134 */
135#define _BRCMS_PREC_NONE 0 /* None = - */
136#define _BRCMS_PREC_BK 2 /* BK - Background */
137#define _BRCMS_PREC_BE 4 /* BE - Best-effort */
138#define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */
139#define _BRCMS_PREC_CL 8 /* CL - Controlled Load */
140#define _BRCMS_PREC_VI 10 /* Vi - Video */
141#define _BRCMS_PREC_VO 12 /* Vo - Voice */
142#define _BRCMS_PREC_NC 14 /* NC - Network Control */
143
144/* synthpu_dly times in us */ 126/* synthpu_dly times in us */
145#define SYNTHPU_DLY_APHY_US 3700 127#define SYNTHPU_DLY_APHY_US 3700
146#define SYNTHPU_DLY_BPHY_US 1050 128#define SYNTHPU_DLY_BPHY_US 1050
@@ -237,17 +219,17 @@
237 219
238#define MAX_DMA_SEGS 4 220#define MAX_DMA_SEGS 4
239 221
240/* Max # of entries in Tx FIFO based on 4kb page size */ 222/* # of entries in Tx FIFO */
241#define NTXD 256 223#define NTXD 64
242/* Max # of entries in Rx FIFO based on 4kb page size */ 224/* Max # of entries in Rx FIFO based on 4kb page size */
243#define NRXD 256 225#define NRXD 256
244 226
227/* Amount of headroom to leave in Tx FIFO */
228#define TX_HEADROOM 4
229
245/* try to keep this # rbufs posted to the chip */ 230/* try to keep this # rbufs posted to the chip */
246#define NRXBUFPOST 32 231#define NRXBUFPOST 32
247 232
248/* data msg txq hiwat mark */
249#define BRCMS_DATAHIWAT 50
250
251/* max # frames to process in brcms_c_recv() */ 233/* max # frames to process in brcms_c_recv() */
252#define RXBND 8 234#define RXBND 8
253/* max # tx status to process in wlc_txstatus() */ 235/* max # tx status to process in wlc_txstatus() */
@@ -283,24 +265,8 @@ struct edcf_acparam {
283 u16 TXOP; 265 u16 TXOP;
284} __packed; 266} __packed;
285 267
286const u8 prio2fifo[NUMPRIO] = {
287 TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */
288 TX_AC_BK_FIFO, /* 1 BK AC_BK Background */
289 TX_AC_BK_FIFO, /* 2 -- AC_BK Background */
290 TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */
291 TX_AC_VI_FIFO, /* 4 CL AC_VI Video */
292 TX_AC_VI_FIFO, /* 5 VI AC_VI Video */
293 TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */
294 TX_AC_VO_FIFO /* 7 NC AC_VO Voice */
295};
296
297/* debug/trace */ 268/* debug/trace */
298uint brcm_msg_level = 269uint brcm_msg_level;
299#if defined(DEBUG)
300 LOG_ERROR_VAL;
301#else
302 0;
303#endif /* DEBUG */
304 270
305/* TX FIFO number to WME/802.1E Access Category */ 271/* TX FIFO number to WME/802.1E Access Category */
306static const u8 wme_fifo2ac[] = { 272static const u8 wme_fifo2ac[] = {
@@ -320,18 +286,6 @@ static const u8 wme_ac2fifo[] = {
320 TX_AC_BK_FIFO 286 TX_AC_BK_FIFO
321}; 287};
322 288
323/* 802.1D Priority to precedence queue mapping */
324const u8 wlc_prio2prec_map[] = {
325 _BRCMS_PREC_BE, /* 0 BE - Best-effort */
326 _BRCMS_PREC_BK, /* 1 BK - Background */
327 _BRCMS_PREC_NONE, /* 2 None = - */
328 _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */
329 _BRCMS_PREC_CL, /* 4 CL - Controlled Load */
330 _BRCMS_PREC_VI, /* 5 Vi - Video */
331 _BRCMS_PREC_VO, /* 6 Vo - Voice */
332 _BRCMS_PREC_NC, /* 7 NC - Network Control */
333};
334
335static const u16 xmtfifo_sz[][NFIFO] = { 289static const u16 xmtfifo_sz[][NFIFO] = {
336 /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */ 290 /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */
337 {20, 192, 192, 21, 17, 5}, 291 {20, 192, 192, 21, 17, 5},
@@ -371,6 +325,36 @@ static const char fifo_names[6][0];
371static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); 325static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
372#endif 326#endif
373 327
328/* Mapping of ieee80211 AC numbers to tx fifos */
329static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = {
330 [IEEE80211_AC_VO] = TX_AC_VO_FIFO,
331 [IEEE80211_AC_VI] = TX_AC_VI_FIFO,
332 [IEEE80211_AC_BE] = TX_AC_BE_FIFO,
333 [IEEE80211_AC_BK] = TX_AC_BK_FIFO,
334};
335
336/* Mapping of tx fifos to ieee80211 AC numbers */
337static const u8 fifo_to_ac_mapping[IEEE80211_NUM_ACS] = {
338 [TX_AC_BK_FIFO] = IEEE80211_AC_BK,
339 [TX_AC_BE_FIFO] = IEEE80211_AC_BE,
340 [TX_AC_VI_FIFO] = IEEE80211_AC_VI,
341 [TX_AC_VO_FIFO] = IEEE80211_AC_VO,
342};
343
344static u8 brcms_ac_to_fifo(u8 ac)
345{
346 if (ac >= ARRAY_SIZE(ac_to_fifo_mapping))
347 return TX_AC_BE_FIFO;
348 return ac_to_fifo_mapping[ac];
349}
350
351static u8 brcms_fifo_to_ac(u8 fifo)
352{
353 if (fifo >= ARRAY_SIZE(fifo_to_ac_mapping))
354 return IEEE80211_AC_BE;
355 return fifo_to_ac_mapping[fifo];
356}
357
374/* Find basic rate for a given rate */ 358/* Find basic rate for a given rate */
375static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) 359static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
376{ 360{
@@ -415,10 +399,15 @@ static bool brcms_deviceremoved(struct brcms_c_info *wlc)
415} 399}
416 400
417/* sum the individual fifo tx pending packet counts */ 401/* sum the individual fifo tx pending packet counts */
418static s16 brcms_txpktpendtot(struct brcms_c_info *wlc) 402static int brcms_txpktpendtot(struct brcms_c_info *wlc)
419{ 403{
420 return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] + 404 int i;
421 wlc->core->txpktpend[2] + wlc->core->txpktpend[3]; 405 int pending = 0;
406
407 for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++)
408 if (wlc->hw->di[i])
409 pending += dma_txpending(wlc->hw->di[i]);
410 return pending;
422} 411}
423 412
424static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc) 413static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
@@ -626,14 +615,11 @@ static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
626 uint rate = rspec2rate(ratespec); 615 uint rate = rspec2rate(ratespec);
627 616
628 if (rate == 0) { 617 if (rate == 0) {
629 wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n", 618 brcms_err(wlc->hw->d11core, "wl%d: WAR: using rate of 1 mbps\n",
630 wlc->pub->unit); 619 wlc->pub->unit);
631 rate = BRCM_RATE_1M; 620 rate = BRCM_RATE_1M;
632 } 621 }
633 622
634 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
635 wlc->pub->unit, ratespec, preamble_type, mac_len);
636
637 if (is_mcs_rate(ratespec)) { 623 if (is_mcs_rate(ratespec)) {
638 uint mcs = ratespec & RSPEC_RATE_MASK; 624 uint mcs = ratespec & RSPEC_RATE_MASK;
639 int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); 625 int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
@@ -696,7 +682,7 @@ static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
696 u16 size; 682 u16 size;
697 u32 value; 683 u32 value;
698 684
699 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); 685 brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
700 686
701 for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) { 687 for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) {
702 size = le16_to_cpu(inits[i].size); 688 size = le16_to_cpu(inits[i].size);
@@ -725,7 +711,6 @@ static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs)
725 711
726static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) 712static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
727{ 713{
728 struct wiphy *wiphy = wlc_hw->wlc->wiphy;
729 struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; 714 struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
730 715
731 /* init microcode host flags */ 716 /* init microcode host flags */
@@ -736,8 +721,9 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
736 if (BRCMS_ISNPHY(wlc_hw->band)) 721 if (BRCMS_ISNPHY(wlc_hw->band))
737 brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); 722 brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
738 else 723 else
739 wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" 724 brcms_err(wlc_hw->d11core,
740 " %d\n", __func__, wlc_hw->unit, 725 "%s: wl%d: unsupported phy in corerev %d\n",
726 __func__, wlc_hw->unit,
741 wlc_hw->corerev); 727 wlc_hw->corerev);
742 } else { 728 } else {
743 if (D11REV_IS(wlc_hw->corerev, 24)) { 729 if (D11REV_IS(wlc_hw->corerev, 24)) {
@@ -745,12 +731,14 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
745 brcms_c_write_inits(wlc_hw, 731 brcms_c_write_inits(wlc_hw,
746 ucode->d11lcn0bsinitvals24); 732 ucode->d11lcn0bsinitvals24);
747 else 733 else
748 wiphy_err(wiphy, "%s: wl%d: unsupported phy in" 734 brcms_err(wlc_hw->d11core,
749 " core rev %d\n", __func__, 735 "%s: wl%d: unsupported phy in core rev %d\n",
750 wlc_hw->unit, wlc_hw->corerev); 736 __func__, wlc_hw->unit,
737 wlc_hw->corerev);
751 } else { 738 } else {
752 wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", 739 brcms_err(wlc_hw->d11core,
753 __func__, wlc_hw->unit, wlc_hw->corerev); 740 "%s: wl%d: unsupported corerev %d\n",
741 __func__, wlc_hw->unit, wlc_hw->corerev);
754 } 742 }
755 } 743 }
756} 744}
@@ -765,7 +753,7 @@ static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v)
765 753
766static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) 754static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
767{ 755{
768 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk); 756 brcms_dbg_info(wlc_hw->d11core, "wl%d: clk %d\n", wlc_hw->unit, clk);
769 757
770 wlc_hw->phyclk = clk; 758 wlc_hw->phyclk = clk;
771 759
@@ -790,8 +778,8 @@ static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
790/* low-level band switch utility routine */ 778/* low-level band switch utility routine */
791static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit) 779static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
792{ 780{
793 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, 781 brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit,
794 bandunit); 782 bandunit);
795 783
796 wlc_hw->band = wlc_hw->bandstate[bandunit]; 784 wlc_hw->band = wlc_hw->bandstate[bandunit];
797 785
@@ -819,7 +807,7 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
819 u32 macintmask; 807 u32 macintmask;
820 u32 macctrl; 808 u32 macctrl;
821 809
822 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); 810 brcms_dbg_mac80211(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
823 macctrl = bcma_read32(wlc_hw->d11core, 811 macctrl = bcma_read32(wlc_hw->d11core,
824 D11REGOFFS(maccontrol)); 812 D11REGOFFS(maccontrol));
825 WARN_ON((macctrl & MCTL_EN_MAC) != 0); 813 WARN_ON((macctrl & MCTL_EN_MAC) != 0);
@@ -841,9 +829,10 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
841static bool 829static bool
842brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) 830brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
843{ 831{
844 struct sk_buff *p; 832 struct sk_buff *p = NULL;
845 uint queue; 833 uint queue = NFIFO;
846 struct d11txh *txh; 834 struct dma_pub *dma = NULL;
835 struct d11txh *txh = NULL;
847 struct scb *scb = NULL; 836 struct scb *scb = NULL;
848 bool free_pdu; 837 bool free_pdu;
849 int tx_rts, tx_frame_count, tx_rts_count; 838 int tx_rts, tx_frame_count, tx_rts_count;
@@ -854,6 +843,11 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
854 struct ieee80211_tx_info *tx_info; 843 struct ieee80211_tx_info *tx_info;
855 struct ieee80211_tx_rate *txrate; 844 struct ieee80211_tx_rate *txrate;
856 int i; 845 int i;
846 bool fatal = true;
847
848 trace_brcms_txstatus(&wlc->hw->d11core->dev, txs->framelen,
849 txs->frameid, txs->status, txs->lasttxtime,
850 txs->sequence, txs->phyerr, txs->ackphyrxsh);
857 851
858 /* discard intermediate indications for ucode with one legitimate case: 852 /* discard intermediate indications for ucode with one legitimate case:
859 * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, 853 * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
@@ -862,34 +856,36 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
862 */ 856 */
863 if (!(txs->status & TX_STATUS_AMPDU) 857 if (!(txs->status & TX_STATUS_AMPDU)
864 && (txs->status & TX_STATUS_INTERMEDIATE)) { 858 && (txs->status & TX_STATUS_INTERMEDIATE)) {
865 BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n"); 859 brcms_dbg_tx(wlc->hw->d11core, "INTERMEDIATE but not AMPDU\n");
866 return false; 860 fatal = false;
861 goto out;
867 } 862 }
868 863
869 queue = txs->frameid & TXFID_QUEUE_MASK; 864 queue = txs->frameid & TXFID_QUEUE_MASK;
870 if (queue >= NFIFO) { 865 if (queue >= NFIFO) {
871 p = NULL; 866 brcms_err(wlc->hw->d11core, "queue %u >= NFIFO\n", queue);
872 goto fatal; 867 goto out;
873 } 868 }
874 869
870 dma = wlc->hw->di[queue];
871
875 p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); 872 p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
876 if (p == NULL) 873 if (p == NULL) {
877 goto fatal; 874 brcms_err(wlc->hw->d11core, "dma_getnexttxp returned null!\n");
875 goto out;
876 }
878 877
879 txh = (struct d11txh *) (p->data); 878 txh = (struct d11txh *) (p->data);
880 mcl = le16_to_cpu(txh->MacTxControlLow); 879 mcl = le16_to_cpu(txh->MacTxControlLow);
881 880
882 if (txs->phyerr) { 881 if (txs->phyerr)
883 if (brcm_msg_level & LOG_ERROR_VAL) { 882 brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n",
884 wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n", 883 txs->phyerr, txh->MainRates);
885 txs->phyerr, txh->MainRates);
886 brcms_c_print_txdesc(txh);
887 }
888 brcms_c_print_txstatus(txs);
889 }
890 884
891 if (txs->frameid != le16_to_cpu(txh->TxFrameID)) 885 if (txs->frameid != le16_to_cpu(txh->TxFrameID)) {
892 goto fatal; 886 brcms_err(wlc->hw->d11core, "frameid != txh->TxFrameID\n");
887 goto out;
888 }
893 tx_info = IEEE80211_SKB_CB(p); 889 tx_info = IEEE80211_SKB_CB(p);
894 h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); 890 h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
895 891
@@ -898,14 +894,24 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
898 894
899 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { 895 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
900 brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); 896 brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
901 return false; 897 fatal = false;
898 goto out;
902 } 899 }
903 900
901 /*
902 * brcms_c_ampdu_dotxstatus() will trace tx descriptors for AMPDU
903 * frames; this traces them for the rest.
904 */
905 trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh));
906
904 supr_status = txs->status & TX_STATUS_SUPR_MASK; 907 supr_status = txs->status & TX_STATUS_SUPR_MASK;
905 if (supr_status == TX_STATUS_SUPR_BADCH) 908 if (supr_status == TX_STATUS_SUPR_BADCH) {
906 BCMMSG(wlc->wiphy, 909 unsigned xfts = le16_to_cpu(txh->XtraFrameTypes);
907 "%s: Pkt tx suppressed, possibly channel %d\n", 910 brcms_dbg_tx(wlc->hw->d11core,
908 __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); 911 "Pkt tx suppressed, dest chan %u, current %d\n",
912 (xfts >> XFTS_CHANNEL_SHIFT) & 0xff,
913 CHSPEC_CHANNEL(wlc->default_bss->chanspec));
914 }
909 915
910 tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS; 916 tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS;
911 tx_frame_count = 917 tx_frame_count =
@@ -916,7 +922,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
916 lastframe = !ieee80211_has_morefrags(h->frame_control); 922 lastframe = !ieee80211_has_morefrags(h->frame_control);
917 923
918 if (!lastframe) { 924 if (!lastframe) {
919 wiphy_err(wlc->wiphy, "Not last frame!\n"); 925 brcms_err(wlc->hw->d11core, "Not last frame!\n");
920 } else { 926 } else {
921 /* 927 /*
922 * Set information to be consumed by Minstrel ht. 928 * Set information to be consumed by Minstrel ht.
@@ -982,26 +988,37 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
982 totlen = p->len; 988 totlen = p->len;
983 free_pdu = true; 989 free_pdu = true;
984 990
985 brcms_c_txfifo_complete(wlc, queue, 1);
986
987 if (lastframe) { 991 if (lastframe) {
988 /* remove PLCP & Broadcom tx descriptor header */ 992 /* remove PLCP & Broadcom tx descriptor header */
989 skb_pull(p, D11_PHY_HDR_LEN); 993 skb_pull(p, D11_PHY_HDR_LEN);
990 skb_pull(p, D11_TXH_LEN); 994 skb_pull(p, D11_TXH_LEN);
991 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); 995 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
992 } else { 996 } else {
993 wiphy_err(wlc->wiphy, "%s: Not last frame => not calling " 997 brcms_err(wlc->hw->d11core,
994 "tx_status\n", __func__); 998 "%s: Not last frame => not calling tx_status\n",
999 __func__);
995 } 1000 }
996 1001
997 return false; 1002 fatal = false;
998 1003
999 fatal: 1004 out:
1000 if (p) 1005 if (fatal) {
1001 brcmu_pkt_buf_free_skb(p); 1006 if (txh)
1007 trace_brcms_txdesc(&wlc->hw->d11core->dev, txh,
1008 sizeof(*txh));
1009 if (p)
1010 brcmu_pkt_buf_free_skb(p);
1011 }
1002 1012
1003 return true; 1013 if (dma && queue < NFIFO) {
1014 u16 ac_queue = brcms_fifo_to_ac(queue);
1015 if (dma->txavail > TX_HEADROOM && queue < TX_BCMC_FIFO &&
1016 ieee80211_queue_stopped(wlc->pub->ieee_hw, ac_queue))
1017 ieee80211_wake_queue(wlc->pub->ieee_hw, ac_queue);
1018 dma_kick_tx(dma);
1019 }
1004 1020
1021 return fatal;
1005} 1022}
1006 1023
1007/* process tx completion events in BMAC 1024/* process tx completion events in BMAC
@@ -1011,7 +1028,6 @@ static bool
1011brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) 1028brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1012{ 1029{
1013 bool morepending = false; 1030 bool morepending = false;
1014 struct brcms_c_info *wlc = wlc_hw->wlc;
1015 struct bcma_device *core; 1031 struct bcma_device *core;
1016 struct tx_status txstatus, *txs; 1032 struct tx_status txstatus, *txs;
1017 u32 s1, s2; 1033 u32 s1, s2;
@@ -1022,8 +1038,6 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1022 */ 1038 */
1023 uint max_tx_num = bound ? TXSBND : -1; 1039 uint max_tx_num = bound ? TXSBND : -1;
1024 1040
1025 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
1026
1027 txs = &txstatus; 1041 txs = &txstatus;
1028 core = wlc_hw->d11core; 1042 core = wlc_hw->d11core;
1029 *fatal = false; 1043 *fatal = false;
@@ -1032,8 +1046,8 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1032 && (s1 & TXS_V)) { 1046 && (s1 & TXS_V)) {
1033 1047
1034 if (s1 == 0xffffffff) { 1048 if (s1 == 0xffffffff) {
1035 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", 1049 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
1036 wlc_hw->unit, __func__); 1050 __func__);
1037 return morepending; 1051 return morepending;
1038 } 1052 }
1039 s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); 1053 s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
@@ -1058,9 +1072,6 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1058 if (n >= max_tx_num) 1072 if (n >= max_tx_num)
1059 morepending = true; 1073 morepending = true;
1060 1074
1061 if (!pktq_empty(&wlc->pkt_queue->q))
1062 brcms_c_send_q(wlc);
1063
1064 return morepending; 1075 return morepending;
1065} 1076}
1066 1077
@@ -1112,7 +1123,6 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
1112 u16 pio_mhf2 = 0; 1123 u16 pio_mhf2 = 0;
1113 struct brcms_hardware *wlc_hw = wlc->hw; 1124 struct brcms_hardware *wlc_hw = wlc->hw;
1114 uint unit = wlc_hw->unit; 1125 uint unit = wlc_hw->unit;
1115 struct wiphy *wiphy = wlc->wiphy;
1116 1126
1117 /* name and offsets for dma_attach */ 1127 /* name and offsets for dma_attach */
1118 snprintf(name, sizeof(name), "wl%d", unit); 1128 snprintf(name, sizeof(name), "wl%d", unit);
@@ -1125,12 +1135,12 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
1125 * TX: TX_AC_BK_FIFO (TX AC Background data packets) 1135 * TX: TX_AC_BK_FIFO (TX AC Background data packets)
1126 * RX: RX_FIFO (RX data packets) 1136 * RX: RX_FIFO (RX data packets)
1127 */ 1137 */
1128 wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, 1138 wlc_hw->di[0] = dma_attach(name, wlc,
1129 (wme ? dmareg(DMA_TX, 0) : 0), 1139 (wme ? dmareg(DMA_TX, 0) : 0),
1130 dmareg(DMA_RX, 0), 1140 dmareg(DMA_RX, 0),
1131 (wme ? NTXD : 0), NRXD, 1141 (wme ? NTXD : 0), NRXD,
1132 RXBUFSZ, -1, NRXBUFPOST, 1142 RXBUFSZ, -1, NRXBUFPOST,
1133 BRCMS_HWRXOFF, &brcm_msg_level); 1143 BRCMS_HWRXOFF);
1134 dma_attach_err |= (NULL == wlc_hw->di[0]); 1144 dma_attach_err |= (NULL == wlc_hw->di[0]);
1135 1145
1136 /* 1146 /*
@@ -1139,10 +1149,9 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
1139 * (legacy) TX_DATA_FIFO (TX data packets) 1149 * (legacy) TX_DATA_FIFO (TX data packets)
1140 * RX: UNUSED 1150 * RX: UNUSED
1141 */ 1151 */
1142 wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, 1152 wlc_hw->di[1] = dma_attach(name, wlc,
1143 dmareg(DMA_TX, 1), 0, 1153 dmareg(DMA_TX, 1), 0,
1144 NTXD, 0, 0, -1, 0, 0, 1154 NTXD, 0, 0, -1, 0, 0);
1145 &brcm_msg_level);
1146 dma_attach_err |= (NULL == wlc_hw->di[1]); 1155 dma_attach_err |= (NULL == wlc_hw->di[1]);
1147 1156
1148 /* 1157 /*
@@ -1150,26 +1159,26 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
1150 * TX: TX_AC_VI_FIFO (TX AC Video data packets) 1159 * TX: TX_AC_VI_FIFO (TX AC Video data packets)
1151 * RX: UNUSED 1160 * RX: UNUSED
1152 */ 1161 */
1153 wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, 1162 wlc_hw->di[2] = dma_attach(name, wlc,
1154 dmareg(DMA_TX, 2), 0, 1163 dmareg(DMA_TX, 2), 0,
1155 NTXD, 0, 0, -1, 0, 0, 1164 NTXD, 0, 0, -1, 0, 0);
1156 &brcm_msg_level);
1157 dma_attach_err |= (NULL == wlc_hw->di[2]); 1165 dma_attach_err |= (NULL == wlc_hw->di[2]);
1158 /* 1166 /*
1159 * FIFO 3 1167 * FIFO 3
1160 * TX: TX_AC_VO_FIFO (TX AC Voice data packets) 1168 * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
1161 * (legacy) TX_CTL_FIFO (TX control & mgmt packets) 1169 * (legacy) TX_CTL_FIFO (TX control & mgmt packets)
1162 */ 1170 */
1163 wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, 1171 wlc_hw->di[3] = dma_attach(name, wlc,
1164 dmareg(DMA_TX, 3), 1172 dmareg(DMA_TX, 3),
1165 0, NTXD, 0, 0, -1, 1173 0, NTXD, 0, 0, -1,
1166 0, 0, &brcm_msg_level); 1174 0, 0);
1167 dma_attach_err |= (NULL == wlc_hw->di[3]); 1175 dma_attach_err |= (NULL == wlc_hw->di[3]);
1168/* Cleaner to leave this as if with AP defined */ 1176/* Cleaner to leave this as if with AP defined */
1169 1177
1170 if (dma_attach_err) { 1178 if (dma_attach_err) {
1171 wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed" 1179 brcms_err(wlc_hw->d11core,
1172 "\n", unit); 1180 "wl%d: wlc_attach: dma_attach failed\n",
1181 unit);
1173 return false; 1182 return false;
1174 } 1183 }
1175 1184
@@ -1503,8 +1512,7 @@ brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset,
1503 u16 mac_m; 1512 u16 mac_m;
1504 u16 mac_h; 1513 u16 mac_h;
1505 1514
1506 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n", 1515 brcms_dbg_rx(core, "wl%d: brcms_b_set_addrmatch\n", wlc_hw->unit);
1507 wlc_hw->unit);
1508 1516
1509 mac_l = addr[0] | (addr[1] << 8); 1517 mac_l = addr[0] | (addr[1] << 8);
1510 mac_m = addr[2] | (addr[3] << 8); 1518 mac_m = addr[2] | (addr[3] << 8);
@@ -1527,7 +1535,7 @@ brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len,
1527 __le32 word_le; 1535 __le32 word_le;
1528 __be32 word_be; 1536 __be32 word_be;
1529 bool be_bit; 1537 bool be_bit;
1530 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); 1538 brcms_dbg_info(core, "wl%d\n", wlc_hw->unit);
1531 1539
1532 bcma_write32(core, D11REGOFFS(tplatewrptr), offset); 1540 bcma_write32(core, D11REGOFFS(tplatewrptr), offset);
1533 1541
@@ -1700,8 +1708,8 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
1700{ 1708{
1701 struct brcms_hardware *wlc_hw = wlc->hw; 1709 struct brcms_hardware *wlc_hw = wlc->hw;
1702 1710
1703 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, 1711 brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit,
1704 wlc_hw->band->bandunit); 1712 wlc_hw->band->bandunit);
1705 1713
1706 brcms_c_ucode_bsinit(wlc_hw); 1714 brcms_c_ucode_bsinit(wlc_hw);
1707 1715
@@ -1736,8 +1744,6 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
1736/* Perform a soft reset of the PHY PLL */ 1744/* Perform a soft reset of the PHY PLL */
1737void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) 1745void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw)
1738{ 1746{
1739 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1740
1741 ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr), 1747 ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr),
1742 ~0, 0); 1748 ~0, 0);
1743 udelay(1); 1749 udelay(1);
@@ -1782,7 +1788,7 @@ void brcms_b_phy_reset(struct brcms_hardware *wlc_hw)
1782 u32 phy_bw_clkbits; 1788 u32 phy_bw_clkbits;
1783 bool phy_in_reset = false; 1789 bool phy_in_reset = false;
1784 1790
1785 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); 1791 brcms_dbg_info(wlc_hw->d11core, "wl%d: reset phy\n", wlc_hw->unit);
1786 1792
1787 if (pih == NULL) 1793 if (pih == NULL)
1788 return; 1794 return;
@@ -1916,7 +1922,7 @@ static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_
1916/* power both the pll and external oscillator on/off */ 1922/* power both the pll and external oscillator on/off */
1917static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) 1923static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
1918{ 1924{
1919 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want); 1925 brcms_dbg_info(wlc_hw->d11core, "wl%d: want %d\n", wlc_hw->unit, want);
1920 1926
1921 /* 1927 /*
1922 * dont power down if plldown is false or 1928 * dont power down if plldown is false or
@@ -2005,7 +2011,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
2005 if (flags == BRCMS_USE_COREFLAGS) 2011 if (flags == BRCMS_USE_COREFLAGS)
2006 flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); 2012 flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
2007 2013
2008 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); 2014 brcms_dbg_info(wlc_hw->d11core, "wl%d: core reset\n", wlc_hw->unit);
2009 2015
2010 /* request FAST clock if not on */ 2016 /* request FAST clock if not on */
2011 fastclk = wlc_hw->forcefastclk; 2017 fastclk = wlc_hw->forcefastclk;
@@ -2016,13 +2022,13 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
2016 if (bcma_core_is_enabled(wlc_hw->d11core)) { 2022 if (bcma_core_is_enabled(wlc_hw->d11core)) {
2017 for (i = 0; i < NFIFO; i++) 2023 for (i = 0; i < NFIFO; i++)
2018 if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) 2024 if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i])))
2019 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: " 2025 brcms_err(wlc_hw->d11core, "wl%d: %s: "
2020 "dma_txreset[%d]: cannot stop dma\n", 2026 "dma_txreset[%d]: cannot stop dma\n",
2021 wlc_hw->unit, __func__, i); 2027 wlc_hw->unit, __func__, i);
2022 2028
2023 if ((wlc_hw->di[RX_FIFO]) 2029 if ((wlc_hw->di[RX_FIFO])
2024 && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) 2030 && (!wlc_dma_rxreset(wlc_hw, RX_FIFO)))
2025 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset" 2031 brcms_err(wlc_hw->d11core, "wl%d: %s: dma_rxreset"
2026 "[%d]: cannot stop dma\n", 2032 "[%d]: cannot stop dma\n",
2027 wlc_hw->unit, __func__, RX_FIFO); 2033 wlc_hw->unit, __func__, RX_FIFO);
2028 } 2034 }
@@ -2235,7 +2241,7 @@ static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
2235 uint i; 2241 uint i;
2236 uint count; 2242 uint count;
2237 2243
2238 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); 2244 brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
2239 2245
2240 count = (nbytes / sizeof(u32)); 2246 count = (nbytes / sizeof(u32));
2241 2247
@@ -2263,8 +2269,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
2263 ucode->bcm43xx_16_mimosz); 2269 ucode->bcm43xx_16_mimosz);
2264 wlc_hw->ucode_loaded = true; 2270 wlc_hw->ucode_loaded = true;
2265 } else 2271 } else
2266 wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " 2272 brcms_err(wlc_hw->d11core,
2267 "corerev %d\n", 2273 "%s: wl%d: unsupported phy in corerev %d\n",
2268 __func__, wlc_hw->unit, wlc_hw->corerev); 2274 __func__, wlc_hw->unit, wlc_hw->corerev);
2269 } else if (D11REV_IS(wlc_hw->corerev, 24)) { 2275 } else if (D11REV_IS(wlc_hw->corerev, 24)) {
2270 if (BRCMS_ISLCNPHY(wlc_hw->band)) { 2276 if (BRCMS_ISLCNPHY(wlc_hw->band)) {
@@ -2272,8 +2278,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
2272 ucode->bcm43xx_24_lcnsz); 2278 ucode->bcm43xx_24_lcnsz);
2273 wlc_hw->ucode_loaded = true; 2279 wlc_hw->ucode_loaded = true;
2274 } else { 2280 } else {
2275 wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " 2281 brcms_err(wlc_hw->d11core,
2276 "corerev %d\n", 2282 "%s: wl%d: unsupported phy in corerev %d\n",
2277 __func__, wlc_hw->unit, wlc_hw->corerev); 2283 __func__, wlc_hw->unit, wlc_hw->corerev);
2278 } 2284 }
2279 } 2285 }
@@ -2310,7 +2316,6 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
2310 uint unit; 2316 uint unit;
2311 uint intstatus, idx; 2317 uint intstatus, idx;
2312 struct bcma_device *core = wlc_hw->d11core; 2318 struct bcma_device *core = wlc_hw->d11core;
2313 struct wiphy *wiphy = wlc_hw->wlc->wiphy;
2314 2319
2315 unit = wlc_hw->unit; 2320 unit = wlc_hw->unit;
2316 2321
@@ -2323,39 +2328,39 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
2323 if (!intstatus) 2328 if (!intstatus)
2324 continue; 2329 continue;
2325 2330
2326 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n", 2331 brcms_dbg_int(core, "wl%d: intstatus%d 0x%x\n",
2327 unit, idx, intstatus); 2332 unit, idx, intstatus);
2328 2333
2329 if (intstatus & I_RO) { 2334 if (intstatus & I_RO) {
2330 wiphy_err(wiphy, "wl%d: fifo %d: receive fifo " 2335 brcms_err(core, "wl%d: fifo %d: receive fifo "
2331 "overflow\n", unit, idx); 2336 "overflow\n", unit, idx);
2332 fatal = true; 2337 fatal = true;
2333 } 2338 }
2334 2339
2335 if (intstatus & I_PC) { 2340 if (intstatus & I_PC) {
2336 wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n", 2341 brcms_err(core, "wl%d: fifo %d: descriptor error\n",
2337 unit, idx); 2342 unit, idx);
2338 fatal = true; 2343 fatal = true;
2339 } 2344 }
2340 2345
2341 if (intstatus & I_PD) { 2346 if (intstatus & I_PD) {
2342 wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit, 2347 brcms_err(core, "wl%d: fifo %d: data error\n", unit,
2343 idx); 2348 idx);
2344 fatal = true; 2349 fatal = true;
2345 } 2350 }
2346 2351
2347 if (intstatus & I_DE) { 2352 if (intstatus & I_DE) {
2348 wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol " 2353 brcms_err(core, "wl%d: fifo %d: descriptor protocol "
2349 "error\n", unit, idx); 2354 "error\n", unit, idx);
2350 fatal = true; 2355 fatal = true;
2351 } 2356 }
2352 2357
2353 if (intstatus & I_RU) 2358 if (intstatus & I_RU)
2354 wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor " 2359 brcms_err(core, "wl%d: fifo %d: receive descriptor "
2355 "underflow\n", idx, unit); 2360 "underflow\n", idx, unit);
2356 2361
2357 if (intstatus & I_XU) { 2362 if (intstatus & I_XU) {
2358 wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo " 2363 brcms_err(core, "wl%d: fifo %d: transmit fifo "
2359 "underflow\n", idx, unit); 2364 "underflow\n", idx, unit);
2360 fatal = true; 2365 fatal = true;
2361 } 2366 }
@@ -2516,13 +2521,13 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
2516{ 2521{
2517 struct brcms_hardware *wlc_hw = wlc->hw; 2522 struct brcms_hardware *wlc_hw = wlc->hw;
2518 struct bcma_device *core = wlc_hw->d11core; 2523 struct bcma_device *core = wlc_hw->d11core;
2519 u32 macintstatus; 2524 u32 macintstatus, mask;
2520 2525
2521 /* macintstatus includes a DMA interrupt summary bit */ 2526 /* macintstatus includes a DMA interrupt summary bit */
2522 macintstatus = bcma_read32(core, D11REGOFFS(macintstatus)); 2527 macintstatus = bcma_read32(core, D11REGOFFS(macintstatus));
2528 mask = in_isr ? wlc->macintmask : wlc->defmacintmask;
2523 2529
2524 BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit, 2530 trace_brcms_macintstatus(&core->dev, in_isr, macintstatus, mask);
2525 macintstatus);
2526 2531
2527 /* detect cardbus removed, in power down(suspend) and in reset */ 2532 /* detect cardbus removed, in power down(suspend) and in reset */
2528 if (brcms_deviceremoved(wlc)) 2533 if (brcms_deviceremoved(wlc))
@@ -2535,7 +2540,7 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
2535 return 0; 2540 return 0;
2536 2541
2537 /* defer unsolicited interrupts */ 2542 /* defer unsolicited interrupts */
2538 macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); 2543 macintstatus &= mask;
2539 2544
2540 /* if not for us */ 2545 /* if not for us */
2541 if (macintstatus == 0) 2546 if (macintstatus == 0)
@@ -2605,8 +2610,8 @@ bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc)
2605 macintstatus = wlc_intstatus(wlc, true); 2610 macintstatus = wlc_intstatus(wlc, true);
2606 2611
2607 if (macintstatus == 0xffffffff) 2612 if (macintstatus == 0xffffffff)
2608 wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code" 2613 brcms_err(wlc_hw->d11core,
2609 " path\n"); 2614 "DEVICEREMOVED detected in the ISR code path\n");
2610 2615
2611 /* it is not for us */ 2616 /* it is not for us */
2612 if (macintstatus == 0) 2617 if (macintstatus == 0)
@@ -2626,10 +2631,9 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
2626 struct brcms_hardware *wlc_hw = wlc->hw; 2631 struct brcms_hardware *wlc_hw = wlc->hw;
2627 struct bcma_device *core = wlc_hw->d11core; 2632 struct bcma_device *core = wlc_hw->d11core;
2628 u32 mc, mi; 2633 u32 mc, mi;
2629 struct wiphy *wiphy = wlc->wiphy;
2630 2634
2631 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, 2635 brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit,
2632 wlc_hw->band->bandunit); 2636 wlc_hw->band->bandunit);
2633 2637
2634 /* 2638 /*
2635 * Track overlapping suspend requests 2639 * Track overlapping suspend requests
@@ -2644,7 +2648,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
2644 mc = bcma_read32(core, D11REGOFFS(maccontrol)); 2648 mc = bcma_read32(core, D11REGOFFS(maccontrol));
2645 2649
2646 if (mc == 0xffffffff) { 2650 if (mc == 0xffffffff) {
2647 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, 2651 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
2648 __func__); 2652 __func__);
2649 brcms_down(wlc->wl); 2653 brcms_down(wlc->wl);
2650 return; 2654 return;
@@ -2655,7 +2659,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
2655 2659
2656 mi = bcma_read32(core, D11REGOFFS(macintstatus)); 2660 mi = bcma_read32(core, D11REGOFFS(macintstatus));
2657 if (mi == 0xffffffff) { 2661 if (mi == 0xffffffff) {
2658 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, 2662 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
2659 __func__); 2663 __func__);
2660 brcms_down(wlc->wl); 2664 brcms_down(wlc->wl);
2661 return; 2665 return;
@@ -2668,10 +2672,10 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
2668 BRCMS_MAX_MAC_SUSPEND); 2672 BRCMS_MAX_MAC_SUSPEND);
2669 2673
2670 if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) { 2674 if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) {
2671 wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" 2675 brcms_err(core, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
2672 " and MI_MACSSPNDD is still not on.\n", 2676 " and MI_MACSSPNDD is still not on.\n",
2673 wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); 2677 wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND);
2674 wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " 2678 brcms_err(core, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
2675 "psm_brc 0x%04x\n", wlc_hw->unit, 2679 "psm_brc 0x%04x\n", wlc_hw->unit,
2676 bcma_read32(core, D11REGOFFS(psmdebug)), 2680 bcma_read32(core, D11REGOFFS(psmdebug)),
2677 bcma_read32(core, D11REGOFFS(phydebug)), 2681 bcma_read32(core, D11REGOFFS(phydebug)),
@@ -2680,7 +2684,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
2680 2684
2681 mc = bcma_read32(core, D11REGOFFS(maccontrol)); 2685 mc = bcma_read32(core, D11REGOFFS(maccontrol));
2682 if (mc == 0xffffffff) { 2686 if (mc == 0xffffffff) {
2683 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, 2687 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
2684 __func__); 2688 __func__);
2685 brcms_down(wlc->wl); 2689 brcms_down(wlc->wl);
2686 return; 2690 return;
@@ -2696,8 +2700,8 @@ void brcms_c_enable_mac(struct brcms_c_info *wlc)
2696 struct bcma_device *core = wlc_hw->d11core; 2700 struct bcma_device *core = wlc_hw->d11core;
2697 u32 mc, mi; 2701 u32 mc, mi;
2698 2702
2699 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, 2703 brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit,
2700 wlc->band->bandunit); 2704 wlc->band->bandunit);
2701 2705
2702 /* 2706 /*
2703 * Track overlapping suspend requests 2707 * Track overlapping suspend requests
@@ -2740,8 +2744,6 @@ static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw)
2740 u32 w, val; 2744 u32 w, val;
2741 struct wiphy *wiphy = wlc_hw->wlc->wiphy; 2745 struct wiphy *wiphy = wlc_hw->wlc->wiphy;
2742 2746
2743 BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
2744
2745 /* Validate dchip register access */ 2747 /* Validate dchip register access */
2746 2748
2747 bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); 2749 bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
@@ -2802,7 +2804,7 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
2802 struct bcma_device *core = wlc_hw->d11core; 2804 struct bcma_device *core = wlc_hw->d11core;
2803 u32 tmp; 2805 u32 tmp;
2804 2806
2805 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); 2807 brcms_dbg_info(core, "wl%d\n", wlc_hw->unit);
2806 2808
2807 tmp = 0; 2809 tmp = 0;
2808 2810
@@ -2818,8 +2820,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
2818 2820
2819 tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st)); 2821 tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st));
2820 if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT) 2822 if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT)
2821 wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY" 2823 brcms_err(core, "%s: turn on PHY PLL failed\n",
2822 " PLL failed\n", __func__); 2824 __func__);
2823 } else { 2825 } else {
2824 bcma_set32(core, D11REGOFFS(clk_ctl_st), 2826 bcma_set32(core, D11REGOFFS(clk_ctl_st),
2825 tmp | CCS_ERSRC_REQ_D11PLL | 2827 tmp | CCS_ERSRC_REQ_D11PLL |
@@ -2835,8 +2837,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
2835 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) 2837 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
2836 != 2838 !=
2837 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) 2839 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
2838 wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on " 2840 brcms_err(core, "%s: turn on PHY PLL failed\n",
2839 "PHY PLL failed\n", __func__); 2841 __func__);
2840 } 2842 }
2841 } else { 2843 } else {
2842 /* 2844 /*
@@ -2854,7 +2856,7 @@ static void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
2854{ 2856{
2855 bool dev_gone; 2857 bool dev_gone;
2856 2858
2857 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); 2859 brcms_dbg_info(wlc_hw->d11core, "wl%d: disable core\n", wlc_hw->unit);
2858 2860
2859 dev_gone = brcms_deviceremoved(wlc_hw->wlc); 2861 dev_gone = brcms_deviceremoved(wlc_hw->wlc);
2860 2862
@@ -2884,12 +2886,14 @@ static void brcms_c_flushqueues(struct brcms_c_info *wlc)
2884 uint i; 2886 uint i;
2885 2887
2886 /* free any posted tx packets */ 2888 /* free any posted tx packets */
2887 for (i = 0; i < NFIFO; i++) 2889 for (i = 0; i < NFIFO; i++) {
2888 if (wlc_hw->di[i]) { 2890 if (wlc_hw->di[i]) {
2889 dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); 2891 dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL);
2890 wlc->core->txpktpend[i] = 0; 2892 if (i < TX_BCMC_FIFO)
2891 BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i); 2893 ieee80211_wake_queue(wlc->pub->ieee_hw,
2894 brcms_fifo_to_ac(i));
2892 } 2895 }
2896 }
2893 2897
2894 /* free any posted rx packets */ 2898 /* free any posted rx packets */
2895 dma_rxreclaim(wlc_hw->di[RX_FIFO]); 2899 dma_rxreclaim(wlc_hw->di[RX_FIFO]);
@@ -3109,7 +3113,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc)
3109 /* check for rx fifo 0 overflow */ 3113 /* check for rx fifo 0 overflow */
3110 delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); 3114 delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
3111 if (delta) 3115 if (delta)
3112 wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n", 3116 brcms_err(wlc->hw->d11core, "wl%d: %u rx fifo 0 overflows!\n",
3113 wlc->pub->unit, delta); 3117 wlc->pub->unit, delta);
3114 3118
3115 /* check for tx fifo underflows */ 3119 /* check for tx fifo underflows */
@@ -3118,8 +3122,9 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc)
3118 (u16) (wlc->core->macstat_snapshot->txfunfl[i] - 3122 (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
3119 txfunfl[i]); 3123 txfunfl[i]);
3120 if (delta) 3124 if (delta)
3121 wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!" 3125 brcms_err(wlc->hw->d11core,
3122 "\n", wlc->pub->unit, delta, i); 3126 "wl%d: %u tx fifo %d underflows!\n",
3127 wlc->pub->unit, delta, i);
3123 } 3128 }
3124#endif /* DEBUG */ 3129#endif /* DEBUG */
3125 3130
@@ -3132,8 +3137,6 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc)
3132 3137
3133static void brcms_b_reset(struct brcms_hardware *wlc_hw) 3138static void brcms_b_reset(struct brcms_hardware *wlc_hw)
3134{ 3139{
3135 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
3136
3137 /* reset the core */ 3140 /* reset the core */
3138 if (!brcms_deviceremoved(wlc_hw->wlc)) 3141 if (!brcms_deviceremoved(wlc_hw->wlc))
3139 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); 3142 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
@@ -3144,7 +3147,7 @@ static void brcms_b_reset(struct brcms_hardware *wlc_hw)
3144 3147
3145void brcms_c_reset(struct brcms_c_info *wlc) 3148void brcms_c_reset(struct brcms_c_info *wlc)
3146{ 3149{
3147 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); 3150 brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);
3148 3151
3149 /* slurp up hw mac counters before core reset */ 3152 /* slurp up hw mac counters before core reset */
3150 brcms_c_statsupd(wlc); 3153 brcms_c_statsupd(wlc);
@@ -3189,10 +3192,9 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc)
3189 bool fifosz_fixup = false; 3192 bool fifosz_fixup = false;
3190 int err = 0; 3193 int err = 0;
3191 u16 buf[NFIFO]; 3194 u16 buf[NFIFO];
3192 struct wiphy *wiphy = wlc->wiphy;
3193 struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; 3195 struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
3194 3196
3195 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); 3197 brcms_dbg_info(core, "wl%d: core init\n", wlc_hw->unit);
3196 3198
3197 /* reset PSM */ 3199 /* reset PSM */
3198 brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); 3200 brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
@@ -3212,7 +3214,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc)
3212 SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) & 3214 SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) &
3213 MI_MACSSPNDD) == 0), 1000 * 1000); 3215 MI_MACSSPNDD) == 0), 1000 * 1000);
3214 if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0) 3216 if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0)
3215 wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-" 3217 brcms_err(core, "wl%d: wlc_coreinit: ucode did not self-"
3216 "suspend!\n", wlc_hw->unit); 3218 "suspend!\n", wlc_hw->unit);
3217 3219
3218 brcms_c_gpio_init(wlc); 3220 brcms_c_gpio_init(wlc);
@@ -3223,18 +3225,18 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc)
3223 if (BRCMS_ISNPHY(wlc_hw->band)) 3225 if (BRCMS_ISNPHY(wlc_hw->band))
3224 brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); 3226 brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
3225 else 3227 else
3226 wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" 3228 brcms_err(core, "%s: wl%d: unsupported phy in corerev"
3227 " %d\n", __func__, wlc_hw->unit, 3229 " %d\n", __func__, wlc_hw->unit,
3228 wlc_hw->corerev); 3230 wlc_hw->corerev);
3229 } else if (D11REV_IS(wlc_hw->corerev, 24)) { 3231 } else if (D11REV_IS(wlc_hw->corerev, 24)) {
3230 if (BRCMS_ISLCNPHY(wlc_hw->band)) 3232 if (BRCMS_ISLCNPHY(wlc_hw->band))
3231 brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24); 3233 brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24);
3232 else 3234 else
3233 wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" 3235 brcms_err(core, "%s: wl%d: unsupported phy in corerev"
3234 " %d\n", __func__, wlc_hw->unit, 3236 " %d\n", __func__, wlc_hw->unit,
3235 wlc_hw->corerev); 3237 wlc_hw->corerev);
3236 } else { 3238 } else {
3237 wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", 3239 brcms_err(core, "%s: wl%d: unsupported corerev %d\n",
3238 __func__, wlc_hw->unit, wlc_hw->corerev); 3240 __func__, wlc_hw->unit, wlc_hw->corerev);
3239 } 3241 }
3240 3242
@@ -3276,7 +3278,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc)
3276 err = -1; 3278 err = -1;
3277 } 3279 }
3278 if (err != 0) 3280 if (err != 0)
3279 wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d" 3281 brcms_err(core, "wlc_coreinit: txfifo mismatch: ucode size %d"
3280 " driver size %d index %d\n", buf[i], 3282 " driver size %d index %d\n", buf[i],
3281 wlc_hw->xmtfifo_sz[i], i); 3283 wlc_hw->xmtfifo_sz[i], i);
3282 3284
@@ -3359,8 +3361,6 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) {
3359 bool fastclk; 3361 bool fastclk;
3360 struct brcms_c_info *wlc = wlc_hw->wlc; 3362 struct brcms_c_info *wlc = wlc_hw->wlc;
3361 3363
3362 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
3363
3364 /* request FAST clock if not on */ 3364 /* request FAST clock if not on */
3365 fastclk = wlc_hw->forcefastclk; 3365 fastclk = wlc_hw->forcefastclk;
3366 if (!fastclk) 3366 if (!fastclk)
@@ -3453,7 +3453,7 @@ static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
3453 rate = (rateset->rates[i] & BRCMS_RATE_MASK); 3453 rate = (rateset->rates[i] & BRCMS_RATE_MASK);
3454 3454
3455 if (rate > BRCM_MAXRATE) { 3455 if (rate > BRCM_MAXRATE) {
3456 wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: " 3456 brcms_err(wlc->hw->d11core, "brcms_c_rate_lookup_init: "
3457 "invalid rate 0x%X in rate set\n", 3457 "invalid rate 0x%X in rate set\n",
3458 rateset->rates[i]); 3458 rateset->rates[i]);
3459 continue; 3459 continue;
@@ -3529,7 +3529,6 @@ static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
3529 uint parkband; 3529 uint parkband;
3530 uint i, band_order[2]; 3530 uint i, band_order[2];
3531 3531
3532 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
3533 /* 3532 /*
3534 * We might have been bandlocked during down and the chip 3533 * We might have been bandlocked during down and the chip
3535 * power-cycled (hibernate). Figure out the right band to park on 3534 * power-cycled (hibernate). Figure out the right band to park on
@@ -3710,8 +3709,8 @@ static void brcms_c_set_ratetable(struct brcms_c_info *wlc)
3710/* band-specific init */ 3709/* band-specific init */
3711static void brcms_c_bsinit(struct brcms_c_info *wlc) 3710static void brcms_c_bsinit(struct brcms_c_info *wlc)
3712{ 3711{
3713 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", 3712 brcms_dbg_info(wlc->hw->d11core, "wl%d: bandunit %d\n",
3714 wlc->pub->unit, wlc->band->bandunit); 3713 wlc->pub->unit, wlc->band->bandunit);
3715 3714
3716 /* write ucode ACK/CTS rate table */ 3715 /* write ucode ACK/CTS rate table */
3717 brcms_c_set_ratetable(wlc); 3716 brcms_c_set_ratetable(wlc);
@@ -3734,7 +3733,8 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
3734 isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : 3733 isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
3735 M_TX_IDLE_BUSY_RATIO_X_16_CCK; 3734 M_TX_IDLE_BUSY_RATIO_X_16_CCK;
3736 if (duty_cycle > 100 || duty_cycle < 0) { 3735 if (duty_cycle > 100 || duty_cycle < 0) {
3737 wiphy_err(wlc->wiphy, "wl%d: duty cycle value off limit\n", 3736 brcms_err(wlc->hw->d11core,
3737 "wl%d: duty cycle value off limit\n",
3738 wlc->pub->unit); 3738 wlc->pub->unit);
3739 return -EINVAL; 3739 return -EINVAL;
3740 } 3740 }
@@ -3752,40 +3752,6 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
3752 return 0; 3752 return 0;
3753} 3753}
3754 3754
3755/*
3756 * Initialize the base precedence map for dequeueing
3757 * from txq based on WME settings
3758 */
3759static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
3760{
3761 wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
3762 memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
3763
3764 wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK;
3765 wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE;
3766 wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI;
3767 wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
3768}
3769
3770static void
3771brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
3772 struct brcms_txq_info *qi, bool on, int prio)
3773{
3774 /* transmit flowcontrol is not yet implemented */
3775}
3776
3777static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc)
3778{
3779 struct brcms_txq_info *qi;
3780
3781 for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
3782 if (qi->stopped) {
3783 brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
3784 qi->stopped = 0;
3785 }
3786 }
3787}
3788
3789/* push sw hps and wake state through hardware */ 3755/* push sw hps and wake state through hardware */
3790static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) 3756static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
3791{ 3757{
@@ -3795,7 +3761,8 @@ static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
3795 3761
3796 hps = brcms_c_ps_allowed(wlc); 3762 hps = brcms_c_ps_allowed(wlc);
3797 3763
3798 BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps); 3764 brcms_dbg_mac80211(wlc->hw->d11core, "wl%d: hps %d\n", wlc->pub->unit,
3765 hps);
3799 3766
3800 v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); 3767 v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
3801 v2 = MCTL_WAKE; 3768 v2 = MCTL_WAKE;
@@ -3881,7 +3848,8 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
3881{ 3848{
3882 uint bandunit; 3849 uint bandunit;
3883 3850
3884 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec); 3851 brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: 0x%x\n", wlc_hw->unit,
3852 chanspec);
3885 3853
3886 wlc_hw->chanspec = chanspec; 3854 wlc_hw->chanspec = chanspec;
3887 3855
@@ -3942,7 +3910,7 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
3942 u16 old_chanspec = wlc->chanspec; 3910 u16 old_chanspec = wlc->chanspec;
3943 3911
3944 if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) { 3912 if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) {
3945 wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n", 3913 brcms_err(wlc->hw->d11core, "wl%d: %s: Bad channel %d\n",
3946 wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); 3914 wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
3947 return; 3915 return;
3948 } 3916 }
@@ -3953,8 +3921,8 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
3953 if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { 3921 if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
3954 switchband = true; 3922 switchband = true;
3955 if (wlc->bandlocked) { 3923 if (wlc->bandlocked) {
3956 wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d " 3924 brcms_err(wlc->hw->d11core,
3957 "band is locked!\n", 3925 "wl%d: %s: chspec %d band is locked!\n",
3958 wlc->pub->unit, __func__, 3926 wlc->pub->unit, __func__,
3959 CHSPEC_CHANNEL(chanspec)); 3927 CHSPEC_CHANNEL(chanspec));
3960 return; 3928 return;
@@ -4018,6 +3986,10 @@ void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
4018 */ 3986 */
4019void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val) 3987void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
4020{ 3988{
3989 /*
3990 * Cannot use brcms_dbg_* here because this function is called
3991 * before wlc is sufficiently initialized.
3992 */
4021 BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); 3993 BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
4022 3994
4023 switch (idx) { 3995 switch (idx) {
@@ -4090,8 +4062,8 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
4090 4062
4091 /* Only apply params if the core is out of reset and has clocks */ 4063 /* Only apply params if the core is out of reset and has clocks */
4092 if (!wlc->clk) { 4064 if (!wlc->clk) {
4093 wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit, 4065 brcms_err(wlc->hw->d11core, "wl%d: %s : no-clock\n",
4094 __func__); 4066 wlc->pub->unit, __func__);
4095 return; 4067 return;
4096 } 4068 }
4097 4069
@@ -4109,7 +4081,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
4109 4081
4110 if (acp_shm.aifs < EDCF_AIFSN_MIN 4082 if (acp_shm.aifs < EDCF_AIFSN_MIN
4111 || acp_shm.aifs > EDCF_AIFSN_MAX) { 4083 || acp_shm.aifs > EDCF_AIFSN_MAX) {
4112 wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad " 4084 brcms_err(wlc->hw->d11core, "wl%d: edcf_setparams: bad "
4113 "aifs %d\n", wlc->pub->unit, acp_shm.aifs); 4085 "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
4114 } else { 4086 } else {
4115 acp_shm.cwmin = params->cw_min; 4087 acp_shm.cwmin = params->cw_min;
@@ -4224,8 +4196,8 @@ static void brcms_c_radio_timer(void *arg)
4224 struct brcms_c_info *wlc = (struct brcms_c_info *) arg; 4196 struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
4225 4197
4226 if (brcms_deviceremoved(wlc)) { 4198 if (brcms_deviceremoved(wlc)) {
4227 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, 4199 brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n",
4228 __func__); 4200 wlc->pub->unit, __func__);
4229 brcms_down(wlc->wl); 4201 brcms_down(wlc->wl);
4230 return; 4202 return;
4231 } 4203 }
@@ -4238,8 +4210,6 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc)
4238{ 4210{
4239 struct brcms_hardware *wlc_hw = wlc->hw; 4211 struct brcms_hardware *wlc_hw = wlc->hw;
4240 4212
4241 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
4242
4243 if (!wlc_hw->up) 4213 if (!wlc_hw->up)
4244 return; 4214 return;
4245 4215
@@ -4258,14 +4228,14 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc)
4258/* common watchdog code */ 4228/* common watchdog code */
4259static void brcms_c_watchdog(struct brcms_c_info *wlc) 4229static void brcms_c_watchdog(struct brcms_c_info *wlc)
4260{ 4230{
4261 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); 4231 brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);
4262 4232
4263 if (!wlc->pub->up) 4233 if (!wlc->pub->up)
4264 return; 4234 return;
4265 4235
4266 if (brcms_deviceremoved(wlc)) { 4236 if (brcms_deviceremoved(wlc)) {
4267 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, 4237 brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n",
4268 __func__); 4238 wlc->pub->unit, __func__);
4269 brcms_down(wlc->wl); 4239 brcms_down(wlc->wl);
4270 return; 4240 return;
4271 } 4241 }
@@ -4437,13 +4407,13 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4437 struct ssb_sprom *sprom = &core->bus->sprom; 4407 struct ssb_sprom *sprom = &core->bus->sprom;
4438 4408
4439 if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) 4409 if (core->bus->hosttype == BCMA_HOSTTYPE_PCI)
4440 BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, 4410 brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit,
4441 pcidev->vendor, 4411 pcidev->vendor,
4442 pcidev->device); 4412 pcidev->device);
4443 else 4413 else
4444 BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, 4414 brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit,
4445 core->bus->boardinfo.vendor, 4415 core->bus->boardinfo.vendor,
4446 core->bus->boardinfo.type); 4416 core->bus->boardinfo.type);
4447 4417
4448 wme = true; 4418 wme = true;
4449 4419
@@ -4715,8 +4685,9 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4715 goto fail; 4685 goto fail;
4716 } 4686 }
4717 4687
4718 BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n", 4688 brcms_dbg_info(wlc_hw->d11core, "deviceid 0x%x nbands %d board 0x%x\n",
4719 wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih)); 4689 wlc_hw->deviceid, wlc_hw->_nbands,
4690 ai_get_boardtype(wlc_hw->sih));
4720 4691
4721 return err; 4692 return err;
4722 4693
@@ -4836,56 +4807,6 @@ static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
4836 bi->flags |= BRCMS_BSS_HT; 4807 bi->flags |= BRCMS_BSS_HT;
4837} 4808}
4838 4809
4839static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc)
4840{
4841 struct brcms_txq_info *qi, *p;
4842
4843 qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC);
4844 if (qi != NULL) {
4845 /*
4846 * Have enough room for control packets along with HI watermark
4847 * Also, add room to txq for total psq packets if all the SCBs
4848 * leave PS mode. The watermark for flowcontrol to OS packets
4849 * will remain the same
4850 */
4851 brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT,
4852 2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT);
4853
4854 /* add this queue to the the global list */
4855 p = wlc->tx_queues;
4856 if (p == NULL) {
4857 wlc->tx_queues = qi;
4858 } else {
4859 while (p->next != NULL)
4860 p = p->next;
4861 p->next = qi;
4862 }
4863 }
4864 return qi;
4865}
4866
4867static void brcms_c_txq_free(struct brcms_c_info *wlc,
4868 struct brcms_txq_info *qi)
4869{
4870 struct brcms_txq_info *p;
4871
4872 if (qi == NULL)
4873 return;
4874
4875 /* remove the queue from the linked list */
4876 p = wlc->tx_queues;
4877 if (p == qi)
4878 wlc->tx_queues = p->next;
4879 else {
4880 while (p != NULL && p->next != qi)
4881 p = p->next;
4882 if (p != NULL)
4883 p->next = p->next->next;
4884 }
4885
4886 kfree(qi);
4887}
4888
4889static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap) 4810static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
4890{ 4811{
4891 uint i; 4812 uint i;
@@ -4991,8 +4912,6 @@ uint brcms_c_detach(struct brcms_c_info *wlc)
4991 if (wlc == NULL) 4912 if (wlc == NULL)
4992 return 0; 4913 return 0;
4993 4914
4994 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
4995
4996 callbacks += brcms_b_detach(wlc); 4915 callbacks += brcms_b_detach(wlc);
4997 4916
4998 /* delete software timers */ 4917 /* delete software timers */
@@ -5005,10 +4924,6 @@ uint brcms_c_detach(struct brcms_c_info *wlc)
5005 4924
5006 brcms_c_detach_module(wlc); 4925 brcms_c_detach_module(wlc);
5007 4926
5008
5009 while (wlc->tx_queues != NULL)
5010 brcms_c_txq_free(wlc, wlc->tx_queues);
5011
5012 brcms_c_detach_mfree(wlc); 4927 brcms_c_detach_mfree(wlc);
5013 return callbacks; 4928 return callbacks;
5014} 4929}
@@ -5026,7 +4941,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
5026 if (wlc_hw->wlc->pub->hw_up) 4941 if (wlc_hw->wlc->pub->hw_up)
5027 return; 4942 return;
5028 4943
5029 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); 4944 brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
5030 4945
5031 /* 4946 /*
5032 * Enable pll and xtal, initialize the power control registers, 4947 * Enable pll and xtal, initialize the power control registers,
@@ -5063,7 +4978,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
5063 4978
5064static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) 4979static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
5065{ 4980{
5066 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); 4981 brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
5067 4982
5068 /* 4983 /*
5069 * Enable pll and xtal, initialize the power control registers, 4984 * Enable pll and xtal, initialize the power control registers,
@@ -5102,8 +5017,6 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
5102 5017
5103static int brcms_b_up_finish(struct brcms_hardware *wlc_hw) 5018static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
5104{ 5019{
5105 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5106
5107 wlc_hw->up = true; 5020 wlc_hw->up = true;
5108 wlc_phy_hw_state_upd(wlc_hw->band->pi, true); 5021 wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
5109 5022
@@ -5135,7 +5048,7 @@ int brcms_c_up(struct brcms_c_info *wlc)
5135{ 5048{
5136 struct ieee80211_channel *ch; 5049 struct ieee80211_channel *ch;
5137 5050
5138 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); 5051 brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);
5139 5052
5140 /* HW is turned off so don't try to access it */ 5053 /* HW is turned off so don't try to access it */
5141 if (wlc->pub->hw_off || brcms_deviceremoved(wlc)) 5054 if (wlc->pub->hw_off || brcms_deviceremoved(wlc))
@@ -5176,8 +5089,8 @@ int brcms_c_up(struct brcms_c_info *wlc)
5176 WL_RADIO_HW_DISABLE); 5089 WL_RADIO_HW_DISABLE);
5177 5090
5178 if (bsscfg->enable && bsscfg->BSS) 5091 if (bsscfg->enable && bsscfg->BSS)
5179 wiphy_err(wlc->wiphy, "wl%d: up" 5092 brcms_err(wlc->hw->d11core,
5180 ": rfdisable -> " 5093 "wl%d: up: rfdisable -> "
5181 "bsscfg_disable()\n", 5094 "bsscfg_disable()\n",
5182 wlc->pub->unit); 5095 wlc->pub->unit);
5183 } 5096 }
@@ -5237,8 +5150,6 @@ static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
5237 bool dev_gone; 5150 bool dev_gone;
5238 uint callbacks = 0; 5151 uint callbacks = 0;
5239 5152
5240 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5241
5242 if (!wlc_hw->up) 5153 if (!wlc_hw->up)
5243 return callbacks; 5154 return callbacks;
5244 5155
@@ -5265,8 +5176,6 @@ static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
5265 uint callbacks = 0; 5176 uint callbacks = 0;
5266 bool dev_gone; 5177 bool dev_gone;
5267 5178
5268 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5269
5270 if (!wlc_hw->up) 5179 if (!wlc_hw->up)
5271 return callbacks; 5180 return callbacks;
5272 5181
@@ -5314,14 +5223,14 @@ uint brcms_c_down(struct brcms_c_info *wlc)
5314 uint callbacks = 0; 5223 uint callbacks = 0;
5315 int i; 5224 int i;
5316 bool dev_gone = false; 5225 bool dev_gone = false;
5317 struct brcms_txq_info *qi;
5318 5226
5319 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); 5227 brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);
5320 5228
5321 /* check if we are already in the going down path */ 5229 /* check if we are already in the going down path */
5322 if (wlc->going_down) { 5230 if (wlc->going_down) {
5323 wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return" 5231 brcms_err(wlc->hw->d11core,
5324 "\n", wlc->pub->unit, __func__); 5232 "wl%d: %s: Driver going down so return\n",
5233 wlc->pub->unit, __func__);
5325 return 0; 5234 return 0;
5326 } 5235 }
5327 if (!wlc->pub->up) 5236 if (!wlc->pub->up)
@@ -5353,13 +5262,6 @@ uint brcms_c_down(struct brcms_c_info *wlc)
5353 5262
5354 wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); 5263 wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
5355 5264
5356 /* clear txq flow control */
5357 brcms_c_txflowcontrol_reset(wlc);
5358
5359 /* flush tx queues */
5360 for (qi = wlc->tx_queues; qi != NULL; qi = qi->next)
5361 brcmu_pktq_flush(&qi->q, true, NULL, NULL);
5362
5363 callbacks += brcms_b_down_finish(wlc->hw); 5265 callbacks += brcms_b_down_finish(wlc->hw);
5364 5266
5365 /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */ 5267 /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
@@ -5441,7 +5343,7 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
5441 5343
5442 default: 5344 default:
5443 /* Error */ 5345 /* Error */
5444 wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n", 5346 brcms_err(wlc->hw->d11core, "wl%d: %s: invalid gmode %d\n",
5445 wlc->pub->unit, __func__, gmode); 5347 wlc->pub->unit, __func__, gmode);
5446 return -ENOTSUPP; 5348 return -ENOTSUPP;
5447 } 5349 }
@@ -5745,45 +5647,6 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
5745 return -ENODATA; 5647 return -ENODATA;
5746} 5648}
5747 5649
5748void brcms_c_print_txstatus(struct tx_status *txs)
5749{
5750 pr_debug("\ntxpkt (MPDU) Complete\n");
5751
5752 pr_debug("FrameID: %04x TxStatus: %04x\n", txs->frameid, txs->status);
5753
5754 pr_debug("[15:12] %d frame attempts\n",
5755 (txs->status & TX_STATUS_FRM_RTX_MASK) >>
5756 TX_STATUS_FRM_RTX_SHIFT);
5757 pr_debug(" [11:8] %d rts attempts\n",
5758 (txs->status & TX_STATUS_RTS_RTX_MASK) >>
5759 TX_STATUS_RTS_RTX_SHIFT);
5760 pr_debug(" [7] %d PM mode indicated\n",
5761 txs->status & TX_STATUS_PMINDCTD ? 1 : 0);
5762 pr_debug(" [6] %d intermediate status\n",
5763 txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0);
5764 pr_debug(" [5] %d AMPDU\n",
5765 txs->status & TX_STATUS_AMPDU ? 1 : 0);
5766 pr_debug(" [4:2] %d Frame Suppressed Reason (%s)\n",
5767 (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT,
5768 (const char *[]) {
5769 "None",
5770 "PMQ Entry",
5771 "Flush request",
5772 "Previous frag failure",
5773 "Channel mismatch",
5774 "Lifetime Expiry",
5775 "Underflow"
5776 } [(txs->status & TX_STATUS_SUPR_MASK) >>
5777 TX_STATUS_SUPR_SHIFT]);
5778 pr_debug(" [1] %d acked\n",
5779 txs->status & TX_STATUS_ACK_RCV ? 1 : 0);
5780
5781 pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n",
5782 txs->lasttxtime, txs->sequence, txs->phyerr,
5783 (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT,
5784 (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
5785}
5786
5787static bool brcms_c_chipmatch_pci(struct bcma_device *core) 5650static bool brcms_c_chipmatch_pci(struct bcma_device *core)
5788{ 5651{
5789 struct pci_dev *pcidev = core->bus->host_pci; 5652 struct pci_dev *pcidev = core->bus->host_pci;
@@ -5832,184 +5695,6 @@ bool brcms_c_chipmatch(struct bcma_device *core)
5832 } 5695 }
5833} 5696}
5834 5697
5835#if defined(DEBUG)
5836void brcms_c_print_txdesc(struct d11txh *txh)
5837{
5838 u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
5839 u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
5840 u16 mfc = le16_to_cpu(txh->MacFrameControl);
5841 u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
5842 u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
5843 u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
5844 u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
5845 u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
5846 u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
5847 u16 mainrates = le16_to_cpu(txh->MainRates);
5848 u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
5849 u8 *iv = txh->IV;
5850 u8 *ra = txh->TxFrameRA;
5851 u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
5852 u8 *rtspfb = txh->RTSPLCPFallback;
5853 u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
5854 u8 *fragpfb = txh->FragPLCPFallback;
5855 u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
5856 u16 mmodelen = le16_to_cpu(txh->MModeLen);
5857 u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
5858 u16 tfid = le16_to_cpu(txh->TxFrameID);
5859 u16 txs = le16_to_cpu(txh->TxStatus);
5860 u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
5861 u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
5862 u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
5863 u16 mmbyte = le16_to_cpu(txh->MinMBytes);
5864
5865 u8 *rtsph = txh->RTSPhyHeader;
5866 struct ieee80211_rts rts = txh->rts_frame;
5867
5868 /* add plcp header along with txh descriptor */
5869 brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48,
5870 "Raw TxDesc + plcp header:\n");
5871
5872 pr_debug("TxCtlLow: %04x ", mtcl);
5873 pr_debug("TxCtlHigh: %04x ", mtch);
5874 pr_debug("FC: %04x ", mfc);
5875 pr_debug("FES Time: %04x\n", tfest);
5876 pr_debug("PhyCtl: %04x%s ", ptcw,
5877 (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
5878 pr_debug("PhyCtl_1: %04x ", ptcw_1);
5879 pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
5880 pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
5881 pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
5882 pr_debug("MainRates: %04x ", mainrates);
5883 pr_debug("XtraFrameTypes: %04x ", xtraft);
5884 pr_debug("\n");
5885
5886 print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV));
5887 print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET,
5888 ra, sizeof(txh->TxFrameRA));
5889
5890 pr_debug("Fb FES Time: %04x ", tfestfb);
5891 print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET,
5892 rtspfb, sizeof(txh->RTSPLCPFallback));
5893 pr_debug("RTS DUR: %04x ", rtsdfb);
5894 print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET,
5895 fragpfb, sizeof(txh->FragPLCPFallback));
5896 pr_debug("DUR: %04x", fragdfb);
5897 pr_debug("\n");
5898
5899 pr_debug("MModeLen: %04x ", mmodelen);
5900 pr_debug("MModeFbrLen: %04x\n", mmodefbrlen);
5901
5902 pr_debug("FrameID: %04x\n", tfid);
5903 pr_debug("TxStatus: %04x\n", txs);
5904
5905 pr_debug("MaxNumMpdu: %04x\n", mnmpdu);
5906 pr_debug("MaxAggbyte: %04x\n", mabyte);
5907 pr_debug("MaxAggbyte_fb: %04x\n", mabyte_f);
5908 pr_debug("MinByte: %04x\n", mmbyte);
5909
5910 print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET,
5911 rtsph, sizeof(txh->RTSPhyHeader));
5912 print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET,
5913 (u8 *)&rts, sizeof(txh->rts_frame));
5914 pr_debug("\n");
5915}
5916#endif /* defined(DEBUG) */
5917
5918#if defined(DEBUG)
5919static int
5920brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
5921 int len)
5922{
5923 int i;
5924 char *p = buf;
5925 char hexstr[16];
5926 int slen = 0, nlen = 0;
5927 u32 bit;
5928 const char *name;
5929
5930 if (len < 2 || !buf)
5931 return 0;
5932
5933 buf[0] = '\0';
5934
5935 for (i = 0; flags != 0; i++) {
5936 bit = bd[i].bit;
5937 name = bd[i].name;
5938 if (bit == 0 && flags != 0) {
5939 /* print any unnamed bits */
5940 snprintf(hexstr, 16, "0x%X", flags);
5941 name = hexstr;
5942 flags = 0; /* exit loop */
5943 } else if ((flags & bit) == 0)
5944 continue;
5945 flags &= ~bit;
5946 nlen = strlen(name);
5947 slen += nlen;
5948 /* count btwn flag space */
5949 if (flags != 0)
5950 slen += 1;
5951 /* need NULL char as well */
5952 if (len <= slen)
5953 break;
5954 /* copy NULL char but don't count it */
5955 strncpy(p, name, nlen + 1);
5956 p += nlen;
5957 /* copy btwn flag space and NULL char */
5958 if (flags != 0)
5959 p += snprintf(p, 2, " ");
5960 len -= slen;
5961 }
5962
5963 /* indicate the str was too short */
5964 if (flags != 0) {
5965 if (len < 2)
5966 p -= 2 - len; /* overwrite last char */
5967 p += snprintf(p, 2, ">");
5968 }
5969
5970 return (int)(p - buf);
5971}
5972#endif /* defined(DEBUG) */
5973
5974#if defined(DEBUG)
5975void brcms_c_print_rxh(struct d11rxhdr *rxh)
5976{
5977 u16 len = rxh->RxFrameSize;
5978 u16 phystatus_0 = rxh->PhyRxStatus_0;
5979 u16 phystatus_1 = rxh->PhyRxStatus_1;
5980 u16 phystatus_2 = rxh->PhyRxStatus_2;
5981 u16 phystatus_3 = rxh->PhyRxStatus_3;
5982 u16 macstatus1 = rxh->RxStatus1;
5983 u16 macstatus2 = rxh->RxStatus2;
5984 char flagstr[64];
5985 char lenbuf[20];
5986 static const struct brcms_c_bit_desc macstat_flags[] = {
5987 {RXS_FCSERR, "FCSErr"},
5988 {RXS_RESPFRAMETX, "Reply"},
5989 {RXS_PBPRES, "PADDING"},
5990 {RXS_DECATMPT, "DeCr"},
5991 {RXS_DECERR, "DeCrErr"},
5992 {RXS_BCNSENT, "Bcn"},
5993 {0, NULL}
5994 };
5995
5996 brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n");
5997
5998 brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64);
5999
6000 snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
6001
6002 pr_debug("RxFrameSize: %6s (%d)%s\n", lenbuf, len,
6003 (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
6004 pr_debug("RxPHYStatus: %04x %04x %04x %04x\n",
6005 phystatus_0, phystatus_1, phystatus_2, phystatus_3);
6006 pr_debug("RxMACStatus: %x %s\n", macstatus1, flagstr);
6007 pr_debug("RXMACaggtype: %x\n",
6008 (macstatus2 & RXS_AGGTYPE_MASK));
6009 pr_debug("RxTSFTime: %04x\n", rxh->RxTSFTime);
6010}
6011#endif /* defined(DEBUG) */
6012
6013u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) 5698u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
6014{ 5699{
6015 u16 table_ptr; 5700 u16 table_ptr;
@@ -6033,86 +5718,6 @@ u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
6033 return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); 5718 return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2));
6034} 5719}
6035 5720
6036static bool
6037brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
6038 struct sk_buff *pkt, int prec, bool head)
6039{
6040 struct sk_buff *p;
6041 int eprec = -1; /* precedence to evict from */
6042
6043 /* Determine precedence from which to evict packet, if any */
6044 if (pktq_pfull(q, prec))
6045 eprec = prec;
6046 else if (pktq_full(q)) {
6047 p = brcmu_pktq_peek_tail(q, &eprec);
6048 if (eprec > prec) {
6049 wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
6050 "\n", __func__, eprec, prec);
6051 return false;
6052 }
6053 }
6054
6055 /* Evict if needed */
6056 if (eprec >= 0) {
6057 bool discard_oldest;
6058
6059 discard_oldest = ac_bitmap_tst(0, eprec);
6060
6061 /* Refuse newer packet unless configured to discard oldest */
6062 if (eprec == prec && !discard_oldest) {
6063 wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
6064 "\n", __func__, prec);
6065 return false;
6066 }
6067
6068 /* Evict packet according to discard policy */
6069 p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
6070 brcmu_pktq_pdeq_tail(q, eprec);
6071 brcmu_pkt_buf_free_skb(p);
6072 }
6073
6074 /* Enqueue */
6075 if (head)
6076 p = brcmu_pktq_penq_head(q, prec, pkt);
6077 else
6078 p = brcmu_pktq_penq(q, prec, pkt);
6079
6080 return true;
6081}
6082
6083/*
6084 * Attempts to queue a packet onto a multiple-precedence queue,
6085 * if necessary evicting a lower precedence packet from the queue.
6086 *
6087 * 'prec' is the precedence number that has already been mapped
6088 * from the packet priority.
6089 *
6090 * Returns true if packet consumed (queued), false if not.
6091 */
6092static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
6093 struct sk_buff *pkt, int prec)
6094{
6095 return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
6096}
6097
6098void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
6099 struct sk_buff *sdu, uint prec)
6100{
6101 struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */
6102 struct pktq *q = &qi->q;
6103 int prio;
6104
6105 prio = sdu->priority;
6106
6107 if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
6108 /*
6109 * we might hit this condtion in case
6110 * packet flooding from mac80211 stack
6111 */
6112 brcmu_pkt_buf_free_skb(sdu);
6113 }
6114}
6115
6116/* 5721/*
6117 * bcmc_fid_generate: 5722 * bcmc_fid_generate:
6118 * Generate frame ID for a BCMC packet. The frag field is not used 5723 * Generate frame ID for a BCMC packet. The frag field is not used
@@ -6140,8 +5745,6 @@ brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec,
6140{ 5745{
6141 uint dur = 0; 5746 uint dur = 0;
6142 5747
6143 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
6144 wlc->pub->unit, rspec, preamble_type);
6145 /* 5748 /*
6146 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that 5749 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
6147 * is less than or equal to the rate of the immediately previous 5750 * is less than or equal to the rate of the immediately previous
@@ -6159,8 +5762,6 @@ static uint
6159brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec, 5762brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec,
6160 u8 preamble_type) 5763 u8 preamble_type)
6161{ 5764{
6162 BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
6163 wlc->pub->unit, rspec, preamble_type);
6164 return brcms_c_calc_ack_time(wlc, rspec, preamble_type); 5765 return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
6165} 5766}
6166 5767
@@ -6168,8 +5769,6 @@ static uint
6168brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec, 5769brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
6169 u8 preamble_type) 5770 u8 preamble_type)
6170{ 5771{
6171 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
6172 "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
6173 /* 5772 /*
6174 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that 5773 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
6175 * is less than or equal to the rate of the immediately previous 5774 * is less than or equal to the rate of the immediately previous
@@ -6223,9 +5822,6 @@ brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
6223 uint nsyms, mac_len, Ndps, kNdps; 5822 uint nsyms, mac_len, Ndps, kNdps;
6224 uint rate = rspec2rate(ratespec); 5823 uint rate = rspec2rate(ratespec);
6225 5824
6226 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
6227 wlc->pub->unit, ratespec, preamble_type, dur);
6228
6229 if (is_mcs_rate(ratespec)) { 5825 if (is_mcs_rate(ratespec)) {
6230 uint mcs = ratespec & RSPEC_RATE_MASK; 5826 uint mcs = ratespec & RSPEC_RATE_MASK;
6231 int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); 5827 int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
@@ -6292,7 +5888,7 @@ static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
6292 return true; 5888 return true;
6293 error: 5889 error:
6294 if (verbose) 5890 if (verbose)
6295 wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x " 5891 brcms_err(wlc->hw->d11core, "wl%d: valid_rate: rate spec 0x%x "
6296 "not in hw_rateset\n", wlc->pub->unit, rspec); 5892 "not in hw_rateset\n", wlc->pub->unit, rspec);
6297 5893
6298 return false; 5894 return false;
@@ -6302,6 +5898,7 @@ static u32
6302mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, 5898mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
6303 u32 int_val) 5899 u32 int_val)
6304{ 5900{
5901 struct bcma_device *core = wlc->hw->d11core;
6305 u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; 5902 u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
6306 u8 rate = int_val & NRATE_RATE_MASK; 5903 u8 rate = int_val & NRATE_RATE_MASK;
6307 u32 rspec; 5904 u32 rspec;
@@ -6318,7 +5915,7 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
6318 if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) { 5915 if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) {
6319 /* mcs only allowed when nmode */ 5916 /* mcs only allowed when nmode */
6320 if (stf > PHY_TXC1_MODE_SDM) { 5917 if (stf > PHY_TXC1_MODE_SDM) {
6321 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n", 5918 brcms_err(core, "wl%d: %s: Invalid stf\n",
6322 wlc->pub->unit, __func__); 5919 wlc->pub->unit, __func__);
6323 bcmerror = -EINVAL; 5920 bcmerror = -EINVAL;
6324 goto done; 5921 goto done;
@@ -6329,8 +5926,8 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
6329 if (!CHSPEC_IS40(wlc->home_chanspec) || 5926 if (!CHSPEC_IS40(wlc->home_chanspec) ||
6330 ((stf != PHY_TXC1_MODE_SISO) 5927 ((stf != PHY_TXC1_MODE_SISO)
6331 && (stf != PHY_TXC1_MODE_CDD))) { 5928 && (stf != PHY_TXC1_MODE_CDD))) {
6332 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs " 5929 brcms_err(core, "wl%d: %s: Invalid mcs 32\n",
6333 "32\n", wlc->pub->unit, __func__); 5930 wlc->pub->unit, __func__);
6334 bcmerror = -EINVAL; 5931 bcmerror = -EINVAL;
6335 goto done; 5932 goto done;
6336 } 5933 }
@@ -6338,9 +5935,9 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
6338 } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { 5935 } else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
6339 /* mcs > 7 must use stf SDM */ 5936 /* mcs > 7 must use stf SDM */
6340 if (stf != PHY_TXC1_MODE_SDM) { 5937 if (stf != PHY_TXC1_MODE_SDM) {
6341 BCMMSG(wlc->wiphy, "wl%d: enabling " 5938 brcms_dbg_mac80211(core, "wl%d: enabling "
6342 "SDM mode for mcs %d\n", 5939 "SDM mode for mcs %d\n",
6343 wlc->pub->unit, rate); 5940 wlc->pub->unit, rate);
6344 stf = PHY_TXC1_MODE_SDM; 5941 stf = PHY_TXC1_MODE_SDM;
6345 } 5942 }
6346 } else { 5943 } else {
@@ -6351,15 +5948,15 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
6351 if ((stf > PHY_TXC1_MODE_STBC) || 5948 if ((stf > PHY_TXC1_MODE_STBC) ||
6352 (!BRCMS_STBC_CAP_PHY(wlc) 5949 (!BRCMS_STBC_CAP_PHY(wlc)
6353 && (stf == PHY_TXC1_MODE_STBC))) { 5950 && (stf == PHY_TXC1_MODE_STBC))) {
6354 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC" 5951 brcms_err(core, "wl%d: %s: Invalid STBC\n",
6355 "\n", wlc->pub->unit, __func__); 5952 wlc->pub->unit, __func__);
6356 bcmerror = -EINVAL; 5953 bcmerror = -EINVAL;
6357 goto done; 5954 goto done;
6358 } 5955 }
6359 } 5956 }
6360 } else if (is_ofdm_rate(rate)) { 5957 } else if (is_ofdm_rate(rate)) {
6361 if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { 5958 if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
6362 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n", 5959 brcms_err(core, "wl%d: %s: Invalid OFDM\n",
6363 wlc->pub->unit, __func__); 5960 wlc->pub->unit, __func__);
6364 bcmerror = -EINVAL; 5961 bcmerror = -EINVAL;
6365 goto done; 5962 goto done;
@@ -6367,20 +5964,20 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
6367 } else if (is_cck_rate(rate)) { 5964 } else if (is_cck_rate(rate)) {
6368 if ((cur_band->bandtype != BRCM_BAND_2G) 5965 if ((cur_band->bandtype != BRCM_BAND_2G)
6369 || (stf != PHY_TXC1_MODE_SISO)) { 5966 || (stf != PHY_TXC1_MODE_SISO)) {
6370 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n", 5967 brcms_err(core, "wl%d: %s: Invalid CCK\n",
6371 wlc->pub->unit, __func__); 5968 wlc->pub->unit, __func__);
6372 bcmerror = -EINVAL; 5969 bcmerror = -EINVAL;
6373 goto done; 5970 goto done;
6374 } 5971 }
6375 } else { 5972 } else {
6376 wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n", 5973 brcms_err(core, "wl%d: %s: Unknown rate type\n",
6377 wlc->pub->unit, __func__); 5974 wlc->pub->unit, __func__);
6378 bcmerror = -EINVAL; 5975 bcmerror = -EINVAL;
6379 goto done; 5976 goto done;
6380 } 5977 }
6381 /* make sure multiple antennae are available for non-siso rates */ 5978 /* make sure multiple antennae are available for non-siso rates */
6382 if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { 5979 if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
6383 wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO " 5980 brcms_err(core, "wl%d: %s: SISO antenna but !SISO "
6384 "request\n", wlc->pub->unit, __func__); 5981 "request\n", wlc->pub->unit, __func__);
6385 bcmerror = -EINVAL; 5982 bcmerror = -EINVAL;
6386 goto done; 5983 goto done;
@@ -6449,7 +6046,7 @@ static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
6449 break; 6046 break;
6450 6047
6451 default: 6048 default:
6452 wiphy_err(wlc->wiphy, 6049 brcms_err(wlc->hw->d11core,
6453 "brcms_c_cck_plcp_set: unsupported rate %d\n", 6050 "brcms_c_cck_plcp_set: unsupported rate %d\n",
6454 rate_500); 6051 rate_500);
6455 rate_500 = BRCM_RATE_1M; 6052 rate_500 = BRCM_RATE_1M;
@@ -6582,7 +6179,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
6582 bw = rspec_get_bw(rspec); 6179 bw = rspec_get_bw(rspec);
6583 /* 10Mhz is not supported yet */ 6180 /* 10Mhz is not supported yet */
6584 if (bw < PHY_TXC1_BW_20MHZ) { 6181 if (bw < PHY_TXC1_BW_20MHZ) {
6585 wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is " 6182 brcms_err(wlc->hw->d11core, "phytxctl1_calc: bw %d is "
6586 "not supported yet, set to 20L\n", bw); 6183 "not supported yet, set to 20L\n", bw);
6587 bw = PHY_TXC1_BW_20MHZ; 6184 bw = PHY_TXC1_BW_20MHZ;
6588 } 6185 }
@@ -6609,7 +6206,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
6609 /* get the phyctl byte from rate phycfg table */ 6206 /* get the phyctl byte from rate phycfg table */
6610 phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec)); 6207 phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec));
6611 if (phycfg == -1) { 6208 if (phycfg == -1) {
6612 wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong " 6209 brcms_err(wlc->hw->d11core, "phytxctl1_calc: wrong "
6613 "legacy OFDM/CCK rate\n"); 6210 "legacy OFDM/CCK rate\n");
6614 phycfg = 0; 6211 phycfg = 0;
6615 } 6212 }
@@ -6689,8 +6286,9 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
6689 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 6286 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
6690 /* non-AP STA should never use BCMC queue */ 6287 /* non-AP STA should never use BCMC queue */
6691 if (queue == TX_BCMC_FIFO) { 6288 if (queue == TX_BCMC_FIFO) {
6692 wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == " 6289 brcms_err(wlc->hw->d11core,
6693 "TX_BCMC!\n", wlc->pub->unit, __func__); 6290 "wl%d: %s: ASSERT queue == TX_BCMC!\n",
6291 wlc->pub->unit, __func__);
6694 frameid = bcmc_fid_generate(wlc, NULL, txh); 6292 frameid = bcmc_fid_generate(wlc, NULL, txh);
6695 } else { 6293 } else {
6696 /* Increment the counter for first fragment */ 6294 /* Increment the counter for first fragment */
@@ -6860,7 +6458,8 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
6860 6458
6861 if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) 6459 if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
6862 && (!is_mcs_rate(rspec[k]))) { 6460 && (!is_mcs_rate(rspec[k]))) {
6863 wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_" 6461 brcms_err(wlc->hw->d11core,
6462 "wl%d: %s: IEEE80211_TX_"
6864 "RC_MCS != is_mcs_rate(rspec)\n", 6463 "RC_MCS != is_mcs_rate(rspec)\n",
6865 wlc->pub->unit, __func__); 6464 wlc->pub->unit, __func__);
6866 } 6465 }
@@ -7254,14 +6853,16 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
7254 wlc->fragthresh[queue] = 6853 wlc->fragthresh[queue] =
7255 (u16) newfragthresh; 6854 (u16) newfragthresh;
7256 } else { 6855 } else {
7257 wiphy_err(wlc->wiphy, "wl%d: %s txop invalid " 6856 brcms_err(wlc->hw->d11core,
6857 "wl%d: %s txop invalid "
7258 "for rate %d\n", 6858 "for rate %d\n",
7259 wlc->pub->unit, fifo_names[queue], 6859 wlc->pub->unit, fifo_names[queue],
7260 rspec2rate(rspec[0])); 6860 rspec2rate(rspec[0]));
7261 } 6861 }
7262 6862
7263 if (dur > wlc->edcf_txop[ac]) 6863 if (dur > wlc->edcf_txop[ac])
7264 wiphy_err(wlc->wiphy, "wl%d: %s: %s txop " 6864 brcms_err(wlc->hw->d11core,
6865 "wl%d: %s: %s txop "
7265 "exceeded phylen %d/%d dur %d/%d\n", 6866 "exceeded phylen %d/%d dur %d/%d\n",
7266 wlc->pub->unit, __func__, 6867 wlc->pub->unit, __func__,
7267 fifo_names[queue], 6868 fifo_names[queue],
@@ -7273,79 +6874,33 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
7273 return 0; 6874 return 0;
7274} 6875}
7275 6876
7276void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, 6877static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb)
7277 struct ieee80211_hw *hw)
7278{ 6878{
7279 u8 prio; 6879 struct dma_pub *dma;
7280 uint fifo; 6880 int fifo, ret = -ENOSPC;
7281 struct scb *scb = &wlc->pri_scb; 6881 struct d11txh *txh;
7282 struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); 6882 u16 frameid = INVALIDFID;
7283
7284 /*
7285 * 802.11 standard requires management traffic
7286 * to go at highest priority
7287 */
7288 prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
7289 MAXPRIO;
7290 fifo = prio2fifo[prio];
7291 if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
7292 return;
7293 brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio));
7294 brcms_c_send_q(wlc);
7295}
7296
7297void brcms_c_send_q(struct brcms_c_info *wlc)
7298{
7299 struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
7300 int prec;
7301 u16 prec_map;
7302 int err = 0, i, count;
7303 uint fifo;
7304 struct brcms_txq_info *qi = wlc->pkt_queue;
7305 struct pktq *q = &qi->q;
7306 struct ieee80211_tx_info *tx_info;
7307
7308 prec_map = wlc->tx_prec_map;
7309 6883
7310 /* Send all the enq'd pkts that we can. 6884 fifo = brcms_ac_to_fifo(skb_get_queue_mapping(skb));
7311 * Dequeue packets with precedence with empty HW fifo only 6885 dma = wlc->hw->di[fifo];
7312 */ 6886 txh = (struct d11txh *)(skb->data);
7313 while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) {
7314 tx_info = IEEE80211_SKB_CB(pkt[0]);
7315 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
7316 err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec);
7317 } else {
7318 count = 1;
7319 err = brcms_c_prep_pdu(wlc, pkt[0], &fifo);
7320 if (!err) {
7321 for (i = 0; i < count; i++)
7322 brcms_c_txfifo(wlc, fifo, pkt[i], true,
7323 1);
7324 }
7325 }
7326 6887
7327 if (err == -EBUSY) { 6888 if (dma->txavail == 0) {
7328 brcmu_pktq_penq_head(q, prec, pkt[0]); 6889 /*
7329 /* 6890 * We sometimes get a frame from mac80211 after stopping
7330 * If send failed due to any other reason than a 6891 * the queues. This only ever seems to be a single frame
7331 * change in HW FIFO condition, quit. Otherwise, 6892 * and is seems likely to be a race. TX_HEADROOM should
7332 * read the new prec_map! 6893 * ensure that we have enough space to handle these stray
7333 */ 6894 * packets, so warn if there isn't. If we're out of space
7334 if (prec_map == wlc->tx_prec_map) 6895 * in the tx ring and the tx queue isn't stopped then
7335 break; 6896 * we've really got a bug; warn loudly if that happens.
7336 prec_map = wlc->tx_prec_map; 6897 */
7337 } 6898 brcms_warn(wlc->hw->d11core,
6899 "Received frame for tx with no space in DMA ring\n");
6900 WARN_ON(!ieee80211_queue_stopped(wlc->pub->ieee_hw,
6901 skb_get_queue_mapping(skb)));
6902 return -ENOSPC;
7338 } 6903 }
7339}
7340
7341void
7342brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
7343 bool commit, s8 txpktpend)
7344{
7345 u16 frameid = INVALIDFID;
7346 struct d11txh *txh;
7347
7348 txh = (struct d11txh *) (p->data);
7349 6904
7350 /* When a BC/MC frame is being committed to the BCMC fifo 6905 /* When a BC/MC frame is being committed to the BCMC fifo
7351 * via DMA (NOT PIO), update ucode or BSS info as appropriate. 6906 * via DMA (NOT PIO), update ucode or BSS info as appropriate.
@@ -7353,16 +6908,6 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
7353 if (fifo == TX_BCMC_FIFO) 6908 if (fifo == TX_BCMC_FIFO)
7354 frameid = le16_to_cpu(txh->TxFrameID); 6909 frameid = le16_to_cpu(txh->TxFrameID);
7355 6910
7356 /*
7357 * Bump up pending count for if not using rpc. If rpc is
7358 * used, this will be handled in brcms_b_txfifo()
7359 */
7360 if (commit) {
7361 wlc->core->txpktpend[fifo] += txpktpend;
7362 BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
7363 txpktpend, wlc->core->txpktpend[fifo]);
7364 }
7365
7366 /* Commit BCMC sequence number in the SHM frame ID location */ 6911 /* Commit BCMC sequence number in the SHM frame ID location */
7367 if (frameid != INVALIDFID) { 6912 if (frameid != INVALIDFID) {
7368 /* 6913 /*
@@ -7372,8 +6917,52 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
7372 brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid); 6917 brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid);
7373 } 6918 }
7374 6919
7375 if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) 6920 ret = brcms_c_txfifo(wlc, fifo, skb);
6921 /*
6922 * The only reason for brcms_c_txfifo to fail is because
6923 * there weren't any DMA descriptors, but we've already
6924 * checked for that. So if it does fail yell loudly.
6925 */
6926 WARN_ON_ONCE(ret);
6927
6928 return ret;
6929}
6930
6931void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
6932 struct ieee80211_hw *hw)
6933{
6934 uint fifo;
6935 struct scb *scb = &wlc->pri_scb;
6936
6937 fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
6938 if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
6939 return;
6940 if (brcms_c_tx(wlc, sdu))
6941 dev_kfree_skb_any(sdu);
6942}
6943
6944int
6945brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p)
6946{
6947 struct dma_pub *dma = wlc->hw->di[fifo];
6948 int ret;
6949 u16 queue;
6950
6951 ret = dma_txfast(wlc, dma, p);
6952 if (ret < 0)
7376 wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n"); 6953 wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
6954
6955 /*
6956 * Stop queue if DMA ring is full. Reserve some free descriptors,
6957 * as we sometimes receive a frame from mac80211 after the queues
6958 * are stopped.
6959 */
6960 queue = skb_get_queue_mapping(p);
6961 if (dma->txavail <= TX_HEADROOM && fifo < TX_BCMC_FIFO &&
6962 !ieee80211_queue_stopped(wlc->pub->ieee_hw, queue))
6963 ieee80211_stop_queue(wlc->pub->ieee_hw, queue);
6964
6965 return ret;
7377} 6966}
7378 6967
7379u32 6968u32
@@ -7423,19 +7012,6 @@ brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
7423 return rts_rspec; 7012 return rts_rspec;
7424} 7013}
7425 7014
7426void
7427brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
7428{
7429 wlc->core->txpktpend[fifo] -= txpktpend;
7430 BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
7431 wlc->core->txpktpend[fifo]);
7432
7433 /* There is more room; mark precedences related to this FIFO sendable */
7434 wlc->tx_prec_map |= wlc->fifo2prec_map[fifo];
7435
7436 /* figure out which bsscfg is being worked on... */
7437}
7438
7439/* Update beacon listen interval in shared memory */ 7015/* Update beacon listen interval in shared memory */
7440static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc) 7016static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
7441{ 7017{
@@ -7508,7 +7084,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7508 7084
7509 /* fill in TSF and flag its presence */ 7085 /* fill in TSF and flag its presence */
7510 rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh); 7086 rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh);
7511 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 7087 rx_status->flag |= RX_FLAG_MACTIME_START;
7512 7088
7513 channel = BRCMS_CHAN_CHANNEL(rxh->RxChan); 7089 channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
7514 7090
@@ -7571,7 +7147,8 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7571 rx_status->rate_idx = 11; 7147 rx_status->rate_idx = 11;
7572 break; 7148 break;
7573 default: 7149 default:
7574 wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__); 7150 brcms_err(wlc->hw->d11core,
7151 "%s: Unknown rate\n", __func__);
7575 } 7152 }
7576 7153
7577 /* 7154 /*
@@ -7590,7 +7167,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7590 } else if (is_ofdm_rate(rspec)) { 7167 } else if (is_ofdm_rate(rspec)) {
7591 rx_status->flag |= RX_FLAG_SHORTPRE; 7168 rx_status->flag |= RX_FLAG_SHORTPRE;
7592 } else { 7169 } else {
7593 wiphy_err(wlc->wiphy, "%s: Unknown modulation\n", 7170 brcms_err(wlc->hw->d11core, "%s: Unknown modulation\n",
7594 __func__); 7171 __func__);
7595 } 7172 }
7596 } 7173 }
@@ -7600,12 +7177,12 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7600 7177
7601 if (rxh->RxStatus1 & RXS_DECERR) { 7178 if (rxh->RxStatus1 & RXS_DECERR) {
7602 rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; 7179 rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
7603 wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_PLCP_CRC\n", 7180 brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_PLCP_CRC\n",
7604 __func__); 7181 __func__);
7605 } 7182 }
7606 if (rxh->RxStatus1 & RXS_FCSERR) { 7183 if (rxh->RxStatus1 & RXS_FCSERR) {
7607 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; 7184 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
7608 wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_FCS_CRC\n", 7185 brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_FCS_CRC\n",
7609 __func__); 7186 __func__);
7610 } 7187 }
7611} 7188}
@@ -7649,9 +7226,6 @@ brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
7649{ 7226{
7650 uint nsyms, len = 0, kNdps; 7227 uint nsyms, len = 0, kNdps;
7651 7228
7652 BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
7653 wlc->pub->unit, rspec2rate(ratespec), mac_len);
7654
7655 if (is_mcs_rate(ratespec)) { 7229 if (is_mcs_rate(ratespec)) {
7656 uint mcs = ratespec & RSPEC_RATE_MASK; 7230 uint mcs = ratespec & RSPEC_RATE_MASK;
7657 int tot_streams = (mcs_2_txstreams(mcs) + 1) + 7231 int tot_streams = (mcs_2_txstreams(mcs) + 1) +
@@ -7883,35 +7457,6 @@ void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
7883 brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); 7457 brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
7884} 7458}
7885 7459
7886/* prepares pdu for transmission. returns BCM error codes */
7887int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
7888{
7889 uint fifo;
7890 struct d11txh *txh;
7891 struct ieee80211_hdr *h;
7892 struct scb *scb;
7893
7894 txh = (struct d11txh *) (pdu->data);
7895 h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
7896
7897 /* get the pkt queue info. This was put at brcms_c_sendctl or
7898 * brcms_c_send for PDU */
7899 fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
7900
7901 scb = NULL;
7902
7903 *fifop = fifo;
7904
7905 /* return if insufficient dma resources */
7906 if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
7907 /* Mark precedences related to this FIFO, unsendable */
7908 /* A fifo is full. Clear precedences related to that FIFO */
7909 wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]);
7910 return -EBUSY;
7911 }
7912 return 0;
7913}
7914
7915int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, 7460int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
7916 uint *blocks) 7461 uint *blocks)
7917{ 7462{
@@ -7977,13 +7522,15 @@ int brcms_c_get_curband(struct brcms_c_info *wlc)
7977void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) 7522void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
7978{ 7523{
7979 int timeout = 20; 7524 int timeout = 20;
7525 int i;
7980 7526
7981 /* flush packet queue when requested */ 7527 /* Kick DMA to send any pending AMPDU */
7982 if (drop) 7528 for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++)
7983 brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL); 7529 if (wlc->hw->di[i])
7530 dma_txflush(wlc->hw->di[i]);
7984 7531
7985 /* wait for queue and DMA fifos to run dry */ 7532 /* wait for queue and DMA fifos to run dry */
7986 while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) { 7533 while (brcms_txpktpendtot(wlc) > 0) {
7987 brcms_msleep(wlc->wl, 1); 7534 brcms_msleep(wlc->wl, 1);
7988 7535
7989 if (--timeout == 0) 7536 if (--timeout == 0)
@@ -8032,8 +7579,6 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
8032 uint len; 7579 uint len;
8033 bool is_amsdu; 7580 bool is_amsdu;
8034 7581
8035 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
8036
8037 /* frame starts with rxhdr */ 7582 /* frame starts with rxhdr */
8038 rxh = (struct d11rxhdr *) (p->data); 7583 rxh = (struct d11rxhdr *) (p->data);
8039 7584
@@ -8043,8 +7588,9 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
8043 /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ 7588 /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
8044 if (rxh->RxStatus1 & RXS_PBPRES) { 7589 if (rxh->RxStatus1 & RXS_PBPRES) {
8045 if (p->len < 2) { 7590 if (p->len < 2) {
8046 wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of " 7591 brcms_err(wlc->hw->d11core,
8047 "len %d\n", wlc->pub->unit, p->len); 7592 "wl%d: recv: rcvd runt of len %d\n",
7593 wlc->pub->unit, p->len);
8048 goto toss; 7594 goto toss;
8049 } 7595 }
8050 skb_pull(p, 2); 7596 skb_pull(p, 2);
@@ -8089,7 +7635,6 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
8089 uint n = 0; 7635 uint n = 0;
8090 uint bound_limit = bound ? RXBND : -1; 7636 uint bound_limit = bound ? RXBND : -1;
8091 7637
8092 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
8093 skb_queue_head_init(&recv_frames); 7638 skb_queue_head_init(&recv_frames);
8094 7639
8095 /* gather received frames */ 7640 /* gather received frames */
@@ -8140,10 +7685,9 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
8140 u32 macintstatus; 7685 u32 macintstatus;
8141 struct brcms_hardware *wlc_hw = wlc->hw; 7686 struct brcms_hardware *wlc_hw = wlc->hw;
8142 struct bcma_device *core = wlc_hw->d11core; 7687 struct bcma_device *core = wlc_hw->d11core;
8143 struct wiphy *wiphy = wlc->wiphy;
8144 7688
8145 if (brcms_deviceremoved(wlc)) { 7689 if (brcms_deviceremoved(wlc)) {
8146 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, 7690 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
8147 __func__); 7691 __func__);
8148 brcms_down(wlc->wl); 7692 brcms_down(wlc->wl);
8149 return false; 7693 return false;
@@ -8153,8 +7697,8 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
8153 macintstatus = wlc->macintstatus; 7697 macintstatus = wlc->macintstatus;
8154 wlc->macintstatus = 0; 7698 wlc->macintstatus = 0;
8155 7699
8156 BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n", 7700 brcms_dbg_int(core, "wl%d: macintstatus 0x%x\n",
8157 wlc_hw->unit, macintstatus); 7701 wlc_hw->unit, macintstatus);
8158 7702
8159 WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ 7703 WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
8160 7704
@@ -8164,7 +7708,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
8164 if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) 7708 if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
8165 wlc->macintstatus |= MI_TFS; 7709 wlc->macintstatus |= MI_TFS;
8166 if (fatal) { 7710 if (fatal) {
8167 wiphy_err(wiphy, "MI_TFS: fatal\n"); 7711 brcms_err(core, "MI_TFS: fatal\n");
8168 goto fatal; 7712 goto fatal;
8169 } 7713 }
8170 } 7714 }
@@ -8174,7 +7718,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
8174 7718
8175 /* ATIM window end */ 7719 /* ATIM window end */
8176 if (macintstatus & MI_ATIMWINEND) { 7720 if (macintstatus & MI_ATIMWINEND) {
8177 BCMMSG(wlc->wiphy, "end of ATIM window\n"); 7721 brcms_dbg_info(core, "end of ATIM window\n");
8178 bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid); 7722 bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid);
8179 wlc->qvalid = 0; 7723 wlc->qvalid = 0;
8180 } 7724 }
@@ -8192,7 +7736,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
8192 wlc_phy_noise_sample_intr(wlc_hw->band->pi); 7736 wlc_phy_noise_sample_intr(wlc_hw->band->pi);
8193 7737
8194 if (macintstatus & MI_GP0) { 7738 if (macintstatus & MI_GP0) {
8195 wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d " 7739 brcms_err(core, "wl%d: PSM microcode watchdog fired at %d "
8196 "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); 7740 "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
8197 7741
8198 printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", 7742 printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
@@ -8206,15 +7750,11 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
8206 bcma_write32(core, D11REGOFFS(gptimer), 0); 7750 bcma_write32(core, D11REGOFFS(gptimer), 0);
8207 7751
8208 if (macintstatus & MI_RFDISABLE) { 7752 if (macintstatus & MI_RFDISABLE) {
8209 BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the" 7753 brcms_dbg_info(core, "wl%d: BMAC Detected a change on the"
8210 " RF Disable Input\n", wlc_hw->unit); 7754 " RF Disable Input\n", wlc_hw->unit);
8211 brcms_rfkill_set_hw_state(wlc->wl); 7755 brcms_rfkill_set_hw_state(wlc->wl);
8212 } 7756 }
8213 7757
8214 /* send any enq'd tx packets. Just makes sure to jump start tx */
8215 if (!pktq_empty(&wlc->pkt_queue->q))
8216 brcms_c_send_q(wlc);
8217
8218 /* it isn't done and needs to be resched if macintstatus is non-zero */ 7758 /* it isn't done and needs to be resched if macintstatus is non-zero */
8219 return wlc->macintstatus != 0; 7759 return wlc->macintstatus != 0;
8220 7760
@@ -8229,7 +7769,7 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
8229 struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; 7769 struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
8230 u16 chanspec; 7770 u16 chanspec;
8231 7771
8232 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); 7772 brcms_dbg_info(core, "wl%d\n", wlc->pub->unit);
8233 7773
8234 chanspec = ch20mhz_chspec(ch->hw_value); 7774 chanspec = ch20mhz_chspec(ch->hw_value);
8235 7775
@@ -8286,9 +7826,6 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
8286 bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF); 7826 bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF);
8287 brcms_c_edcf_setparams(wlc, false); 7827 brcms_c_edcf_setparams(wlc, false);
8288 7828
8289 /* Init precedence maps for empty FIFOs */
8290 brcms_c_tx_prec_map_init(wlc);
8291
8292 /* read the ucode version if we have not yet done so */ 7829 /* read the ucode version if we have not yet done so */
8293 if (wlc->ucode_rev == 0) { 7830 if (wlc->ucode_rev == 0) {
8294 wlc->ucode_rev = 7831 wlc->ucode_rev =
@@ -8303,9 +7840,6 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
8303 if (mute_tx) 7840 if (mute_tx)
8304 brcms_b_mute(wlc->hw, true); 7841 brcms_b_mute(wlc->hw, true);
8305 7842
8306 /* clear tx flow control */
8307 brcms_c_txflowcontrol_reset(wlc);
8308
8309 /* enable the RF Disable Delay timer */ 7843 /* enable the RF Disable Delay timer */
8310 bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT); 7844 bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT);
8311 7845
@@ -8464,15 +7998,6 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
8464 * Complete the wlc default state initializations.. 7998 * Complete the wlc default state initializations..
8465 */ 7999 */
8466 8000
8467 /* allocate our initial queue */
8468 wlc->pkt_queue = brcms_c_txq_alloc(wlc);
8469 if (wlc->pkt_queue == NULL) {
8470 wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
8471 unit, __func__);
8472 err = 100;
8473 goto fail;
8474 }
8475
8476 wlc->bsscfg->wlc = wlc; 8001 wlc->bsscfg->wlc = wlc;
8477 8002
8478 wlc->mimoft = FT_HT; 8003 wlc->mimoft = FT_HT;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index 8debc74c54e..fb447747c2c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -101,9 +101,6 @@
101 101
102#define DATA_BLOCK_TX_SUPR (1 << 4) 102#define DATA_BLOCK_TX_SUPR (1 << 4)
103 103
104/* 802.1D Priority to TX FIFO number for wme */
105extern const u8 prio2fifo[];
106
107/* Ucode MCTL_WAKE override bits */ 104/* Ucode MCTL_WAKE override bits */
108#define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01 105#define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01
109#define BRCMS_WAKE_OVERRIDE_PHYREG 0x02 106#define BRCMS_WAKE_OVERRIDE_PHYREG 0x02
@@ -242,7 +239,6 @@ struct brcms_core {
242 239
243 /* fifo */ 240 /* fifo */
244 uint *txavail[NFIFO]; /* # tx descriptors available */ 241 uint *txavail[NFIFO]; /* # tx descriptors available */
245 s16 txpktpend[NFIFO]; /* tx admission control */
246 242
247 struct macstat *macstat_snapshot; /* mac hw prev read values */ 243 struct macstat *macstat_snapshot; /* mac hw prev read values */
248}; 244};
@@ -382,19 +378,6 @@ struct brcms_hardware {
382 */ 378 */
383}; 379};
384 380
385/* TX Queue information
386 *
387 * Each flow of traffic out of the device has a TX Queue with independent
388 * flow control. Several interfaces may be associated with a single TX Queue
389 * if they belong to the same flow of traffic from the device. For multi-channel
390 * operation there are independent TX Queues for each channel.
391 */
392struct brcms_txq_info {
393 struct brcms_txq_info *next;
394 struct pktq q;
395 uint stopped; /* tx flow control bits */
396};
397
398/* 381/*
399 * Principal common driver data structure. 382 * Principal common driver data structure.
400 * 383 *
@@ -435,11 +418,8 @@ struct brcms_txq_info {
435 * WDlast: last time wlc_watchdog() was called. 418 * WDlast: last time wlc_watchdog() was called.
436 * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac. 419 * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac.
437 * wme_retries: per-AC retry limits. 420 * wme_retries: per-AC retry limits.
438 * tx_prec_map: Precedence map based on HW FIFO space.
439 * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME.
440 * bsscfg: set of BSS configurations, idx 0 is default and always valid. 421 * bsscfg: set of BSS configurations, idx 0 is default and always valid.
441 * cfg: the primary bsscfg (can be AP or STA). 422 * cfg: the primary bsscfg (can be AP or STA).
442 * tx_queues: common TX Queue list.
443 * modulecb: 423 * modulecb:
444 * mimoft: SIGN or 11N. 424 * mimoft: SIGN or 11N.
445 * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode. 425 * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode.
@@ -469,7 +449,6 @@ struct brcms_txq_info {
469 * tempsense_lasttime; 449 * tempsense_lasttime;
470 * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM. 450 * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM.
471 * tx_duty_cycle_cck: maximum allowed duty cycle for CCK. 451 * tx_duty_cycle_cck: maximum allowed duty cycle for CCK.
472 * pkt_queue: txq for transmit packets.
473 * wiphy: 452 * wiphy:
474 * pri_scb: primary Station Control Block 453 * pri_scb: primary Station Control Block
475 */ 454 */
@@ -533,14 +512,9 @@ struct brcms_c_info {
533 u16 edcf_txop[IEEE80211_NUM_ACS]; 512 u16 edcf_txop[IEEE80211_NUM_ACS];
534 513
535 u16 wme_retries[IEEE80211_NUM_ACS]; 514 u16 wme_retries[IEEE80211_NUM_ACS];
536 u16 tx_prec_map;
537 u16 fifo2prec_map[NFIFO];
538 515
539 struct brcms_bss_cfg *bsscfg; 516 struct brcms_bss_cfg *bsscfg;
540 517
541 /* tx queue */
542 struct brcms_txq_info *tx_queues;
543
544 struct modulecb *modulecb; 518 struct modulecb *modulecb;
545 519
546 u8 mimoft; 520 u8 mimoft;
@@ -585,7 +559,6 @@ struct brcms_c_info {
585 u16 tx_duty_cycle_ofdm; 559 u16 tx_duty_cycle_ofdm;
586 u16 tx_duty_cycle_cck; 560 u16 tx_duty_cycle_cck;
587 561
588 struct brcms_txq_info *pkt_queue;
589 struct wiphy *wiphy; 562 struct wiphy *wiphy;
590 struct scb pri_scb; 563 struct scb pri_scb;
591}; 564};
@@ -637,30 +610,13 @@ struct brcms_bss_cfg {
637 struct brcms_bss_info *current_bss; 610 struct brcms_bss_info *current_bss;
638}; 611};
639 612
640extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, 613extern int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
641 struct sk_buff *p, 614 struct sk_buff *p);
642 bool commit, s8 txpktpend);
643extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
644 s8 txpktpend);
645extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
646 struct sk_buff *sdu, uint prec);
647extern void brcms_c_print_txstatus(struct tx_status *txs);
648extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, 615extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
649 uint *blocks); 616 uint *blocks);
650 617
651#if defined(DEBUG)
652extern void brcms_c_print_txdesc(struct d11txh *txh);
653#else
654static inline void brcms_c_print_txdesc(struct d11txh *txh)
655{
656}
657#endif
658
659extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); 618extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
660extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); 619extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags);
661extern void brcms_c_send_q(struct brcms_c_info *wlc);
662extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
663 uint *fifo);
664extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, 620extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
665 uint mac_len); 621 uint mac_len);
666extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, 622extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc,
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 5855f4fd16d..0148dec104f 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -200,43 +200,6 @@ enum wlc_par_id {
200/* WL11N Support */ 200/* WL11N Support */
201#define AMPDU_AGG_HOST 1 201#define AMPDU_AGG_HOST 1
202 202
203/* pri is priority encoded in the packet. This maps the Packet priority to
204 * enqueue precedence as defined in wlc_prec_map
205 */
206extern const u8 wlc_prio2prec_map[];
207#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7]
208
209#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */
210
211/* Mask to describe all precedence levels */
212#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT)
213
214/*
215 * This maps priority to one precedence higher - Used by PS-Poll response
216 * packets to simulate enqueue-at-head operation, but still maintain the
217 * order on the queue
218 */
219#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\
220 BRCMS_PREC_COUNT - 1)
221
222/* Define a bitmap of precedences comprised by each AC */
223#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
224 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \
225 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \
226 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
227#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
228 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \
229 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \
230 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
231#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
232 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \
233 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \
234 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
235#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
236 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \
237 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \
238 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
239
240/* network protection config */ 203/* network protection config */
241#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */ 204#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */
242#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */ 205#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
index ed1d1aa71d2..dd916272249 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
@@ -23,6 +23,7 @@
23#include "channel.h" 23#include "channel.h"
24#include "main.h" 24#include "main.h"
25#include "stf.h" 25#include "stf.h"
26#include "debug.h"
26 27
27#define MIN_SPATIAL_EXPANSION 0 28#define MIN_SPATIAL_EXPANSION 0
28#define MAX_SPATIAL_EXPANSION 1 29#define MAX_SPATIAL_EXPANSION 1
@@ -160,8 +161,8 @@ bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
160static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, 161static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
161 u8 core_mask) 162 u8 core_mask)
162{ 163{
163 BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n", 164 brcms_dbg_ht(wlc->hw->d11core, "wl%d: Nsts %d core_mask %x\n",
164 wlc->pub->unit, Nsts, core_mask); 165 wlc->pub->unit, Nsts, core_mask);
165 166
166 if (hweight8(core_mask) > wlc->stf->txstreams) 167 if (hweight8(core_mask) > wlc->stf->txstreams)
167 core_mask = 0; 168 core_mask = 0;
@@ -194,7 +195,8 @@ static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
194 int i; 195 int i;
195 u8 core_mask = 0; 196 u8 core_mask = 0;
196 197
197 BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val); 198 brcms_dbg_ht(wlc->hw->d11core, "wl%d: val %x\n", wlc->pub->unit,
199 val);
198 200
199 wlc->stf->spatial_policy = (s8) val; 201 wlc->stf->spatial_policy = (s8) val;
200 for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { 202 for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/types.h b/drivers/net/wireless/brcm80211/brcmsmac/types.h
index e11ae83111e..ae1f3ad40d4 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/types.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
@@ -246,7 +246,7 @@
246 246
247#define BCMMSG(dev, fmt, args...) \ 247#define BCMMSG(dev, fmt, args...) \
248do { \ 248do { \
249 if (brcm_msg_level & LOG_TRACE_VAL) \ 249 if (brcm_msg_level & BRCM_DL_INFO) \
250 wiphy_err(dev, "%s: " fmt, __func__, ##args); \ 250 wiphy_err(dev, "%s: " fmt, __func__, ##args); \
251} while (0) 251} while (0)
252 252
@@ -281,7 +281,6 @@ struct ieee80211_tx_queue_params;
281struct brcms_info; 281struct brcms_info;
282struct brcms_c_info; 282struct brcms_c_info;
283struct brcms_hardware; 283struct brcms_hardware;
284struct brcms_txq_info;
285struct brcms_band; 284struct brcms_band;
286struct dma_pub; 285struct dma_pub;
287struct si_pub; 286struct si_pub;
diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
index f0d8c04a9c8..fb7cbcf8117 100644
--- a/drivers/net/wireless/brcm80211/include/defs.h
+++ b/drivers/net/wireless/brcm80211/include/defs.h
@@ -78,9 +78,14 @@
78#define PM_OFF 0 78#define PM_OFF 0
79#define PM_MAX 1 79#define PM_MAX 1
80 80
81/* Message levels */ 81/* Debug levels */
82#define LOG_ERROR_VAL 0x00000001 82#define BRCM_DL_INFO 0x00000001
83#define LOG_TRACE_VAL 0x00000002 83#define BRCM_DL_MAC80211 0x00000002
84#define BRCM_DL_RX 0x00000004
85#define BRCM_DL_TX 0x00000008
86#define BRCM_DL_INT 0x00000010
87#define BRCM_DL_DMA 0x00000020
88#define BRCM_DL_HT 0x00000040
84 89
85#define PM_OFF 0 90#define PM_OFF 0
86#define PM_MAX 1 91#define PM_MAX 1
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 29b8fa1adef..46938bc9886 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -1788,10 +1788,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1788 } 1788 }
1789 1789
1790 /* Initialize the geo */ 1790 /* Initialize the geo */
1791 if (libipw_set_geo(priv->ieee, &ipw_geos[0])) { 1791 libipw_set_geo(priv->ieee, &ipw_geos[0]);
1792 printk(KERN_WARNING DRV_NAME "Could not set geo\n");
1793 return 0;
1794 }
1795 priv->ieee->freq_band = LIBIPW_24GHZ_BAND; 1792 priv->ieee->freq_band = LIBIPW_24GHZ_BAND;
1796 1793
1797 lock = LOCK_NONE; 1794 lock = LOCK_NONE;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 768bf612533..482f505f3f3 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -11269,10 +11269,31 @@ static const struct libipw_geo ipw_geos[] = {
11269 } 11269 }
11270}; 11270};
11271 11271
11272static void ipw_set_geo(struct ipw_priv *priv)
11273{
11274 int j;
11275
11276 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
11277 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
11278 ipw_geos[j].name, 3))
11279 break;
11280 }
11281
11282 if (j == ARRAY_SIZE(ipw_geos)) {
11283 IPW_WARNING("SKU [%c%c%c] not recognized.\n",
11284 priv->eeprom[EEPROM_COUNTRY_CODE + 0],
11285 priv->eeprom[EEPROM_COUNTRY_CODE + 1],
11286 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
11287 j = 0;
11288 }
11289
11290 libipw_set_geo(priv->ieee, &ipw_geos[j]);
11291}
11292
11272#define MAX_HW_RESTARTS 5 11293#define MAX_HW_RESTARTS 5
11273static int ipw_up(struct ipw_priv *priv) 11294static int ipw_up(struct ipw_priv *priv)
11274{ 11295{
11275 int rc, i, j; 11296 int rc, i;
11276 11297
11277 /* Age scan list entries found before suspend */ 11298 /* Age scan list entries found before suspend */
11278 if (priv->suspend_time) { 11299 if (priv->suspend_time) {
@@ -11310,22 +11331,7 @@ static int ipw_up(struct ipw_priv *priv)
11310 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); 11331 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
11311 memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN); 11332 memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN);
11312 11333
11313 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) { 11334 ipw_set_geo(priv);
11314 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
11315 ipw_geos[j].name, 3))
11316 break;
11317 }
11318 if (j == ARRAY_SIZE(ipw_geos)) {
11319 IPW_WARNING("SKU [%c%c%c] not recognized.\n",
11320 priv->eeprom[EEPROM_COUNTRY_CODE + 0],
11321 priv->eeprom[EEPROM_COUNTRY_CODE + 1],
11322 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
11323 j = 0;
11324 }
11325 if (libipw_set_geo(priv->ieee, &ipw_geos[j])) {
11326 IPW_WARNING("Could not set geography.");
11327 return 0;
11328 }
11329 11335
11330 if (priv->status & STATUS_RF_KILL_SW) { 11336 if (priv->status & STATUS_RF_KILL_SW) {
11331 IPW_WARNING("Radio disabled by module parameter.\n"); 11337 IPW_WARNING("Radio disabled by module parameter.\n");
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
index 0b22fb42173..6eede52ad8c 100644
--- a/drivers/net/wireless/ipw2x00/libipw.h
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -978,7 +978,7 @@ extern void libipw_network_reset(struct libipw_network *network);
978/* libipw_geo.c */ 978/* libipw_geo.c */
979extern const struct libipw_geo *libipw_get_geo(struct libipw_device 979extern const struct libipw_geo *libipw_get_geo(struct libipw_device
980 *ieee); 980 *ieee);
981extern int libipw_set_geo(struct libipw_device *ieee, 981extern void libipw_set_geo(struct libipw_device *ieee,
982 const struct libipw_geo *geo); 982 const struct libipw_geo *geo);
983 983
984extern int libipw_is_valid_channel(struct libipw_device *ieee, 984extern int libipw_is_valid_channel(struct libipw_device *ieee,
diff --git a/drivers/net/wireless/ipw2x00/libipw_geo.c b/drivers/net/wireless/ipw2x00/libipw_geo.c
index c9fe3c99cb0..218f2a32de2 100644
--- a/drivers/net/wireless/ipw2x00/libipw_geo.c
+++ b/drivers/net/wireless/ipw2x00/libipw_geo.c
@@ -132,7 +132,7 @@ u8 libipw_freq_to_channel(struct libipw_device * ieee, u32 freq)
132 return 0; 132 return 0;
133} 133}
134 134
135int libipw_set_geo(struct libipw_device *ieee, 135void libipw_set_geo(struct libipw_device *ieee,
136 const struct libipw_geo *geo) 136 const struct libipw_geo *geo)
137{ 137{
138 memcpy(ieee->geo.name, geo->name, 3); 138 memcpy(ieee->geo.name, geo->name, 3);
@@ -143,7 +143,6 @@ int libipw_set_geo(struct libipw_device *ieee,
143 sizeof(struct libipw_channel)); 143 sizeof(struct libipw_channel));
144 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * 144 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
145 sizeof(struct libipw_channel)); 145 sizeof(struct libipw_channel));
146 return 0;
147} 146}
148 147
149const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee) 148const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee)
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index 87e53989433..e0b9d7fa5de 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -516,7 +516,7 @@ static void
516il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) 516il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
517{ 517{
518 struct ieee80211_hdr *header; 518 struct ieee80211_hdr *header;
519 struct ieee80211_rx_status rx_status; 519 struct ieee80211_rx_status rx_status = {};
520 struct il_rx_pkt *pkt = rxb_addr(rxb); 520 struct il_rx_pkt *pkt = rxb_addr(rxb);
521 struct il3945_rx_frame_stats *rx_stats = IL_RX_STATS(pkt); 521 struct il3945_rx_frame_stats *rx_stats = IL_RX_STATS(pkt);
522 struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt); 522 struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt);
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index eac4dc8bc87..07ffa575e3e 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -613,7 +613,7 @@ void
613il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) 613il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
614{ 614{
615 struct ieee80211_hdr *header; 615 struct ieee80211_hdr *header;
616 struct ieee80211_rx_status rx_status; 616 struct ieee80211_rx_status rx_status = {};
617 struct il_rx_pkt *pkt = rxb_addr(rxb); 617 struct il_rx_pkt *pkt = rxb_addr(rxb);
618 struct il_rx_phy_res *phy_res; 618 struct il_rx_phy_res *phy_res;
619 __le32 rx_pkt_status; 619 __le32 rx_pkt_status;
@@ -686,7 +686,7 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
686 686
687 /* TSF isn't reliable. In order to allow smooth user experience, 687 /* TSF isn't reliable. In order to allow smooth user experience,
688 * this W/A doesn't propagate it to the mac80211 */ 688 * this W/A doesn't propagate it to the mac80211 */
689 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU; */ 689 /*rx_status.flag |= RX_FLAG_MACTIME_START; */
690 690
691 il->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); 691 il->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
692 692
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index b4bb813362b..e254cba4557 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -2919,9 +2919,8 @@ do { \
2919#define IL_DBG(level, fmt, args...) \ 2919#define IL_DBG(level, fmt, args...) \
2920do { \ 2920do { \
2921 if (il_get_debug_level(il) & level) \ 2921 if (il_get_debug_level(il) & level) \
2922 dev_printk(KERN_ERR, &il->hw->wiphy->dev, \ 2922 dev_err(&il->hw->wiphy->dev, "%c %s " fmt, \
2923 "%c %s " fmt, in_interrupt() ? 'I' : 'U', \ 2923 in_interrupt() ? 'I' : 'U', __func__ , ##args); \
2924 __func__ , ## args); \
2925} while (0) 2924} while (0)
2926 2925
2927#define il_print_hex_dump(il, level, p, len) \ 2926#define il_print_hex_dump(il, level, p, len) \
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 727fbb5db9d..5cf43236421 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -133,12 +133,3 @@ config IWLWIFI_P2P
133 support when it is loaded. 133 support when it is loaded.
134 134
135 Say Y only if you want to experiment with P2P. 135 Say Y only if you want to experiment with P2P.
136
137config IWLWIFI_EXPERIMENTAL_MFP
138 bool "support MFP (802.11w) even if uCode doesn't advertise"
139 depends on IWLWIFI
140 help
141 This option enables experimental MFP (802.11W) support
142 even if the microcode doesn't advertise it.
143
144 Say Y only if you want to experiment with MFP.
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 75e12f29d9e..33b3ad2e546 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -176,8 +176,8 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr);
176/* lib */ 176/* lib */
177int iwlagn_send_tx_power(struct iwl_priv *priv); 177int iwlagn_send_tx_power(struct iwl_priv *priv);
178void iwlagn_temperature(struct iwl_priv *priv); 178void iwlagn_temperature(struct iwl_priv *priv);
179int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); 179int iwlagn_txfifo_flush(struct iwl_priv *priv);
180void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); 180void iwlagn_dev_txfifo_flush(struct iwl_priv *priv);
181int iwlagn_send_beacon_cmd(struct iwl_priv *priv); 181int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
182int iwl_send_statistics_request(struct iwl_priv *priv, 182int iwl_send_statistics_request(struct iwl_priv *priv,
183 u8 flags, bool clear); 183 u8 flags, bool clear);
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 01128c96b5d..71ab76b2b39 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -986,8 +986,7 @@ struct iwl_rem_sta_cmd {
986 986
987#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) 987#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00)
988 988
989#define IWL_DROP_SINGLE 0 989#define IWL_DROP_ALL BIT(1)
990#define IWL_DROP_ALL (BIT(IWL_RXON_CTX_BSS) | BIT(IWL_RXON_CTX_PAN))
991 990
992/* 991/*
993 * REPLY_TXFIFO_FLUSH = 0x1e(command and response) 992 * REPLY_TXFIFO_FLUSH = 0x1e(command and response)
@@ -1004,14 +1003,14 @@ struct iwl_rem_sta_cmd {
1004 * the flush operation ends when both the scheduler DMA done and TXFIFO empty 1003 * the flush operation ends when both the scheduler DMA done and TXFIFO empty
1005 * are set. 1004 * are set.
1006 * 1005 *
1007 * @fifo_control: bit mask for which queues to flush 1006 * @queue_control: bit mask for which queues to flush
1008 * @flush_control: flush controls 1007 * @flush_control: flush controls
1009 * 0: Dump single MSDU 1008 * 0: Dump single MSDU
1010 * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable. 1009 * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable.
1011 * 2: Dump all FIFO 1010 * 2: Dump all FIFO
1012 */ 1011 */
1013struct iwl_txfifo_flush_cmd { 1012struct iwl_txfifo_flush_cmd {
1014 __le32 fifo_control; 1013 __le32 queue_control;
1015 __le16 flush_control; 1014 __le16 flush_control;
1016 __le16 reserved; 1015 __le16 reserved;
1017} __packed; 1016} __packed;
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
index 1a98fa3ab06..769a08bca86 100644
--- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
@@ -2101,7 +2101,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
2101 if (iwl_is_rfkill(priv)) 2101 if (iwl_is_rfkill(priv))
2102 return -EFAULT; 2102 return -EFAULT;
2103 2103
2104 iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); 2104 iwlagn_dev_txfifo_flush(priv);
2105 2105
2106 return count; 2106 return count;
2107} 2107}
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 8141f91c372..29c571a5625 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -789,7 +789,6 @@ struct iwl_priv {
789 /* remain-on-channel offload support */ 789 /* remain-on-channel offload support */
790 struct ieee80211_channel *hw_roc_channel; 790 struct ieee80211_channel *hw_roc_channel;
791 struct delayed_work hw_roc_disable_work; 791 struct delayed_work hw_roc_disable_work;
792 enum nl80211_channel_type hw_roc_chantype;
793 int hw_roc_duration; 792 int hw_roc_duration;
794 bool hw_roc_setup, hw_roc_start_notified; 793 bool hw_roc_setup, hw_roc_start_notified;
795 794
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index bef88c1a2c9..7e59be4b89b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -136,7 +136,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
136 * 1. acquire mutex before calling 136 * 1. acquire mutex before calling
137 * 2. make sure rf is on and not in exit state 137 * 2. make sure rf is on and not in exit state
138 */ 138 */
139int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) 139int iwlagn_txfifo_flush(struct iwl_priv *priv)
140{ 140{
141 struct iwl_txfifo_flush_cmd flush_cmd; 141 struct iwl_txfifo_flush_cmd flush_cmd;
142 struct iwl_host_cmd cmd = { 142 struct iwl_host_cmd cmd = {
@@ -146,35 +146,34 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
146 .data = { &flush_cmd, }, 146 .data = { &flush_cmd, },
147 }; 147 };
148 148
149 might_sleep();
150
151 memset(&flush_cmd, 0, sizeof(flush_cmd)); 149 memset(&flush_cmd, 0, sizeof(flush_cmd));
152 if (flush_control & BIT(IWL_RXON_CTX_BSS)) 150
153 flush_cmd.fifo_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | 151 flush_cmd.queue_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK |
154 IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | 152 IWL_SCD_BE_MSK | IWL_SCD_BK_MSK |
155 IWL_SCD_MGMT_MSK; 153 IWL_SCD_MGMT_MSK;
156 if ((flush_control & BIT(IWL_RXON_CTX_PAN)) && 154 if ((priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)))
157 (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) 155 flush_cmd.queue_control |= IWL_PAN_SCD_VO_MSK |
158 flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK | 156 IWL_PAN_SCD_VI_MSK |
159 IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK | 157 IWL_PAN_SCD_BE_MSK |
160 IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | 158 IWL_PAN_SCD_BK_MSK |
161 IWL_PAN_SCD_MULTICAST_MSK; 159 IWL_PAN_SCD_MGMT_MSK |
160 IWL_PAN_SCD_MULTICAST_MSK;
162 161
163 if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE) 162 if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE)
164 flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; 163 flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK;
165 164
166 IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", 165 IWL_DEBUG_INFO(priv, "queue control: 0x%x\n",
167 flush_cmd.fifo_control); 166 flush_cmd.queue_control);
168 flush_cmd.flush_control = cpu_to_le16(flush_control); 167 flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL);
169 168
170 return iwl_dvm_send_cmd(priv, &cmd); 169 return iwl_dvm_send_cmd(priv, &cmd);
171} 170}
172 171
173void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) 172void iwlagn_dev_txfifo_flush(struct iwl_priv *priv)
174{ 173{
175 mutex_lock(&priv->mutex); 174 mutex_lock(&priv->mutex);
176 ieee80211_stop_queues(priv->hw); 175 ieee80211_stop_queues(priv->hw);
177 if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { 176 if (iwlagn_txfifo_flush(priv)) {
178 IWL_ERR(priv, "flush request fail\n"); 177 IWL_ERR(priv, "flush request fail\n");
179 goto done; 178 goto done;
180 } 179 }
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 2d9eee93c74..fb959b00b20 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -168,10 +168,13 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
168 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 168 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
169 IEEE80211_HW_SUPPORTS_STATIC_SMPS; 169 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
170 170
171#ifndef CONFIG_IWLWIFI_EXPERIMENTAL_MFP 171 /*
172 /* enable 11w if the uCode advertise */ 172 * Enable 11w if advertised by firmware and software crypto
173 if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) 173 * is not enabled (as the firmware will interpret some mgmt
174#endif /* !CONFIG_IWLWIFI_EXPERIMENTAL_MFP */ 174 * packets, so enabling it with software crypto isn't safe)
175 */
176 if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP &&
177 !iwlwifi_mod_params.sw_crypto)
175 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 178 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
176 179
177 hw->sta_data_size = sizeof(struct iwl_station_priv); 180 hw->sta_data_size = sizeof(struct iwl_station_priv);
@@ -1019,7 +1022,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
1019 */ 1022 */
1020 if (drop) { 1023 if (drop) {
1021 IWL_DEBUG_MAC80211(priv, "send flush command\n"); 1024 IWL_DEBUG_MAC80211(priv, "send flush command\n");
1022 if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { 1025 if (iwlagn_txfifo_flush(priv)) {
1023 IWL_ERR(priv, "flush request fail\n"); 1026 IWL_ERR(priv, "flush request fail\n");
1024 goto done; 1027 goto done;
1025 } 1028 }
@@ -1032,8 +1035,8 @@ done:
1032} 1035}
1033 1036
1034static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, 1037static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
1038 struct ieee80211_vif *vif,
1035 struct ieee80211_channel *channel, 1039 struct ieee80211_channel *channel,
1036 enum nl80211_channel_type channel_type,
1037 int duration) 1040 int duration)
1038{ 1041{
1039 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1042 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
@@ -1065,7 +1068,6 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
1065 } 1068 }
1066 1069
1067 priv->hw_roc_channel = channel; 1070 priv->hw_roc_channel = channel;
1068 priv->hw_roc_chantype = channel_type;
1069 /* convert from ms to TU */ 1071 /* convert from ms to TU */
1070 priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024); 1072 priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024);
1071 priv->hw_roc_start_notified = false; 1073 priv->hw_roc_start_notified = false;
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 30e761d31e9..e3a07c91681 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -511,7 +511,7 @@ static void iwl_bg_tx_flush(struct work_struct *work)
511 return; 511 return;
512 512
513 IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); 513 IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
514 iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); 514 iwlagn_dev_txfifo_flush(priv);
515} 515}
516 516
517/* 517/*
@@ -1191,8 +1191,6 @@ static void iwl_option_config(struct iwl_priv *priv)
1191 1191
1192static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) 1192static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
1193{ 1193{
1194 priv->eeprom_data->sku = priv->eeprom_data->sku;
1195
1196 if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE && 1194 if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE &&
1197 !priv->cfg->ht_params) { 1195 !priv->cfg->ht_params) {
1198 IWL_ERR(priv, "Invalid 11n configuration\n"); 1196 IWL_ERR(priv, "Invalid 11n configuration\n");
@@ -1204,7 +1202,7 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
1204 return -EINVAL; 1202 return -EINVAL;
1205 } 1203 }
1206 1204
1207 IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); 1205 IWL_DEBUG_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku);
1208 1206
1209 priv->hw_params.tx_chains_num = 1207 priv->hw_params.tx_chains_num =
1210 num_of_ant(priv->eeprom_data->valid_tx_ant); 1208 num_of_ant(priv->eeprom_data->valid_tx_ant);
@@ -1214,9 +1212,9 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
1214 priv->hw_params.rx_chains_num = 1212 priv->hw_params.rx_chains_num =
1215 num_of_ant(priv->eeprom_data->valid_rx_ant); 1213 num_of_ant(priv->eeprom_data->valid_rx_ant);
1216 1214
1217 IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", 1215 IWL_DEBUG_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n",
1218 priv->eeprom_data->valid_tx_ant, 1216 priv->eeprom_data->valid_tx_ant,
1219 priv->eeprom_data->valid_rx_ant); 1217 priv->eeprom_data->valid_rx_ant);
1220 1218
1221 return 0; 1219 return 0;
1222} 1220}
@@ -1231,7 +1229,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1231 struct iwl_op_mode *op_mode; 1229 struct iwl_op_mode *op_mode;
1232 u16 num_mac; 1230 u16 num_mac;
1233 u32 ucode_flags; 1231 u32 ucode_flags;
1234 struct iwl_trans_config trans_cfg; 1232 struct iwl_trans_config trans_cfg = {};
1235 static const u8 no_reclaim_cmds[] = { 1233 static const u8 no_reclaim_cmds[] = {
1236 REPLY_RX_PHY_CMD, 1234 REPLY_RX_PHY_CMD,
1237 REPLY_RX_MPDU_CMD, 1235 REPLY_RX_MPDU_CMD,
@@ -1507,10 +1505,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
1507 1505
1508 iwl_tt_exit(priv); 1506 iwl_tt_exit(priv);
1509 1507
1510 /*This will stop the queues, move the device to low power state */
1511 priv->ucode_loaded = false;
1512 iwl_trans_stop_device(priv->trans);
1513
1514 kfree(priv->eeprom_blob); 1508 kfree(priv->eeprom_blob);
1515 iwl_free_eeprom_data(priv->eeprom_data); 1509 iwl_free_eeprom_data(priv->eeprom_data);
1516 1510
@@ -1926,8 +1920,6 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
1926 * commands by clearing the ready bit */ 1920 * commands by clearing the ready bit */
1927 clear_bit(STATUS_READY, &priv->status); 1921 clear_bit(STATUS_READY, &priv->status);
1928 1922
1929 wake_up(&priv->trans->wait_command_queue);
1930
1931 if (!ondemand) { 1923 if (!ondemand) {
1932 /* 1924 /*
1933 * If firmware keep reloading, then it indicate something 1925 * If firmware keep reloading, then it indicate something
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index 5a9c325804f..cac4f37cc42 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -631,8 +631,6 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
631 test_bit(STATUS_RF_KILL_HW, &priv->status))) 631 test_bit(STATUS_RF_KILL_HW, &priv->status)))
632 wiphy_rfkill_set_hw_state(priv->hw->wiphy, 632 wiphy_rfkill_set_hw_state(priv->hw->wiphy,
633 test_bit(STATUS_RF_KILL_HW, &priv->status)); 633 test_bit(STATUS_RF_KILL_HW, &priv->status));
634 else
635 wake_up(&priv->trans->wait_command_queue);
636 return 0; 634 return 0;
637} 635}
638 636
@@ -901,7 +899,7 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
901 struct iwl_device_cmd *cmd) 899 struct iwl_device_cmd *cmd)
902{ 900{
903 struct ieee80211_hdr *header; 901 struct ieee80211_hdr *header;
904 struct ieee80211_rx_status rx_status; 902 struct ieee80211_rx_status rx_status = {};
905 struct iwl_rx_packet *pkt = rxb_addr(rxb); 903 struct iwl_rx_packet *pkt = rxb_addr(rxb);
906 struct iwl_rx_phy_res *phy_res; 904 struct iwl_rx_phy_res *phy_res;
907 __le32 rx_pkt_status; 905 __le32 rx_pkt_status;
@@ -951,7 +949,7 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
951 949
952 /* TSF isn't reliable. In order to allow smooth user experience, 950 /* TSF isn't reliable. In order to allow smooth user experience,
953 * this W/A doesn't propagate it to the mac80211 */ 951 * this W/A doesn't propagate it to the mac80211 */
954 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ 952 /*rx_status.flag |= RX_FLAG_MACTIME_START;*/
955 953
956 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); 954 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
957 955
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index f5ca73a8987..4ae031f6726 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -1075,14 +1075,11 @@ static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status)
1075 1075
1076static void iwlagn_set_tx_status(struct iwl_priv *priv, 1076static void iwlagn_set_tx_status(struct iwl_priv *priv,
1077 struct ieee80211_tx_info *info, 1077 struct ieee80211_tx_info *info,
1078 struct iwlagn_tx_resp *tx_resp, 1078 struct iwlagn_tx_resp *tx_resp)
1079 bool is_agg)
1080{ 1079{
1081 u16 status = le16_to_cpu(tx_resp->status.status); 1080 u16 status = le16_to_cpu(tx_resp->status.status);
1082 1081
1083 info->status.rates[0].count = tx_resp->failure_frame + 1; 1082 info->status.rates[0].count = tx_resp->failure_frame + 1;
1084 if (is_agg)
1085 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
1086 info->flags |= iwl_tx_status_to_mac80211(status); 1083 info->flags |= iwl_tx_status_to_mac80211(status);
1087 iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), 1084 iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
1088 info); 1085 info);
@@ -1231,7 +1228,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1231 if (is_agg && !iwl_is_tx_success(status)) 1228 if (is_agg && !iwl_is_tx_success(status))
1232 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 1229 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1233 iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(skb), 1230 iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(skb),
1234 tx_resp, is_agg); 1231 tx_resp);
1235 if (!is_agg) 1232 if (!is_agg)
1236 iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); 1233 iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
1237 1234
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 2cb1efbc5ed..95e6d33f515 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -254,7 +254,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
254 int ret; 254 int ret;
255 int i; 255 int i;
256 256
257 iwl_trans_fw_alive(priv->trans); 257 iwl_trans_fw_alive(priv->trans, 0);
258 258
259 if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN && 259 if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN &&
260 priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE) { 260 priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 87f465a49df..196266aa5a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -150,7 +150,7 @@ enum iwl_led_mode {
150struct iwl_base_params { 150struct iwl_base_params {
151 int eeprom_size; 151 int eeprom_size;
152 int num_of_queues; /* def: HW dependent */ 152 int num_of_queues; /* def: HW dependent */
153 /* for iwl_apm_init() */ 153 /* for iwl_pcie_apm_init() */
154 u32 pll_cfg_val; 154 u32 pll_cfg_val;
155 155
156 const u16 max_ll_items; 156 const u16 max_ll_items;
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 678717bf62e..b3fde5f7b9b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -306,7 +306,7 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
306 memcpy(__get_dynamic_array(data), 306 memcpy(__get_dynamic_array(data),
307 ((u8 *)rxbuf) + offs, len - offs); 307 ((u8 *)rxbuf) + offs, len - offs);
308 ), 308 ),
309 TP_printk("[%s] TX frame data", __get_str(dev)) 309 TP_printk("[%s] RX frame data", __get_str(dev))
310); 310);
311 311
312#undef TRACE_SYSTEM 312#undef TRACE_SYSTEM
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index f10170fe879..4a9dc9629ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -889,8 +889,8 @@ int iwl_eeprom_check_version(struct iwl_eeprom_data *data,
889{ 889{
890 if (data->eeprom_version >= trans->cfg->eeprom_ver || 890 if (data->eeprom_version >= trans->cfg->eeprom_ver ||
891 data->calib_version >= trans->cfg->eeprom_calib_ver) { 891 data->calib_version >= trans->cfg->eeprom_calib_ver) {
892 IWL_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", 892 IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n",
893 data->eeprom_version, data->calib_version); 893 data->eeprom_version, data->calib_version);
894 return 0; 894 return 0;
895 } 895 }
896 896
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 80604664174..ec48563d3c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -267,7 +267,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
267 267
268#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS (20) 268#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS (20)
269#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS (4) 269#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS (4)
270#define RX_RB_TIMEOUT (0x10) 270#define RX_RB_TIMEOUT (0x11)
271 271
272#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000) 272#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000)
273#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000) 273#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000)
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index f75ea6d73ff..e378ea6dca9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -221,14 +221,21 @@ struct iwl_device_cmd {
221/** 221/**
222 * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command 222 * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command
223 * 223 *
224 * IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's 224 * @IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's
225 * ring. The transport layer doesn't map the command's buffer to DMA, but 225 * ring. The transport layer doesn't map the command's buffer to DMA, but
226 * rather copies it to an previously allocated DMA buffer. This flag tells 226 * rather copies it to an previously allocated DMA buffer. This flag tells
227 * the transport layer not to copy the command, but to map the existing 227 * the transport layer not to copy the command, but to map the existing
228 * buffer. This can save memcpy and is worth with very big comamnds. 228 * buffer (that is passed in) instead. This saves the memcpy and allows
229 * commands that are bigger than the fixed buffer to be submitted.
230 * Note that a TFD entry after a NOCOPY one cannot be a normal copied one.
231 * @IWL_HCMD_DFL_DUP: Only valid without NOCOPY, duplicate the memory for this
232 * chunk internally and free it again after the command completes. This
233 * can (currently) be used only once per command.
234 * Note that a TFD entry after a DUP one cannot be a normal copied one.
229 */ 235 */
230enum iwl_hcmd_dataflag { 236enum iwl_hcmd_dataflag {
231 IWL_HCMD_DFL_NOCOPY = BIT(0), 237 IWL_HCMD_DFL_NOCOPY = BIT(0),
238 IWL_HCMD_DFL_DUP = BIT(1),
232}; 239};
233 240
234/** 241/**
@@ -348,14 +355,17 @@ struct iwl_trans;
348 * @start_fw: allocates and inits all the resources for the transport 355 * @start_fw: allocates and inits all the resources for the transport
349 * layer. Also kick a fw image. 356 * layer. Also kick a fw image.
350 * May sleep 357 * May sleep
351 * @fw_alive: called when the fw sends alive notification 358 * @fw_alive: called when the fw sends alive notification. If the fw provides
359 * the SCD base address in SRAM, then provide it here, or 0 otherwise.
352 * May sleep 360 * May sleep
353 * @stop_device:stops the whole device (embedded CPU put to reset) 361 * @stop_device:stops the whole device (embedded CPU put to reset)
354 * May sleep 362 * May sleep
355 * @wowlan_suspend: put the device into the correct mode for WoWLAN during 363 * @wowlan_suspend: put the device into the correct mode for WoWLAN during
356 * suspend. This is optional, if not implemented WoWLAN will not be 364 * suspend. This is optional, if not implemented WoWLAN will not be
357 * supported. This callback may sleep. 365 * supported. This callback may sleep.
358 * @send_cmd:send a host command 366 * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted.
367 * If RFkill is asserted in the middle of a SYNC host command, it must
368 * return -ERFKILL straight away.
359 * May sleep only if CMD_SYNC is set 369 * May sleep only if CMD_SYNC is set
360 * @tx: send an skb 370 * @tx: send an skb
361 * Must be atomic 371 * Must be atomic
@@ -385,7 +395,7 @@ struct iwl_trans_ops {
385 int (*start_hw)(struct iwl_trans *iwl_trans); 395 int (*start_hw)(struct iwl_trans *iwl_trans);
386 void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); 396 void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving);
387 int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); 397 int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw);
388 void (*fw_alive)(struct iwl_trans *trans); 398 void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
389 void (*stop_device)(struct iwl_trans *trans); 399 void (*stop_device)(struct iwl_trans *trans);
390 400
391 void (*wowlan_suspend)(struct iwl_trans *trans); 401 void (*wowlan_suspend)(struct iwl_trans *trans);
@@ -438,7 +448,6 @@ enum iwl_trans_state {
438 * Set during transport allocation. 448 * Set during transport allocation.
439 * @hw_id_str: a string with info about HW ID. Set during transport allocation. 449 * @hw_id_str: a string with info about HW ID. Set during transport allocation.
440 * @pm_support: set to true in start_hw if link pm is supported 450 * @pm_support: set to true in start_hw if link pm is supported
441 * @wait_command_queue: the wait_queue for SYNC host commands
442 * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only. 451 * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
443 * The user should use iwl_trans_{alloc,free}_tx_cmd. 452 * The user should use iwl_trans_{alloc,free}_tx_cmd.
444 * @dev_cmd_headroom: room needed for the transport's private use before the 453 * @dev_cmd_headroom: room needed for the transport's private use before the
@@ -465,8 +474,6 @@ struct iwl_trans {
465 474
466 bool pm_support; 475 bool pm_support;
467 476
468 wait_queue_head_t wait_command_queue;
469
470 /* The following fields are internal only */ 477 /* The following fields are internal only */
471 struct kmem_cache *dev_cmd_pool; 478 struct kmem_cache *dev_cmd_pool;
472 size_t dev_cmd_headroom; 479 size_t dev_cmd_headroom;
@@ -508,13 +515,13 @@ static inline void iwl_trans_stop_hw(struct iwl_trans *trans,
508 trans->state = IWL_TRANS_NO_FW; 515 trans->state = IWL_TRANS_NO_FW;
509} 516}
510 517
511static inline void iwl_trans_fw_alive(struct iwl_trans *trans) 518static inline void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr)
512{ 519{
513 might_sleep(); 520 might_sleep();
514 521
515 trans->state = IWL_TRANS_FW_ALIVE; 522 trans->state = IWL_TRANS_FW_ALIVE;
516 523
517 trans->ops->fw_alive(trans); 524 trans->ops->fw_alive(trans, scd_addr);
518} 525}
519 526
520static inline int iwl_trans_start_fw(struct iwl_trans *trans, 527static inline int iwl_trans_start_fw(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 2a467539670..956fe6c370b 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -69,7 +69,6 @@
69 69
70#include "iwl-trans.h" 70#include "iwl-trans.h"
71#include "iwl-drv.h" 71#include "iwl-drv.h"
72#include "iwl-trans.h"
73 72
74#include "cfg.h" 73#include "cfg.h"
75#include "internal.h" 74#include "internal.h"
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 401178f44a3..d91d2e8c62f 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -73,7 +73,7 @@ struct isr_statistics {
73}; 73};
74 74
75/** 75/**
76 * struct iwl_rx_queue - Rx queue 76 * struct iwl_rxq - Rx queue
77 * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) 77 * @bd: driver's pointer to buffer of receive buffer descriptors (rbd)
78 * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) 78 * @bd_dma: bus address of buffer of receive buffer descriptors (rbd)
79 * @pool: 79 * @pool:
@@ -91,7 +91,7 @@ struct isr_statistics {
91 * 91 *
92 * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers 92 * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers
93 */ 93 */
94struct iwl_rx_queue { 94struct iwl_rxq {
95 __le32 *bd; 95 __le32 *bd;
96 dma_addr_t bd_dma; 96 dma_addr_t bd_dma;
97 struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; 97 struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
@@ -157,8 +157,8 @@ struct iwl_cmd_meta {
157 * 32 since we don't need so many commands pending. Since the HW 157 * 32 since we don't need so many commands pending. Since the HW
158 * still uses 256 BDs for DMA though, n_bd stays 256. As a result, 158 * still uses 256 BDs for DMA though, n_bd stays 256. As a result,
159 * the software buffers (in the variables @meta, @txb in struct 159 * the software buffers (in the variables @meta, @txb in struct
160 * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds 160 * iwl_txq) only have 32 entries, while the HW buffers (@tfds in
161 * in the same struct) have 256. 161 * the same struct) have 256.
162 * This means that we end up with the following: 162 * This means that we end up with the following:
163 * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 | 163 * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 |
164 * SW entries: | 0 | ... | 31 | 164 * SW entries: | 0 | ... | 31 |
@@ -182,15 +182,17 @@ struct iwl_queue {
182#define TFD_TX_CMD_SLOTS 256 182#define TFD_TX_CMD_SLOTS 256
183#define TFD_CMD_SLOTS 32 183#define TFD_CMD_SLOTS 32
184 184
185struct iwl_pcie_tx_queue_entry { 185struct iwl_pcie_txq_entry {
186 struct iwl_device_cmd *cmd; 186 struct iwl_device_cmd *cmd;
187 struct iwl_device_cmd *copy_cmd; 187 struct iwl_device_cmd *copy_cmd;
188 struct sk_buff *skb; 188 struct sk_buff *skb;
189 /* buffer to free after command completes */
190 const void *free_buf;
189 struct iwl_cmd_meta meta; 191 struct iwl_cmd_meta meta;
190}; 192};
191 193
192/** 194/**
193 * struct iwl_tx_queue - Tx Queue for DMA 195 * struct iwl_txq - Tx Queue for DMA
194 * @q: generic Rx/Tx queue descriptor 196 * @q: generic Rx/Tx queue descriptor
195 * @tfds: transmit frame descriptors (DMA memory) 197 * @tfds: transmit frame descriptors (DMA memory)
196 * @entries: transmit entries (driver state) 198 * @entries: transmit entries (driver state)
@@ -203,10 +205,10 @@ struct iwl_pcie_tx_queue_entry {
203 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame 205 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
204 * descriptors) and required locking structures. 206 * descriptors) and required locking structures.
205 */ 207 */
206struct iwl_tx_queue { 208struct iwl_txq {
207 struct iwl_queue q; 209 struct iwl_queue q;
208 struct iwl_tfd *tfds; 210 struct iwl_tfd *tfds;
209 struct iwl_pcie_tx_queue_entry *entries; 211 struct iwl_pcie_txq_entry *entries;
210 spinlock_t lock; 212 spinlock_t lock;
211 struct timer_list stuck_timer; 213 struct timer_list stuck_timer;
212 struct iwl_trans_pcie *trans_pcie; 214 struct iwl_trans_pcie *trans_pcie;
@@ -236,7 +238,7 @@ struct iwl_tx_queue {
236 * @wd_timeout: queue watchdog timeout (jiffies) 238 * @wd_timeout: queue watchdog timeout (jiffies)
237 */ 239 */
238struct iwl_trans_pcie { 240struct iwl_trans_pcie {
239 struct iwl_rx_queue rxq; 241 struct iwl_rxq rxq;
240 struct work_struct rx_replenish; 242 struct work_struct rx_replenish;
241 struct iwl_trans *trans; 243 struct iwl_trans *trans;
242 struct iwl_drv *drv; 244 struct iwl_drv *drv;
@@ -258,7 +260,7 @@ struct iwl_trans_pcie {
258 struct iwl_dma_ptr scd_bc_tbls; 260 struct iwl_dma_ptr scd_bc_tbls;
259 struct iwl_dma_ptr kw; 261 struct iwl_dma_ptr kw;
260 262
261 struct iwl_tx_queue *txq; 263 struct iwl_txq *txq;
262 unsigned long queue_used[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; 264 unsigned long queue_used[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
263 unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; 265 unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
264 266
@@ -268,6 +270,8 @@ struct iwl_trans_pcie {
268 270
269 bool ucode_write_complete; 271 bool ucode_write_complete;
270 wait_queue_head_t ucode_write_waitq; 272 wait_queue_head_t ucode_write_waitq;
273 wait_queue_head_t wait_command_queue;
274
271 unsigned long status; 275 unsigned long status;
272 u8 cmd_queue; 276 u8 cmd_queue;
273 u8 cmd_fifo; 277 u8 cmd_fifo;
@@ -283,13 +287,23 @@ struct iwl_trans_pcie {
283 unsigned long wd_timeout; 287 unsigned long wd_timeout;
284}; 288};
285 289
286/***************************************************** 290/**
287* DRIVER STATUS FUNCTIONS 291 * enum iwl_pcie_status: status of the PCIe transport
288******************************************************/ 292 * @STATUS_HCMD_ACTIVE: a SYNC command is being processed
289#define STATUS_HCMD_ACTIVE 0 293 * @STATUS_DEVICE_ENABLED: APM is enabled
290#define STATUS_DEVICE_ENABLED 1 294 * @STATUS_TPOWER_PMI: the device might be asleep (need to wake it up)
291#define STATUS_TPOWER_PMI 2 295 * @STATUS_INT_ENABLED: interrupts are enabled
292#define STATUS_INT_ENABLED 3 296 * @STATUS_RFKILL: the HW RFkill switch is in KILL position
297 * @STATUS_FW_ERROR: the fw is in error state
298 */
299enum iwl_pcie_status {
300 STATUS_HCMD_ACTIVE,
301 STATUS_DEVICE_ENABLED,
302 STATUS_TPOWER_PMI,
303 STATUS_INT_ENABLED,
304 STATUS_RFKILL,
305 STATUS_FW_ERROR,
306};
293 307
294#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ 308#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
295 ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific)) 309 ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific))
@@ -301,6 +315,10 @@ iwl_trans_pcie_get_trans(struct iwl_trans_pcie *trans_pcie)
301 trans_specific); 315 trans_specific);
302} 316}
303 317
318/*
319 * Convention: trans API functions: iwl_trans_pcie_XXX
320 * Other functions: iwl_pcie_XXX
321 */
304struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, 322struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
305 const struct pci_device_id *ent, 323 const struct pci_device_id *ent,
306 const struct iwl_cfg *cfg); 324 const struct iwl_cfg *cfg);
@@ -309,50 +327,43 @@ void iwl_trans_pcie_free(struct iwl_trans *trans);
309/***************************************************** 327/*****************************************************
310* RX 328* RX
311******************************************************/ 329******************************************************/
312void iwl_bg_rx_replenish(struct work_struct *data); 330int iwl_pcie_rx_init(struct iwl_trans *trans);
313void iwl_irq_tasklet(struct iwl_trans *trans); 331void iwl_pcie_tasklet(struct iwl_trans *trans);
314void iwl_rx_replenish(struct iwl_trans *trans); 332int iwl_pcie_rx_stop(struct iwl_trans *trans);
315void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, 333void iwl_pcie_rx_free(struct iwl_trans *trans);
316 struct iwl_rx_queue *q);
317 334
318/***************************************************** 335/*****************************************************
319* ICT 336* ICT - interrupt handling
320******************************************************/ 337******************************************************/
321void iwl_reset_ict(struct iwl_trans *trans); 338irqreturn_t iwl_pcie_isr_ict(int irq, void *data);
322void iwl_disable_ict(struct iwl_trans *trans); 339int iwl_pcie_alloc_ict(struct iwl_trans *trans);
323int iwl_alloc_isr_ict(struct iwl_trans *trans); 340void iwl_pcie_free_ict(struct iwl_trans *trans);
324void iwl_free_isr_ict(struct iwl_trans *trans); 341void iwl_pcie_reset_ict(struct iwl_trans *trans);
325irqreturn_t iwl_isr_ict(int irq, void *data); 342void iwl_pcie_disable_ict(struct iwl_trans *trans);
326 343
327/***************************************************** 344/*****************************************************
328* TX / HCMD 345* TX / HCMD
329******************************************************/ 346******************************************************/
330void iwl_txq_update_write_ptr(struct iwl_trans *trans, 347int iwl_pcie_tx_init(struct iwl_trans *trans);
331 struct iwl_tx_queue *txq); 348void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr);
332int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, 349int iwl_pcie_tx_stop(struct iwl_trans *trans);
333 struct iwl_tx_queue *txq, 350void iwl_pcie_tx_free(struct iwl_trans *trans);
334 dma_addr_t addr, u16 len, u8 reset);
335int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id);
336int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
337void iwl_tx_cmd_complete(struct iwl_trans *trans,
338 struct iwl_rx_cmd_buffer *rxb, int handler_status);
339void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
340 struct iwl_tx_queue *txq,
341 u16 byte_cnt);
342void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, 351void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
343 int sta_id, int tid, int frame_limit, u16 ssn); 352 int sta_id, int tid, int frame_limit, u16 ssn);
344void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); 353void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue);
345void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, 354int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
346 enum dma_data_direction dma_dir); 355 struct iwl_device_cmd *dev_cmd, int txq_id);
347int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, 356void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq);
348 struct sk_buff_head *skbs); 357int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
349int iwl_queue_space(const struct iwl_queue *q); 358void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
350 359 struct iwl_rx_cmd_buffer *rxb, int handler_status);
360void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
361 struct sk_buff_head *skbs);
351/***************************************************** 362/*****************************************************
352* Error handling 363* Error handling
353******************************************************/ 364******************************************************/
354int iwl_dump_fh(struct iwl_trans *trans, char **buf); 365int iwl_pcie_dump_fh(struct iwl_trans *trans, char **buf);
355void iwl_dump_csr(struct iwl_trans *trans); 366void iwl_pcie_dump_csr(struct iwl_trans *trans);
356 367
357/***************************************************** 368/*****************************************************
358* Helpers 369* Helpers
@@ -388,7 +399,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
388} 399}
389 400
390static inline void iwl_wake_queue(struct iwl_trans *trans, 401static inline void iwl_wake_queue(struct iwl_trans *trans,
391 struct iwl_tx_queue *txq) 402 struct iwl_txq *txq)
392{ 403{
393 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 404 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
394 405
@@ -399,7 +410,7 @@ static inline void iwl_wake_queue(struct iwl_trans *trans,
399} 410}
400 411
401static inline void iwl_stop_queue(struct iwl_trans *trans, 412static inline void iwl_stop_queue(struct iwl_trans *trans,
402 struct iwl_tx_queue *txq) 413 struct iwl_txq *txq)
403{ 414{
404 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 415 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
405 416
@@ -411,7 +422,7 @@ static inline void iwl_stop_queue(struct iwl_trans *trans,
411 txq->q.id); 422 txq->q.id);
412} 423}
413 424
414static inline int iwl_queue_used(const struct iwl_queue *q, int i) 425static inline bool iwl_queue_used(const struct iwl_queue *q, int i)
415{ 426{
416 return q->write_ptr >= q->read_ptr ? 427 return q->write_ptr >= q->read_ptr ?
417 (i >= q->read_ptr && i < q->write_ptr) : 428 (i >= q->read_ptr && i < q->write_ptr) :
@@ -423,8 +434,8 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index)
423 return index & (q->n_window - 1); 434 return index & (q->n_window - 1);
424} 435}
425 436
426static inline const char * 437static inline const char *get_cmd_string(struct iwl_trans_pcie *trans_pcie,
427trans_pcie_get_cmd_string(struct iwl_trans_pcie *trans_pcie, u8 cmd) 438 u8 cmd)
428{ 439{
429 if (!trans_pcie->command_names || !trans_pcie->command_names[cmd]) 440 if (!trans_pcie->command_names || !trans_pcie->command_names[cmd])
430 return "UNKNOWN"; 441 return "UNKNOWN";
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 41d821fbdb9..bb32510fdd6 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -76,7 +76,7 @@
76 * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When 76 * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When
77 * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled 77 * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
78 * to replenish the iwl->rxq->rx_free. 78 * to replenish the iwl->rxq->rx_free.
79 * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the 79 * + In iwl_pcie_rx_replenish (scheduled) if 'processed' != 'read' then the
80 * iwl->rxq is replenished and the READ INDEX is updated (updating the 80 * iwl->rxq is replenished and the READ INDEX is updated (updating the
81 * 'processed' and 'read' driver indexes as well) 81 * 'processed' and 'read' driver indexes as well)
82 * + A received packet is processed and handed to the kernel network stack, 82 * + A received packet is processed and handed to the kernel network stack,
@@ -89,28 +89,28 @@
89 * 89 *
90 * Driver sequence: 90 * Driver sequence:
91 * 91 *
92 * iwl_rx_queue_alloc() Allocates rx_free 92 * iwl_rxq_alloc() Allocates rx_free
93 * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls 93 * iwl_pcie_rx_replenish() Replenishes rx_free list from rx_used, and calls
94 * iwl_rx_queue_restock 94 * iwl_pcie_rxq_restock
95 * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx 95 * iwl_pcie_rxq_restock() Moves available buffers from rx_free into Rx
96 * queue, updates firmware pointers, and updates 96 * queue, updates firmware pointers, and updates
97 * the WRITE index. If insufficient rx_free buffers 97 * the WRITE index. If insufficient rx_free buffers
98 * are available, schedules iwl_rx_replenish 98 * are available, schedules iwl_pcie_rx_replenish
99 * 99 *
100 * -- enable interrupts -- 100 * -- enable interrupts --
101 * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the 101 * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the
102 * READ INDEX, detaching the SKB from the pool. 102 * READ INDEX, detaching the SKB from the pool.
103 * Moves the packet buffer from queue to rx_used. 103 * Moves the packet buffer from queue to rx_used.
104 * Calls iwl_rx_queue_restock to refill any empty 104 * Calls iwl_pcie_rxq_restock to refill any empty
105 * slots. 105 * slots.
106 * ... 106 * ...
107 * 107 *
108 */ 108 */
109 109
110/** 110/*
111 * iwl_rx_queue_space - Return number of free slots available in queue. 111 * iwl_rxq_space - Return number of free slots available in queue.
112 */ 112 */
113static int iwl_rx_queue_space(const struct iwl_rx_queue *q) 113static int iwl_rxq_space(const struct iwl_rxq *q)
114{ 114{
115 int s = q->read - q->write; 115 int s = q->read - q->write;
116 if (s <= 0) 116 if (s <= 0)
@@ -122,11 +122,28 @@ static int iwl_rx_queue_space(const struct iwl_rx_queue *q)
122 return s; 122 return s;
123} 123}
124 124
125/** 125/*
126 * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue 126 * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
127 */
128static inline __le32 iwl_pcie_dma_addr2rbd_ptr(dma_addr_t dma_addr)
129{
130 return cpu_to_le32((u32)(dma_addr >> 8));
131}
132
133/*
134 * iwl_pcie_rx_stop - stops the Rx DMA
135 */
136int iwl_pcie_rx_stop(struct iwl_trans *trans)
137{
138 iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
139 return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG,
140 FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
141}
142
143/*
144 * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue
127 */ 145 */
128void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, 146static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q)
129 struct iwl_rx_queue *q)
130{ 147{
131 unsigned long flags; 148 unsigned long flags;
132 u32 reg; 149 u32 reg;
@@ -176,16 +193,8 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans,
176 spin_unlock_irqrestore(&q->lock, flags); 193 spin_unlock_irqrestore(&q->lock, flags);
177} 194}
178 195
179/** 196/*
180 * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr 197 * iwl_pcie_rxq_restock - refill RX queue from pre-allocated pool
181 */
182static inline __le32 iwl_dma_addr2rbd_ptr(dma_addr_t dma_addr)
183{
184 return cpu_to_le32((u32)(dma_addr >> 8));
185}
186
187/**
188 * iwl_rx_queue_restock - refill RX queue from pre-allocated pool
189 * 198 *
190 * If there are slots in the RX queue that need to be restocked, 199 * If there are slots in the RX queue that need to be restocked,
191 * and we have free pre-allocated buffers, fill the ranks as much 200 * and we have free pre-allocated buffers, fill the ranks as much
@@ -195,11 +204,10 @@ static inline __le32 iwl_dma_addr2rbd_ptr(dma_addr_t dma_addr)
195 * also updates the memory address in the firmware to reference the new 204 * also updates the memory address in the firmware to reference the new
196 * target buffer. 205 * target buffer.
197 */ 206 */
198static void iwl_rx_queue_restock(struct iwl_trans *trans) 207static void iwl_pcie_rxq_restock(struct iwl_trans *trans)
199{ 208{
200 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 209 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
201 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 210 struct iwl_rxq *rxq = &trans_pcie->rxq;
202 struct list_head *element;
203 struct iwl_rx_mem_buffer *rxb; 211 struct iwl_rx_mem_buffer *rxb;
204 unsigned long flags; 212 unsigned long flags;
205 213
@@ -215,18 +223,18 @@ static void iwl_rx_queue_restock(struct iwl_trans *trans)
215 return; 223 return;
216 224
217 spin_lock_irqsave(&rxq->lock, flags); 225 spin_lock_irqsave(&rxq->lock, flags);
218 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { 226 while ((iwl_rxq_space(rxq) > 0) && (rxq->free_count)) {
219 /* The overwritten rxb must be a used one */ 227 /* The overwritten rxb must be a used one */
220 rxb = rxq->queue[rxq->write]; 228 rxb = rxq->queue[rxq->write];
221 BUG_ON(rxb && rxb->page); 229 BUG_ON(rxb && rxb->page);
222 230
223 /* Get next free Rx buffer, remove from free list */ 231 /* Get next free Rx buffer, remove from free list */
224 element = rxq->rx_free.next; 232 rxb = list_first_entry(&rxq->rx_free, struct iwl_rx_mem_buffer,
225 rxb = list_entry(element, struct iwl_rx_mem_buffer, list); 233 list);
226 list_del(element); 234 list_del(&rxb->list);
227 235
228 /* Point to Rx buffer via next RBD in circular buffer */ 236 /* Point to Rx buffer via next RBD in circular buffer */
229 rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(rxb->page_dma); 237 rxq->bd[rxq->write] = iwl_pcie_dma_addr2rbd_ptr(rxb->page_dma);
230 rxq->queue[rxq->write] = rxb; 238 rxq->queue[rxq->write] = rxb;
231 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; 239 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
232 rxq->free_count--; 240 rxq->free_count--;
@@ -243,24 +251,23 @@ static void iwl_rx_queue_restock(struct iwl_trans *trans)
243 spin_lock_irqsave(&rxq->lock, flags); 251 spin_lock_irqsave(&rxq->lock, flags);
244 rxq->need_update = 1; 252 rxq->need_update = 1;
245 spin_unlock_irqrestore(&rxq->lock, flags); 253 spin_unlock_irqrestore(&rxq->lock, flags);
246 iwl_rx_queue_update_write_ptr(trans, rxq); 254 iwl_pcie_rxq_inc_wr_ptr(trans, rxq);
247 } 255 }
248} 256}
249 257
250/* 258/*
251 * iwl_rx_allocate - allocate a page for each used RBD 259 * iwl_pcie_rxq_alloc_rbs - allocate a page for each used RBD
252 * 260 *
253 * A used RBD is an Rx buffer that has been given to the stack. To use it again 261 * A used RBD is an Rx buffer that has been given to the stack. To use it again
254 * a page must be allocated and the RBD must point to the page. This function 262 * a page must be allocated and the RBD must point to the page. This function
255 * doesn't change the HW pointer but handles the list of pages that is used by 263 * doesn't change the HW pointer but handles the list of pages that is used by
256 * iwl_rx_queue_restock. The latter function will update the HW to use the newly 264 * iwl_pcie_rxq_restock. The latter function will update the HW to use the newly
257 * allocated buffers. 265 * allocated buffers.
258 */ 266 */
259static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) 267static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority)
260{ 268{
261 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 269 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
262 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 270 struct iwl_rxq *rxq = &trans_pcie->rxq;
263 struct list_head *element;
264 struct iwl_rx_mem_buffer *rxb; 271 struct iwl_rx_mem_buffer *rxb;
265 struct page *page; 272 struct page *page;
266 unsigned long flags; 273 unsigned long flags;
@@ -308,10 +315,9 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority)
308 __free_pages(page, trans_pcie->rx_page_order); 315 __free_pages(page, trans_pcie->rx_page_order);
309 return; 316 return;
310 } 317 }
311 element = rxq->rx_used.next; 318 rxb = list_first_entry(&rxq->rx_used, struct iwl_rx_mem_buffer,
312 rxb = list_entry(element, struct iwl_rx_mem_buffer, list); 319 list);
313 list_del(element); 320 list_del(&rxb->list);
314
315 spin_unlock_irqrestore(&rxq->lock, flags); 321 spin_unlock_irqrestore(&rxq->lock, flags);
316 322
317 BUG_ON(rxb->page); 323 BUG_ON(rxb->page);
@@ -343,47 +349,227 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority)
343 } 349 }
344} 350}
345 351
352static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans)
353{
354 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
355 struct iwl_rxq *rxq = &trans_pcie->rxq;
356 int i;
357
358 /* Fill the rx_used queue with _all_ of the Rx buffers */
359 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
360 /* In the reset function, these buffers may have been allocated
361 * to an SKB, so we need to unmap and free potential storage */
362 if (rxq->pool[i].page != NULL) {
363 dma_unmap_page(trans->dev, rxq->pool[i].page_dma,
364 PAGE_SIZE << trans_pcie->rx_page_order,
365 DMA_FROM_DEVICE);
366 __free_pages(rxq->pool[i].page,
367 trans_pcie->rx_page_order);
368 rxq->pool[i].page = NULL;
369 }
370 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
371 }
372}
373
346/* 374/*
347 * iwl_rx_replenish - Move all used buffers from rx_used to rx_free 375 * iwl_pcie_rx_replenish - Move all used buffers from rx_used to rx_free
348 * 376 *
349 * When moving to rx_free an page is allocated for the slot. 377 * When moving to rx_free an page is allocated for the slot.
350 * 378 *
351 * Also restock the Rx queue via iwl_rx_queue_restock. 379 * Also restock the Rx queue via iwl_pcie_rxq_restock.
352 * This is called as a scheduled work item (except for during initialization) 380 * This is called as a scheduled work item (except for during initialization)
353 */ 381 */
354void iwl_rx_replenish(struct iwl_trans *trans) 382static void iwl_pcie_rx_replenish(struct iwl_trans *trans)
355{ 383{
356 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 384 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
357 unsigned long flags; 385 unsigned long flags;
358 386
359 iwl_rx_allocate(trans, GFP_KERNEL); 387 iwl_pcie_rxq_alloc_rbs(trans, GFP_KERNEL);
360 388
361 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 389 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
362 iwl_rx_queue_restock(trans); 390 iwl_pcie_rxq_restock(trans);
363 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 391 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
364} 392}
365 393
366static void iwl_rx_replenish_now(struct iwl_trans *trans) 394static void iwl_pcie_rx_replenish_now(struct iwl_trans *trans)
367{ 395{
368 iwl_rx_allocate(trans, GFP_ATOMIC); 396 iwl_pcie_rxq_alloc_rbs(trans, GFP_ATOMIC);
369 397
370 iwl_rx_queue_restock(trans); 398 iwl_pcie_rxq_restock(trans);
371} 399}
372 400
373void iwl_bg_rx_replenish(struct work_struct *data) 401static void iwl_pcie_rx_replenish_work(struct work_struct *data)
374{ 402{
375 struct iwl_trans_pcie *trans_pcie = 403 struct iwl_trans_pcie *trans_pcie =
376 container_of(data, struct iwl_trans_pcie, rx_replenish); 404 container_of(data, struct iwl_trans_pcie, rx_replenish);
377 405
378 iwl_rx_replenish(trans_pcie->trans); 406 iwl_pcie_rx_replenish(trans_pcie->trans);
407}
408
409static int iwl_pcie_rx_alloc(struct iwl_trans *trans)
410{
411 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
412 struct iwl_rxq *rxq = &trans_pcie->rxq;
413 struct device *dev = trans->dev;
414
415 memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq));
416
417 spin_lock_init(&rxq->lock);
418
419 if (WARN_ON(rxq->bd || rxq->rb_stts))
420 return -EINVAL;
421
422 /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */
423 rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,
424 &rxq->bd_dma, GFP_KERNEL);
425 if (!rxq->bd)
426 goto err_bd;
427
428 /*Allocate the driver's pointer to receive buffer status */
429 rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts),
430 &rxq->rb_stts_dma, GFP_KERNEL);
431 if (!rxq->rb_stts)
432 goto err_rb_stts;
433
434 return 0;
435
436err_rb_stts:
437 dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,
438 rxq->bd, rxq->bd_dma);
439 memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
440 rxq->bd = NULL;
441err_bd:
442 return -ENOMEM;
443}
444
445static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)
446{
447 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
448 u32 rb_size;
449 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
450
451 if (trans_pcie->rx_buf_size_8k)
452 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
453 else
454 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
455
456 /* Stop Rx DMA */
457 iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
458
459 /* Reset driver's Rx queue write index */
460 iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
461
462 /* Tell device where to find RBD circular buffer in DRAM */
463 iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
464 (u32)(rxq->bd_dma >> 8));
465
466 /* Tell device where in DRAM to update its Rx status */
467 iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG,
468 rxq->rb_stts_dma >> 4);
469
470 /* Enable Rx DMA
471 * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
472 * the credit mechanism in 5000 HW RX FIFO
473 * Direct rx interrupts to hosts
474 * Rx buffer size 4 or 8k
475 * RB timeout 0x10
476 * 256 RBDs
477 */
478 iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG,
479 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
480 FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
481 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
482 rb_size|
483 (RX_RB_TIMEOUT << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
484 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
485
486 /* Set interrupt coalescing timer to default (2048 usecs) */
487 iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
488}
489
490int iwl_pcie_rx_init(struct iwl_trans *trans)
491{
492 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
493 struct iwl_rxq *rxq = &trans_pcie->rxq;
494
495 int i, err;
496 unsigned long flags;
497
498 if (!rxq->bd) {
499 err = iwl_pcie_rx_alloc(trans);
500 if (err)
501 return err;
502 }
503
504 spin_lock_irqsave(&rxq->lock, flags);
505 INIT_LIST_HEAD(&rxq->rx_free);
506 INIT_LIST_HEAD(&rxq->rx_used);
507
508 INIT_WORK(&trans_pcie->rx_replenish,
509 iwl_pcie_rx_replenish_work);
510
511 iwl_pcie_rxq_free_rbs(trans);
512
513 for (i = 0; i < RX_QUEUE_SIZE; i++)
514 rxq->queue[i] = NULL;
515
516 /* Set us so that we have processed and used all buffers, but have
517 * not restocked the Rx queue with fresh buffers */
518 rxq->read = rxq->write = 0;
519 rxq->write_actual = 0;
520 rxq->free_count = 0;
521 spin_unlock_irqrestore(&rxq->lock, flags);
522
523 iwl_pcie_rx_replenish(trans);
524
525 iwl_pcie_rx_hw_init(trans, rxq);
526
527 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
528 rxq->need_update = 1;
529 iwl_pcie_rxq_inc_wr_ptr(trans, rxq);
530 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
531
532 return 0;
533}
534
535void iwl_pcie_rx_free(struct iwl_trans *trans)
536{
537 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
538 struct iwl_rxq *rxq = &trans_pcie->rxq;
539 unsigned long flags;
540
541 /*if rxq->bd is NULL, it means that nothing has been allocated,
542 * exit now */
543 if (!rxq->bd) {
544 IWL_DEBUG_INFO(trans, "Free NULL rx context\n");
545 return;
546 }
547
548 spin_lock_irqsave(&rxq->lock, flags);
549 iwl_pcie_rxq_free_rbs(trans);
550 spin_unlock_irqrestore(&rxq->lock, flags);
551
552 dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE,
553 rxq->bd, rxq->bd_dma);
554 memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
555 rxq->bd = NULL;
556
557 if (rxq->rb_stts)
558 dma_free_coherent(trans->dev,
559 sizeof(struct iwl_rb_status),
560 rxq->rb_stts, rxq->rb_stts_dma);
561 else
562 IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n");
563 memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma));
564 rxq->rb_stts = NULL;
379} 565}
380 566
381static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, 567static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
382 struct iwl_rx_mem_buffer *rxb) 568 struct iwl_rx_mem_buffer *rxb)
383{ 569{
384 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 570 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
385 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 571 struct iwl_rxq *rxq = &trans_pcie->rxq;
386 struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; 572 struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
387 unsigned long flags; 573 unsigned long flags;
388 bool page_stolen = false; 574 bool page_stolen = false;
389 int max_len = PAGE_SIZE << trans_pcie->rx_page_order; 575 int max_len = PAGE_SIZE << trans_pcie->rx_page_order;
@@ -413,8 +599,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
413 break; 599 break;
414 600
415 IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n", 601 IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n",
416 rxcb._offset, 602 rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd),
417 trans_pcie_get_cmd_string(trans_pcie, pkt->hdr.cmd),
418 pkt->hdr.cmd); 603 pkt->hdr.cmd);
419 604
420 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 605 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
@@ -446,7 +631,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
446 cmd_index = get_cmd_index(&txq->q, index); 631 cmd_index = get_cmd_index(&txq->q, index);
447 632
448 if (reclaim) { 633 if (reclaim) {
449 struct iwl_pcie_tx_queue_entry *ent; 634 struct iwl_pcie_txq_entry *ent;
450 ent = &txq->entries[cmd_index]; 635 ent = &txq->entries[cmd_index];
451 cmd = ent->copy_cmd; 636 cmd = ent->copy_cmd;
452 WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD); 637 WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD);
@@ -460,6 +645,9 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
460 /* The original command isn't needed any more */ 645 /* The original command isn't needed any more */
461 kfree(txq->entries[cmd_index].copy_cmd); 646 kfree(txq->entries[cmd_index].copy_cmd);
462 txq->entries[cmd_index].copy_cmd = NULL; 647 txq->entries[cmd_index].copy_cmd = NULL;
648 /* nor is the duplicated part of the command */
649 kfree(txq->entries[cmd_index].free_buf);
650 txq->entries[cmd_index].free_buf = NULL;
463 } 651 }
464 652
465 /* 653 /*
@@ -473,7 +661,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
473 * iwl_trans_send_cmd() 661 * iwl_trans_send_cmd()
474 * as we reclaim the driver command queue */ 662 * as we reclaim the driver command queue */
475 if (!rxcb._page_stolen) 663 if (!rxcb._page_stolen)
476 iwl_tx_cmd_complete(trans, &rxcb, err); 664 iwl_pcie_hcmd_complete(trans, &rxcb, err);
477 else 665 else
478 IWL_WARN(trans, "Claim null rxb?\n"); 666 IWL_WARN(trans, "Claim null rxb?\n");
479 } 667 }
@@ -515,17 +703,13 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
515 spin_unlock_irqrestore(&rxq->lock, flags); 703 spin_unlock_irqrestore(&rxq->lock, flags);
516} 704}
517 705
518/** 706/*
519 * iwl_rx_handle - Main entry function for receiving responses from uCode 707 * iwl_pcie_rx_handle - Main entry function for receiving responses from fw
520 *
521 * Uses the priv->rx_handlers callback function array to invoke
522 * the appropriate handlers, including command responses,
523 * frame-received notifications, and other notifications.
524 */ 708 */
525static void iwl_rx_handle(struct iwl_trans *trans) 709static void iwl_pcie_rx_handle(struct iwl_trans *trans)
526{ 710{
527 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 711 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
528 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 712 struct iwl_rxq *rxq = &trans_pcie->rxq;
529 u32 r, i; 713 u32 r, i;
530 u8 fill_rx = 0; 714 u8 fill_rx = 0;
531 u32 count = 8; 715 u32 count = 8;
@@ -556,7 +740,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
556 740
557 IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n", 741 IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n",
558 r, i, rxb); 742 r, i, rxb);
559 iwl_rx_handle_rxbuf(trans, rxb); 743 iwl_pcie_rx_handle_rb(trans, rxb);
560 744
561 i = (i + 1) & RX_QUEUE_MASK; 745 i = (i + 1) & RX_QUEUE_MASK;
562 /* If there are a lot of unused frames, 746 /* If there are a lot of unused frames,
@@ -565,7 +749,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
565 count++; 749 count++;
566 if (count >= 8) { 750 if (count >= 8) {
567 rxq->read = i; 751 rxq->read = i;
568 iwl_rx_replenish_now(trans); 752 iwl_pcie_rx_replenish_now(trans);
569 count = 0; 753 count = 0;
570 } 754 }
571 } 755 }
@@ -574,39 +758,41 @@ static void iwl_rx_handle(struct iwl_trans *trans)
574 /* Backtrack one entry */ 758 /* Backtrack one entry */
575 rxq->read = i; 759 rxq->read = i;
576 if (fill_rx) 760 if (fill_rx)
577 iwl_rx_replenish_now(trans); 761 iwl_pcie_rx_replenish_now(trans);
578 else 762 else
579 iwl_rx_queue_restock(trans); 763 iwl_pcie_rxq_restock(trans);
580} 764}
581 765
582/** 766/*
583 * iwl_irq_handle_error - called for HW or SW error interrupt from card 767 * iwl_pcie_irq_handle_error - called for HW or SW error interrupt from card
584 */ 768 */
585static void iwl_irq_handle_error(struct iwl_trans *trans) 769static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
586{ 770{
771 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
772
587 /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ 773 /* W/A for WiFi/WiMAX coex and WiMAX own the RF */
588 if (trans->cfg->internal_wimax_coex && 774 if (trans->cfg->internal_wimax_coex &&
589 (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & 775 (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) &
590 APMS_CLK_VAL_MRB_FUNC_MODE) || 776 APMS_CLK_VAL_MRB_FUNC_MODE) ||
591 (iwl_read_prph(trans, APMG_PS_CTRL_REG) & 777 (iwl_read_prph(trans, APMG_PS_CTRL_REG) &
592 APMG_PS_CTRL_VAL_RESET_REQ))) { 778 APMG_PS_CTRL_VAL_RESET_REQ))) {
593 struct iwl_trans_pcie *trans_pcie =
594 IWL_TRANS_GET_PCIE_TRANS(trans);
595
596 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 779 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
597 iwl_op_mode_wimax_active(trans->op_mode); 780 iwl_op_mode_wimax_active(trans->op_mode);
598 wake_up(&trans->wait_command_queue); 781 wake_up(&trans_pcie->wait_command_queue);
599 return; 782 return;
600 } 783 }
601 784
602 iwl_dump_csr(trans); 785 iwl_pcie_dump_csr(trans);
603 iwl_dump_fh(trans, NULL); 786 iwl_pcie_dump_fh(trans, NULL);
787
788 set_bit(STATUS_FW_ERROR, &trans_pcie->status);
789 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
790 wake_up(&trans_pcie->wait_command_queue);
604 791
605 iwl_op_mode_nic_error(trans->op_mode); 792 iwl_op_mode_nic_error(trans->op_mode);
606} 793}
607 794
608/* tasklet for iwlagn interrupt */ 795void iwl_pcie_tasklet(struct iwl_trans *trans)
609void iwl_irq_tasklet(struct iwl_trans *trans)
610{ 796{
611 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 797 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
612 struct isr_statistics *isr_stats = &trans_pcie->isr_stats; 798 struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
@@ -658,7 +844,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
658 iwl_disable_interrupts(trans); 844 iwl_disable_interrupts(trans);
659 845
660 isr_stats->hw++; 846 isr_stats->hw++;
661 iwl_irq_handle_error(trans); 847 iwl_pcie_irq_handle_error(trans);
662 848
663 handled |= CSR_INT_BIT_HW_ERR; 849 handled |= CSR_INT_BIT_HW_ERR;
664 850
@@ -695,6 +881,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
695 isr_stats->rfkill++; 881 isr_stats->rfkill++;
696 882
697 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); 883 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
884 if (hw_rfkill) {
885 set_bit(STATUS_RFKILL, &trans_pcie->status);
886 if (test_and_clear_bit(STATUS_HCMD_ACTIVE,
887 &trans_pcie->status))
888 IWL_DEBUG_RF_KILL(trans,
889 "Rfkill while SYNC HCMD in flight\n");
890 wake_up(&trans_pcie->wait_command_queue);
891 } else {
892 clear_bit(STATUS_RFKILL, &trans_pcie->status);
893 }
698 894
699 handled |= CSR_INT_BIT_RF_KILL; 895 handled |= CSR_INT_BIT_RF_KILL;
700 } 896 }
@@ -711,17 +907,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
711 IWL_ERR(trans, "Microcode SW error detected. " 907 IWL_ERR(trans, "Microcode SW error detected. "
712 " Restarting 0x%X.\n", inta); 908 " Restarting 0x%X.\n", inta);
713 isr_stats->sw++; 909 isr_stats->sw++;
714 iwl_irq_handle_error(trans); 910 iwl_pcie_irq_handle_error(trans);
715 handled |= CSR_INT_BIT_SW_ERR; 911 handled |= CSR_INT_BIT_SW_ERR;
716 } 912 }
717 913
718 /* uCode wakes up after power-down sleep */ 914 /* uCode wakes up after power-down sleep */
719 if (inta & CSR_INT_BIT_WAKEUP) { 915 if (inta & CSR_INT_BIT_WAKEUP) {
720 IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); 916 IWL_DEBUG_ISR(trans, "Wakeup interrupt\n");
721 iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); 917 iwl_pcie_rxq_inc_wr_ptr(trans, &trans_pcie->rxq);
722 for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) 918 for (i = 0; i < trans->cfg->base_params->num_of_queues; i++)
723 iwl_txq_update_write_ptr(trans, 919 iwl_pcie_txq_inc_wr_ptr(trans, &trans_pcie->txq[i]);
724 &trans_pcie->txq[i]);
725 920
726 isr_stats->wakeup++; 921 isr_stats->wakeup++;
727 922
@@ -759,7 +954,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
759 iwl_write8(trans, CSR_INT_PERIODIC_REG, 954 iwl_write8(trans, CSR_INT_PERIODIC_REG,
760 CSR_INT_PERIODIC_DIS); 955 CSR_INT_PERIODIC_DIS);
761 956
762 iwl_rx_handle(trans); 957 iwl_pcie_rx_handle(trans);
763 958
764 /* 959 /*
765 * Enable periodic interrupt in 8 msec only if we received 960 * Enable periodic interrupt in 8 msec only if we received
@@ -817,7 +1012,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
817#define ICT_COUNT (ICT_SIZE / sizeof(u32)) 1012#define ICT_COUNT (ICT_SIZE / sizeof(u32))
818 1013
819/* Free dram table */ 1014/* Free dram table */
820void iwl_free_isr_ict(struct iwl_trans *trans) 1015void iwl_pcie_free_ict(struct iwl_trans *trans)
821{ 1016{
822 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1017 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
823 1018
@@ -830,13 +1025,12 @@ void iwl_free_isr_ict(struct iwl_trans *trans)
830 } 1025 }
831} 1026}
832 1027
833
834/* 1028/*
835 * allocate dram shared table, it is an aligned memory 1029 * allocate dram shared table, it is an aligned memory
836 * block of ICT_SIZE. 1030 * block of ICT_SIZE.
837 * also reset all data related to ICT table interrupt. 1031 * also reset all data related to ICT table interrupt.
838 */ 1032 */
839int iwl_alloc_isr_ict(struct iwl_trans *trans) 1033int iwl_pcie_alloc_ict(struct iwl_trans *trans)
840{ 1034{
841 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1035 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
842 1036
@@ -849,7 +1043,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans)
849 1043
850 /* just an API sanity check ... it is guaranteed to be aligned */ 1044 /* just an API sanity check ... it is guaranteed to be aligned */
851 if (WARN_ON(trans_pcie->ict_tbl_dma & (ICT_SIZE - 1))) { 1045 if (WARN_ON(trans_pcie->ict_tbl_dma & (ICT_SIZE - 1))) {
852 iwl_free_isr_ict(trans); 1046 iwl_pcie_free_ict(trans);
853 return -EINVAL; 1047 return -EINVAL;
854 } 1048 }
855 1049
@@ -870,7 +1064,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans)
870/* Device is going up inform it about using ICT interrupt table, 1064/* Device is going up inform it about using ICT interrupt table,
871 * also we need to tell the driver to start using ICT interrupt. 1065 * also we need to tell the driver to start using ICT interrupt.
872 */ 1066 */
873void iwl_reset_ict(struct iwl_trans *trans) 1067void iwl_pcie_reset_ict(struct iwl_trans *trans)
874{ 1068{
875 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1069 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
876 u32 val; 1070 u32 val;
@@ -900,7 +1094,7 @@ void iwl_reset_ict(struct iwl_trans *trans)
900} 1094}
901 1095
902/* Device is going down disable ict interrupt usage */ 1096/* Device is going down disable ict interrupt usage */
903void iwl_disable_ict(struct iwl_trans *trans) 1097void iwl_pcie_disable_ict(struct iwl_trans *trans)
904{ 1098{
905 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1099 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
906 unsigned long flags; 1100 unsigned long flags;
@@ -911,7 +1105,7 @@ void iwl_disable_ict(struct iwl_trans *trans)
911} 1105}
912 1106
913/* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */ 1107/* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */
914static irqreturn_t iwl_isr(int irq, void *data) 1108static irqreturn_t iwl_pcie_isr(int irq, void *data)
915{ 1109{
916 struct iwl_trans *trans = data; 1110 struct iwl_trans *trans = data;
917 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1111 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -958,7 +1152,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
958#endif 1152#endif
959 1153
960 trans_pcie->inta |= inta; 1154 trans_pcie->inta |= inta;
961 /* iwl_irq_tasklet() will service interrupts and re-enable them */ 1155 /* iwl_pcie_tasklet() will service interrupts and re-enable them */
962 if (likely(inta)) 1156 if (likely(inta))
963 tasklet_schedule(&trans_pcie->irq_tasklet); 1157 tasklet_schedule(&trans_pcie->irq_tasklet);
964 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && 1158 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
@@ -983,7 +1177,7 @@ none:
983 * the interrupt we need to service, driver will set the entries back to 0 and 1177 * the interrupt we need to service, driver will set the entries back to 0 and
984 * set index. 1178 * set index.
985 */ 1179 */
986irqreturn_t iwl_isr_ict(int irq, void *data) 1180irqreturn_t iwl_pcie_isr_ict(int irq, void *data)
987{ 1181{
988 struct iwl_trans *trans = data; 1182 struct iwl_trans *trans = data;
989 struct iwl_trans_pcie *trans_pcie; 1183 struct iwl_trans_pcie *trans_pcie;
@@ -1003,14 +1197,13 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
1003 * use legacy interrupt. 1197 * use legacy interrupt.
1004 */ 1198 */
1005 if (unlikely(!trans_pcie->use_ict)) { 1199 if (unlikely(!trans_pcie->use_ict)) {
1006 irqreturn_t ret = iwl_isr(irq, data); 1200 irqreturn_t ret = iwl_pcie_isr(irq, data);
1007 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 1201 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1008 return ret; 1202 return ret;
1009 } 1203 }
1010 1204
1011 trace_iwlwifi_dev_irq(trans->dev); 1205 trace_iwlwifi_dev_irq(trans->dev);
1012 1206
1013
1014 /* Disable (but don't clear!) interrupts here to avoid 1207 /* Disable (but don't clear!) interrupts here to avoid
1015 * back-to-back ISRs and sporadic interrupts from our NIC. 1208 * back-to-back ISRs and sporadic interrupts from our NIC.
1016 * If we have something to service, the tasklet will re-enable ints. 1209 * If we have something to service, the tasklet will re-enable ints.
@@ -1019,7 +1212,6 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
1019 inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ 1212 inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */
1020 iwl_write32(trans, CSR_INT_MASK, 0x00000000); 1213 iwl_write32(trans, CSR_INT_MASK, 0x00000000);
1021 1214
1022
1023 /* Ignore interrupt if there's nothing in NIC to service. 1215 /* Ignore interrupt if there's nothing in NIC to service.
1024 * This may be due to IRQ shared with another device, 1216 * This may be due to IRQ shared with another device,
1025 * or due to sporadic interrupts thrown from our NIC. */ 1217 * or due to sporadic interrupts thrown from our NIC. */
@@ -1068,7 +1260,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
1068 inta &= trans_pcie->inta_mask; 1260 inta &= trans_pcie->inta_mask;
1069 trans_pcie->inta |= inta; 1261 trans_pcie->inta |= inta;
1070 1262
1071 /* iwl_irq_tasklet() will service interrupts and re-enable them */ 1263 /* iwl_pcie_tasklet() will service interrupts and re-enable them */
1072 if (likely(inta)) 1264 if (likely(inta))
1073 tasklet_schedule(&trans_pcie->irq_tasklet); 1265 tasklet_schedule(&trans_pcie->irq_tasklet);
1074 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && 1266 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index f95d88df777..f6c21e7edaf 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -74,584 +74,8 @@
74#include "iwl-prph.h" 74#include "iwl-prph.h"
75#include "iwl-agn-hw.h" 75#include "iwl-agn-hw.h"
76#include "internal.h" 76#include "internal.h"
77/* FIXME: need to abstract out TX command (once we know what it looks like) */
78#include "dvm/commands.h"
79 77
80#define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ 78static void iwl_pcie_set_pwr_vmain(struct iwl_trans *trans)
81 (((1<<trans->cfg->base_params->num_of_queues) - 1) &\
82 (~(1<<(trans_pcie)->cmd_queue)))
83
84static int iwl_trans_rx_alloc(struct iwl_trans *trans)
85{
86 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
87 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
88 struct device *dev = trans->dev;
89
90 memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq));
91
92 spin_lock_init(&rxq->lock);
93
94 if (WARN_ON(rxq->bd || rxq->rb_stts))
95 return -EINVAL;
96
97 /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */
98 rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,
99 &rxq->bd_dma, GFP_KERNEL);
100 if (!rxq->bd)
101 goto err_bd;
102
103 /*Allocate the driver's pointer to receive buffer status */
104 rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts),
105 &rxq->rb_stts_dma, GFP_KERNEL);
106 if (!rxq->rb_stts)
107 goto err_rb_stts;
108
109 return 0;
110
111err_rb_stts:
112 dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,
113 rxq->bd, rxq->bd_dma);
114 memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
115 rxq->bd = NULL;
116err_bd:
117 return -ENOMEM;
118}
119
120static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans)
121{
122 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
123 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
124 int i;
125
126 /* Fill the rx_used queue with _all_ of the Rx buffers */
127 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
128 /* In the reset function, these buffers may have been allocated
129 * to an SKB, so we need to unmap and free potential storage */
130 if (rxq->pool[i].page != NULL) {
131 dma_unmap_page(trans->dev, rxq->pool[i].page_dma,
132 PAGE_SIZE << trans_pcie->rx_page_order,
133 DMA_FROM_DEVICE);
134 __free_pages(rxq->pool[i].page,
135 trans_pcie->rx_page_order);
136 rxq->pool[i].page = NULL;
137 }
138 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
139 }
140}
141
142static void iwl_trans_rx_hw_init(struct iwl_trans *trans,
143 struct iwl_rx_queue *rxq)
144{
145 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
146 u32 rb_size;
147 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
148 u32 rb_timeout = RX_RB_TIMEOUT; /* FIXME: RX_RB_TIMEOUT for all devices? */
149
150 if (trans_pcie->rx_buf_size_8k)
151 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
152 else
153 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
154
155 /* Stop Rx DMA */
156 iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
157
158 /* Reset driver's Rx queue write index */
159 iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
160
161 /* Tell device where to find RBD circular buffer in DRAM */
162 iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
163 (u32)(rxq->bd_dma >> 8));
164
165 /* Tell device where in DRAM to update its Rx status */
166 iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG,
167 rxq->rb_stts_dma >> 4);
168
169 /* Enable Rx DMA
170 * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
171 * the credit mechanism in 5000 HW RX FIFO
172 * Direct rx interrupts to hosts
173 * Rx buffer size 4 or 8k
174 * RB timeout 0x10
175 * 256 RBDs
176 */
177 iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG,
178 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
179 FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
180 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
181 rb_size|
182 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
183 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
184
185 /* Set interrupt coalescing timer to default (2048 usecs) */
186 iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
187}
188
189static int iwl_rx_init(struct iwl_trans *trans)
190{
191 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
192 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
193
194 int i, err;
195 unsigned long flags;
196
197 if (!rxq->bd) {
198 err = iwl_trans_rx_alloc(trans);
199 if (err)
200 return err;
201 }
202
203 spin_lock_irqsave(&rxq->lock, flags);
204 INIT_LIST_HEAD(&rxq->rx_free);
205 INIT_LIST_HEAD(&rxq->rx_used);
206
207 iwl_trans_rxq_free_rx_bufs(trans);
208
209 for (i = 0; i < RX_QUEUE_SIZE; i++)
210 rxq->queue[i] = NULL;
211
212 /* Set us so that we have processed and used all buffers, but have
213 * not restocked the Rx queue with fresh buffers */
214 rxq->read = rxq->write = 0;
215 rxq->write_actual = 0;
216 rxq->free_count = 0;
217 spin_unlock_irqrestore(&rxq->lock, flags);
218
219 iwl_rx_replenish(trans);
220
221 iwl_trans_rx_hw_init(trans, rxq);
222
223 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
224 rxq->need_update = 1;
225 iwl_rx_queue_update_write_ptr(trans, rxq);
226 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
227
228 return 0;
229}
230
231static void iwl_trans_pcie_rx_free(struct iwl_trans *trans)
232{
233 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
234 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
235 unsigned long flags;
236
237 /*if rxq->bd is NULL, it means that nothing has been allocated,
238 * exit now */
239 if (!rxq->bd) {
240 IWL_DEBUG_INFO(trans, "Free NULL rx context\n");
241 return;
242 }
243
244 spin_lock_irqsave(&rxq->lock, flags);
245 iwl_trans_rxq_free_rx_bufs(trans);
246 spin_unlock_irqrestore(&rxq->lock, flags);
247
248 dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE,
249 rxq->bd, rxq->bd_dma);
250 memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
251 rxq->bd = NULL;
252
253 if (rxq->rb_stts)
254 dma_free_coherent(trans->dev,
255 sizeof(struct iwl_rb_status),
256 rxq->rb_stts, rxq->rb_stts_dma);
257 else
258 IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n");
259 memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma));
260 rxq->rb_stts = NULL;
261}
262
263static int iwl_trans_rx_stop(struct iwl_trans *trans)
264{
265
266 /* stop Rx DMA */
267 iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
268 return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG,
269 FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
270}
271
272static int iwlagn_alloc_dma_ptr(struct iwl_trans *trans,
273 struct iwl_dma_ptr *ptr, size_t size)
274{
275 if (WARN_ON(ptr->addr))
276 return -EINVAL;
277
278 ptr->addr = dma_alloc_coherent(trans->dev, size,
279 &ptr->dma, GFP_KERNEL);
280 if (!ptr->addr)
281 return -ENOMEM;
282 ptr->size = size;
283 return 0;
284}
285
286static void iwlagn_free_dma_ptr(struct iwl_trans *trans,
287 struct iwl_dma_ptr *ptr)
288{
289 if (unlikely(!ptr->addr))
290 return;
291
292 dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma);
293 memset(ptr, 0, sizeof(*ptr));
294}
295
296static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
297{
298 struct iwl_tx_queue *txq = (void *)data;
299 struct iwl_queue *q = &txq->q;
300 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
301 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
302 u32 scd_sram_addr = trans_pcie->scd_base_addr +
303 SCD_TX_STTS_QUEUE_OFFSET(txq->q.id);
304 u8 buf[16];
305 int i;
306
307 spin_lock(&txq->lock);
308 /* check if triggered erroneously */
309 if (txq->q.read_ptr == txq->q.write_ptr) {
310 spin_unlock(&txq->lock);
311 return;
312 }
313 spin_unlock(&txq->lock);
314
315 IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id,
316 jiffies_to_msecs(trans_pcie->wd_timeout));
317 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
318 txq->q.read_ptr, txq->q.write_ptr);
319
320 iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf));
321
322 iwl_print_hex_error(trans, buf, sizeof(buf));
323
324 for (i = 0; i < FH_TCSR_CHNL_NUM; i++)
325 IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", i,
326 iwl_read_direct32(trans, FH_TX_TRB_REG(i)));
327
328 for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
329 u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(i));
330 u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7;
331 bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE));
332 u32 tbl_dw =
333 iwl_read_targ_mem(trans,
334 trans_pcie->scd_base_addr +
335 SCD_TRANS_TBL_OFFSET_QUEUE(i));
336
337 if (i & 0x1)
338 tbl_dw = (tbl_dw & 0xFFFF0000) >> 16;
339 else
340 tbl_dw = tbl_dw & 0x0000FFFF;
341
342 IWL_ERR(trans,
343 "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n",
344 i, active ? "" : "in", fifo, tbl_dw,
345 iwl_read_prph(trans,
346 SCD_QUEUE_RDPTR(i)) & (txq->q.n_bd - 1),
347 iwl_read_prph(trans, SCD_QUEUE_WRPTR(i)));
348 }
349
350 for (i = q->read_ptr; i != q->write_ptr;
351 i = iwl_queue_inc_wrap(i, q->n_bd)) {
352 struct iwl_tx_cmd *tx_cmd =
353 (struct iwl_tx_cmd *)txq->entries[i].cmd->payload;
354 IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
355 get_unaligned_le32(&tx_cmd->scratch));
356 }
357
358 iwl_op_mode_nic_error(trans->op_mode);
359}
360
361static int iwl_trans_txq_alloc(struct iwl_trans *trans,
362 struct iwl_tx_queue *txq, int slots_num,
363 u32 txq_id)
364{
365 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
366 size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX;
367 int i;
368
369 if (WARN_ON(txq->entries || txq->tfds))
370 return -EINVAL;
371
372 setup_timer(&txq->stuck_timer, iwl_trans_pcie_queue_stuck_timer,
373 (unsigned long)txq);
374 txq->trans_pcie = trans_pcie;
375
376 txq->q.n_window = slots_num;
377
378 txq->entries = kcalloc(slots_num,
379 sizeof(struct iwl_pcie_tx_queue_entry),
380 GFP_KERNEL);
381
382 if (!txq->entries)
383 goto error;
384
385 if (txq_id == trans_pcie->cmd_queue)
386 for (i = 0; i < slots_num; i++) {
387 txq->entries[i].cmd =
388 kmalloc(sizeof(struct iwl_device_cmd),
389 GFP_KERNEL);
390 if (!txq->entries[i].cmd)
391 goto error;
392 }
393
394 /* Circular buffer of transmit frame descriptors (TFDs),
395 * shared with device */
396 txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz,
397 &txq->q.dma_addr, GFP_KERNEL);
398 if (!txq->tfds) {
399 IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
400 goto error;
401 }
402 txq->q.id = txq_id;
403
404 return 0;
405error:
406 if (txq->entries && txq_id == trans_pcie->cmd_queue)
407 for (i = 0; i < slots_num; i++)
408 kfree(txq->entries[i].cmd);
409 kfree(txq->entries);
410 txq->entries = NULL;
411
412 return -ENOMEM;
413
414}
415
416static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq,
417 int slots_num, u32 txq_id)
418{
419 int ret;
420
421 txq->need_update = 0;
422
423 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
424 * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
425 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
426
427 /* Initialize queue's high/low-water marks, and head/tail indexes */
428 ret = iwl_queue_init(&txq->q, TFD_QUEUE_SIZE_MAX, slots_num,
429 txq_id);
430 if (ret)
431 return ret;
432
433 spin_lock_init(&txq->lock);
434
435 /*
436 * Tell nic where to find circular buffer of Tx Frame Descriptors for
437 * given Tx queue, and enable the DMA channel used for that queue.
438 * Circular buffer (TFD queue in DRAM) physical base address */
439 iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id),
440 txq->q.dma_addr >> 8);
441
442 return 0;
443}
444
445/**
446 * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's
447 */
448static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
449{
450 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
451 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
452 struct iwl_queue *q = &txq->q;
453 enum dma_data_direction dma_dir;
454
455 if (!q->n_bd)
456 return;
457
458 /* In the command queue, all the TBs are mapped as BIDI
459 * so unmap them as such.
460 */
461 if (txq_id == trans_pcie->cmd_queue)
462 dma_dir = DMA_BIDIRECTIONAL;
463 else
464 dma_dir = DMA_TO_DEVICE;
465
466 spin_lock_bh(&txq->lock);
467 while (q->write_ptr != q->read_ptr) {
468 iwl_txq_free_tfd(trans, txq, dma_dir);
469 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
470 }
471 spin_unlock_bh(&txq->lock);
472}
473
474/**
475 * iwl_tx_queue_free - Deallocate DMA queue.
476 * @txq: Transmit queue to deallocate.
477 *
478 * Empty queue by removing and destroying all BD's.
479 * Free all buffers.
480 * 0-fill, but do not free "txq" descriptor structure.
481 */
482static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id)
483{
484 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
485 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
486 struct device *dev = trans->dev;
487 int i;
488
489 if (WARN_ON(!txq))
490 return;
491
492 iwl_tx_queue_unmap(trans, txq_id);
493
494 /* De-alloc array of command/tx buffers */
495 if (txq_id == trans_pcie->cmd_queue)
496 for (i = 0; i < txq->q.n_window; i++) {
497 kfree(txq->entries[i].cmd);
498 kfree(txq->entries[i].copy_cmd);
499 }
500
501 /* De-alloc circular buffer of TFDs */
502 if (txq->q.n_bd) {
503 dma_free_coherent(dev, sizeof(struct iwl_tfd) *
504 txq->q.n_bd, txq->tfds, txq->q.dma_addr);
505 memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr));
506 }
507
508 kfree(txq->entries);
509 txq->entries = NULL;
510
511 del_timer_sync(&txq->stuck_timer);
512
513 /* 0-fill queue descriptor structure */
514 memset(txq, 0, sizeof(*txq));
515}
516
517/**
518 * iwl_trans_tx_free - Free TXQ Context
519 *
520 * Destroy all TX DMA queues and structures
521 */
522static void iwl_trans_pcie_tx_free(struct iwl_trans *trans)
523{
524 int txq_id;
525 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
526
527 /* Tx queues */
528 if (trans_pcie->txq) {
529 for (txq_id = 0;
530 txq_id < trans->cfg->base_params->num_of_queues; txq_id++)
531 iwl_tx_queue_free(trans, txq_id);
532 }
533
534 kfree(trans_pcie->txq);
535 trans_pcie->txq = NULL;
536
537 iwlagn_free_dma_ptr(trans, &trans_pcie->kw);
538
539 iwlagn_free_dma_ptr(trans, &trans_pcie->scd_bc_tbls);
540}
541
542/**
543 * iwl_trans_tx_alloc - allocate TX context
544 * Allocate all Tx DMA structures and initialize them
545 *
546 * @param priv
547 * @return error code
548 */
549static int iwl_trans_tx_alloc(struct iwl_trans *trans)
550{
551 int ret;
552 int txq_id, slots_num;
553 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
554
555 u16 scd_bc_tbls_size = trans->cfg->base_params->num_of_queues *
556 sizeof(struct iwlagn_scd_bc_tbl);
557
558 /*It is not allowed to alloc twice, so warn when this happens.
559 * We cannot rely on the previous allocation, so free and fail */
560 if (WARN_ON(trans_pcie->txq)) {
561 ret = -EINVAL;
562 goto error;
563 }
564
565 ret = iwlagn_alloc_dma_ptr(trans, &trans_pcie->scd_bc_tbls,
566 scd_bc_tbls_size);
567 if (ret) {
568 IWL_ERR(trans, "Scheduler BC Table allocation failed\n");
569 goto error;
570 }
571
572 /* Alloc keep-warm buffer */
573 ret = iwlagn_alloc_dma_ptr(trans, &trans_pcie->kw, IWL_KW_SIZE);
574 if (ret) {
575 IWL_ERR(trans, "Keep Warm allocation failed\n");
576 goto error;
577 }
578
579 trans_pcie->txq = kcalloc(trans->cfg->base_params->num_of_queues,
580 sizeof(struct iwl_tx_queue), GFP_KERNEL);
581 if (!trans_pcie->txq) {
582 IWL_ERR(trans, "Not enough memory for txq\n");
583 ret = ENOMEM;
584 goto error;
585 }
586
587 /* Alloc and init all Tx queues, including the command queue (#4/#9) */
588 for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
589 txq_id++) {
590 slots_num = (txq_id == trans_pcie->cmd_queue) ?
591 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
592 ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id],
593 slots_num, txq_id);
594 if (ret) {
595 IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id);
596 goto error;
597 }
598 }
599
600 return 0;
601
602error:
603 iwl_trans_pcie_tx_free(trans);
604
605 return ret;
606}
607static int iwl_tx_init(struct iwl_trans *trans)
608{
609 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
610 int ret;
611 int txq_id, slots_num;
612 unsigned long flags;
613 bool alloc = false;
614
615 if (!trans_pcie->txq) {
616 ret = iwl_trans_tx_alloc(trans);
617 if (ret)
618 goto error;
619 alloc = true;
620 }
621
622 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
623
624 /* Turn off all Tx DMA fifos */
625 iwl_write_prph(trans, SCD_TXFACT, 0);
626
627 /* Tell NIC where to find the "keep warm" buffer */
628 iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
629 trans_pcie->kw.dma >> 4);
630
631 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
632
633 /* Alloc and init all Tx queues, including the command queue (#4/#9) */
634 for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
635 txq_id++) {
636 slots_num = (txq_id == trans_pcie->cmd_queue) ?
637 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
638 ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id],
639 slots_num, txq_id);
640 if (ret) {
641 IWL_ERR(trans, "Tx %d queue init failed\n", txq_id);
642 goto error;
643 }
644 }
645
646 return 0;
647error:
648 /*Upon error, free only if we allocated something */
649 if (alloc)
650 iwl_trans_pcie_tx_free(trans);
651 return ret;
652}
653
654static void iwl_set_pwr_vmain(struct iwl_trans *trans)
655{ 79{
656/* 80/*
657 * (for documentation purposes) 81 * (for documentation purposes)
@@ -673,18 +97,11 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans)
673#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 97#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
674#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 98#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
675 99
676static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) 100static void iwl_pcie_apm_config(struct iwl_trans *trans)
677{ 101{
678 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 102 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
679 u16 pci_lnk_ctl; 103 u16 lctl;
680
681 pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL,
682 &pci_lnk_ctl);
683 return pci_lnk_ctl;
684}
685 104
686static void iwl_apm_config(struct iwl_trans *trans)
687{
688 /* 105 /*
689 * HW bug W/A for instability in PCIe bus L0S->L1 transition. 106 * HW bug W/A for instability in PCIe bus L0S->L1 transition.
690 * Check if BIOS (or OS) enabled L1-ASPM on this device. 107 * Check if BIOS (or OS) enabled L1-ASPM on this device.
@@ -693,29 +110,27 @@ static void iwl_apm_config(struct iwl_trans *trans)
693 * If not (unlikely), enable L0S, so there is at least some 110 * If not (unlikely), enable L0S, so there is at least some
694 * power savings, even without L1. 111 * power savings, even without L1.
695 */ 112 */
696 u16 lctl = iwl_pciexp_link_ctrl(trans); 113 pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl);
697 114
698 if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == 115 if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
699 PCI_CFG_LINK_CTRL_VAL_L1_EN) { 116 PCI_CFG_LINK_CTRL_VAL_L1_EN) {
700 /* L1-ASPM enabled; disable(!) L0S */ 117 /* L1-ASPM enabled; disable(!) L0S */
701 iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); 118 iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
702 dev_printk(KERN_INFO, trans->dev, 119 dev_info(trans->dev, "L1 Enabled; Disabling L0S\n");
703 "L1 Enabled; Disabling L0S\n");
704 } else { 120 } else {
705 /* L1-ASPM disabled; enable(!) L0S */ 121 /* L1-ASPM disabled; enable(!) L0S */
706 iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); 122 iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
707 dev_printk(KERN_INFO, trans->dev, 123 dev_info(trans->dev, "L1 Disabled; Enabling L0S\n");
708 "L1 Disabled; Enabling L0S\n");
709 } 124 }
710 trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); 125 trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
711} 126}
712 127
713/* 128/*
714 * Start up NIC's basic functionality after it has been reset 129 * Start up NIC's basic functionality after it has been reset
715 * (e.g. after platform boot, or shutdown via iwl_apm_stop()) 130 * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop())
716 * NOTE: This does not load uCode nor start the embedded processor 131 * NOTE: This does not load uCode nor start the embedded processor
717 */ 132 */
718static int iwl_apm_init(struct iwl_trans *trans) 133static int iwl_pcie_apm_init(struct iwl_trans *trans)
719{ 134{
720 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 135 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
721 int ret = 0; 136 int ret = 0;
@@ -747,7 +162,7 @@ static int iwl_apm_init(struct iwl_trans *trans)
747 iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, 162 iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
748 CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); 163 CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
749 164
750 iwl_apm_config(trans); 165 iwl_pcie_apm_config(trans);
751 166
752 /* Configure analog phase-lock-loop before activating to D0A */ 167 /* Configure analog phase-lock-loop before activating to D0A */
753 if (trans->cfg->base_params->pll_cfg_val) 168 if (trans->cfg->base_params->pll_cfg_val)
@@ -793,7 +208,7 @@ out:
793 return ret; 208 return ret;
794} 209}
795 210
796static int iwl_apm_stop_master(struct iwl_trans *trans) 211static int iwl_pcie_apm_stop_master(struct iwl_trans *trans)
797{ 212{
798 int ret = 0; 213 int ret = 0;
799 214
@@ -811,7 +226,7 @@ static int iwl_apm_stop_master(struct iwl_trans *trans)
811 return ret; 226 return ret;
812} 227}
813 228
814static void iwl_apm_stop(struct iwl_trans *trans) 229static void iwl_pcie_apm_stop(struct iwl_trans *trans)
815{ 230{
816 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 231 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
817 IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); 232 IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
@@ -819,7 +234,7 @@ static void iwl_apm_stop(struct iwl_trans *trans)
819 clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); 234 clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status);
820 235
821 /* Stop device's DMA activity */ 236 /* Stop device's DMA activity */
822 iwl_apm_stop_master(trans); 237 iwl_pcie_apm_stop_master(trans);
823 238
824 /* Reset the entire device */ 239 /* Reset the entire device */
825 iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); 240 iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
@@ -834,29 +249,29 @@ static void iwl_apm_stop(struct iwl_trans *trans)
834 CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 249 CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
835} 250}
836 251
837static int iwl_nic_init(struct iwl_trans *trans) 252static int iwl_pcie_nic_init(struct iwl_trans *trans)
838{ 253{
839 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 254 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
840 unsigned long flags; 255 unsigned long flags;
841 256
842 /* nic_init */ 257 /* nic_init */
843 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 258 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
844 iwl_apm_init(trans); 259 iwl_pcie_apm_init(trans);
845 260
846 /* Set interrupt coalescing calibration timer to default (512 usecs) */ 261 /* Set interrupt coalescing calibration timer to default (512 usecs) */
847 iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); 262 iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
848 263
849 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 264 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
850 265
851 iwl_set_pwr_vmain(trans); 266 iwl_pcie_set_pwr_vmain(trans);
852 267
853 iwl_op_mode_nic_config(trans->op_mode); 268 iwl_op_mode_nic_config(trans->op_mode);
854 269
855 /* Allocate the RX queue, or reset if it is already allocated */ 270 /* Allocate the RX queue, or reset if it is already allocated */
856 iwl_rx_init(trans); 271 iwl_pcie_rx_init(trans);
857 272
858 /* Allocate or reset and init all Tx and Command queues */ 273 /* Allocate or reset and init all Tx and Command queues */
859 if (iwl_tx_init(trans)) 274 if (iwl_pcie_tx_init(trans))
860 return -ENOMEM; 275 return -ENOMEM;
861 276
862 if (trans->cfg->base_params->shadow_reg_enable) { 277 if (trans->cfg->base_params->shadow_reg_enable) {
@@ -871,7 +286,7 @@ static int iwl_nic_init(struct iwl_trans *trans)
871#define HW_READY_TIMEOUT (50) 286#define HW_READY_TIMEOUT (50)
872 287
873/* Note: returns poll_bit return value, which is >= 0 if success */ 288/* Note: returns poll_bit return value, which is >= 0 if success */
874static int iwl_set_hw_ready(struct iwl_trans *trans) 289static int iwl_pcie_set_hw_ready(struct iwl_trans *trans)
875{ 290{
876 int ret; 291 int ret;
877 292
@@ -889,14 +304,14 @@ static int iwl_set_hw_ready(struct iwl_trans *trans)
889} 304}
890 305
891/* Note: returns standard 0/-ERROR code */ 306/* Note: returns standard 0/-ERROR code */
892static int iwl_prepare_card_hw(struct iwl_trans *trans) 307static int iwl_pcie_prepare_card_hw(struct iwl_trans *trans)
893{ 308{
894 int ret; 309 int ret;
895 int t = 0; 310 int t = 0;
896 311
897 IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); 312 IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n");
898 313
899 ret = iwl_set_hw_ready(trans); 314 ret = iwl_pcie_set_hw_ready(trans);
900 /* If the card is ready, exit 0 */ 315 /* If the card is ready, exit 0 */
901 if (ret >= 0) 316 if (ret >= 0)
902 return 0; 317 return 0;
@@ -906,7 +321,7 @@ static int iwl_prepare_card_hw(struct iwl_trans *trans)
906 CSR_HW_IF_CONFIG_REG_PREPARE); 321 CSR_HW_IF_CONFIG_REG_PREPARE);
907 322
908 do { 323 do {
909 ret = iwl_set_hw_ready(trans); 324 ret = iwl_pcie_set_hw_ready(trans);
910 if (ret >= 0) 325 if (ret >= 0)
911 return 0; 326 return 0;
912 327
@@ -920,7 +335,7 @@ static int iwl_prepare_card_hw(struct iwl_trans *trans)
920/* 335/*
921 * ucode 336 * ucode
922 */ 337 */
923static int iwl_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr, 338static int iwl_pcie_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr,
924 dma_addr_t phy_addr, u32 byte_cnt) 339 dma_addr_t phy_addr, u32 byte_cnt)
925{ 340{
926 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 341 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -967,7 +382,7 @@ static int iwl_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr,
967 return 0; 382 return 0;
968} 383}
969 384
970static int iwl_load_section(struct iwl_trans *trans, u8 section_num, 385static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
971 const struct fw_desc *section) 386 const struct fw_desc *section)
972{ 387{
973 u8 *v_addr; 388 u8 *v_addr;
@@ -988,8 +403,9 @@ static int iwl_load_section(struct iwl_trans *trans, u8 section_num,
988 copy_size = min_t(u32, PAGE_SIZE, section->len - offset); 403 copy_size = min_t(u32, PAGE_SIZE, section->len - offset);
989 404
990 memcpy(v_addr, (u8 *)section->data + offset, copy_size); 405 memcpy(v_addr, (u8 *)section->data + offset, copy_size);
991 ret = iwl_load_firmware_chunk(trans, section->offset + offset, 406 ret = iwl_pcie_load_firmware_chunk(trans,
992 p_addr, copy_size); 407 section->offset + offset,
408 p_addr, copy_size);
993 if (ret) { 409 if (ret) {
994 IWL_ERR(trans, 410 IWL_ERR(trans,
995 "Could not load the [%d] uCode section\n", 411 "Could not load the [%d] uCode section\n",
@@ -1002,7 +418,7 @@ static int iwl_load_section(struct iwl_trans *trans, u8 section_num,
1002 return ret; 418 return ret;
1003} 419}
1004 420
1005static int iwl_load_given_ucode(struct iwl_trans *trans, 421static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
1006 const struct fw_img *image) 422 const struct fw_img *image)
1007{ 423{
1008 int i, ret = 0; 424 int i, ret = 0;
@@ -1011,7 +427,7 @@ static int iwl_load_given_ucode(struct iwl_trans *trans,
1011 if (!image->sec[i].data) 427 if (!image->sec[i].data)
1012 break; 428 break;
1013 429
1014 ret = iwl_load_section(trans, i, &image->sec[i]); 430 ret = iwl_pcie_load_section(trans, i, &image->sec[i]);
1015 if (ret) 431 if (ret)
1016 return ret; 432 return ret;
1017 } 433 }
@@ -1025,15 +441,18 @@ static int iwl_load_given_ucode(struct iwl_trans *trans,
1025static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, 441static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
1026 const struct fw_img *fw) 442 const struct fw_img *fw)
1027{ 443{
444 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1028 int ret; 445 int ret;
1029 bool hw_rfkill; 446 bool hw_rfkill;
1030 447
1031 /* This may fail if AMT took ownership of the device */ 448 /* This may fail if AMT took ownership of the device */
1032 if (iwl_prepare_card_hw(trans)) { 449 if (iwl_pcie_prepare_card_hw(trans)) {
1033 IWL_WARN(trans, "Exit HW not ready\n"); 450 IWL_WARN(trans, "Exit HW not ready\n");
1034 return -EIO; 451 return -EIO;
1035 } 452 }
1036 453
454 clear_bit(STATUS_FW_ERROR, &trans_pcie->status);
455
1037 iwl_enable_rfkill_int(trans); 456 iwl_enable_rfkill_int(trans);
1038 457
1039 /* If platform's RF_KILL switch is NOT set to KILL */ 458 /* If platform's RF_KILL switch is NOT set to KILL */
@@ -1044,7 +463,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
1044 463
1045 iwl_write32(trans, CSR_INT, 0xFFFFFFFF); 464 iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
1046 465
1047 ret = iwl_nic_init(trans); 466 ret = iwl_pcie_nic_init(trans);
1048 if (ret) { 467 if (ret) {
1049 IWL_ERR(trans, "Unable to init nic\n"); 468 IWL_ERR(trans, "Unable to init nic\n");
1050 return ret; 469 return ret;
@@ -1064,125 +483,13 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
1064 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 483 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
1065 484
1066 /* Load the given image to the HW */ 485 /* Load the given image to the HW */
1067 return iwl_load_given_ucode(trans, fw); 486 return iwl_pcie_load_given_ucode(trans, fw);
1068} 487}
1069 488
1070/* 489static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)
1071 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
1072 */
1073static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
1074{ 490{
1075 struct iwl_trans_pcie __maybe_unused *trans_pcie = 491 iwl_pcie_reset_ict(trans);
1076 IWL_TRANS_GET_PCIE_TRANS(trans); 492 iwl_pcie_tx_start(trans, scd_addr);
1077
1078 iwl_write_prph(trans, SCD_TXFACT, mask);
1079}
1080
1081static void iwl_tx_start(struct iwl_trans *trans)
1082{
1083 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1084 u32 a;
1085 int chan;
1086 u32 reg_val;
1087
1088 /* make sure all queue are not stopped/used */
1089 memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped));
1090 memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used));
1091
1092 trans_pcie->scd_base_addr =
1093 iwl_read_prph(trans, SCD_SRAM_BASE_ADDR);
1094 a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND;
1095 /* reset conext data memory */
1096 for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND;
1097 a += 4)
1098 iwl_write_targ_mem(trans, a, 0);
1099 /* reset tx status memory */
1100 for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND;
1101 a += 4)
1102 iwl_write_targ_mem(trans, a, 0);
1103 for (; a < trans_pcie->scd_base_addr +
1104 SCD_TRANS_TBL_OFFSET_QUEUE(
1105 trans->cfg->base_params->num_of_queues);
1106 a += 4)
1107 iwl_write_targ_mem(trans, a, 0);
1108
1109 iwl_write_prph(trans, SCD_DRAM_BASE_ADDR,
1110 trans_pcie->scd_bc_tbls.dma >> 10);
1111
1112 /* The chain extension of the SCD doesn't work well. This feature is
1113 * enabled by default by the HW, so we need to disable it manually.
1114 */
1115 iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
1116
1117 iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue,
1118 trans_pcie->cmd_fifo);
1119
1120 /* Activate all Tx DMA/FIFO channels */
1121 iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7));
1122
1123 /* Enable DMA channel */
1124 for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++)
1125 iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
1126 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
1127 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
1128
1129 /* Update FH chicken bits */
1130 reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG);
1131 iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG,
1132 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
1133
1134 /* Enable L1-Active */
1135 iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
1136 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1137}
1138
1139static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans)
1140{
1141 iwl_reset_ict(trans);
1142 iwl_tx_start(trans);
1143}
1144
1145/**
1146 * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
1147 */
1148static int iwl_trans_tx_stop(struct iwl_trans *trans)
1149{
1150 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1151 int ch, txq_id, ret;
1152 unsigned long flags;
1153
1154 /* Turn off all Tx DMA fifos */
1155 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
1156
1157 iwl_trans_txq_set_sched(trans, 0);
1158
1159 /* Stop each Tx DMA channel, and wait for it to be idle */
1160 for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
1161 iwl_write_direct32(trans,
1162 FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
1163 ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG,
1164 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000);
1165 if (ret < 0)
1166 IWL_ERR(trans,
1167 "Failing on timeout while stopping DMA channel %d [0x%08x]\n",
1168 ch,
1169 iwl_read_direct32(trans,
1170 FH_TSSR_TX_STATUS_REG));
1171 }
1172 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1173
1174 if (!trans_pcie->txq) {
1175 IWL_WARN(trans,
1176 "Stopping tx queues that aren't allocated...\n");
1177 return 0;
1178 }
1179
1180 /* Unmap DMA from host system and free skb's */
1181 for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
1182 txq_id++)
1183 iwl_tx_queue_unmap(trans, txq_id);
1184
1185 return 0;
1186} 493}
1187 494
1188static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) 495static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
@@ -1196,7 +503,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
1196 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 503 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1197 504
1198 /* device going down, Stop using ICT table */ 505 /* device going down, Stop using ICT table */
1199 iwl_disable_ict(trans); 506 iwl_pcie_disable_ict(trans);
1200 507
1201 /* 508 /*
1202 * If a HW restart happens during firmware loading, 509 * If a HW restart happens during firmware loading,
@@ -1206,8 +513,8 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
1206 * already dead. 513 * already dead.
1207 */ 514 */
1208 if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { 515 if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) {
1209 iwl_trans_tx_stop(trans); 516 iwl_pcie_tx_stop(trans);
1210 iwl_trans_rx_stop(trans); 517 iwl_pcie_rx_stop(trans);
1211 518
1212 /* Power-down device's busmaster DMA clocks */ 519 /* Power-down device's busmaster DMA clocks */
1213 iwl_write_prph(trans, APMG_CLK_DIS_REG, 520 iwl_write_prph(trans, APMG_CLK_DIS_REG,
@@ -1220,7 +527,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
1220 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 527 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1221 528
1222 /* Stop the device, and put it in low power state */ 529 /* Stop the device, and put it in low power state */
1223 iwl_apm_stop(trans); 530 iwl_pcie_apm_stop(trans);
1224 531
1225 /* Upon stop, the APM issues an interrupt if HW RF kill is set. 532 /* Upon stop, the APM issues an interrupt if HW RF kill is set.
1226 * Clean again the interrupt here 533 * Clean again the interrupt here
@@ -1245,6 +552,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
1245 clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); 552 clear_bit(STATUS_INT_ENABLED, &trans_pcie->status);
1246 clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); 553 clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status);
1247 clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status); 554 clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status);
555 clear_bit(STATUS_RFKILL, &trans_pcie->status);
1248} 556}
1249 557
1250static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) 558static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans)
@@ -1258,171 +566,6 @@ static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans)
1258 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 566 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1259} 567}
1260 568
1261static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1262 struct iwl_device_cmd *dev_cmd, int txq_id)
1263{
1264 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1265 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1266 struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;
1267 struct iwl_cmd_meta *out_meta;
1268 struct iwl_tx_queue *txq;
1269 struct iwl_queue *q;
1270 dma_addr_t phys_addr = 0;
1271 dma_addr_t txcmd_phys;
1272 dma_addr_t scratch_phys;
1273 u16 len, firstlen, secondlen;
1274 u8 wait_write_ptr = 0;
1275 __le16 fc = hdr->frame_control;
1276 u8 hdr_len = ieee80211_hdrlen(fc);
1277 u16 __maybe_unused wifi_seq;
1278
1279 txq = &trans_pcie->txq[txq_id];
1280 q = &txq->q;
1281
1282 if (unlikely(!test_bit(txq_id, trans_pcie->queue_used))) {
1283 WARN_ON_ONCE(1);
1284 return -EINVAL;
1285 }
1286
1287 spin_lock(&txq->lock);
1288
1289 /* In AGG mode, the index in the ring must correspond to the WiFi
1290 * sequence number. This is a HW requirements to help the SCD to parse
1291 * the BA.
1292 * Check here that the packets are in the right place on the ring.
1293 */
1294#ifdef CONFIG_IWLWIFI_DEBUG
1295 wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
1296 WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) &&
1297 ((wifi_seq & 0xff) != q->write_ptr),
1298 "Q: %d WiFi Seq %d tfdNum %d",
1299 txq_id, wifi_seq, q->write_ptr);
1300#endif
1301
1302 /* Set up driver data for this TFD */
1303 txq->entries[q->write_ptr].skb = skb;
1304 txq->entries[q->write_ptr].cmd = dev_cmd;
1305
1306 dev_cmd->hdr.cmd = REPLY_TX;
1307 dev_cmd->hdr.sequence =
1308 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
1309 INDEX_TO_SEQ(q->write_ptr)));
1310
1311 /* Set up first empty entry in queue's array of Tx/cmd buffers */
1312 out_meta = &txq->entries[q->write_ptr].meta;
1313
1314 /*
1315 * Use the first empty entry in this queue's command buffer array
1316 * to contain the Tx command and MAC header concatenated together
1317 * (payload data will be in another buffer).
1318 * Size of this varies, due to varying MAC header length.
1319 * If end is not dword aligned, we'll have 2 extra bytes at the end
1320 * of the MAC header (device reads on dword boundaries).
1321 * We'll tell device about this padding later.
1322 */
1323 len = sizeof(struct iwl_tx_cmd) +
1324 sizeof(struct iwl_cmd_header) + hdr_len;
1325 firstlen = (len + 3) & ~3;
1326
1327 /* Tell NIC about any 2-byte padding after MAC header */
1328 if (firstlen != len)
1329 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
1330
1331 /* Physical address of this Tx command's header (not MAC header!),
1332 * within command buffer array. */
1333 txcmd_phys = dma_map_single(trans->dev,
1334 &dev_cmd->hdr, firstlen,
1335 DMA_BIDIRECTIONAL);
1336 if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
1337 goto out_err;
1338 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
1339 dma_unmap_len_set(out_meta, len, firstlen);
1340
1341 if (!ieee80211_has_morefrags(fc)) {
1342 txq->need_update = 1;
1343 } else {
1344 wait_write_ptr = 1;
1345 txq->need_update = 0;
1346 }
1347
1348 /* Set up TFD's 2nd entry to point directly to remainder of skb,
1349 * if any (802.11 null frames have no payload). */
1350 secondlen = skb->len - hdr_len;
1351 if (secondlen > 0) {
1352 phys_addr = dma_map_single(trans->dev, skb->data + hdr_len,
1353 secondlen, DMA_TO_DEVICE);
1354 if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
1355 dma_unmap_single(trans->dev,
1356 dma_unmap_addr(out_meta, mapping),
1357 dma_unmap_len(out_meta, len),
1358 DMA_BIDIRECTIONAL);
1359 goto out_err;
1360 }
1361 }
1362
1363 /* Attach buffers to TFD */
1364 iwlagn_txq_attach_buf_to_tfd(trans, txq, txcmd_phys, firstlen, 1);
1365 if (secondlen > 0)
1366 iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr,
1367 secondlen, 0);
1368
1369 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
1370 offsetof(struct iwl_tx_cmd, scratch);
1371
1372 /* take back ownership of DMA buffer to enable update */
1373 dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,
1374 DMA_BIDIRECTIONAL);
1375 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
1376 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
1377
1378 IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n",
1379 le16_to_cpu(dev_cmd->hdr.sequence));
1380 IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
1381
1382 /* Set up entry for this TFD in Tx byte-count array */
1383 iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
1384
1385 dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
1386 DMA_BIDIRECTIONAL);
1387
1388 trace_iwlwifi_dev_tx(trans->dev, skb,
1389 &txq->tfds[txq->q.write_ptr],
1390 sizeof(struct iwl_tfd),
1391 &dev_cmd->hdr, firstlen,
1392 skb->data + hdr_len, secondlen);
1393 trace_iwlwifi_dev_tx_data(trans->dev, skb,
1394 skb->data + hdr_len, secondlen);
1395
1396 /* start timer if queue currently empty */
1397 if (txq->need_update && q->read_ptr == q->write_ptr &&
1398 trans_pcie->wd_timeout)
1399 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
1400
1401 /* Tell device the write index *just past* this latest filled TFD */
1402 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
1403 iwl_txq_update_write_ptr(trans, txq);
1404
1405 /*
1406 * At this point the frame is "transmitted" successfully
1407 * and we will get a TX status notification eventually,
1408 * regardless of the value of ret. "ret" only indicates
1409 * whether or not we should update the write pointer.
1410 */
1411 if (iwl_queue_space(q) < q->high_mark) {
1412 if (wait_write_ptr) {
1413 txq->need_update = 1;
1414 iwl_txq_update_write_ptr(trans, txq);
1415 } else {
1416 iwl_stop_queue(trans, txq);
1417 }
1418 }
1419 spin_unlock(&txq->lock);
1420 return 0;
1421 out_err:
1422 spin_unlock(&txq->lock);
1423 return -1;
1424}
1425
1426static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) 569static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
1427{ 570{
1428 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 571 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -1433,29 +576,28 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
1433 576
1434 if (!trans_pcie->irq_requested) { 577 if (!trans_pcie->irq_requested) {
1435 tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) 578 tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long))
1436 iwl_irq_tasklet, (unsigned long)trans); 579 iwl_pcie_tasklet, (unsigned long)trans);
1437 580
1438 iwl_alloc_isr_ict(trans); 581 iwl_pcie_alloc_ict(trans);
1439 582
1440 err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED, 583 err = request_irq(trans_pcie->irq, iwl_pcie_isr_ict,
1441 DRV_NAME, trans); 584 IRQF_SHARED, DRV_NAME, trans);
1442 if (err) { 585 if (err) {
1443 IWL_ERR(trans, "Error allocating IRQ %d\n", 586 IWL_ERR(trans, "Error allocating IRQ %d\n",
1444 trans_pcie->irq); 587 trans_pcie->irq);
1445 goto error; 588 goto error;
1446 } 589 }
1447 590
1448 INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish);
1449 trans_pcie->irq_requested = true; 591 trans_pcie->irq_requested = true;
1450 } 592 }
1451 593
1452 err = iwl_prepare_card_hw(trans); 594 err = iwl_pcie_prepare_card_hw(trans);
1453 if (err) { 595 if (err) {
1454 IWL_ERR(trans, "Error while preparing HW: %d\n", err); 596 IWL_ERR(trans, "Error while preparing HW: %d\n", err);
1455 goto err_free_irq; 597 goto err_free_irq;
1456 } 598 }
1457 599
1458 iwl_apm_init(trans); 600 iwl_pcie_apm_init(trans);
1459 601
1460 /* From now on, the op_mode will be kept updated about RF kill state */ 602 /* From now on, the op_mode will be kept updated about RF kill state */
1461 iwl_enable_rfkill_int(trans); 603 iwl_enable_rfkill_int(trans);
@@ -1469,7 +611,7 @@ err_free_irq:
1469 trans_pcie->irq_requested = false; 611 trans_pcie->irq_requested = false;
1470 free_irq(trans_pcie->irq, trans); 612 free_irq(trans_pcie->irq, trans);
1471error: 613error:
1472 iwl_free_isr_ict(trans); 614 iwl_pcie_free_ict(trans);
1473 tasklet_kill(&trans_pcie->irq_tasklet); 615 tasklet_kill(&trans_pcie->irq_tasklet);
1474 return err; 616 return err;
1475} 617}
@@ -1485,7 +627,7 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans,
1485 iwl_disable_interrupts(trans); 627 iwl_disable_interrupts(trans);
1486 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 628 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1487 629
1488 iwl_apm_stop(trans); 630 iwl_pcie_apm_stop(trans);
1489 631
1490 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 632 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
1491 iwl_disable_interrupts(trans); 633 iwl_disable_interrupts(trans);
@@ -1509,27 +651,6 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans,
1509 } 651 }
1510} 652}
1511 653
1512static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
1513 struct sk_buff_head *skbs)
1514{
1515 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1516 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
1517 /* n_bd is usually 256 => n_bd - 1 = 0xff */
1518 int tfd_num = ssn & (txq->q.n_bd - 1);
1519
1520 spin_lock(&txq->lock);
1521
1522 if (txq->q.read_ptr != tfd_num) {
1523 IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n",
1524 txq_id, txq->q.read_ptr, tfd_num, ssn);
1525 iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs);
1526 if (iwl_queue_space(&txq->q) > txq->q.low_mark)
1527 iwl_wake_queue(trans, txq);
1528 }
1529
1530 spin_unlock(&txq->lock);
1531}
1532
1533static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) 654static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val)
1534{ 655{
1535 writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); 656 writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
@@ -1576,12 +697,12 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
1576{ 697{
1577 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 698 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1578 699
1579 iwl_trans_pcie_tx_free(trans); 700 iwl_pcie_tx_free(trans);
1580 iwl_trans_pcie_rx_free(trans); 701 iwl_pcie_rx_free(trans);
1581 702
1582 if (trans_pcie->irq_requested == true) { 703 if (trans_pcie->irq_requested == true) {
1583 free_irq(trans_pcie->irq, trans); 704 free_irq(trans_pcie->irq, trans);
1584 iwl_free_isr_ict(trans); 705 iwl_pcie_free_ict(trans);
1585 } 706 }
1586 707
1587 pci_disable_msi(trans_pcie->pci_dev); 708 pci_disable_msi(trans_pcie->pci_dev);
@@ -1627,10 +748,10 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
1627 748
1628#define IWL_FLUSH_WAIT_MS 2000 749#define IWL_FLUSH_WAIT_MS 2000
1629 750
1630static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) 751static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans)
1631{ 752{
1632 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 753 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1633 struct iwl_tx_queue *txq; 754 struct iwl_txq *txq;
1634 struct iwl_queue *q; 755 struct iwl_queue *q;
1635 int cnt; 756 int cnt;
1636 unsigned long now = jiffies; 757 unsigned long now = jiffies;
@@ -1674,7 +795,7 @@ static const char *get_fh_string(int cmd)
1674#undef IWL_CMD 795#undef IWL_CMD
1675} 796}
1676 797
1677int iwl_dump_fh(struct iwl_trans *trans, char **buf) 798int iwl_pcie_dump_fh(struct iwl_trans *trans, char **buf)
1678{ 799{
1679 int i; 800 int i;
1680 static const u32 fh_tbl[] = { 801 static const u32 fh_tbl[] = {
@@ -1753,7 +874,7 @@ static const char *get_csr_string(int cmd)
1753#undef IWL_CMD 874#undef IWL_CMD
1754} 875}
1755 876
1756void iwl_dump_csr(struct iwl_trans *trans) 877void iwl_pcie_dump_csr(struct iwl_trans *trans)
1757{ 878{
1758 int i; 879 int i;
1759 static const u32 csr_tbl[] = { 880 static const u32 csr_tbl[] = {
@@ -1810,7 +931,6 @@ static ssize_t iwl_dbgfs_##name##_write(struct file *file, \
1810 const char __user *user_buf, \ 931 const char __user *user_buf, \
1811 size_t count, loff_t *ppos); 932 size_t count, loff_t *ppos);
1812 933
1813
1814#define DEBUGFS_READ_FILE_OPS(name) \ 934#define DEBUGFS_READ_FILE_OPS(name) \
1815 DEBUGFS_READ_FUNC(name); \ 935 DEBUGFS_READ_FUNC(name); \
1816static const struct file_operations iwl_dbgfs_##name##_ops = { \ 936static const struct file_operations iwl_dbgfs_##name##_ops = { \
@@ -1843,7 +963,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
1843{ 963{
1844 struct iwl_trans *trans = file->private_data; 964 struct iwl_trans *trans = file->private_data;
1845 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 965 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1846 struct iwl_tx_queue *txq; 966 struct iwl_txq *txq;
1847 struct iwl_queue *q; 967 struct iwl_queue *q;
1848 char *buf; 968 char *buf;
1849 int pos = 0; 969 int pos = 0;
@@ -1880,7 +1000,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1880{ 1000{
1881 struct iwl_trans *trans = file->private_data; 1001 struct iwl_trans *trans = file->private_data;
1882 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1002 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1883 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 1003 struct iwl_rxq *rxq = &trans_pcie->rxq;
1884 char buf[256]; 1004 char buf[256];
1885 int pos = 0; 1005 int pos = 0;
1886 const size_t bufsz = sizeof(buf); 1006 const size_t bufsz = sizeof(buf);
@@ -1999,7 +1119,7 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file,
1999 if (sscanf(buf, "%d", &csr) != 1) 1119 if (sscanf(buf, "%d", &csr) != 1)
2000 return -EFAULT; 1120 return -EFAULT;
2001 1121
2002 iwl_dump_csr(trans); 1122 iwl_pcie_dump_csr(trans);
2003 1123
2004 return count; 1124 return count;
2005} 1125}
@@ -2013,7 +1133,7 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
2013 int pos = 0; 1133 int pos = 0;
2014 ssize_t ret = -EFAULT; 1134 ssize_t ret = -EFAULT;
2015 1135
2016 ret = pos = iwl_dump_fh(trans, &buf); 1136 ret = pos = iwl_pcie_dump_fh(trans, &buf);
2017 if (buf) { 1137 if (buf) {
2018 ret = simple_read_from_buffer(user_buf, 1138 ret = simple_read_from_buffer(user_buf,
2019 count, ppos, buf, pos); 1139 count, ppos, buf, pos);
@@ -2082,7 +1202,7 @@ static const struct iwl_trans_ops trans_ops_pcie = {
2082 1202
2083 .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, 1203 .wowlan_suspend = iwl_trans_pcie_wowlan_suspend,
2084 1204
2085 .send_cmd = iwl_trans_pcie_send_cmd, 1205 .send_cmd = iwl_trans_pcie_send_hcmd,
2086 1206
2087 .tx = iwl_trans_pcie_tx, 1207 .tx = iwl_trans_pcie_tx,
2088 .reclaim = iwl_trans_pcie_reclaim, 1208 .reclaim = iwl_trans_pcie_reclaim,
@@ -2092,7 +1212,7 @@ static const struct iwl_trans_ops trans_ops_pcie = {
2092 1212
2093 .dbgfs_register = iwl_trans_pcie_dbgfs_register, 1213 .dbgfs_register = iwl_trans_pcie_dbgfs_register,
2094 1214
2095 .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty, 1215 .wait_tx_queue_empty = iwl_trans_pcie_wait_txq_empty,
2096 1216
2097#ifdef CONFIG_PM_SLEEP 1217#ifdef CONFIG_PM_SLEEP
2098 .suspend = iwl_trans_pcie_suspend, 1218 .suspend = iwl_trans_pcie_suspend,
@@ -2117,7 +1237,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2117 trans = kzalloc(sizeof(struct iwl_trans) + 1237 trans = kzalloc(sizeof(struct iwl_trans) +
2118 sizeof(struct iwl_trans_pcie), GFP_KERNEL); 1238 sizeof(struct iwl_trans_pcie), GFP_KERNEL);
2119 1239
2120 if (WARN_ON(!trans)) 1240 if (!trans)
2121 return NULL; 1241 return NULL;
2122 1242
2123 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1243 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -2150,43 +1270,38 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2150 DMA_BIT_MASK(32)); 1270 DMA_BIT_MASK(32));
2151 /* both attempts failed: */ 1271 /* both attempts failed: */
2152 if (err) { 1272 if (err) {
2153 dev_printk(KERN_ERR, &pdev->dev, 1273 dev_err(&pdev->dev, "No suitable DMA available\n");
2154 "No suitable DMA available.\n");
2155 goto out_pci_disable_device; 1274 goto out_pci_disable_device;
2156 } 1275 }
2157 } 1276 }
2158 1277
2159 err = pci_request_regions(pdev, DRV_NAME); 1278 err = pci_request_regions(pdev, DRV_NAME);
2160 if (err) { 1279 if (err) {
2161 dev_printk(KERN_ERR, &pdev->dev, 1280 dev_err(&pdev->dev, "pci_request_regions failed\n");
2162 "pci_request_regions failed\n");
2163 goto out_pci_disable_device; 1281 goto out_pci_disable_device;
2164 } 1282 }
2165 1283
2166 trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); 1284 trans_pcie->hw_base = pci_ioremap_bar(pdev, 0);
2167 if (!trans_pcie->hw_base) { 1285 if (!trans_pcie->hw_base) {
2168 dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed\n"); 1286 dev_err(&pdev->dev, "pci_ioremap_bar failed\n");
2169 err = -ENODEV; 1287 err = -ENODEV;
2170 goto out_pci_release_regions; 1288 goto out_pci_release_regions;
2171 } 1289 }
2172 1290
2173 dev_printk(KERN_INFO, &pdev->dev,
2174 "pci_resource_len = 0x%08llx\n",
2175 (unsigned long long) pci_resource_len(pdev, 0));
2176 dev_printk(KERN_INFO, &pdev->dev,
2177 "pci_resource_base = %p\n", trans_pcie->hw_base);
2178
2179 dev_printk(KERN_INFO, &pdev->dev,
2180 "HW Revision ID = 0x%X\n", pdev->revision);
2181
2182 /* We disable the RETRY_TIMEOUT register (0x41) to keep 1291 /* We disable the RETRY_TIMEOUT register (0x41) to keep
2183 * PCI Tx retries from interfering with C3 CPU state */ 1292 * PCI Tx retries from interfering with C3 CPU state */
2184 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); 1293 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
2185 1294
2186 err = pci_enable_msi(pdev); 1295 err = pci_enable_msi(pdev);
2187 if (err) 1296 if (err) {
2188 dev_printk(KERN_ERR, &pdev->dev, 1297 dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err);
2189 "pci_enable_msi failed(0X%x)\n", err); 1298 /* enable rfkill interrupt: hw bug w/a */
1299 pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
1300 if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
1301 pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
1302 pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
1303 }
1304 }
2190 1305
2191 trans->dev = &pdev->dev; 1306 trans->dev = &pdev->dev;
2192 trans_pcie->irq = pdev->irq; 1307 trans_pcie->irq = pdev->irq;
@@ -2196,16 +1311,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2196 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), 1311 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
2197 "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); 1312 "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
2198 1313
2199 /* TODO: Move this away, not needed if not MSI */
2200 /* enable rfkill interrupt: hw bug w/a */
2201 pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
2202 if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
2203 pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
2204 pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
2205 }
2206
2207 /* Initialize the wait queue for commands */ 1314 /* Initialize the wait queue for commands */
2208 init_waitqueue_head(&trans->wait_command_queue); 1315 init_waitqueue_head(&trans_pcie->wait_command_queue);
2209 spin_lock_init(&trans->reg_lock); 1316 spin_lock_init(&trans->reg_lock);
2210 1317
2211 snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name), 1318 snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name),
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index db3efbb84d9..6c5b867c353 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -42,12 +42,170 @@
42#define IWL_TX_CRC_SIZE 4 42#define IWL_TX_CRC_SIZE 4
43#define IWL_TX_DELIMITER_SIZE 4 43#define IWL_TX_DELIMITER_SIZE 4
44 44
45/** 45/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
46 * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array 46 * DMA services
47 *
48 * Theory of operation
49 *
50 * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
51 * of buffer descriptors, each of which points to one or more data buffers for
52 * the device to read from or fill. Driver and device exchange status of each
53 * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty
54 * entries in each circular buffer, to protect against confusing empty and full
55 * queue states.
56 *
57 * The device reads or writes the data in the queues via the device's several
58 * DMA/FIFO channels. Each queue is mapped to a single DMA channel.
59 *
60 * For Tx queue, there are low mark and high mark limits. If, after queuing
61 * the packet for Tx, free space become < low mark, Tx queue stopped. When
62 * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
63 * Tx queue resumed.
64 *
65 ***************************************************/
66static int iwl_queue_space(const struct iwl_queue *q)
67{
68 int s = q->read_ptr - q->write_ptr;
69
70 if (q->read_ptr > q->write_ptr)
71 s -= q->n_bd;
72
73 if (s <= 0)
74 s += q->n_window;
75 /* keep some reserve to not confuse empty and full situations */
76 s -= 2;
77 if (s < 0)
78 s = 0;
79 return s;
80}
81
82/*
83 * iwl_queue_init - Initialize queue's high/low-water and read/write indexes
84 */
85static int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id)
86{
87 q->n_bd = count;
88 q->n_window = slots_num;
89 q->id = id;
90
91 /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
92 * and iwl_queue_dec_wrap are broken. */
93 if (WARN_ON(!is_power_of_2(count)))
94 return -EINVAL;
95
96 /* slots_num must be power-of-two size, otherwise
97 * get_cmd_index is broken. */
98 if (WARN_ON(!is_power_of_2(slots_num)))
99 return -EINVAL;
100
101 q->low_mark = q->n_window / 4;
102 if (q->low_mark < 4)
103 q->low_mark = 4;
104
105 q->high_mark = q->n_window / 8;
106 if (q->high_mark < 2)
107 q->high_mark = 2;
108
109 q->write_ptr = 0;
110 q->read_ptr = 0;
111
112 return 0;
113}
114
115static int iwl_pcie_alloc_dma_ptr(struct iwl_trans *trans,
116 struct iwl_dma_ptr *ptr, size_t size)
117{
118 if (WARN_ON(ptr->addr))
119 return -EINVAL;
120
121 ptr->addr = dma_alloc_coherent(trans->dev, size,
122 &ptr->dma, GFP_KERNEL);
123 if (!ptr->addr)
124 return -ENOMEM;
125 ptr->size = size;
126 return 0;
127}
128
129static void iwl_pcie_free_dma_ptr(struct iwl_trans *trans,
130 struct iwl_dma_ptr *ptr)
131{
132 if (unlikely(!ptr->addr))
133 return;
134
135 dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma);
136 memset(ptr, 0, sizeof(*ptr));
137}
138
139static void iwl_pcie_txq_stuck_timer(unsigned long data)
140{
141 struct iwl_txq *txq = (void *)data;
142 struct iwl_queue *q = &txq->q;
143 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
144 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
145 u32 scd_sram_addr = trans_pcie->scd_base_addr +
146 SCD_TX_STTS_QUEUE_OFFSET(txq->q.id);
147 u8 buf[16];
148 int i;
149
150 spin_lock(&txq->lock);
151 /* check if triggered erroneously */
152 if (txq->q.read_ptr == txq->q.write_ptr) {
153 spin_unlock(&txq->lock);
154 return;
155 }
156 spin_unlock(&txq->lock);
157
158 IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id,
159 jiffies_to_msecs(trans_pcie->wd_timeout));
160 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
161 txq->q.read_ptr, txq->q.write_ptr);
162
163 iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf));
164
165 iwl_print_hex_error(trans, buf, sizeof(buf));
166
167 for (i = 0; i < FH_TCSR_CHNL_NUM; i++)
168 IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", i,
169 iwl_read_direct32(trans, FH_TX_TRB_REG(i)));
170
171 for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
172 u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(i));
173 u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7;
174 bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE));
175 u32 tbl_dw =
176 iwl_read_targ_mem(trans,
177 trans_pcie->scd_base_addr +
178 SCD_TRANS_TBL_OFFSET_QUEUE(i));
179
180 if (i & 0x1)
181 tbl_dw = (tbl_dw & 0xFFFF0000) >> 16;
182 else
183 tbl_dw = tbl_dw & 0x0000FFFF;
184
185 IWL_ERR(trans,
186 "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n",
187 i, active ? "" : "in", fifo, tbl_dw,
188 iwl_read_prph(trans,
189 SCD_QUEUE_RDPTR(i)) & (txq->q.n_bd - 1),
190 iwl_read_prph(trans, SCD_QUEUE_WRPTR(i)));
191 }
192
193 for (i = q->read_ptr; i != q->write_ptr;
194 i = iwl_queue_inc_wrap(i, q->n_bd)) {
195 struct iwl_tx_cmd *tx_cmd =
196 (struct iwl_tx_cmd *)txq->entries[i].cmd->payload;
197 IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
198 get_unaligned_le32(&tx_cmd->scratch));
199 }
200
201 iwl_op_mode_nic_error(trans->op_mode);
202}
203
204/*
205 * iwl_pcie_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
47 */ 206 */
48void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, 207static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
49 struct iwl_tx_queue *txq, 208 struct iwl_txq *txq, u16 byte_cnt)
50 u16 byte_cnt)
51{ 209{
52 struct iwlagn_scd_bc_tbl *scd_bc_tbl; 210 struct iwlagn_scd_bc_tbl *scd_bc_tbl;
53 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 211 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -88,10 +246,36 @@ void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
88 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; 246 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
89} 247}
90 248
91/** 249static void iwl_pcie_txq_inval_byte_cnt_tbl(struct iwl_trans *trans,
92 * iwl_txq_update_write_ptr - Send new write index to hardware 250 struct iwl_txq *txq)
251{
252 struct iwl_trans_pcie *trans_pcie =
253 IWL_TRANS_GET_PCIE_TRANS(trans);
254 struct iwlagn_scd_bc_tbl *scd_bc_tbl = trans_pcie->scd_bc_tbls.addr;
255 int txq_id = txq->q.id;
256 int read_ptr = txq->q.read_ptr;
257 u8 sta_id = 0;
258 __le16 bc_ent;
259 struct iwl_tx_cmd *tx_cmd =
260 (void *)txq->entries[txq->q.read_ptr].cmd->payload;
261
262 WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
263
264 if (txq_id != trans_pcie->cmd_queue)
265 sta_id = tx_cmd->sta_id;
266
267 bc_ent = cpu_to_le16(1 | (sta_id << 12));
268 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
269
270 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
271 scd_bc_tbl[txq_id].
272 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
273}
274
275/*
276 * iwl_pcie_txq_inc_wr_ptr - Send new write index to hardware
93 */ 277 */
94void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) 278void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq)
95{ 279{
96 u32 reg = 0; 280 u32 reg = 0;
97 int txq_id = txq->q.id; 281 int txq_id = txq->q.id;
@@ -137,7 +321,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq)
137 txq->need_update = 0; 321 txq->need_update = 0;
138} 322}
139 323
140static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) 324static inline dma_addr_t iwl_pcie_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
141{ 325{
142 struct iwl_tfd_tb *tb = &tfd->tbs[idx]; 326 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
143 327
@@ -149,15 +333,15 @@ static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
149 return addr; 333 return addr;
150} 334}
151 335
152static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) 336static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
153{ 337{
154 struct iwl_tfd_tb *tb = &tfd->tbs[idx]; 338 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
155 339
156 return le16_to_cpu(tb->hi_n_len) >> 4; 340 return le16_to_cpu(tb->hi_n_len) >> 4;
157} 341}
158 342
159static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, 343static inline void iwl_pcie_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
160 dma_addr_t addr, u16 len) 344 dma_addr_t addr, u16 len)
161{ 345{
162 struct iwl_tfd_tb *tb = &tfd->tbs[idx]; 346 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
163 u16 hi_n_len = len << 4; 347 u16 hi_n_len = len << 4;
@@ -171,19 +355,20 @@ static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
171 tfd->num_tbs = idx + 1; 355 tfd->num_tbs = idx + 1;
172} 356}
173 357
174static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) 358static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd)
175{ 359{
176 return tfd->num_tbs & 0x1f; 360 return tfd->num_tbs & 0x1f;
177} 361}
178 362
179static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, 363static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
180 struct iwl_tfd *tfd, enum dma_data_direction dma_dir) 364 struct iwl_cmd_meta *meta, struct iwl_tfd *tfd,
365 enum dma_data_direction dma_dir)
181{ 366{
182 int i; 367 int i;
183 int num_tbs; 368 int num_tbs;
184 369
185 /* Sanity check on number of chunks */ 370 /* Sanity check on number of chunks */
186 num_tbs = iwl_tfd_get_num_tbs(tfd); 371 num_tbs = iwl_pcie_tfd_get_num_tbs(tfd);
187 372
188 if (num_tbs >= IWL_NUM_OF_TBS) { 373 if (num_tbs >= IWL_NUM_OF_TBS) {
189 IWL_ERR(trans, "Too many chunks: %i\n", num_tbs); 374 IWL_ERR(trans, "Too many chunks: %i\n", num_tbs);
@@ -200,14 +385,14 @@ static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta,
200 385
201 /* Unmap chunks, if any. */ 386 /* Unmap chunks, if any. */
202 for (i = 1; i < num_tbs; i++) 387 for (i = 1; i < num_tbs; i++)
203 dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), 388 dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i),
204 iwl_tfd_tb_get_len(tfd, i), dma_dir); 389 iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir);
205 390
206 tfd->num_tbs = 0; 391 tfd->num_tbs = 0;
207} 392}
208 393
209/** 394/*
210 * iwl_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] 395 * iwl_pcie_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
211 * @trans - transport private data 396 * @trans - transport private data
212 * @txq - tx queue 397 * @txq - tx queue
213 * @dma_dir - the direction of the DMA mapping 398 * @dma_dir - the direction of the DMA mapping
@@ -215,8 +400,8 @@ static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta,
215 * Does NOT advance any TFD circular buffer read/write indexes 400 * Does NOT advance any TFD circular buffer read/write indexes
216 * Does NOT free the TFD itself (which is within circular buffer) 401 * Does NOT free the TFD itself (which is within circular buffer)
217 */ 402 */
218void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, 403static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
219 enum dma_data_direction dma_dir) 404 enum dma_data_direction dma_dir)
220{ 405{
221 struct iwl_tfd *tfd_tmp = txq->tfds; 406 struct iwl_tfd *tfd_tmp = txq->tfds;
222 407
@@ -227,8 +412,8 @@ void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
227 lockdep_assert_held(&txq->lock); 412 lockdep_assert_held(&txq->lock);
228 413
229 /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ 414 /* We have only q->n_window txq->entries, but we use q->n_bd tfds */
230 iwl_unmap_tfd(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], 415 iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr],
231 dma_dir); 416 dma_dir);
232 417
233 /* free SKB */ 418 /* free SKB */
234 if (txq->entries) { 419 if (txq->entries) {
@@ -247,10 +432,8 @@ void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
247 } 432 }
248} 433}
249 434
250int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, 435static int iwl_pcie_txq_build_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
251 struct iwl_tx_queue *txq, 436 dma_addr_t addr, u16 len, u8 reset)
252 dma_addr_t addr, u16 len,
253 u8 reset)
254{ 437{
255 struct iwl_queue *q; 438 struct iwl_queue *q;
256 struct iwl_tfd *tfd, *tfd_tmp; 439 struct iwl_tfd *tfd, *tfd_tmp;
@@ -263,7 +446,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans,
263 if (reset) 446 if (reset)
264 memset(tfd, 0, sizeof(*tfd)); 447 memset(tfd, 0, sizeof(*tfd));
265 448
266 num_tbs = iwl_tfd_get_num_tbs(tfd); 449 num_tbs = iwl_pcie_tfd_get_num_tbs(tfd);
267 450
268 /* Each TFD can point to a maximum 20 Tx buffers */ 451 /* Each TFD can point to a maximum 20 Tx buffers */
269 if (num_tbs >= IWL_NUM_OF_TBS) { 452 if (num_tbs >= IWL_NUM_OF_TBS) {
@@ -279,108 +462,534 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans,
279 IWL_ERR(trans, "Unaligned address = %llx\n", 462 IWL_ERR(trans, "Unaligned address = %llx\n",
280 (unsigned long long)addr); 463 (unsigned long long)addr);
281 464
282 iwl_tfd_set_tb(tfd, num_tbs, addr, len); 465 iwl_pcie_tfd_set_tb(tfd, num_tbs, addr, len);
283 466
284 return 0; 467 return 0;
285} 468}
286 469
287/*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** 470static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
288 * DMA services 471 struct iwl_txq *txq, int slots_num,
289 * 472 u32 txq_id)
290 * Theory of operation 473{
291 * 474 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
292 * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer 475 size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX;
293 * of buffer descriptors, each of which points to one or more data buffers for 476 int i;
294 * the device to read from or fill. Driver and device exchange status of each 477
295 * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty 478 if (WARN_ON(txq->entries || txq->tfds))
296 * entries in each circular buffer, to protect against confusing empty and full 479 return -EINVAL;
297 * queue states. 480
298 * 481 setup_timer(&txq->stuck_timer, iwl_pcie_txq_stuck_timer,
299 * The device reads or writes the data in the queues via the device's several 482 (unsigned long)txq);
300 * DMA/FIFO channels. Each queue is mapped to a single DMA channel. 483 txq->trans_pcie = trans_pcie;
301 * 484
302 * For Tx queue, there are low mark and high mark limits. If, after queuing 485 txq->q.n_window = slots_num;
303 * the packet for Tx, free space become < low mark, Tx queue stopped. When 486
304 * reclaiming packets (on 'tx done IRQ), if free space become > high mark, 487 txq->entries = kcalloc(slots_num,
305 * Tx queue resumed. 488 sizeof(struct iwl_pcie_txq_entry),
489 GFP_KERNEL);
490
491 if (!txq->entries)
492 goto error;
493
494 if (txq_id == trans_pcie->cmd_queue)
495 for (i = 0; i < slots_num; i++) {
496 txq->entries[i].cmd =
497 kmalloc(sizeof(struct iwl_device_cmd),
498 GFP_KERNEL);
499 if (!txq->entries[i].cmd)
500 goto error;
501 }
502
503 /* Circular buffer of transmit frame descriptors (TFDs),
504 * shared with device */
505 txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz,
506 &txq->q.dma_addr, GFP_KERNEL);
507 if (!txq->tfds) {
508 IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
509 goto error;
510 }
511 txq->q.id = txq_id;
512
513 return 0;
514error:
515 if (txq->entries && txq_id == trans_pcie->cmd_queue)
516 for (i = 0; i < slots_num; i++)
517 kfree(txq->entries[i].cmd);
518 kfree(txq->entries);
519 txq->entries = NULL;
520
521 return -ENOMEM;
522
523}
524
525static int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
526 int slots_num, u32 txq_id)
527{
528 int ret;
529
530 txq->need_update = 0;
531
532 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
533 * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
534 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
535
536 /* Initialize queue's high/low-water marks, and head/tail indexes */
537 ret = iwl_queue_init(&txq->q, TFD_QUEUE_SIZE_MAX, slots_num,
538 txq_id);
539 if (ret)
540 return ret;
541
542 spin_lock_init(&txq->lock);
543
544 /*
545 * Tell nic where to find circular buffer of Tx Frame Descriptors for
546 * given Tx queue, and enable the DMA channel used for that queue.
547 * Circular buffer (TFD queue in DRAM) physical base address */
548 iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id),
549 txq->q.dma_addr >> 8);
550
551 return 0;
552}
553
554/*
555 * iwl_pcie_txq_unmap - Unmap any remaining DMA mappings and free skb's
556 */
557static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
558{
559 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
560 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
561 struct iwl_queue *q = &txq->q;
562 enum dma_data_direction dma_dir;
563
564 if (!q->n_bd)
565 return;
566
567 /* In the command queue, all the TBs are mapped as BIDI
568 * so unmap them as such.
569 */
570 if (txq_id == trans_pcie->cmd_queue)
571 dma_dir = DMA_BIDIRECTIONAL;
572 else
573 dma_dir = DMA_TO_DEVICE;
574
575 spin_lock_bh(&txq->lock);
576 while (q->write_ptr != q->read_ptr) {
577 iwl_pcie_txq_free_tfd(trans, txq, dma_dir);
578 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
579 }
580 spin_unlock_bh(&txq->lock);
581}
582
583/*
584 * iwl_pcie_txq_free - Deallocate DMA queue.
585 * @txq: Transmit queue to deallocate.
306 * 586 *
307 ***************************************************/ 587 * Empty queue by removing and destroying all BD's.
588 * Free all buffers.
589 * 0-fill, but do not free "txq" descriptor structure.
590 */
591static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
592{
593 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
594 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
595 struct device *dev = trans->dev;
596 int i;
308 597
309int iwl_queue_space(const struct iwl_queue *q) 598 if (WARN_ON(!txq))
599 return;
600
601 iwl_pcie_txq_unmap(trans, txq_id);
602
603 /* De-alloc array of command/tx buffers */
604 if (txq_id == trans_pcie->cmd_queue)
605 for (i = 0; i < txq->q.n_window; i++) {
606 kfree(txq->entries[i].cmd);
607 kfree(txq->entries[i].copy_cmd);
608 kfree(txq->entries[i].free_buf);
609 }
610
611 /* De-alloc circular buffer of TFDs */
612 if (txq->q.n_bd) {
613 dma_free_coherent(dev, sizeof(struct iwl_tfd) *
614 txq->q.n_bd, txq->tfds, txq->q.dma_addr);
615 memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr));
616 }
617
618 kfree(txq->entries);
619 txq->entries = NULL;
620
621 del_timer_sync(&txq->stuck_timer);
622
623 /* 0-fill queue descriptor structure */
624 memset(txq, 0, sizeof(*txq));
625}
626
627/*
628 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
629 */
630static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask)
310{ 631{
311 int s = q->read_ptr - q->write_ptr; 632 struct iwl_trans_pcie __maybe_unused *trans_pcie =
633 IWL_TRANS_GET_PCIE_TRANS(trans);
312 634
313 if (q->read_ptr > q->write_ptr) 635 iwl_write_prph(trans, SCD_TXFACT, mask);
314 s -= q->n_bd; 636}
315 637
316 if (s <= 0) 638void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
317 s += q->n_window; 639{
318 /* keep some reserve to not confuse empty and full situations */ 640 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
319 s -= 2; 641 u32 a;
320 if (s < 0) 642 int chan;
321 s = 0; 643 u32 reg_val;
322 return s; 644
645 /* make sure all queue are not stopped/used */
646 memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped));
647 memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used));
648
649 trans_pcie->scd_base_addr =
650 iwl_read_prph(trans, SCD_SRAM_BASE_ADDR);
651
652 WARN_ON(scd_base_addr != 0 &&
653 scd_base_addr != trans_pcie->scd_base_addr);
654
655 a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND;
656 /* reset conext data memory */
657 for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND;
658 a += 4)
659 iwl_write_targ_mem(trans, a, 0);
660 /* reset tx status memory */
661 for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND;
662 a += 4)
663 iwl_write_targ_mem(trans, a, 0);
664 for (; a < trans_pcie->scd_base_addr +
665 SCD_TRANS_TBL_OFFSET_QUEUE(
666 trans->cfg->base_params->num_of_queues);
667 a += 4)
668 iwl_write_targ_mem(trans, a, 0);
669
670 iwl_write_prph(trans, SCD_DRAM_BASE_ADDR,
671 trans_pcie->scd_bc_tbls.dma >> 10);
672
673 /* The chain extension of the SCD doesn't work well. This feature is
674 * enabled by default by the HW, so we need to disable it manually.
675 */
676 iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
677
678 iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue,
679 trans_pcie->cmd_fifo);
680
681 /* Activate all Tx DMA/FIFO channels */
682 iwl_pcie_txq_set_sched(trans, IWL_MASK(0, 7));
683
684 /* Enable DMA channel */
685 for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++)
686 iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
687 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
688 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
689
690 /* Update FH chicken bits */
691 reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG);
692 iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG,
693 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
694
695 /* Enable L1-Active */
696 iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
697 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
323} 698}
324 699
325/** 700/*
326 * iwl_queue_init - Initialize queue's high/low-water and read/write indexes 701 * iwl_pcie_tx_stop - Stop all Tx DMA channels
327 */ 702 */
328int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id) 703int iwl_pcie_tx_stop(struct iwl_trans *trans)
329{ 704{
330 q->n_bd = count; 705 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
331 q->n_window = slots_num; 706 int ch, txq_id, ret;
332 q->id = id; 707 unsigned long flags;
333 708
334 /* count must be power-of-two size, otherwise iwl_queue_inc_wrap 709 /* Turn off all Tx DMA fifos */
335 * and iwl_queue_dec_wrap are broken. */ 710 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
336 if (WARN_ON(!is_power_of_2(count)))
337 return -EINVAL;
338 711
339 /* slots_num must be power-of-two size, otherwise 712 iwl_pcie_txq_set_sched(trans, 0);
340 * get_cmd_index is broken. */
341 if (WARN_ON(!is_power_of_2(slots_num)))
342 return -EINVAL;
343 713
344 q->low_mark = q->n_window / 4; 714 /* Stop each Tx DMA channel, and wait for it to be idle */
345 if (q->low_mark < 4) 715 for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
346 q->low_mark = 4; 716 iwl_write_direct32(trans,
717 FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
718 ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG,
719 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000);
720 if (ret < 0)
721 IWL_ERR(trans,
722 "Failing on timeout while stopping DMA channel %d [0x%08x]\n",
723 ch,
724 iwl_read_direct32(trans,
725 FH_TSSR_TX_STATUS_REG));
726 }
727 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
347 728
348 q->high_mark = q->n_window / 8; 729 if (!trans_pcie->txq) {
349 if (q->high_mark < 2) 730 IWL_WARN(trans,
350 q->high_mark = 2; 731 "Stopping tx queues that aren't allocated...\n");
732 return 0;
733 }
351 734
352 q->write_ptr = q->read_ptr = 0; 735 /* Unmap DMA from host system and free skb's */
736 for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
737 txq_id++)
738 iwl_pcie_txq_unmap(trans, txq_id);
353 739
354 return 0; 740 return 0;
355} 741}
356 742
357static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, 743/*
358 struct iwl_tx_queue *txq) 744 * iwl_trans_tx_free - Free TXQ Context
745 *
746 * Destroy all TX DMA queues and structures
747 */
748void iwl_pcie_tx_free(struct iwl_trans *trans)
359{ 749{
360 struct iwl_trans_pcie *trans_pcie = 750 int txq_id;
361 IWL_TRANS_GET_PCIE_TRANS(trans); 751 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
362 struct iwlagn_scd_bc_tbl *scd_bc_tbl = trans_pcie->scd_bc_tbls.addr;
363 int txq_id = txq->q.id;
364 int read_ptr = txq->q.read_ptr;
365 u8 sta_id = 0;
366 __le16 bc_ent;
367 struct iwl_tx_cmd *tx_cmd =
368 (void *)txq->entries[txq->q.read_ptr].cmd->payload;
369 752
370 WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); 753 /* Tx queues */
754 if (trans_pcie->txq) {
755 for (txq_id = 0;
756 txq_id < trans->cfg->base_params->num_of_queues; txq_id++)
757 iwl_pcie_txq_free(trans, txq_id);
758 }
371 759
372 if (txq_id != trans_pcie->cmd_queue) 760 kfree(trans_pcie->txq);
373 sta_id = tx_cmd->sta_id; 761 trans_pcie->txq = NULL;
374 762
375 bc_ent = cpu_to_le16(1 | (sta_id << 12)); 763 iwl_pcie_free_dma_ptr(trans, &trans_pcie->kw);
376 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
377 764
378 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP) 765 iwl_pcie_free_dma_ptr(trans, &trans_pcie->scd_bc_tbls);
379 scd_bc_tbl[txq_id]. 766}
380 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; 767
768/*
769 * iwl_pcie_tx_alloc - allocate TX context
770 * Allocate all Tx DMA structures and initialize them
771 */
772static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
773{
774 int ret;
775 int txq_id, slots_num;
776 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
777
778 u16 scd_bc_tbls_size = trans->cfg->base_params->num_of_queues *
779 sizeof(struct iwlagn_scd_bc_tbl);
780
781 /*It is not allowed to alloc twice, so warn when this happens.
782 * We cannot rely on the previous allocation, so free and fail */
783 if (WARN_ON(trans_pcie->txq)) {
784 ret = -EINVAL;
785 goto error;
786 }
787
788 ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->scd_bc_tbls,
789 scd_bc_tbls_size);
790 if (ret) {
791 IWL_ERR(trans, "Scheduler BC Table allocation failed\n");
792 goto error;
793 }
794
795 /* Alloc keep-warm buffer */
796 ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->kw, IWL_KW_SIZE);
797 if (ret) {
798 IWL_ERR(trans, "Keep Warm allocation failed\n");
799 goto error;
800 }
801
802 trans_pcie->txq = kcalloc(trans->cfg->base_params->num_of_queues,
803 sizeof(struct iwl_txq), GFP_KERNEL);
804 if (!trans_pcie->txq) {
805 IWL_ERR(trans, "Not enough memory for txq\n");
806 ret = ENOMEM;
807 goto error;
808 }
809
810 /* Alloc and init all Tx queues, including the command queue (#4/#9) */
811 for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
812 txq_id++) {
813 slots_num = (txq_id == trans_pcie->cmd_queue) ?
814 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
815 ret = iwl_pcie_txq_alloc(trans, &trans_pcie->txq[txq_id],
816 slots_num, txq_id);
817 if (ret) {
818 IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id);
819 goto error;
820 }
821 }
822
823 return 0;
824
825error:
826 iwl_pcie_tx_free(trans);
827
828 return ret;
829}
830int iwl_pcie_tx_init(struct iwl_trans *trans)
831{
832 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
833 int ret;
834 int txq_id, slots_num;
835 unsigned long flags;
836 bool alloc = false;
837
838 if (!trans_pcie->txq) {
839 ret = iwl_pcie_tx_alloc(trans);
840 if (ret)
841 goto error;
842 alloc = true;
843 }
844
845 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
846
847 /* Turn off all Tx DMA fifos */
848 iwl_write_prph(trans, SCD_TXFACT, 0);
849
850 /* Tell NIC where to find the "keep warm" buffer */
851 iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
852 trans_pcie->kw.dma >> 4);
853
854 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
855
856 /* Alloc and init all Tx queues, including the command queue (#4/#9) */
857 for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
858 txq_id++) {
859 slots_num = (txq_id == trans_pcie->cmd_queue) ?
860 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
861 ret = iwl_pcie_txq_init(trans, &trans_pcie->txq[txq_id],
862 slots_num, txq_id);
863 if (ret) {
864 IWL_ERR(trans, "Tx %d queue init failed\n", txq_id);
865 goto error;
866 }
867 }
868
869 return 0;
870error:
871 /*Upon error, free only if we allocated something */
872 if (alloc)
873 iwl_pcie_tx_free(trans);
874 return ret;
875}
876
877static inline void iwl_pcie_txq_progress(struct iwl_trans_pcie *trans_pcie,
878 struct iwl_txq *txq)
879{
880 if (!trans_pcie->wd_timeout)
881 return;
882
883 /*
884 * if empty delete timer, otherwise move timer forward
885 * since we're making progress on this queue
886 */
887 if (txq->q.read_ptr == txq->q.write_ptr)
888 del_timer(&txq->stuck_timer);
889 else
890 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
891}
892
893/* Frees buffers until index _not_ inclusive */
894void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
895 struct sk_buff_head *skbs)
896{
897 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
898 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
899 /* n_bd is usually 256 => n_bd - 1 = 0xff */
900 int tfd_num = ssn & (txq->q.n_bd - 1);
901 struct iwl_queue *q = &txq->q;
902 int last_to_free;
903
904 /* This function is not meant to release cmd queue*/
905 if (WARN_ON(txq_id == trans_pcie->cmd_queue))
906 return;
907
908 spin_lock(&txq->lock);
909
910 if (txq->q.read_ptr == tfd_num)
911 goto out;
912
913 IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n",
914 txq_id, txq->q.read_ptr, tfd_num, ssn);
915
916 /*Since we free until index _not_ inclusive, the one before index is
917 * the last we will free. This one must be used */
918 last_to_free = iwl_queue_dec_wrap(tfd_num, q->n_bd);
919
920 if (!iwl_queue_used(q, last_to_free)) {
921 IWL_ERR(trans,
922 "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n",
923 __func__, txq_id, last_to_free, q->n_bd,
924 q->write_ptr, q->read_ptr);
925 goto out;
926 }
927
928 if (WARN_ON(!skb_queue_empty(skbs)))
929 goto out;
930
931 for (;
932 q->read_ptr != tfd_num;
933 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
934
935 if (WARN_ON_ONCE(txq->entries[txq->q.read_ptr].skb == NULL))
936 continue;
937
938 __skb_queue_tail(skbs, txq->entries[txq->q.read_ptr].skb);
939
940 txq->entries[txq->q.read_ptr].skb = NULL;
941
942 iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
943
944 iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE);
945 }
946
947 iwl_pcie_txq_progress(trans_pcie, txq);
948
949 if (iwl_queue_space(&txq->q) > txq->q.low_mark)
950 iwl_wake_queue(trans, txq);
951out:
952 spin_unlock(&txq->lock);
953}
954
955/*
956 * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd
957 *
958 * When FW advances 'R' index, all entries between old and new 'R' index
959 * need to be reclaimed. As result, some free space forms. If there is
960 * enough free space (> low mark), wake the stack that feeds us.
961 */
962static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
963{
964 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
965 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
966 struct iwl_queue *q = &txq->q;
967 int nfreed = 0;
968
969 lockdep_assert_held(&txq->lock);
970
971 if ((idx >= q->n_bd) || (!iwl_queue_used(q, idx))) {
972 IWL_ERR(trans,
973 "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n",
974 __func__, txq_id, idx, q->n_bd,
975 q->write_ptr, q->read_ptr);
976 return;
977 }
978
979 for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
980 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
981
982 if (nfreed++ > 0) {
983 IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n",
984 idx, q->write_ptr, q->read_ptr);
985 iwl_op_mode_nic_error(trans->op_mode);
986 }
987 }
988
989 iwl_pcie_txq_progress(trans_pcie, txq);
381} 990}
382 991
383static int iwl_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, 992static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
384 u16 txq_id) 993 u16 txq_id)
385{ 994{
386 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 995 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -405,7 +1014,8 @@ static int iwl_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
405 return 0; 1014 return 0;
406} 1015}
407 1016
408static inline void iwl_txq_set_inactive(struct iwl_trans *trans, u16 txq_id) 1017static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans,
1018 u16 txq_id)
409{ 1019{
410 /* Simply stop the queue, but don't change any configuration; 1020 /* Simply stop the queue, but don't change any configuration;
411 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ 1021 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
@@ -424,7 +1034,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
424 WARN_ONCE(1, "queue %d already used - expect issues", txq_id); 1034 WARN_ONCE(1, "queue %d already used - expect issues", txq_id);
425 1035
426 /* Stop this Tx queue before configuring it */ 1036 /* Stop this Tx queue before configuring it */
427 iwl_txq_set_inactive(trans, txq_id); 1037 iwl_pcie_txq_set_inactive(trans, txq_id);
428 1038
429 /* Set this queue as a chain-building queue unless it is CMD queue */ 1039 /* Set this queue as a chain-building queue unless it is CMD queue */
430 if (txq_id != trans_pcie->cmd_queue) 1040 if (txq_id != trans_pcie->cmd_queue)
@@ -435,7 +1045,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
435 u16 ra_tid = BUILD_RAxTID(sta_id, tid); 1045 u16 ra_tid = BUILD_RAxTID(sta_id, tid);
436 1046
437 /* Map receiver-address / traffic-ID to this queue */ 1047 /* Map receiver-address / traffic-ID to this queue */
438 iwl_txq_set_ratid_map(trans, ra_tid, txq_id); 1048 iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id);
439 1049
440 /* enable aggregations for the queue */ 1050 /* enable aggregations for the queue */
441 iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); 1051 iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
@@ -489,18 +1099,20 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
489 return; 1099 return;
490 } 1100 }
491 1101
492 iwl_txq_set_inactive(trans, txq_id); 1102 iwl_pcie_txq_set_inactive(trans, txq_id);
493 1103
494 _iwl_write_targ_mem_dwords(trans, stts_addr, 1104 _iwl_write_targ_mem_dwords(trans, stts_addr,
495 zero_val, ARRAY_SIZE(zero_val)); 1105 zero_val, ARRAY_SIZE(zero_val));
496 1106
1107 iwl_pcie_txq_unmap(trans, txq_id);
1108
497 IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); 1109 IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
498} 1110}
499 1111
500/*************** HOST COMMAND QUEUE FUNCTIONS *****/ 1112/*************** HOST COMMAND QUEUE FUNCTIONS *****/
501 1113
502/** 1114/*
503 * iwl_enqueue_hcmd - enqueue a uCode command 1115 * iwl_pcie_enqueue_hcmd - enqueue a uCode command
504 * @priv: device private data point 1116 * @priv: device private data point
505 * @cmd: a point to the ucode command structure 1117 * @cmd: a point to the ucode command structure
506 * 1118 *
@@ -508,15 +1120,17 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
508 * failed. On success, it turns the index (> 0) of command in the 1120 * failed. On success, it turns the index (> 0) of command in the
509 * command queue. 1121 * command queue.
510 */ 1122 */
511static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) 1123static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1124 struct iwl_host_cmd *cmd)
512{ 1125{
513 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1126 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
514 struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; 1127 struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
515 struct iwl_queue *q = &txq->q; 1128 struct iwl_queue *q = &txq->q;
516 struct iwl_device_cmd *out_cmd; 1129 struct iwl_device_cmd *out_cmd;
517 struct iwl_cmd_meta *out_meta; 1130 struct iwl_cmd_meta *out_meta;
1131 void *dup_buf = NULL;
518 dma_addr_t phys_addr; 1132 dma_addr_t phys_addr;
519 u32 idx; 1133 int idx;
520 u16 copy_size, cmd_size; 1134 u16 copy_size, cmd_size;
521 bool had_nocopy = false; 1135 bool had_nocopy = false;
522 int i; 1136 int i;
@@ -533,10 +1147,33 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
533 continue; 1147 continue;
534 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { 1148 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
535 had_nocopy = true; 1149 had_nocopy = true;
1150 if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
1151 idx = -EINVAL;
1152 goto free_dup_buf;
1153 }
1154 } else if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) {
1155 /*
1156 * This is also a chunk that isn't copied
1157 * to the static buffer so set had_nocopy.
1158 */
1159 had_nocopy = true;
1160
1161 /* only allowed once */
1162 if (WARN_ON(dup_buf)) {
1163 idx = -EINVAL;
1164 goto free_dup_buf;
1165 }
1166
1167 dup_buf = kmemdup(cmd->data[i], cmd->len[i],
1168 GFP_ATOMIC);
1169 if (!dup_buf)
1170 return -ENOMEM;
536 } else { 1171 } else {
537 /* NOCOPY must not be followed by normal! */ 1172 /* NOCOPY must not be followed by normal! */
538 if (WARN_ON(had_nocopy)) 1173 if (WARN_ON(had_nocopy)) {
539 return -EINVAL; 1174 idx = -EINVAL;
1175 goto free_dup_buf;
1176 }
540 copy_size += cmd->len[i]; 1177 copy_size += cmd->len[i];
541 } 1178 }
542 cmd_size += cmd->len[i]; 1179 cmd_size += cmd->len[i];
@@ -550,9 +1187,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
550 */ 1187 */
551 if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE, 1188 if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE,
552 "Command %s (%#x) is too large (%d bytes)\n", 1189 "Command %s (%#x) is too large (%d bytes)\n",
553 trans_pcie_get_cmd_string(trans_pcie, cmd->id), 1190 get_cmd_string(trans_pcie, cmd->id), cmd->id, copy_size)) {
554 cmd->id, copy_size)) 1191 idx = -EINVAL;
555 return -EINVAL; 1192 goto free_dup_buf;
1193 }
556 1194
557 spin_lock_bh(&txq->lock); 1195 spin_lock_bh(&txq->lock);
558 1196
@@ -561,7 +1199,8 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
561 1199
562 IWL_ERR(trans, "No space in command queue\n"); 1200 IWL_ERR(trans, "No space in command queue\n");
563 iwl_op_mode_cmd_queue_full(trans->op_mode); 1201 iwl_op_mode_cmd_queue_full(trans->op_mode);
564 return -ENOSPC; 1202 idx = -ENOSPC;
1203 goto free_dup_buf;
565 } 1204 }
566 1205
567 idx = get_cmd_index(q, q->write_ptr); 1206 idx = get_cmd_index(q, q->write_ptr);
@@ -585,7 +1224,8 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
585 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 1224 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
586 if (!cmd->len[i]) 1225 if (!cmd->len[i])
587 continue; 1226 continue;
588 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) 1227 if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1228 IWL_HCMD_DFL_DUP))
589 break; 1229 break;
590 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); 1230 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);
591 cmd_pos += cmd->len[i]; 1231 cmd_pos += cmd->len[i];
@@ -610,7 +1250,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
610 1250
611 IWL_DEBUG_HC(trans, 1251 IWL_DEBUG_HC(trans,
612 "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", 1252 "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n",
613 trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd), 1253 get_cmd_string(trans_pcie, out_cmd->hdr.cmd),
614 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), 1254 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
615 cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); 1255 cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);
616 1256
@@ -624,28 +1264,35 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
624 dma_unmap_addr_set(out_meta, mapping, phys_addr); 1264 dma_unmap_addr_set(out_meta, mapping, phys_addr);
625 dma_unmap_len_set(out_meta, len, copy_size); 1265 dma_unmap_len_set(out_meta, len, copy_size);
626 1266
627 iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, copy_size, 1); 1267 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1);
628 1268
629 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 1269 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
1270 const void *data = cmd->data[i];
1271
630 if (!cmd->len[i]) 1272 if (!cmd->len[i])
631 continue; 1273 continue;
632 if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) 1274 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1275 IWL_HCMD_DFL_DUP)))
633 continue; 1276 continue;
634 phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], 1277 if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
1278 data = dup_buf;
1279 phys_addr = dma_map_single(trans->dev, (void *)data,
635 cmd->len[i], DMA_BIDIRECTIONAL); 1280 cmd->len[i], DMA_BIDIRECTIONAL);
636 if (dma_mapping_error(trans->dev, phys_addr)) { 1281 if (dma_mapping_error(trans->dev, phys_addr)) {
637 iwl_unmap_tfd(trans, out_meta, 1282 iwl_pcie_tfd_unmap(trans, out_meta,
638 &txq->tfds[q->write_ptr], 1283 &txq->tfds[q->write_ptr],
639 DMA_BIDIRECTIONAL); 1284 DMA_BIDIRECTIONAL);
640 idx = -ENOMEM; 1285 idx = -ENOMEM;
641 goto out; 1286 goto out;
642 } 1287 }
643 1288
644 iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, 1289 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0);
645 cmd->len[i], 0);
646 } 1290 }
647 1291
648 out_meta->flags = cmd->flags; 1292 out_meta->flags = cmd->flags;
1293 if (WARN_ON_ONCE(txq->entries[idx].free_buf))
1294 kfree(txq->entries[idx].free_buf);
1295 txq->entries[idx].free_buf = dup_buf;
649 1296
650 txq->need_update = 1; 1297 txq->need_update = 1;
651 1298
@@ -658,70 +1305,18 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
658 1305
659 /* Increment and update queue's write index */ 1306 /* Increment and update queue's write index */
660 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 1307 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
661 iwl_txq_update_write_ptr(trans, txq); 1308 iwl_pcie_txq_inc_wr_ptr(trans, txq);
662 1309
663 out: 1310 out:
664 spin_unlock_bh(&txq->lock); 1311 spin_unlock_bh(&txq->lock);
1312 free_dup_buf:
1313 if (idx < 0)
1314 kfree(dup_buf);
665 return idx; 1315 return idx;
666} 1316}
667 1317
668static inline void iwl_queue_progress(struct iwl_trans_pcie *trans_pcie, 1318/*
669 struct iwl_tx_queue *txq) 1319 * iwl_pcie_hcmd_complete - Pull unused buffers off the queue and reclaim them
670{
671 if (!trans_pcie->wd_timeout)
672 return;
673
674 /*
675 * if empty delete timer, otherwise move timer forward
676 * since we're making progress on this queue
677 */
678 if (txq->q.read_ptr == txq->q.write_ptr)
679 del_timer(&txq->stuck_timer);
680 else
681 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
682}
683
684/**
685 * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd
686 *
687 * When FW advances 'R' index, all entries between old and new 'R' index
688 * need to be reclaimed. As result, some free space forms. If there is
689 * enough free space (> low mark), wake the stack that feeds us.
690 */
691static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
692 int idx)
693{
694 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
695 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
696 struct iwl_queue *q = &txq->q;
697 int nfreed = 0;
698
699 lockdep_assert_held(&txq->lock);
700
701 if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
702 IWL_ERR(trans,
703 "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n",
704 __func__, txq_id, idx, q->n_bd,
705 q->write_ptr, q->read_ptr);
706 return;
707 }
708
709 for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
710 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
711
712 if (nfreed++ > 0) {
713 IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n",
714 idx, q->write_ptr, q->read_ptr);
715 iwl_op_mode_nic_error(trans->op_mode);
716 }
717
718 }
719
720 iwl_queue_progress(trans_pcie, txq);
721}
722
723/**
724 * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
725 * @rxb: Rx buffer to reclaim 1320 * @rxb: Rx buffer to reclaim
726 * @handler_status: return value of the handler of the command 1321 * @handler_status: return value of the handler of the command
727 * (put in setup_rx_handlers) 1322 * (put in setup_rx_handlers)
@@ -730,8 +1325,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
730 * will be executed. The attached skb (if present) will only be freed 1325 * will be executed. The attached skb (if present) will only be freed
731 * if the callback returns 1 1326 * if the callback returns 1
732 */ 1327 */
733void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, 1328void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
734 int handler_status) 1329 struct iwl_rx_cmd_buffer *rxb, int handler_status)
735{ 1330{
736 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1331 struct iwl_rx_packet *pkt = rxb_addr(rxb);
737 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 1332 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
@@ -741,7 +1336,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
741 struct iwl_device_cmd *cmd; 1336 struct iwl_device_cmd *cmd;
742 struct iwl_cmd_meta *meta; 1337 struct iwl_cmd_meta *meta;
743 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1338 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
744 struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; 1339 struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
745 1340
746 /* If a Tx command is being handled and it isn't in the actual 1341 /* If a Tx command is being handled and it isn't in the actual
747 * command queue then there a command routing bug has been introduced 1342 * command queue then there a command routing bug has been introduced
@@ -761,7 +1356,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
761 cmd = txq->entries[cmd_index].cmd; 1356 cmd = txq->entries[cmd_index].cmd;
762 meta = &txq->entries[cmd_index].meta; 1357 meta = &txq->entries[cmd_index].meta;
763 1358
764 iwl_unmap_tfd(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); 1359 iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL);
765 1360
766 /* Input error checking is done when commands are added to queue. */ 1361 /* Input error checking is done when commands are added to queue. */
767 if (meta->flags & CMD_WANT_SKB) { 1362 if (meta->flags & CMD_WANT_SKB) {
@@ -773,20 +1368,18 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
773 meta->source->handler_status = handler_status; 1368 meta->source->handler_status = handler_status;
774 } 1369 }
775 1370
776 iwl_hcmd_queue_reclaim(trans, txq_id, index); 1371 iwl_pcie_cmdq_reclaim(trans, txq_id, index);
777 1372
778 if (!(meta->flags & CMD_ASYNC)) { 1373 if (!(meta->flags & CMD_ASYNC)) {
779 if (!test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { 1374 if (!test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) {
780 IWL_WARN(trans, 1375 IWL_WARN(trans,
781 "HCMD_ACTIVE already clear for command %s\n", 1376 "HCMD_ACTIVE already clear for command %s\n",
782 trans_pcie_get_cmd_string(trans_pcie, 1377 get_cmd_string(trans_pcie, cmd->hdr.cmd));
783 cmd->hdr.cmd));
784 } 1378 }
785 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 1379 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
786 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", 1380 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
787 trans_pcie_get_cmd_string(trans_pcie, 1381 get_cmd_string(trans_pcie, cmd->hdr.cmd));
788 cmd->hdr.cmd)); 1382 wake_up(&trans_pcie->wait_command_queue);
789 wake_up(&trans->wait_command_queue);
790 } 1383 }
791 1384
792 meta->flags = 0; 1385 meta->flags = 0;
@@ -796,7 +1389,8 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
796 1389
797#define HOST_COMPLETE_TIMEOUT (2 * HZ) 1390#define HOST_COMPLETE_TIMEOUT (2 * HZ)
798 1391
799static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) 1392static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans,
1393 struct iwl_host_cmd *cmd)
800{ 1394{
801 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1395 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
802 int ret; 1396 int ret;
@@ -805,59 +1399,59 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
805 if (WARN_ON(cmd->flags & CMD_WANT_SKB)) 1399 if (WARN_ON(cmd->flags & CMD_WANT_SKB))
806 return -EINVAL; 1400 return -EINVAL;
807 1401
808 1402 ret = iwl_pcie_enqueue_hcmd(trans, cmd);
809 ret = iwl_enqueue_hcmd(trans, cmd);
810 if (ret < 0) { 1403 if (ret < 0) {
811 IWL_ERR(trans, 1404 IWL_ERR(trans,
812 "Error sending %s: enqueue_hcmd failed: %d\n", 1405 "Error sending %s: enqueue_hcmd failed: %d\n",
813 trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); 1406 get_cmd_string(trans_pcie, cmd->id), ret);
814 return ret; 1407 return ret;
815 } 1408 }
816 return 0; 1409 return 0;
817} 1410}
818 1411
819static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) 1412static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1413 struct iwl_host_cmd *cmd)
820{ 1414{
821 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1415 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
822 int cmd_idx; 1416 int cmd_idx;
823 int ret; 1417 int ret;
824 1418
825 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", 1419 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
826 trans_pcie_get_cmd_string(trans_pcie, cmd->id)); 1420 get_cmd_string(trans_pcie, cmd->id));
827 1421
828 if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, 1422 if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE,
829 &trans_pcie->status))) { 1423 &trans_pcie->status))) {
830 IWL_ERR(trans, "Command %s: a command is already active!\n", 1424 IWL_ERR(trans, "Command %s: a command is already active!\n",
831 trans_pcie_get_cmd_string(trans_pcie, cmd->id)); 1425 get_cmd_string(trans_pcie, cmd->id));
832 return -EIO; 1426 return -EIO;
833 } 1427 }
834 1428
835 IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", 1429 IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n",
836 trans_pcie_get_cmd_string(trans_pcie, cmd->id)); 1430 get_cmd_string(trans_pcie, cmd->id));
837 1431
838 cmd_idx = iwl_enqueue_hcmd(trans, cmd); 1432 cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd);
839 if (cmd_idx < 0) { 1433 if (cmd_idx < 0) {
840 ret = cmd_idx; 1434 ret = cmd_idx;
841 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 1435 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
842 IWL_ERR(trans, 1436 IWL_ERR(trans,
843 "Error sending %s: enqueue_hcmd failed: %d\n", 1437 "Error sending %s: enqueue_hcmd failed: %d\n",
844 trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); 1438 get_cmd_string(trans_pcie, cmd->id), ret);
845 return ret; 1439 return ret;
846 } 1440 }
847 1441
848 ret = wait_event_timeout(trans->wait_command_queue, 1442 ret = wait_event_timeout(trans_pcie->wait_command_queue,
849 !test_bit(STATUS_HCMD_ACTIVE, 1443 !test_bit(STATUS_HCMD_ACTIVE,
850 &trans_pcie->status), 1444 &trans_pcie->status),
851 HOST_COMPLETE_TIMEOUT); 1445 HOST_COMPLETE_TIMEOUT);
852 if (!ret) { 1446 if (!ret) {
853 if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { 1447 if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) {
854 struct iwl_tx_queue *txq = 1448 struct iwl_txq *txq =
855 &trans_pcie->txq[trans_pcie->cmd_queue]; 1449 &trans_pcie->txq[trans_pcie->cmd_queue];
856 struct iwl_queue *q = &txq->q; 1450 struct iwl_queue *q = &txq->q;
857 1451
858 IWL_ERR(trans, 1452 IWL_ERR(trans,
859 "Error sending %s: time out after %dms.\n", 1453 "Error sending %s: time out after %dms.\n",
860 trans_pcie_get_cmd_string(trans_pcie, cmd->id), 1454 get_cmd_string(trans_pcie, cmd->id),
861 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 1455 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
862 1456
863 IWL_ERR(trans, 1457 IWL_ERR(trans,
@@ -867,16 +1461,28 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
867 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 1461 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
868 IWL_DEBUG_INFO(trans, 1462 IWL_DEBUG_INFO(trans,
869 "Clearing HCMD_ACTIVE for command %s\n", 1463 "Clearing HCMD_ACTIVE for command %s\n",
870 trans_pcie_get_cmd_string(trans_pcie, 1464 get_cmd_string(trans_pcie, cmd->id));
871 cmd->id));
872 ret = -ETIMEDOUT; 1465 ret = -ETIMEDOUT;
873 goto cancel; 1466 goto cancel;
874 } 1467 }
875 } 1468 }
876 1469
1470 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) {
1471 IWL_ERR(trans, "FW error in SYNC CMD %s\n",
1472 get_cmd_string(trans_pcie, cmd->id));
1473 ret = -EIO;
1474 goto cancel;
1475 }
1476
1477 if (test_bit(STATUS_RFKILL, &trans_pcie->status)) {
1478 IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n");
1479 ret = -ERFKILL;
1480 goto cancel;
1481 }
1482
877 if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { 1483 if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) {
878 IWL_ERR(trans, "Error: Response NULL in '%s'\n", 1484 IWL_ERR(trans, "Error: Response NULL in '%s'\n",
879 trans_pcie_get_cmd_string(trans_pcie, cmd->id)); 1485 get_cmd_string(trans_pcie, cmd->id));
880 ret = -EIO; 1486 ret = -EIO;
881 goto cancel; 1487 goto cancel;
882 } 1488 }
@@ -903,64 +1509,183 @@ cancel:
903 return ret; 1509 return ret;
904} 1510}
905 1511
906int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) 1512int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
907{ 1513{
1514 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1515
1516 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
1517 return -EIO;
1518
1519 if (test_bit(STATUS_RFKILL, &trans_pcie->status))
1520 return -ERFKILL;
1521
908 if (cmd->flags & CMD_ASYNC) 1522 if (cmd->flags & CMD_ASYNC)
909 return iwl_send_cmd_async(trans, cmd); 1523 return iwl_pcie_send_hcmd_async(trans, cmd);
910 1524
911 return iwl_send_cmd_sync(trans, cmd); 1525 /* We still can fail on RFKILL that can be asserted while we wait */
1526 return iwl_pcie_send_hcmd_sync(trans, cmd);
912} 1527}
913 1528
914/* Frees buffers until index _not_ inclusive */ 1529int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
915int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, 1530 struct iwl_device_cmd *dev_cmd, int txq_id)
916 struct sk_buff_head *skbs)
917{ 1531{
918 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1532 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
919 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; 1533 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
920 struct iwl_queue *q = &txq->q; 1534 struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
921 int last_to_free; 1535 struct iwl_cmd_meta *out_meta;
922 int freed = 0; 1536 struct iwl_txq *txq;
1537 struct iwl_queue *q;
1538 dma_addr_t phys_addr = 0;
1539 dma_addr_t txcmd_phys;
1540 dma_addr_t scratch_phys;
1541 u16 len, firstlen, secondlen;
1542 u8 wait_write_ptr = 0;
1543 __le16 fc = hdr->frame_control;
1544 u8 hdr_len = ieee80211_hdrlen(fc);
1545 u16 __maybe_unused wifi_seq;
1546
1547 txq = &trans_pcie->txq[txq_id];
1548 q = &txq->q;
923 1549
924 /* This function is not meant to release cmd queue*/ 1550 if (unlikely(!test_bit(txq_id, trans_pcie->queue_used))) {
925 if (WARN_ON(txq_id == trans_pcie->cmd_queue)) 1551 WARN_ON_ONCE(1);
926 return 0; 1552 return -EINVAL;
1553 }
927 1554
928 lockdep_assert_held(&txq->lock); 1555 spin_lock(&txq->lock);
929 1556
930 /*Since we free until index _not_ inclusive, the one before index is 1557 /* In AGG mode, the index in the ring must correspond to the WiFi
931 * the last we will free. This one must be used */ 1558 * sequence number. This is a HW requirements to help the SCD to parse
932 last_to_free = iwl_queue_dec_wrap(index, q->n_bd); 1559 * the BA.
1560 * Check here that the packets are in the right place on the ring.
1561 */
1562#ifdef CONFIG_IWLWIFI_DEBUG
1563 wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
1564 WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) &&
1565 ((wifi_seq & 0xff) != q->write_ptr),
1566 "Q: %d WiFi Seq %d tfdNum %d",
1567 txq_id, wifi_seq, q->write_ptr);
1568#endif
1569
1570 /* Set up driver data for this TFD */
1571 txq->entries[q->write_ptr].skb = skb;
1572 txq->entries[q->write_ptr].cmd = dev_cmd;
1573
1574 dev_cmd->hdr.cmd = REPLY_TX;
1575 dev_cmd->hdr.sequence =
1576 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
1577 INDEX_TO_SEQ(q->write_ptr)));
1578
1579 /* Set up first empty entry in queue's array of Tx/cmd buffers */
1580 out_meta = &txq->entries[q->write_ptr].meta;
933 1581
934 if ((index >= q->n_bd) || 1582 /*
935 (iwl_queue_used(q, last_to_free) == 0)) { 1583 * Use the first empty entry in this queue's command buffer array
936 IWL_ERR(trans, 1584 * to contain the Tx command and MAC header concatenated together
937 "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", 1585 * (payload data will be in another buffer).
938 __func__, txq_id, last_to_free, q->n_bd, 1586 * Size of this varies, due to varying MAC header length.
939 q->write_ptr, q->read_ptr); 1587 * If end is not dword aligned, we'll have 2 extra bytes at the end
940 return 0; 1588 * of the MAC header (device reads on dword boundaries).
1589 * We'll tell device about this padding later.
1590 */
1591 len = sizeof(struct iwl_tx_cmd) +
1592 sizeof(struct iwl_cmd_header) + hdr_len;
1593 firstlen = (len + 3) & ~3;
1594
1595 /* Tell NIC about any 2-byte padding after MAC header */
1596 if (firstlen != len)
1597 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
1598
1599 /* Physical address of this Tx command's header (not MAC header!),
1600 * within command buffer array. */
1601 txcmd_phys = dma_map_single(trans->dev,
1602 &dev_cmd->hdr, firstlen,
1603 DMA_BIDIRECTIONAL);
1604 if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
1605 goto out_err;
1606 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
1607 dma_unmap_len_set(out_meta, len, firstlen);
1608
1609 if (!ieee80211_has_morefrags(fc)) {
1610 txq->need_update = 1;
1611 } else {
1612 wait_write_ptr = 1;
1613 txq->need_update = 0;
941 } 1614 }
942 1615
943 if (WARN_ON(!skb_queue_empty(skbs))) 1616 /* Set up TFD's 2nd entry to point directly to remainder of skb,
944 return 0; 1617 * if any (802.11 null frames have no payload). */
1618 secondlen = skb->len - hdr_len;
1619 if (secondlen > 0) {
1620 phys_addr = dma_map_single(trans->dev, skb->data + hdr_len,
1621 secondlen, DMA_TO_DEVICE);
1622 if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
1623 dma_unmap_single(trans->dev,
1624 dma_unmap_addr(out_meta, mapping),
1625 dma_unmap_len(out_meta, len),
1626 DMA_BIDIRECTIONAL);
1627 goto out_err;
1628 }
1629 }
945 1630
946 for (; 1631 /* Attach buffers to TFD */
947 q->read_ptr != index; 1632 iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1);
948 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { 1633 if (secondlen > 0)
1634 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0);
949 1635
950 if (WARN_ON_ONCE(txq->entries[txq->q.read_ptr].skb == NULL)) 1636 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
951 continue; 1637 offsetof(struct iwl_tx_cmd, scratch);
952 1638
953 __skb_queue_tail(skbs, txq->entries[txq->q.read_ptr].skb); 1639 /* take back ownership of DMA buffer to enable update */
1640 dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,
1641 DMA_BIDIRECTIONAL);
1642 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
1643 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
954 1644
955 txq->entries[txq->q.read_ptr].skb = NULL; 1645 IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n",
1646 le16_to_cpu(dev_cmd->hdr.sequence));
1647 IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
956 1648
957 iwlagn_txq_inval_byte_cnt_tbl(trans, txq); 1649 /* Set up entry for this TFD in Tx byte-count array */
1650 iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
958 1651
959 iwl_txq_free_tfd(trans, txq, DMA_TO_DEVICE); 1652 dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
960 freed++; 1653 DMA_BIDIRECTIONAL);
961 } 1654
1655 trace_iwlwifi_dev_tx(trans->dev, skb,
1656 &txq->tfds[txq->q.write_ptr],
1657 sizeof(struct iwl_tfd),
1658 &dev_cmd->hdr, firstlen,
1659 skb->data + hdr_len, secondlen);
1660 trace_iwlwifi_dev_tx_data(trans->dev, skb,
1661 skb->data + hdr_len, secondlen);
962 1662
963 iwl_queue_progress(trans_pcie, txq); 1663 /* start timer if queue currently empty */
1664 if (txq->need_update && q->read_ptr == q->write_ptr &&
1665 trans_pcie->wd_timeout)
1666 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
1667
1668 /* Tell device the write index *just past* this latest filled TFD */
1669 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
1670 iwl_pcie_txq_inc_wr_ptr(trans, txq);
964 1671
965 return freed; 1672 /*
1673 * At this point the frame is "transmitted" successfully
1674 * and we will get a TX status notification eventually,
1675 * regardless of the value of ret. "ret" only indicates
1676 * whether or not we should update the write pointer.
1677 */
1678 if (iwl_queue_space(q) < q->high_mark) {
1679 if (wait_write_ptr) {
1680 txq->need_update = 1;
1681 iwl_pcie_txq_inc_wr_ptr(trans, txq);
1682 } else {
1683 iwl_stop_queue(trans, txq);
1684 }
1685 }
1686 spin_unlock(&txq->lock);
1687 return 0;
1688out_err:
1689 spin_unlock(&txq->lock);
1690 return -1;
966} 1691}
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 1c10b542ab2..ec36868f6fc 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -436,19 +436,19 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
436 */ 436 */
437 437
438static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy, 438static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
439 struct ieee80211_channel *channel, 439 struct cfg80211_chan_def *chandef)
440 enum nl80211_channel_type channel_type)
441{ 440{
442 struct lbs_private *priv = wiphy_priv(wiphy); 441 struct lbs_private *priv = wiphy_priv(wiphy);
443 int ret = -ENOTSUPP; 442 int ret = -ENOTSUPP;
444 443
445 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", 444 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
446 channel->center_freq, channel_type); 445 chandef->chan->center_freq,
446 cfg80211_get_chandef_type(chandef));
447 447
448 if (channel_type != NL80211_CHAN_NO_HT) 448 if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
449 goto out; 449 goto out;
450 450
451 ret = lbs_set_channel(priv, channel->hw_value); 451 ret = lbs_set_channel(priv, chandef->chan->hw_value);
452 452
453 out: 453 out:
454 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 454 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
@@ -1734,7 +1734,7 @@ static void lbs_join_post(struct lbs_private *priv,
1734 /* Fake DS channel IE */ 1734 /* Fake DS channel IE */
1735 *fake++ = WLAN_EID_DS_PARAMS; 1735 *fake++ = WLAN_EID_DS_PARAMS;
1736 *fake++ = 1; 1736 *fake++ = 1;
1737 *fake++ = params->channel->hw_value; 1737 *fake++ = params->chandef.chan->hw_value;
1738 /* Fake IBSS params IE */ 1738 /* Fake IBSS params IE */
1739 *fake++ = WLAN_EID_IBSS_PARAMS; 1739 *fake++ = WLAN_EID_IBSS_PARAMS;
1740 *fake++ = 2; 1740 *fake++ = 2;
@@ -1755,7 +1755,7 @@ static void lbs_join_post(struct lbs_private *priv,
1755 lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); 1755 lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie);
1756 1756
1757 bss = cfg80211_inform_bss(priv->wdev->wiphy, 1757 bss = cfg80211_inform_bss(priv->wdev->wiphy,
1758 params->channel, 1758 params->chandef.chan,
1759 bssid, 1759 bssid,
1760 0, 1760 0,
1761 capability, 1761 capability,
@@ -1833,7 +1833,7 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
1833 cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval); 1833 cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval);
1834 cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS; 1834 cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS;
1835 cmd.bss.ds.header.len = 1; 1835 cmd.bss.ds.header.len = 1;
1836 cmd.bss.ds.channel = params->channel->hw_value; 1836 cmd.bss.ds.channel = params->chandef.chan->hw_value;
1837 cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS; 1837 cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1838 cmd.bss.ibss.header.len = 2; 1838 cmd.bss.ibss.header.len = 2;
1839 cmd.bss.ibss.atimwindow = 0; 1839 cmd.bss.ibss.atimwindow = 0;
@@ -1942,7 +1942,7 @@ static int lbs_ibss_start_new(struct lbs_private *priv,
1942 cmd.ibss.atimwindow = 0; 1942 cmd.ibss.atimwindow = 0;
1943 cmd.ds.header.id = WLAN_EID_DS_PARAMS; 1943 cmd.ds.header.id = WLAN_EID_DS_PARAMS;
1944 cmd.ds.header.len = 1; 1944 cmd.ds.header.len = 1;
1945 cmd.ds.channel = params->channel->hw_value; 1945 cmd.ds.channel = params->chandef.chan->hw_value;
1946 /* Only v8 and below support setting probe delay */ 1946 /* Only v8 and below support setting probe delay */
1947 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) 1947 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8)
1948 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); 1948 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
@@ -1987,18 +1987,18 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1987 1987
1988 lbs_deb_enter(LBS_DEB_CFG80211); 1988 lbs_deb_enter(LBS_DEB_CFG80211);
1989 1989
1990 if (!params->channel) { 1990 if (!params->chandef.chan) {
1991 ret = -ENOTSUPP; 1991 ret = -ENOTSUPP;
1992 goto out; 1992 goto out;
1993 } 1993 }
1994 1994
1995 ret = lbs_set_channel(priv, params->channel->hw_value); 1995 ret = lbs_set_channel(priv, params->chandef.chan->hw_value);
1996 if (ret) 1996 if (ret)
1997 goto out; 1997 goto out;
1998 1998
1999 /* Search if someone is beaconing. This assumes that the 1999 /* Search if someone is beaconing. This assumes that the
2000 * bss list is populated already */ 2000 * bss list is populated already */
2001 bss = cfg80211_get_bss(wiphy, params->channel, params->bssid, 2001 bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid,
2002 params->ssid, params->ssid_len, 2002 params->ssid, params->ssid_len,
2003 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); 2003 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
2004 2004
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 4cb234349fb..739309e70d8 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -588,17 +588,38 @@ static int if_sdio_prog_real(struct if_sdio_card *card,
588 size = fw->size; 588 size = fw->size;
589 589
590 while (size) { 590 while (size) {
591 ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); 591 timeout = jiffies + HZ;
592 if (ret) 592 while (1) {
593 goto release; 593 ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
594 if (ret)
595 goto release;
594 596
595 req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); 597 req_size = sdio_readb(card->func, IF_SDIO_RD_BASE,
596 if (ret) 598 &ret);
597 goto release; 599 if (ret)
600 goto release;
601
602 req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1,
603 &ret) << 8;
604 if (ret)
605 goto release;
606
607 /*
608 * For SD8688 wait until the length is not 0, 1 or 2
609 * before downloading the first FW block,
610 * since BOOT code writes the register to indicate the
611 * helper/FW download winner,
612 * the value could be 1 or 2 (Func1 or Func2).
613 */
614 if ((size != fw->size) || (req_size > 2))
615 break;
616 if (time_after(jiffies, timeout)) {
617 ret = -ETIMEDOUT;
618 goto release;
619 }
620 mdelay(1);
621 }
598 622
599 req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8;
600 if (ret)
601 goto release;
602/* 623/*
603 lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size); 624 lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size);
604*/ 625*/
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 429ca3215fd..2aa8a1aa118 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -44,9 +44,9 @@ static int radios = 2;
44module_param(radios, int, 0444); 44module_param(radios, int, 0444);
45MODULE_PARM_DESC(radios, "Number of simulated radios"); 45MODULE_PARM_DESC(radios, "Number of simulated radios");
46 46
47static bool fake_hw_scan; 47static int channels = 1;
48module_param(fake_hw_scan, bool, 0444); 48module_param(channels, int, 0444);
49MODULE_PARM_DESC(fake_hw_scan, "Install fake (no-op) hw-scan handler"); 49MODULE_PARM_DESC(channels, "Number of concurrent channels");
50 50
51/** 51/**
52 * enum hwsim_regtest - the type of regulatory tests we offer 52 * enum hwsim_regtest - the type of regulatory tests we offer
@@ -166,7 +166,9 @@ struct hwsim_vif_priv {
166static inline void hwsim_check_magic(struct ieee80211_vif *vif) 166static inline void hwsim_check_magic(struct ieee80211_vif *vif)
167{ 167{
168 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 168 struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
169 WARN_ON(vp->magic != HWSIM_VIF_MAGIC); 169 WARN(vp->magic != HWSIM_VIF_MAGIC,
170 "Invalid VIF (%p) magic %#x, %pM, %d/%d\n",
171 vif, vp->magic, vif->addr, vif->type, vif->p2p);
170} 172}
171 173
172static inline void hwsim_set_magic(struct ieee80211_vif *vif) 174static inline void hwsim_set_magic(struct ieee80211_vif *vif)
@@ -185,7 +187,7 @@ struct hwsim_sta_priv {
185 u32 magic; 187 u32 magic;
186}; 188};
187 189
188#define HWSIM_STA_MAGIC 0x6d537748 190#define HWSIM_STA_MAGIC 0x6d537749
189 191
190static inline void hwsim_check_sta_magic(struct ieee80211_sta *sta) 192static inline void hwsim_check_sta_magic(struct ieee80211_sta *sta)
191{ 193{
@@ -205,6 +207,30 @@ static inline void hwsim_clear_sta_magic(struct ieee80211_sta *sta)
205 sp->magic = 0; 207 sp->magic = 0;
206} 208}
207 209
210struct hwsim_chanctx_priv {
211 u32 magic;
212};
213
214#define HWSIM_CHANCTX_MAGIC 0x6d53774a
215
216static inline void hwsim_check_chanctx_magic(struct ieee80211_chanctx_conf *c)
217{
218 struct hwsim_chanctx_priv *cp = (void *)c->drv_priv;
219 WARN_ON(cp->magic != HWSIM_CHANCTX_MAGIC);
220}
221
222static inline void hwsim_set_chanctx_magic(struct ieee80211_chanctx_conf *c)
223{
224 struct hwsim_chanctx_priv *cp = (void *)c->drv_priv;
225 cp->magic = HWSIM_CHANCTX_MAGIC;
226}
227
228static inline void hwsim_clear_chanctx_magic(struct ieee80211_chanctx_conf *c)
229{
230 struct hwsim_chanctx_priv *cp = (void *)c->drv_priv;
231 cp->magic = 0;
232}
233
208static struct class *hwsim_class; 234static struct class *hwsim_class;
209 235
210static struct net_device *hwsim_mon; /* global monitor netdev */ 236static struct net_device *hwsim_mon; /* global monitor netdev */
@@ -299,6 +325,13 @@ struct mac80211_hwsim_data {
299 325
300 struct mac_address addresses[2]; 326 struct mac_address addresses[2];
301 327
328 struct ieee80211_channel *tmp_chan;
329 struct delayed_work roc_done;
330 struct delayed_work hw_scan;
331 struct cfg80211_scan_request *hw_scan_request;
332 struct ieee80211_vif *hw_scan_vif;
333 int scan_chan_idx;
334
302 struct ieee80211_channel *channel; 335 struct ieee80211_channel *channel;
303 unsigned long beacon_int; /* in jiffies unit */ 336 unsigned long beacon_int; /* in jiffies unit */
304 unsigned int rx_filter; 337 unsigned int rx_filter;
@@ -396,7 +429,8 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
396} 429}
397 430
398static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, 431static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
399 struct sk_buff *tx_skb) 432 struct sk_buff *tx_skb,
433 struct ieee80211_channel *chan)
400{ 434{
401 struct mac80211_hwsim_data *data = hw->priv; 435 struct mac80211_hwsim_data *data = hw->priv;
402 struct sk_buff *skb; 436 struct sk_buff *skb;
@@ -423,7 +457,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
423 hdr->rt_tsft = __mac80211_hwsim_get_tsf(data); 457 hdr->rt_tsft = __mac80211_hwsim_get_tsf(data);
424 hdr->rt_flags = 0; 458 hdr->rt_flags = 0;
425 hdr->rt_rate = txrate->bitrate / 5; 459 hdr->rt_rate = txrate->bitrate / 5;
426 hdr->rt_channel = cpu_to_le16(data->channel->center_freq); 460 hdr->rt_channel = cpu_to_le16(chan->center_freq);
427 flags = IEEE80211_CHAN_2GHZ; 461 flags = IEEE80211_CHAN_2GHZ;
428 if (txrate->flags & IEEE80211_RATE_ERP_G) 462 if (txrate->flags & IEEE80211_RATE_ERP_G)
429 flags |= IEEE80211_CHAN_OFDM; 463 flags |= IEEE80211_CHAN_OFDM;
@@ -441,9 +475,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
441} 475}
442 476
443 477
444static void mac80211_hwsim_monitor_ack(struct ieee80211_hw *hw, const u8 *addr) 478static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
479 const u8 *addr)
445{ 480{
446 struct mac80211_hwsim_data *data = hw->priv;
447 struct sk_buff *skb; 481 struct sk_buff *skb;
448 struct hwsim_radiotap_hdr *hdr; 482 struct hwsim_radiotap_hdr *hdr;
449 u16 flags; 483 u16 flags;
@@ -464,7 +498,7 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_hw *hw, const u8 *addr)
464 (1 << IEEE80211_RADIOTAP_CHANNEL)); 498 (1 << IEEE80211_RADIOTAP_CHANNEL));
465 hdr->rt_flags = 0; 499 hdr->rt_flags = 0;
466 hdr->rt_rate = 0; 500 hdr->rt_rate = 0;
467 hdr->rt_channel = cpu_to_le16(data->channel->center_freq); 501 hdr->rt_channel = cpu_to_le16(chan->center_freq);
468 flags = IEEE80211_CHAN_2GHZ; 502 flags = IEEE80211_CHAN_2GHZ;
469 hdr->rt_chbitmask = cpu_to_le16(flags); 503 hdr->rt_chbitmask = cpu_to_le16(flags);
470 504
@@ -537,6 +571,7 @@ static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
537 md.ret = false; 571 md.ret = false;
538 md.addr = addr; 572 md.addr = addr;
539 ieee80211_iterate_active_interfaces_atomic(data->hw, 573 ieee80211_iterate_active_interfaces_atomic(data->hw,
574 IEEE80211_IFACE_ITER_NORMAL,
540 mac80211_hwsim_addr_iter, 575 mac80211_hwsim_addr_iter,
541 &md); 576 &md);
542 577
@@ -556,12 +591,6 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
556 int i; 591 int i;
557 struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; 592 struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES];
558 593
559 if (data->idle) {
560 wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n");
561 dev_kfree_skb(my_skb);
562 return;
563 }
564
565 if (data->ps != PS_DISABLED) 594 if (data->ps != PS_DISABLED)
566 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); 595 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
567 /* If the queue contains MAX_QUEUE skb's drop some */ 596 /* If the queue contains MAX_QUEUE skb's drop some */
@@ -629,8 +658,38 @@ nla_put_failure:
629 printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); 658 printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
630} 659}
631 660
661static bool hwsim_chans_compat(struct ieee80211_channel *c1,
662 struct ieee80211_channel *c2)
663{
664 if (!c1 || !c2)
665 return false;
666
667 return c1->center_freq == c2->center_freq;
668}
669
670struct tx_iter_data {
671 struct ieee80211_channel *channel;
672 bool receive;
673};
674
675static void mac80211_hwsim_tx_iter(void *_data, u8 *addr,
676 struct ieee80211_vif *vif)
677{
678 struct tx_iter_data *data = _data;
679
680 if (!vif->chanctx_conf)
681 return;
682
683 if (!hwsim_chans_compat(data->channel,
684 rcu_dereference(vif->chanctx_conf)->def.chan))
685 return;
686
687 data->receive = true;
688}
689
632static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, 690static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
633 struct sk_buff *skb) 691 struct sk_buff *skb,
692 struct ieee80211_channel *chan)
634{ 693{
635 struct mac80211_hwsim_data *data = hw->priv, *data2; 694 struct mac80211_hwsim_data *data = hw->priv, *data2;
636 bool ack = false; 695 bool ack = false;
@@ -639,15 +698,10 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
639 struct ieee80211_rx_status rx_status; 698 struct ieee80211_rx_status rx_status;
640 struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); 699 struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info);
641 700
642 if (data->idle) {
643 wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n");
644 return false;
645 }
646
647 memset(&rx_status, 0, sizeof(rx_status)); 701 memset(&rx_status, 0, sizeof(rx_status));
648 rx_status.flag |= RX_FLAG_MACTIME_MPDU; 702 rx_status.flag |= RX_FLAG_MACTIME_START;
649 rx_status.freq = data->channel->center_freq; 703 rx_status.freq = chan->center_freq;
650 rx_status.band = data->channel->band; 704 rx_status.band = chan->band;
651 rx_status.rate_idx = info->control.rates[0].idx; 705 rx_status.rate_idx = info->control.rates[0].idx;
652 if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) 706 if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS)
653 rx_status.flag |= RX_FLAG_HT; 707 rx_status.flag |= RX_FLAG_HT;
@@ -673,17 +727,35 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
673 list_for_each_entry(data2, &hwsim_radios, list) { 727 list_for_each_entry(data2, &hwsim_radios, list) {
674 struct sk_buff *nskb; 728 struct sk_buff *nskb;
675 struct ieee80211_mgmt *mgmt; 729 struct ieee80211_mgmt *mgmt;
730 struct tx_iter_data tx_iter_data = {
731 .receive = false,
732 .channel = chan,
733 };
676 734
677 if (data == data2) 735 if (data == data2)
678 continue; 736 continue;
679 737
680 if (data2->idle || !data2->started || 738 if (!data2->started || (data2->idle && !data2->tmp_chan) ||
681 !hwsim_ps_rx_ok(data2, skb) || !data2->channel || 739 !hwsim_ps_rx_ok(data2, skb))
682 data->channel->center_freq != data2->channel->center_freq ||
683 !(data->group & data2->group))
684 continue; 740 continue;
685 741
686 nskb = skb_copy(skb, GFP_ATOMIC); 742 if (!(data->group & data2->group))
743 continue;
744
745 if (!hwsim_chans_compat(chan, data2->tmp_chan) &&
746 !hwsim_chans_compat(chan, data2->channel)) {
747 ieee80211_iterate_active_interfaces_atomic(
748 data2->hw, IEEE80211_IFACE_ITER_NORMAL,
749 mac80211_hwsim_tx_iter, &tx_iter_data);
750 if (!tx_iter_data.receive)
751 continue;
752 }
753
754 /*
755 * reserve some space for our vendor and the normal
756 * radiotap header, since we're copying anyway
757 */
758 nskb = skb_copy_expand(skb, 64, 0, GFP_ATOMIC);
687 if (nskb == NULL) 759 if (nskb == NULL)
688 continue; 760 continue;
689 761
@@ -701,6 +773,33 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
701 (data->tsf_offset - data2->tsf_offset) + 773 (data->tsf_offset - data2->tsf_offset) +
702 24 * 8 * 10 / txrate->bitrate); 774 24 * 8 * 10 / txrate->bitrate);
703 775
776#if 0
777 /*
778 * Don't enable this code by default as the OUI 00:00:00
779 * is registered to Xerox so we shouldn't use it here, it
780 * might find its way into pcap files.
781 * Note that this code requires the headroom in the SKB
782 * that was allocated earlier.
783 */
784 rx_status.vendor_radiotap_oui[0] = 0x00;
785 rx_status.vendor_radiotap_oui[1] = 0x00;
786 rx_status.vendor_radiotap_oui[2] = 0x00;
787 rx_status.vendor_radiotap_subns = 127;
788 /*
789 * Radiotap vendor namespaces can (and should) also be
790 * split into fields by using the standard radiotap
791 * presence bitmap mechanism. Use just BIT(0) here for
792 * the presence bitmap.
793 */
794 rx_status.vendor_radiotap_bitmap = BIT(0);
795 /* We have 8 bytes of (dummy) data */
796 rx_status.vendor_radiotap_len = 8;
797 /* For testing, also require it to be aligned */
798 rx_status.vendor_radiotap_align = 8;
799 /* push the data */
800 memcpy(skb_push(nskb, 8), "ABCDEFGH", 8);
801#endif
802
704 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); 803 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
705 ieee80211_rx_irqsafe(data2->hw, nskb); 804 ieee80211_rx_irqsafe(data2->hw, nskb);
706 } 805 }
@@ -713,18 +812,51 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
713 struct ieee80211_tx_control *control, 812 struct ieee80211_tx_control *control,
714 struct sk_buff *skb) 813 struct sk_buff *skb)
715{ 814{
815 struct mac80211_hwsim_data *data = hw->priv;
816 struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);
817 struct ieee80211_chanctx_conf *chanctx_conf;
818 struct ieee80211_channel *channel;
716 bool ack; 819 bool ack;
717 struct ieee80211_tx_info *txi;
718 u32 _portid; 820 u32 _portid;
719 821
720 mac80211_hwsim_monitor_rx(hw, skb); 822 if (WARN_ON(skb->len < 10)) {
721
722 if (skb->len < 10) {
723 /* Should not happen; just a sanity check for addr1 use */ 823 /* Should not happen; just a sanity check for addr1 use */
724 dev_kfree_skb(skb); 824 dev_kfree_skb(skb);
725 return; 825 return;
726 } 826 }
727 827
828 if (channels == 1) {
829 channel = data->channel;
830 } else if (txi->hw_queue == 4) {
831 channel = data->tmp_chan;
832 } else {
833 chanctx_conf = rcu_dereference(txi->control.vif->chanctx_conf);
834 if (chanctx_conf)
835 channel = chanctx_conf->def.chan;
836 else
837 channel = NULL;
838 }
839
840 if (WARN(!channel, "TX w/o channel - queue = %d\n", txi->hw_queue)) {
841 dev_kfree_skb(skb);
842 return;
843 }
844
845 if (data->idle && !data->tmp_chan) {
846 wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n");
847 dev_kfree_skb(skb);
848 return;
849 }
850
851 if (txi->control.vif)
852 hwsim_check_magic(txi->control.vif);
853 if (control->sta)
854 hwsim_check_sta_magic(control->sta);
855
856 txi->rate_driver_data[0] = channel;
857
858 mac80211_hwsim_monitor_rx(hw, skb, channel);
859
728 /* wmediumd mode check */ 860 /* wmediumd mode check */
729 _portid = ACCESS_ONCE(wmediumd_portid); 861 _portid = ACCESS_ONCE(wmediumd_portid);
730 862
@@ -732,15 +864,13 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
732 return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); 864 return mac80211_hwsim_tx_frame_nl(hw, skb, _portid);
733 865
734 /* NO wmediumd detected, perfect medium simulation */ 866 /* NO wmediumd detected, perfect medium simulation */
735 ack = mac80211_hwsim_tx_frame_no_nl(hw, skb); 867 ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel);
736 868
737 if (ack && skb->len >= 16) { 869 if (ack && skb->len >= 16) {
738 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 870 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
739 mac80211_hwsim_monitor_ack(hw, hdr->addr2); 871 mac80211_hwsim_monitor_ack(channel, hdr->addr2);
740 } 872 }
741 873
742 txi = IEEE80211_SKB_CB(skb);
743
744 ieee80211_tx_info_clear_status(txi); 874 ieee80211_tx_info_clear_status(txi);
745 875
746 /* frame was transmitted at most favorable rate at first attempt */ 876 /* frame was transmitted at most favorable rate at first attempt */
@@ -778,6 +908,13 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
778 __func__, ieee80211_vif_type_p2p(vif), 908 __func__, ieee80211_vif_type_p2p(vif),
779 vif->addr); 909 vif->addr);
780 hwsim_set_magic(vif); 910 hwsim_set_magic(vif);
911
912 vif->cab_queue = 0;
913 vif->hw_queue[IEEE80211_AC_VO] = 0;
914 vif->hw_queue[IEEE80211_AC_VI] = 1;
915 vif->hw_queue[IEEE80211_AC_BE] = 2;
916 vif->hw_queue[IEEE80211_AC_BK] = 3;
917
781 return 0; 918 return 0;
782} 919}
783 920
@@ -807,14 +944,26 @@ static void mac80211_hwsim_remove_interface(
807 hwsim_clear_magic(vif); 944 hwsim_clear_magic(vif);
808} 945}
809 946
947static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
948 struct sk_buff *skb,
949 struct ieee80211_channel *chan)
950{
951 u32 _pid = ACCESS_ONCE(wmediumd_portid);
952
953 mac80211_hwsim_monitor_rx(hw, skb, chan);
954
955 if (_pid)
956 return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
957
958 mac80211_hwsim_tx_frame_no_nl(hw, skb, chan);
959 dev_kfree_skb(skb);
960}
810 961
811static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, 962static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
812 struct ieee80211_vif *vif) 963 struct ieee80211_vif *vif)
813{ 964{
814 struct ieee80211_hw *hw = arg; 965 struct ieee80211_hw *hw = arg;
815 struct sk_buff *skb; 966 struct sk_buff *skb;
816 struct ieee80211_tx_info *info;
817 u32 _portid;
818 967
819 hwsim_check_magic(vif); 968 hwsim_check_magic(vif);
820 969
@@ -826,18 +975,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
826 skb = ieee80211_beacon_get(hw, vif); 975 skb = ieee80211_beacon_get(hw, vif);
827 if (skb == NULL) 976 if (skb == NULL)
828 return; 977 return;
829 info = IEEE80211_SKB_CB(skb);
830
831 mac80211_hwsim_monitor_rx(hw, skb);
832
833 /* wmediumd mode check */
834 _portid = ACCESS_ONCE(wmediumd_portid);
835
836 if (_portid)
837 return mac80211_hwsim_tx_frame_nl(hw, skb, _portid);
838 978
839 mac80211_hwsim_tx_frame_no_nl(hw, skb); 979 mac80211_hwsim_tx_frame(hw, skb,
840 dev_kfree_skb(skb); 980 rcu_dereference(vif->chanctx_conf)->def.chan);
841} 981}
842 982
843 983
@@ -850,7 +990,8 @@ static void mac80211_hwsim_beacon(unsigned long arg)
850 return; 990 return;
851 991
852 ieee80211_iterate_active_interfaces_atomic( 992 ieee80211_iterate_active_interfaces_atomic(
853 hw, mac80211_hwsim_beacon_tx, hw); 993 hw, IEEE80211_IFACE_ITER_NORMAL,
994 mac80211_hwsim_beacon_tx, hw);
854 995
855 data->beacon_timer.expires = jiffies + data->beacon_int; 996 data->beacon_timer.expires = jiffies + data->beacon_int;
856 add_timer(&data->beacon_timer); 997 add_timer(&data->beacon_timer);
@@ -877,7 +1018,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
877 wiphy_debug(hw->wiphy, 1018 wiphy_debug(hw->wiphy,
878 "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", 1019 "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
879 __func__, 1020 __func__,
880 conf->channel->center_freq, 1021 conf->channel ? conf->channel->center_freq : 0,
881 hwsim_chantypes[conf->channel_type], 1022 hwsim_chantypes[conf->channel_type],
882 !!(conf->flags & IEEE80211_CONF_IDLE), 1023 !!(conf->flags & IEEE80211_CONF_IDLE),
883 !!(conf->flags & IEEE80211_CONF_PS), 1024 !!(conf->flags & IEEE80211_CONF_PS),
@@ -886,6 +1027,9 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
886 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); 1027 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
887 1028
888 data->channel = conf->channel; 1029 data->channel = conf->channel;
1030
1031 WARN_ON(data->channel && channels > 1);
1032
889 data->power_level = conf->power_level; 1033 data->power_level = conf->power_level;
890 if (!data->started || !data->beacon_int) 1034 if (!data->started || !data->beacon_int)
891 del_timer(&data->beacon_timer); 1035 del_timer(&data->beacon_timer);
@@ -963,15 +1107,17 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
963 } 1107 }
964 1108
965 if (changed & BSS_CHANGED_HT) { 1109 if (changed & BSS_CHANGED_HT) {
966 wiphy_debug(hw->wiphy, " HT: op_mode=0x%x, chantype=%s\n", 1110 wiphy_debug(hw->wiphy, " HT: op_mode=0x%x\n",
967 info->ht_operation_mode, 1111 info->ht_operation_mode);
968 hwsim_chantypes[info->channel_type]);
969 } 1112 }
970 1113
971 if (changed & BSS_CHANGED_BASIC_RATES) { 1114 if (changed & BSS_CHANGED_BASIC_RATES) {
972 wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n", 1115 wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n",
973 (unsigned long long) info->basic_rates); 1116 (unsigned long long) info->basic_rates);
974 } 1117 }
1118
1119 if (changed & BSS_CHANGED_TXPOWER)
1120 wiphy_debug(hw->wiphy, " TX Power: %d dBm\n", info->txpower);
975} 1121}
976 1122
977static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw, 1123static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,
@@ -1166,45 +1312,96 @@ static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop)
1166 /* Not implemented, queues only on kernel side */ 1312 /* Not implemented, queues only on kernel side */
1167} 1313}
1168 1314
1169struct hw_scan_done { 1315static void hw_scan_work(struct work_struct *work)
1170 struct delayed_work w;
1171 struct ieee80211_hw *hw;
1172};
1173
1174static void hw_scan_done(struct work_struct *work)
1175{ 1316{
1176 struct hw_scan_done *hsd = 1317 struct mac80211_hwsim_data *hwsim =
1177 container_of(work, struct hw_scan_done, w.work); 1318 container_of(work, struct mac80211_hwsim_data, hw_scan.work);
1319 struct cfg80211_scan_request *req = hwsim->hw_scan_request;
1320 int dwell, i;
1321
1322 mutex_lock(&hwsim->mutex);
1323 if (hwsim->scan_chan_idx >= req->n_channels) {
1324 wiphy_debug(hwsim->hw->wiphy, "hw scan complete\n");
1325 ieee80211_scan_completed(hwsim->hw, false);
1326 hwsim->hw_scan_request = NULL;
1327 hwsim->hw_scan_vif = NULL;
1328 hwsim->tmp_chan = NULL;
1329 mutex_unlock(&hwsim->mutex);
1330 return;
1331 }
1178 1332
1179 ieee80211_scan_completed(hsd->hw, false); 1333 wiphy_debug(hwsim->hw->wiphy, "hw scan %d MHz\n",
1180 kfree(hsd); 1334 req->channels[hwsim->scan_chan_idx]->center_freq);
1335
1336 hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx];
1337 if (hwsim->tmp_chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
1338 !req->n_ssids) {
1339 dwell = 120;
1340 } else {
1341 dwell = 30;
1342 /* send probes */
1343 for (i = 0; i < req->n_ssids; i++) {
1344 struct sk_buff *probe;
1345
1346 probe = ieee80211_probereq_get(hwsim->hw,
1347 hwsim->hw_scan_vif,
1348 req->ssids[i].ssid,
1349 req->ssids[i].ssid_len,
1350 req->ie, req->ie_len);
1351 if (!probe)
1352 continue;
1353 local_bh_disable();
1354 mac80211_hwsim_tx_frame(hwsim->hw, probe,
1355 hwsim->tmp_chan);
1356 local_bh_enable();
1357 }
1358 }
1359 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan,
1360 msecs_to_jiffies(dwell));
1361 hwsim->scan_chan_idx++;
1362 mutex_unlock(&hwsim->mutex);
1181} 1363}
1182 1364
1183static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, 1365static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
1184 struct ieee80211_vif *vif, 1366 struct ieee80211_vif *vif,
1185 struct cfg80211_scan_request *req) 1367 struct cfg80211_scan_request *req)
1186{ 1368{
1187 struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL); 1369 struct mac80211_hwsim_data *hwsim = hw->priv;
1188 int i;
1189
1190 if (!hsd)
1191 return -ENOMEM;
1192 1370
1193 hsd->hw = hw; 1371 mutex_lock(&hwsim->mutex);
1194 INIT_DELAYED_WORK(&hsd->w, hw_scan_done); 1372 if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) {
1373 mutex_unlock(&hwsim->mutex);
1374 return -EBUSY;
1375 }
1376 hwsim->hw_scan_request = req;
1377 hwsim->hw_scan_vif = vif;
1378 hwsim->scan_chan_idx = 0;
1379 mutex_unlock(&hwsim->mutex);
1195 1380
1196 printk(KERN_DEBUG "hwsim hw_scan request\n"); 1381 wiphy_debug(hw->wiphy, "hwsim hw_scan request\n");
1197 for (i = 0; i < req->n_channels; i++)
1198 printk(KERN_DEBUG "hwsim hw_scan freq %d\n",
1199 req->channels[i]->center_freq);
1200 print_hex_dump(KERN_DEBUG, "scan IEs: ", DUMP_PREFIX_OFFSET,
1201 16, 1, req->ie, req->ie_len, 1);
1202 1382
1203 ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ); 1383 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0);
1204 1384
1205 return 0; 1385 return 0;
1206} 1386}
1207 1387
1388static void mac80211_hwsim_cancel_hw_scan(struct ieee80211_hw *hw,
1389 struct ieee80211_vif *vif)
1390{
1391 struct mac80211_hwsim_data *hwsim = hw->priv;
1392
1393 wiphy_debug(hw->wiphy, "hwsim cancel_hw_scan\n");
1394
1395 cancel_delayed_work_sync(&hwsim->hw_scan);
1396
1397 mutex_lock(&hwsim->mutex);
1398 ieee80211_scan_completed(hwsim->hw, true);
1399 hwsim->tmp_chan = NULL;
1400 hwsim->hw_scan_request = NULL;
1401 hwsim->hw_scan_vif = NULL;
1402 mutex_unlock(&hwsim->mutex);
1403}
1404
1208static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw) 1405static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw)
1209{ 1406{
1210 struct mac80211_hwsim_data *hwsim = hw->priv; 1407 struct mac80211_hwsim_data *hwsim = hw->priv;
@@ -1235,6 +1432,111 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw)
1235 mutex_unlock(&hwsim->mutex); 1432 mutex_unlock(&hwsim->mutex);
1236} 1433}
1237 1434
1435static void hw_roc_done(struct work_struct *work)
1436{
1437 struct mac80211_hwsim_data *hwsim =
1438 container_of(work, struct mac80211_hwsim_data, roc_done.work);
1439
1440 mutex_lock(&hwsim->mutex);
1441 ieee80211_remain_on_channel_expired(hwsim->hw);
1442 hwsim->tmp_chan = NULL;
1443 mutex_unlock(&hwsim->mutex);
1444
1445 wiphy_debug(hwsim->hw->wiphy, "hwsim ROC expired\n");
1446}
1447
1448static int mac80211_hwsim_roc(struct ieee80211_hw *hw,
1449 struct ieee80211_vif *vif,
1450 struct ieee80211_channel *chan,
1451 int duration)
1452{
1453 struct mac80211_hwsim_data *hwsim = hw->priv;
1454
1455 mutex_lock(&hwsim->mutex);
1456 if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) {
1457 mutex_unlock(&hwsim->mutex);
1458 return -EBUSY;
1459 }
1460
1461 hwsim->tmp_chan = chan;
1462 mutex_unlock(&hwsim->mutex);
1463
1464 wiphy_debug(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n",
1465 chan->center_freq, duration);
1466
1467 ieee80211_ready_on_channel(hw);
1468
1469 ieee80211_queue_delayed_work(hw, &hwsim->roc_done,
1470 msecs_to_jiffies(duration));
1471 return 0;
1472}
1473
1474static int mac80211_hwsim_croc(struct ieee80211_hw *hw)
1475{
1476 struct mac80211_hwsim_data *hwsim = hw->priv;
1477
1478 cancel_delayed_work_sync(&hwsim->roc_done);
1479
1480 mutex_lock(&hwsim->mutex);
1481 hwsim->tmp_chan = NULL;
1482 mutex_unlock(&hwsim->mutex);
1483
1484 wiphy_debug(hw->wiphy, "hwsim ROC canceled\n");
1485
1486 return 0;
1487}
1488
1489static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
1490 struct ieee80211_chanctx_conf *ctx)
1491{
1492 hwsim_set_chanctx_magic(ctx);
1493 wiphy_debug(hw->wiphy,
1494 "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
1495 ctx->def.chan->center_freq, ctx->def.width,
1496 ctx->def.center_freq1, ctx->def.center_freq2);
1497 return 0;
1498}
1499
1500static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
1501 struct ieee80211_chanctx_conf *ctx)
1502{
1503 wiphy_debug(hw->wiphy,
1504 "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
1505 ctx->def.chan->center_freq, ctx->def.width,
1506 ctx->def.center_freq1, ctx->def.center_freq2);
1507 hwsim_check_chanctx_magic(ctx);
1508 hwsim_clear_chanctx_magic(ctx);
1509}
1510
1511static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw,
1512 struct ieee80211_chanctx_conf *ctx,
1513 u32 changed)
1514{
1515 hwsim_check_chanctx_magic(ctx);
1516 wiphy_debug(hw->wiphy,
1517 "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
1518 ctx->def.chan->center_freq, ctx->def.width,
1519 ctx->def.center_freq1, ctx->def.center_freq2);
1520}
1521
1522static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw,
1523 struct ieee80211_vif *vif,
1524 struct ieee80211_chanctx_conf *ctx)
1525{
1526 hwsim_check_magic(vif);
1527 hwsim_check_chanctx_magic(ctx);
1528
1529 return 0;
1530}
1531
1532static void mac80211_hwsim_unassign_vif_chanctx(struct ieee80211_hw *hw,
1533 struct ieee80211_vif *vif,
1534 struct ieee80211_chanctx_conf *ctx)
1535{
1536 hwsim_check_magic(vif);
1537 hwsim_check_chanctx_magic(ctx);
1538}
1539
1238static struct ieee80211_ops mac80211_hwsim_ops = 1540static struct ieee80211_ops mac80211_hwsim_ops =
1239{ 1541{
1240 .tx = mac80211_hwsim_tx, 1542 .tx = mac80211_hwsim_tx,
@@ -1315,7 +1617,6 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
1315 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 1617 struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
1316 struct sk_buff *skb; 1618 struct sk_buff *skb;
1317 struct ieee80211_pspoll *pspoll; 1619 struct ieee80211_pspoll *pspoll;
1318 u32 _portid;
1319 1620
1320 if (!vp->assoc) 1621 if (!vp->assoc)
1321 return; 1622 return;
@@ -1335,25 +1636,18 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
1335 memcpy(pspoll->bssid, vp->bssid, ETH_ALEN); 1636 memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
1336 memcpy(pspoll->ta, mac, ETH_ALEN); 1637 memcpy(pspoll->ta, mac, ETH_ALEN);
1337 1638
1338 /* wmediumd mode check */ 1639 rcu_read_lock();
1339 _portid = ACCESS_ONCE(wmediumd_portid); 1640 mac80211_hwsim_tx_frame(data->hw, skb,
1340 1641 rcu_dereference(vif->chanctx_conf)->def.chan);
1341 if (_portid) 1642 rcu_read_unlock();
1342 return mac80211_hwsim_tx_frame_nl(data->hw, skb, _portid);
1343
1344 if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb))
1345 printk(KERN_DEBUG "%s: PS-poll frame not ack'ed\n", __func__);
1346 dev_kfree_skb(skb);
1347} 1643}
1348 1644
1349
1350static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, 1645static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
1351 struct ieee80211_vif *vif, int ps) 1646 struct ieee80211_vif *vif, int ps)
1352{ 1647{
1353 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 1648 struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
1354 struct sk_buff *skb; 1649 struct sk_buff *skb;
1355 struct ieee80211_hdr *hdr; 1650 struct ieee80211_hdr *hdr;
1356 u32 _portid;
1357 1651
1358 if (!vp->assoc) 1652 if (!vp->assoc)
1359 return; 1653 return;
@@ -1374,15 +1668,10 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
1374 memcpy(hdr->addr2, mac, ETH_ALEN); 1668 memcpy(hdr->addr2, mac, ETH_ALEN);
1375 memcpy(hdr->addr3, vp->bssid, ETH_ALEN); 1669 memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
1376 1670
1377 /* wmediumd mode check */ 1671 rcu_read_lock();
1378 _portid = ACCESS_ONCE(wmediumd_portid); 1672 mac80211_hwsim_tx_frame(data->hw, skb,
1379 1673 rcu_dereference(vif->chanctx_conf)->def.chan);
1380 if (_portid) 1674 rcu_read_unlock();
1381 return mac80211_hwsim_tx_frame_nl(data->hw, skb, _portid);
1382
1383 if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb))
1384 printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__);
1385 dev_kfree_skb(skb);
1386} 1675}
1387 1676
1388 1677
@@ -1423,14 +1712,17 @@ static int hwsim_fops_ps_write(void *dat, u64 val)
1423 1712
1424 if (val == PS_MANUAL_POLL) { 1713 if (val == PS_MANUAL_POLL) {
1425 ieee80211_iterate_active_interfaces(data->hw, 1714 ieee80211_iterate_active_interfaces(data->hw,
1715 IEEE80211_IFACE_ITER_NORMAL,
1426 hwsim_send_ps_poll, data); 1716 hwsim_send_ps_poll, data);
1427 data->ps_poll_pending = true; 1717 data->ps_poll_pending = true;
1428 } else if (old_ps == PS_DISABLED && val != PS_DISABLED) { 1718 } else if (old_ps == PS_DISABLED && val != PS_DISABLED) {
1429 ieee80211_iterate_active_interfaces(data->hw, 1719 ieee80211_iterate_active_interfaces(data->hw,
1720 IEEE80211_IFACE_ITER_NORMAL,
1430 hwsim_send_nullfunc_ps, 1721 hwsim_send_nullfunc_ps,
1431 data); 1722 data);
1432 } else if (old_ps != PS_DISABLED && val == PS_DISABLED) { 1723 } else if (old_ps != PS_DISABLED && val == PS_DISABLED) {
1433 ieee80211_iterate_active_interfaces(data->hw, 1724 ieee80211_iterate_active_interfaces(data->hw,
1725 IEEE80211_IFACE_ITER_NORMAL,
1434 hwsim_send_nullfunc_no_ps, 1726 hwsim_send_nullfunc_no_ps,
1435 data); 1727 data);
1436 } 1728 }
@@ -1551,7 +1843,8 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
1551 (hwsim_flags & HWSIM_TX_STAT_ACK)) { 1843 (hwsim_flags & HWSIM_TX_STAT_ACK)) {
1552 if (skb->len >= 16) { 1844 if (skb->len >= 16) {
1553 hdr = (struct ieee80211_hdr *) skb->data; 1845 hdr = (struct ieee80211_hdr *) skb->data;
1554 mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2); 1846 mac80211_hwsim_monitor_ack(txi->rate_driver_data[0],
1847 hdr->addr2);
1555 } 1848 }
1556 txi->flags |= IEEE80211_TX_STAT_ACK; 1849 txi->flags |= IEEE80211_TX_STAT_ACK;
1557 } 1850 }
@@ -1566,7 +1859,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
1566 struct genl_info *info) 1859 struct genl_info *info)
1567{ 1860{
1568 1861
1569 struct mac80211_hwsim_data *data2; 1862 struct mac80211_hwsim_data *data2;
1570 struct ieee80211_rx_status rx_status; 1863 struct ieee80211_rx_status rx_status;
1571 struct mac_address *dst; 1864 struct mac_address *dst;
1572 int frame_data_len; 1865 int frame_data_len;
@@ -1574,9 +1867,9 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
1574 struct sk_buff *skb = NULL; 1867 struct sk_buff *skb = NULL;
1575 1868
1576 if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] || 1869 if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
1577 !info->attrs[HWSIM_ATTR_FRAME] || 1870 !info->attrs[HWSIM_ATTR_FRAME] ||
1578 !info->attrs[HWSIM_ATTR_RX_RATE] || 1871 !info->attrs[HWSIM_ATTR_RX_RATE] ||
1579 !info->attrs[HWSIM_ATTR_SIGNAL]) 1872 !info->attrs[HWSIM_ATTR_SIGNAL])
1580 goto out; 1873 goto out;
1581 1874
1582 dst = (struct mac_address *)nla_data( 1875 dst = (struct mac_address *)nla_data(
@@ -1604,7 +1897,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
1604 1897
1605 /* check if radio is configured properly */ 1898 /* check if radio is configured properly */
1606 1899
1607 if (data2->idle || !data2->started || !data2->channel) 1900 if (data2->idle || !data2->started)
1608 goto out; 1901 goto out;
1609 1902
1610 /*A frame is received from user space*/ 1903 /*A frame is received from user space*/
@@ -1688,6 +1981,11 @@ static struct notifier_block hwsim_netlink_notifier = {
1688static int hwsim_init_netlink(void) 1981static int hwsim_init_netlink(void)
1689{ 1982{
1690 int rc; 1983 int rc;
1984
1985 /* userspace test API hasn't been adjusted for multi-channel */
1986 if (channels > 1)
1987 return 0;
1988
1691 printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); 1989 printk(KERN_INFO "mac80211_hwsim: initializing netlink\n");
1692 1990
1693 rc = genl_register_family_with_ops(&hwsim_genl_family, 1991 rc = genl_register_family_with_ops(&hwsim_genl_family,
@@ -1710,6 +2008,10 @@ static void hwsim_exit_netlink(void)
1710{ 2008{
1711 int ret; 2009 int ret;
1712 2010
2011 /* userspace test API hasn't been adjusted for multi-channel */
2012 if (channels > 1)
2013 return;
2014
1713 printk(KERN_INFO "mac80211_hwsim: closing netlink\n"); 2015 printk(KERN_INFO "mac80211_hwsim: closing netlink\n");
1714 /* unregister the notifier */ 2016 /* unregister the notifier */
1715 netlink_unregister_notifier(&hwsim_netlink_notifier); 2017 netlink_unregister_notifier(&hwsim_netlink_notifier);
@@ -1732,7 +2034,7 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = {
1732 { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }, 2034 { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
1733}; 2035};
1734 2036
1735static const struct ieee80211_iface_combination hwsim_if_comb = { 2037static struct ieee80211_iface_combination hwsim_if_comb = {
1736 .limits = hwsim_if_limits, 2038 .limits = hwsim_if_limits,
1737 .n_limits = ARRAY_SIZE(hwsim_if_limits), 2039 .n_limits = ARRAY_SIZE(hwsim_if_limits),
1738 .max_interfaces = 2048, 2040 .max_interfaces = 2048,
@@ -1750,10 +2052,30 @@ static int __init init_mac80211_hwsim(void)
1750 if (radios < 1 || radios > 100) 2052 if (radios < 1 || radios > 100)
1751 return -EINVAL; 2053 return -EINVAL;
1752 2054
1753 if (fake_hw_scan) { 2055 if (channels < 1)
2056 return -EINVAL;
2057
2058 if (channels > 1) {
2059 hwsim_if_comb.num_different_channels = channels;
1754 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan; 2060 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan;
2061 mac80211_hwsim_ops.cancel_hw_scan =
2062 mac80211_hwsim_cancel_hw_scan;
1755 mac80211_hwsim_ops.sw_scan_start = NULL; 2063 mac80211_hwsim_ops.sw_scan_start = NULL;
1756 mac80211_hwsim_ops.sw_scan_complete = NULL; 2064 mac80211_hwsim_ops.sw_scan_complete = NULL;
2065 mac80211_hwsim_ops.remain_on_channel =
2066 mac80211_hwsim_roc;
2067 mac80211_hwsim_ops.cancel_remain_on_channel =
2068 mac80211_hwsim_croc;
2069 mac80211_hwsim_ops.add_chanctx =
2070 mac80211_hwsim_add_chanctx;
2071 mac80211_hwsim_ops.remove_chanctx =
2072 mac80211_hwsim_remove_chanctx;
2073 mac80211_hwsim_ops.change_chanctx =
2074 mac80211_hwsim_change_chanctx;
2075 mac80211_hwsim_ops.assign_vif_chanctx =
2076 mac80211_hwsim_assign_vif_chanctx;
2077 mac80211_hwsim_ops.unassign_vif_chanctx =
2078 mac80211_hwsim_unassign_vif_chanctx;
1757 } 2079 }
1758 2080
1759 spin_lock_init(&hwsim_radio_lock); 2081 spin_lock_init(&hwsim_radio_lock);
@@ -1803,13 +2125,18 @@ static int __init init_mac80211_hwsim(void)
1803 hw->wiphy->iface_combinations = &hwsim_if_comb; 2125 hw->wiphy->iface_combinations = &hwsim_if_comb;
1804 hw->wiphy->n_iface_combinations = 1; 2126 hw->wiphy->n_iface_combinations = 1;
1805 2127
1806 if (fake_hw_scan) { 2128 if (channels > 1) {
1807 hw->wiphy->max_scan_ssids = 255; 2129 hw->wiphy->max_scan_ssids = 255;
1808 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; 2130 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
2131 hw->wiphy->max_remain_on_channel_duration = 1000;
1809 } 2132 }
1810 2133
2134 INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
2135 INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work);
2136
1811 hw->channel_change_time = 1; 2137 hw->channel_change_time = 1;
1812 hw->queues = 4; 2138 hw->queues = 5;
2139 hw->offchannel_tx_hw_queue = 4;
1813 hw->wiphy->interface_modes = 2140 hw->wiphy->interface_modes =
1814 BIT(NL80211_IFTYPE_STATION) | 2141 BIT(NL80211_IFTYPE_STATION) |
1815 BIT(NL80211_IFTYPE_AP) | 2142 BIT(NL80211_IFTYPE_AP) |
@@ -1824,7 +2151,8 @@ static int __init init_mac80211_hwsim(void)
1824 IEEE80211_HW_SUPPORTS_STATIC_SMPS | 2151 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
1825 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 2152 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
1826 IEEE80211_HW_AMPDU_AGGREGATION | 2153 IEEE80211_HW_AMPDU_AGGREGATION |
1827 IEEE80211_HW_WANT_MONITOR_VIF; 2154 IEEE80211_HW_WANT_MONITOR_VIF |
2155 IEEE80211_HW_QUEUE_CONTROL;
1828 2156
1829 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | 2157 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
1830 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 2158 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
@@ -1874,6 +2202,34 @@ static int __init init_mac80211_hwsim(void)
1874 sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 2202 sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1875 2203
1876 hw->wiphy->bands[band] = sband; 2204 hw->wiphy->bands[band] = sband;
2205
2206 if (channels == 1)
2207 continue;
2208
2209 sband->vht_cap.vht_supported = true;
2210 sband->vht_cap.cap =
2211 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
2212 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
2213 IEEE80211_VHT_CAP_RXLDPC |
2214 IEEE80211_VHT_CAP_SHORT_GI_80 |
2215 IEEE80211_VHT_CAP_SHORT_GI_160 |
2216 IEEE80211_VHT_CAP_TXSTBC |
2217 IEEE80211_VHT_CAP_RXSTBC_1 |
2218 IEEE80211_VHT_CAP_RXSTBC_2 |
2219 IEEE80211_VHT_CAP_RXSTBC_3 |
2220 IEEE80211_VHT_CAP_RXSTBC_4 |
2221 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT;
2222 sband->vht_cap.vht_mcs.rx_mcs_map =
2223 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 |
2224 IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 |
2225 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 |
2226 IEEE80211_VHT_MCS_SUPPORT_0_8 << 6 |
2227 IEEE80211_VHT_MCS_SUPPORT_0_8 << 8 |
2228 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 |
2229 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 |
2230 IEEE80211_VHT_MCS_SUPPORT_0_8 << 14);
2231 sband->vht_cap.vht_mcs.tx_mcs_map =
2232 sband->vht_cap.vht_mcs.rx_mcs_map;
1877 } 2233 }
1878 /* By default all radios are belonging to the first group */ 2234 /* By default all radios are belonging to the first group */
1879 data->group = 1; 2235 data->group = 1;
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 395f1bfd410..68d52cfc1eb 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -197,7 +197,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
197 ra_list_flags); 197 ra_list_flags);
198 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); 198 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
199 199
200 mwifiex_write_data_complete(adapter, skb_src, 0); 200 mwifiex_write_data_complete(adapter, skb_src, 0, 0);
201 201
202 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); 202 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
203 203
@@ -256,7 +256,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
256 if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) { 256 if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
257 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 257 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
258 ra_list_flags); 258 ra_list_flags);
259 mwifiex_write_data_complete(adapter, skb_aggr, -1); 259 mwifiex_write_data_complete(adapter, skb_aggr, 1, -1);
260 return -1; 260 return -1;
261 } 261 }
262 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && 262 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA &&
@@ -282,13 +282,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
282 dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", 282 dev_err(adapter->dev, "%s: host_to_card failed: %#x\n",
283 __func__, ret); 283 __func__, ret);
284 adapter->dbg.num_tx_host_to_card_failure++; 284 adapter->dbg.num_tx_host_to_card_failure++;
285 mwifiex_write_data_complete(adapter, skb_aggr, ret); 285 mwifiex_write_data_complete(adapter, skb_aggr, 1, ret);
286 return 0; 286 return 0;
287 case -EINPROGRESS: 287 case -EINPROGRESS:
288 adapter->data_sent = false; 288 adapter->data_sent = false;
289 break; 289 break;
290 case 0: 290 case 0:
291 mwifiex_write_data_complete(adapter, skb_aggr, ret); 291 mwifiex_write_data_complete(adapter, skb_aggr, 1, ret);
292 break; 292 break;
293 default: 293 default:
294 break; 294 break;
diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig
index 8e384fae3e6..b2e27723f80 100644
--- a/drivers/net/wireless/mwifiex/Kconfig
+++ b/drivers/net/wireless/mwifiex/Kconfig
@@ -1,7 +1,6 @@
1config MWIFIEX 1config MWIFIEX
2 tristate "Marvell WiFi-Ex Driver" 2 tristate "Marvell WiFi-Ex Driver"
3 depends on CFG80211 3 depends on CFG80211
4 select LIB80211
5 ---help--- 4 ---help---
6 This adds support for wireless adapters based on Marvell 5 This adds support for wireless adapters based on Marvell
7 802.11n chipsets. 6 802.11n chipsets.
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index fdb1eb86102..3b1c27712ad 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -180,10 +180,8 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
180static int 180static int
181mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 181mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
182 struct ieee80211_channel *chan, bool offchan, 182 struct ieee80211_channel *chan, bool offchan,
183 enum nl80211_channel_type channel_type, 183 unsigned int wait, const u8 *buf, size_t len,
184 bool channel_type_valid, unsigned int wait, 184 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
185 const u8 *buf, size_t len, bool no_cck,
186 bool dont_wait_for_ack, u64 *cookie)
187{ 185{
188 struct sk_buff *skb; 186 struct sk_buff *skb;
189 u16 pkt_len; 187 u16 pkt_len;
@@ -253,7 +251,6 @@ static int
253mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy, 251mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
254 struct wireless_dev *wdev, 252 struct wireless_dev *wdev,
255 struct ieee80211_channel *chan, 253 struct ieee80211_channel *chan,
256 enum nl80211_channel_type channel_type,
257 unsigned int duration, u64 *cookie) 254 unsigned int duration, u64 *cookie)
258{ 255{
259 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); 256 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
@@ -271,15 +268,14 @@ mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
271 } 268 }
272 269
273 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan, 270 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan,
274 &channel_type, duration); 271 duration);
275 272
276 if (!ret) { 273 if (!ret) {
277 *cookie = random32() | 1; 274 *cookie = random32() | 1;
278 priv->roc_cfg.cookie = *cookie; 275 priv->roc_cfg.cookie = *cookie;
279 priv->roc_cfg.chan = *chan; 276 priv->roc_cfg.chan = *chan;
280 priv->roc_cfg.chan_type = channel_type;
281 277
282 cfg80211_ready_on_channel(wdev, *cookie, chan, channel_type, 278 cfg80211_ready_on_channel(wdev, *cookie, chan,
283 duration, GFP_ATOMIC); 279 duration, GFP_ATOMIC);
284 280
285 wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie); 281 wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie);
@@ -302,13 +298,11 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
302 return -ENOENT; 298 return -ENOENT;
303 299
304 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE, 300 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE,
305 &priv->roc_cfg.chan, 301 &priv->roc_cfg.chan, 0);
306 &priv->roc_cfg.chan_type, 0);
307 302
308 if (!ret) { 303 if (!ret) {
309 cfg80211_remain_on_channel_expired(wdev, cookie, 304 cfg80211_remain_on_channel_expired(wdev, cookie,
310 &priv->roc_cfg.chan, 305 &priv->roc_cfg.chan,
311 priv->roc_cfg.chan_type,
312 GFP_ATOMIC); 306 GFP_ATOMIC);
313 307
314 memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg)); 308 memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg));
@@ -324,6 +318,7 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
324 */ 318 */
325static int 319static int
326mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, 320mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
321 struct wireless_dev *wdev,
327 enum nl80211_tx_power_setting type, 322 enum nl80211_tx_power_setting type,
328 int mbm) 323 int mbm)
329{ 324{
@@ -1296,21 +1291,23 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1296 return -EINVAL; 1291 return -EINVAL;
1297 } 1292 }
1298 1293
1299 bss_cfg->channel = 1294 bss_cfg->channel = ieee80211_frequency_to_channel(
1300 (u8)ieee80211_frequency_to_channel(params->channel->center_freq); 1295 params->chandef.chan->center_freq);
1301 1296
1302 /* Set appropriate bands */ 1297 /* Set appropriate bands */
1303 if (params->channel->band == IEEE80211_BAND_2GHZ) { 1298 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1304 bss_cfg->band_cfg = BAND_CONFIG_BG; 1299 bss_cfg->band_cfg = BAND_CONFIG_BG;
1305 1300
1306 if (params->channel_type == NL80211_CHAN_NO_HT) 1301 if (cfg80211_get_chandef_type(&params->chandef) ==
1302 NL80211_CHAN_NO_HT)
1307 config_bands = BAND_B | BAND_G; 1303 config_bands = BAND_B | BAND_G;
1308 else 1304 else
1309 config_bands = BAND_B | BAND_G | BAND_GN; 1305 config_bands = BAND_B | BAND_G | BAND_GN;
1310 } else { 1306 } else {
1311 bss_cfg->band_cfg = BAND_CONFIG_A; 1307 bss_cfg->band_cfg = BAND_CONFIG_A;
1312 1308
1313 if (params->channel_type == NL80211_CHAN_NO_HT) 1309 if (cfg80211_get_chandef_type(&params->chandef) ==
1310 NL80211_CHAN_NO_HT)
1314 config_bands = BAND_A; 1311 config_bands = BAND_A;
1315 else 1312 else
1316 config_bands = BAND_AN | BAND_A; 1313 config_bands = BAND_AN | BAND_A;
@@ -1683,7 +1680,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1683 int index = 0, i; 1680 int index = 0, i;
1684 u8 config_bands = 0; 1681 u8 config_bands = 0;
1685 1682
1686 if (params->channel->band == IEEE80211_BAND_2GHZ) { 1683 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1687 if (!params->basic_rates) { 1684 if (!params->basic_rates) {
1688 config_bands = BAND_B | BAND_G; 1685 config_bands = BAND_B | BAND_G;
1689 } else { 1686 } else {
@@ -1708,10 +1705,12 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1708 } 1705 }
1709 } 1706 }
1710 1707
1711 if (params->channel_type != NL80211_CHAN_NO_HT) 1708 if (cfg80211_get_chandef_type(&params->chandef) !=
1709 NL80211_CHAN_NO_HT)
1712 config_bands |= BAND_GN; 1710 config_bands |= BAND_GN;
1713 } else { 1711 } else {
1714 if (params->channel_type == NL80211_CHAN_NO_HT) 1712 if (cfg80211_get_chandef_type(&params->chandef) !=
1713 NL80211_CHAN_NO_HT)
1715 config_bands = BAND_A; 1714 config_bands = BAND_A;
1716 else 1715 else
1717 config_bands = BAND_AN | BAND_A; 1716 config_bands = BAND_AN | BAND_A;
@@ -1728,9 +1727,10 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1728 } 1727 }
1729 1728
1730 adapter->sec_chan_offset = 1729 adapter->sec_chan_offset =
1731 mwifiex_chan_type_to_sec_chan_offset(params->channel_type); 1730 mwifiex_chan_type_to_sec_chan_offset(
1732 priv->adhoc_channel = 1731 cfg80211_get_chandef_type(&params->chandef));
1733 ieee80211_frequency_to_channel(params->channel->center_freq); 1732 priv->adhoc_channel = ieee80211_frequency_to_channel(
1733 params->chandef.chan->center_freq);
1734 1734
1735 wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n", 1735 wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n",
1736 config_bands, priv->adhoc_channel, adapter->sec_chan_offset); 1736 config_bands, priv->adhoc_channel, adapter->sec_chan_offset);
@@ -1764,7 +1764,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1764 1764
1765 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, 1765 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
1766 params->bssid, priv->bss_mode, 1766 params->bssid, priv->bss_mode,
1767 params->channel, NULL, params->privacy); 1767 params->chandef.chan, NULL,
1768 params->privacy);
1768done: 1769done:
1769 if (!ret) { 1770 if (!ret) {
1770 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); 1771 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
@@ -2080,8 +2081,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2080 return ERR_PTR(-EINVAL); 2081 return ERR_PTR(-EINVAL);
2081 } 2082 }
2082 2083
2083 dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, 2084 dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name,
2084 ether_setup, 1); 2085 ether_setup, IEEE80211_NUM_ACS, 1);
2085 if (!dev) { 2086 if (!dev) {
2086 wiphy_err(wiphy, "no memory available for netdevice\n"); 2087 wiphy_err(wiphy, "no memory available for netdevice\n");
2087 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 2088 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
@@ -2143,8 +2144,7 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2143 mwifiex_dev_debugfs_remove(priv); 2144 mwifiex_dev_debugfs_remove(priv);
2144#endif 2145#endif
2145 2146
2146 if (!netif_queue_stopped(priv->netdev)) 2147 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
2147 netif_stop_queue(priv->netdev);
2148 2148
2149 if (netif_carrier_ok(priv->netdev)) 2149 if (netif_carrier_ok(priv->netdev))
2150 netif_carrier_off(priv->netdev); 2150 netif_carrier_off(priv->netdev);
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index be52a0a8d64..5f438e6c215 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -949,6 +949,9 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
949 } 949 }
950 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) 950 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
951 mwifiex_init_fw_complete(adapter); 951 mwifiex_init_fw_complete(adapter);
952
953 if (adapter->if_ops.card_reset)
954 adapter->if_ops.card_reset(adapter);
952} 955}
953 956
954/* 957/*
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index a870b5885c0..46e34aa65d1 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -178,6 +178,7 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
178 (struct mwifiex_private *) file->private_data; 178 (struct mwifiex_private *) file->private_data;
179 struct net_device *netdev = priv->netdev; 179 struct net_device *netdev = priv->netdev;
180 struct netdev_hw_addr *ha; 180 struct netdev_hw_addr *ha;
181 struct netdev_queue *txq;
181 unsigned long page = get_zeroed_page(GFP_KERNEL); 182 unsigned long page = get_zeroed_page(GFP_KERNEL);
182 char *p = (char *) page, fmt[64]; 183 char *p = (char *) page, fmt[64];
183 struct mwifiex_bss_info info; 184 struct mwifiex_bss_info info;
@@ -229,8 +230,13 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
229 p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); 230 p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
230 p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev)) 231 p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev))
231 ? "on" : "off")); 232 ? "on" : "off"));
232 p += sprintf(p, "tx queue %s\n", ((netif_queue_stopped(priv->netdev)) 233 p += sprintf(p, "tx queue");
233 ? "stopped" : "started")); 234 for (i = 0; i < netdev->num_tx_queues; i++) {
235 txq = netdev_get_tx_queue(netdev, i);
236 p += sprintf(p, " %d:%s", i, netif_tx_queue_stopped(txq) ?
237 "stopped" : "started");
238 }
239 p += sprintf(p, "\n");
234 240
235 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, 241 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
236 (unsigned long) p - page); 242 (unsigned long) p - page);
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 482faace790..39f03ce5a5b 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -388,9 +388,17 @@ void mwifiex_wake_up_net_dev_queue(struct net_device *netdev,
388 struct mwifiex_adapter *adapter) 388 struct mwifiex_adapter *adapter)
389{ 389{
390 unsigned long dev_queue_flags; 390 unsigned long dev_queue_flags;
391 unsigned int i;
391 392
392 spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags); 393 spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags);
393 netif_tx_wake_all_queues(netdev); 394
395 for (i = 0; i < netdev->num_tx_queues; i++) {
396 struct netdev_queue *txq = netdev_get_tx_queue(netdev, i);
397
398 if (netif_tx_queue_stopped(txq))
399 netif_tx_wake_queue(txq);
400 }
401
394 spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags); 402 spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags);
395} 403}
396 404
@@ -401,9 +409,17 @@ void mwifiex_stop_net_dev_queue(struct net_device *netdev,
401 struct mwifiex_adapter *adapter) 409 struct mwifiex_adapter *adapter)
402{ 410{
403 unsigned long dev_queue_flags; 411 unsigned long dev_queue_flags;
412 unsigned int i;
404 413
405 spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags); 414 spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags);
406 netif_tx_stop_all_queues(netdev); 415
416 for (i = 0; i < netdev->num_tx_queues; i++) {
417 struct netdev_queue *txq = netdev_get_tx_queue(netdev, i);
418
419 if (!netif_tx_queue_stopped(txq))
420 netif_tx_stop_queue(txq);
421 }
422
407 spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags); 423 spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags);
408} 424}
409 425
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 7b0858af8f5..88664ae667b 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -721,8 +721,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
721 721
722 if (!netif_carrier_ok(priv->netdev)) 722 if (!netif_carrier_ok(priv->netdev))
723 netif_carrier_on(priv->netdev); 723 netif_carrier_on(priv->netdev);
724 if (netif_queue_stopped(priv->netdev)) 724 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
725 netif_wake_queue(priv->netdev);
726 725
727 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) 726 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
728 priv->scan_block = true; 727 priv->scan_block = true;
@@ -1238,8 +1237,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
1238 1237
1239 if (!netif_carrier_ok(priv->netdev)) 1238 if (!netif_carrier_ok(priv->netdev))
1240 netif_carrier_on(priv->netdev); 1239 netif_carrier_on(priv->netdev);
1241 if (netif_queue_stopped(priv->netdev)) 1240 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
1242 netif_wake_queue(priv->netdev);
1243 1241
1244 mwifiex_save_curr_bcn(priv); 1242 mwifiex_save_curr_bcn(priv);
1245 1243
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 1df767bc8b6..9c802ede9c3 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -282,6 +282,7 @@ exit_main_proc:
282 mwifiex_shutdown_drv(adapter); 282 mwifiex_shutdown_drv(adapter);
283 return ret; 283 return ret;
284} 284}
285EXPORT_SYMBOL_GPL(mwifiex_main_process);
285 286
286/* 287/*
287 * This function frees the adapter structure. 288 * This function frees the adapter structure.
@@ -412,49 +413,6 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
412} 413}
413 414
414/* 415/*
415 * This function fills a driver buffer.
416 *
417 * The function associates a given SKB with the provided driver buffer
418 * and also updates some of the SKB parameters, including IP header,
419 * priority and timestamp.
420 */
421static void
422mwifiex_fill_buffer(struct sk_buff *skb)
423{
424 struct ethhdr *eth;
425 struct iphdr *iph;
426 struct timeval tv;
427 u8 tid = 0;
428
429 eth = (struct ethhdr *) skb->data;
430 switch (eth->h_proto) {
431 case __constant_htons(ETH_P_IP):
432 iph = ip_hdr(skb);
433 tid = IPTOS_PREC(iph->tos);
434 pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
435 eth->h_proto, tid, skb->priority);
436 break;
437 case __constant_htons(ETH_P_ARP):
438 pr_debug("data: ARP packet: %04x\n", eth->h_proto);
439 default:
440 break;
441 }
442/* Offset for TOS field in the IP header */
443#define IPTOS_OFFSET 5
444 tid = (tid >> IPTOS_OFFSET);
445 skb->priority = tid;
446 /* Record the current time the packet was queued; used to
447 determine the amount of time the packet was queued in
448 the driver before it was sent to the firmware.
449 The delay is then sent along with the packet to the
450 firmware for aggregate delay calculation for stats and
451 MSDU lifetime expiry.
452 */
453 do_gettimeofday(&tv);
454 skb->tstamp = timeval_to_ktime(tv);
455}
456
457/*
458 * CFG802.11 network device handler for open. 416 * CFG802.11 network device handler for open.
459 * 417 *
460 * Starts the data queue. 418 * Starts the data queue.
@@ -488,17 +446,23 @@ mwifiex_close(struct net_device *dev)
488 */ 446 */
489int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) 447int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
490{ 448{
491 mwifiex_wmm_add_buf_txqueue(priv, skb); 449 struct netdev_queue *txq;
450 int index = mwifiex_1d_to_wmm_queue[skb->priority];
451
452 if (atomic_inc_return(&priv->wmm_tx_pending[index]) >= MAX_TX_PENDING) {
453 txq = netdev_get_tx_queue(priv->netdev, index);
454 if (!netif_tx_queue_stopped(txq)) {
455 netif_tx_stop_queue(txq);
456 dev_dbg(priv->adapter->dev, "stop queue: %d\n", index);
457 }
458 }
459
492 atomic_inc(&priv->adapter->tx_pending); 460 atomic_inc(&priv->adapter->tx_pending);
461 mwifiex_wmm_add_buf_txqueue(priv, skb);
493 462
494 if (priv->adapter->scan_delay_cnt) 463 if (priv->adapter->scan_delay_cnt)
495 atomic_set(&priv->adapter->is_tx_received, true); 464 atomic_set(&priv->adapter->is_tx_received, true);
496 465
497 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
498 mwifiex_set_trans_start(priv->netdev);
499 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
500 }
501
502 queue_work(priv->adapter->workqueue, &priv->adapter->main_work); 466 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
503 467
504 return 0; 468 return 0;
@@ -513,6 +477,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
513 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 477 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
514 struct sk_buff *new_skb; 478 struct sk_buff *new_skb;
515 struct mwifiex_txinfo *tx_info; 479 struct mwifiex_txinfo *tx_info;
480 struct timeval tv;
516 481
517 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", 482 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
518 jiffies, priv->bss_type, priv->bss_num); 483 jiffies, priv->bss_type, priv->bss_num);
@@ -550,7 +515,16 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
550 tx_info = MWIFIEX_SKB_TXCB(skb); 515 tx_info = MWIFIEX_SKB_TXCB(skb);
551 tx_info->bss_num = priv->bss_num; 516 tx_info->bss_num = priv->bss_num;
552 tx_info->bss_type = priv->bss_type; 517 tx_info->bss_type = priv->bss_type;
553 mwifiex_fill_buffer(skb); 518
519 /* Record the current time the packet was queued; used to
520 * determine the amount of time the packet was queued in
521 * the driver before it was sent to the firmware.
522 * The delay is then sent along with the packet to the
523 * firmware for aggregate delay calculation for stats and
524 * MSDU lifetime expiry.
525 */
526 do_gettimeofday(&tv);
527 skb->tstamp = timeval_to_ktime(tv);
554 528
555 mwifiex_queue_tx_pkt(priv, skb); 529 mwifiex_queue_tx_pkt(priv, skb);
556 530
@@ -630,6 +604,13 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
630 return &priv->stats; 604 return &priv->stats;
631} 605}
632 606
607static u16
608mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb)
609{
610 skb->priority = cfg80211_classify8021d(skb);
611 return mwifiex_1d_to_wmm_queue[skb->priority];
612}
613
633/* Network device handlers */ 614/* Network device handlers */
634static const struct net_device_ops mwifiex_netdev_ops = { 615static const struct net_device_ops mwifiex_netdev_ops = {
635 .ndo_open = mwifiex_open, 616 .ndo_open = mwifiex_open,
@@ -639,6 +620,7 @@ static const struct net_device_ops mwifiex_netdev_ops = {
639 .ndo_tx_timeout = mwifiex_tx_timeout, 620 .ndo_tx_timeout = mwifiex_tx_timeout,
640 .ndo_get_stats = mwifiex_get_stats, 621 .ndo_get_stats = mwifiex_get_stats,
641 .ndo_set_rx_mode = mwifiex_set_multicast_list, 622 .ndo_set_rx_mode = mwifiex_set_multicast_list,
623 .ndo_select_queue = mwifiex_netdev_select_wmm_queue,
642}; 624};
643 625
644/* 626/*
@@ -838,9 +820,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
838 for (i = 0; i < adapter->priv_num; i++) { 820 for (i = 0; i < adapter->priv_num; i++) {
839 priv = adapter->priv[i]; 821 priv = adapter->priv[i];
840 if (priv && priv->netdev) { 822 if (priv && priv->netdev) {
841 if (!netif_queue_stopped(priv->netdev)) 823 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
842 mwifiex_stop_net_dev_queue(priv->netdev,
843 adapter);
844 if (netif_carrier_ok(priv->netdev)) 824 if (netif_carrier_ok(priv->netdev))
845 netif_carrier_off(priv->netdev); 825 netif_carrier_off(priv->netdev);
846 } 826 }
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 81f8772dcb0..1b3cfc82194 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -371,7 +371,6 @@ struct wps {
371struct mwifiex_roc_cfg { 371struct mwifiex_roc_cfg {
372 u64 cookie; 372 u64 cookie;
373 struct ieee80211_channel chan; 373 struct ieee80211_channel chan;
374 enum nl80211_channel_type chan_type;
375}; 374};
376 375
377struct mwifiex_adapter; 376struct mwifiex_adapter;
@@ -440,6 +439,7 @@ struct mwifiex_private {
440 u8 wmm_enabled; 439 u8 wmm_enabled;
441 u8 wmm_qosinfo; 440 u8 wmm_qosinfo;
442 struct mwifiex_wmm_desc wmm; 441 struct mwifiex_wmm_desc wmm;
442 atomic_t wmm_tx_pending[IEEE80211_NUM_ACS];
443 struct list_head sta_list; 443 struct list_head sta_list;
444 /* spin lock for associated station list */ 444 /* spin lock for associated station list */
445 spinlock_t sta_list_spinlock; 445 spinlock_t sta_list_spinlock;
@@ -600,6 +600,7 @@ struct mwifiex_if_ops {
600 int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *); 600 int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *);
601 int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *); 601 int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *);
602 int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); 602 int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
603 void (*card_reset) (struct mwifiex_adapter *);
603}; 604};
604 605
605struct mwifiex_adapter { 606struct mwifiex_adapter {
@@ -788,7 +789,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
788 struct mwifiex_tx_param *tx_param); 789 struct mwifiex_tx_param *tx_param);
789int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags); 790int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags);
790int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, 791int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
791 struct sk_buff *skb, int status); 792 struct sk_buff *skb, int aggr, int status);
792void mwifiex_clean_txrx(struct mwifiex_private *priv); 793void mwifiex_clean_txrx(struct mwifiex_private *priv);
793u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv); 794u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv);
794void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter); 795void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter);
@@ -1016,7 +1017,6 @@ int mwifiex_get_ver_ext(struct mwifiex_private *priv);
1016 1017
1017int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, 1018int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1018 struct ieee80211_channel *chan, 1019 struct ieee80211_channel *chan,
1019 enum nl80211_channel_type *channel_type,
1020 unsigned int duration); 1020 unsigned int duration);
1021 1021
1022int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role); 1022int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role);
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 82cf0fa2d9f..5a1c1d0e559 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -906,8 +906,8 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
906/* 906/*
907 * SDIO interrupt handler. 907 * SDIO interrupt handler.
908 * 908 *
909 * This function reads the interrupt status from firmware and assigns 909 * This function reads the interrupt status from firmware and handles
910 * the main process in workqueue which will handle the interrupt. 910 * the interrupt in current thread (ksdioirqd) right away.
911 */ 911 */
912static void 912static void
913mwifiex_sdio_interrupt(struct sdio_func *func) 913mwifiex_sdio_interrupt(struct sdio_func *func)
@@ -930,7 +930,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func)
930 adapter->ps_state = PS_STATE_AWAKE; 930 adapter->ps_state = PS_STATE_AWAKE;
931 931
932 mwifiex_interrupt_status(adapter); 932 mwifiex_interrupt_status(adapter);
933 queue_work(adapter->workqueue, &adapter->main_work); 933 mwifiex_main_process(adapter);
934} 934}
935 935
936/* 936/*
@@ -1749,6 +1749,37 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
1749 port, card->mp_data_port_mask); 1749 port, card->mp_data_port_mask);
1750} 1750}
1751 1751
1752static struct mmc_host *reset_host;
1753static void sdio_card_reset_worker(struct work_struct *work)
1754{
1755 /* The actual reset operation must be run outside of driver thread.
1756 * This is because mmc_remove_host() will cause the device to be
1757 * instantly destroyed, and the driver then needs to end its thread,
1758 * leading to a deadlock.
1759 *
1760 * We run it in a totally independent workqueue.
1761 */
1762
1763 pr_err("Resetting card...\n");
1764 mmc_remove_host(reset_host);
1765 /* 20ms delay is based on experiment with sdhci controller */
1766 mdelay(20);
1767 mmc_add_host(reset_host);
1768}
1769static DECLARE_WORK(card_reset_work, sdio_card_reset_worker);
1770
1771/* This function resets the card */
1772static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter)
1773{
1774 struct sdio_mmc_card *card = adapter->card;
1775
1776 if (work_pending(&card_reset_work))
1777 return;
1778
1779 reset_host = card->func->card->host;
1780 schedule_work(&card_reset_work);
1781}
1782
1752static struct mwifiex_if_ops sdio_ops = { 1783static struct mwifiex_if_ops sdio_ops = {
1753 .init_if = mwifiex_init_sdio, 1784 .init_if = mwifiex_init_sdio,
1754 .cleanup_if = mwifiex_cleanup_sdio, 1785 .cleanup_if = mwifiex_cleanup_sdio,
@@ -1767,6 +1798,7 @@ static struct mwifiex_if_ops sdio_ops = {
1767 .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf, 1798 .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf,
1768 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, 1799 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
1769 .event_complete = mwifiex_sdio_event_complete, 1800 .event_complete = mwifiex_sdio_event_complete,
1801 .card_reset = mwifiex_sdio_card_reset,
1770}; 1802};
1771 1803
1772/* 1804/*
@@ -1804,6 +1836,7 @@ mwifiex_sdio_cleanup_module(void)
1804 /* Set the flag as user is removing this module. */ 1836 /* Set the flag as user is removing this module. */
1805 user_rmmod = 1; 1837 user_rmmod = 1;
1806 1838
1839 cancel_work_sync(&card_reset_work);
1807 sdio_unregister_driver(&mwifiex_sdio); 1840 sdio_unregister_driver(&mwifiex_sdio);
1808} 1841}
1809 1842
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 21033738ef0..8cc5468654b 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -25,6 +25,7 @@
25#include <linux/mmc/sdio_ids.h> 25#include <linux/mmc/sdio_ids.h>
26#include <linux/mmc/sdio_func.h> 26#include <linux/mmc/sdio_func.h>
27#include <linux/mmc/card.h> 27#include <linux/mmc/card.h>
28#include <linux/mmc/host.h>
28 29
29#include "main.h" 30#include "main.h"
30 31
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 8132119e1a2..41aafc7454e 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -124,8 +124,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
124 } 124 }
125 memset(priv->cfg_bssid, 0, ETH_ALEN); 125 memset(priv->cfg_bssid, 0, ETH_ALEN);
126 126
127 if (!netif_queue_stopped(priv->netdev)) 127 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
128 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
129 if (netif_carrier_ok(priv->netdev)) 128 if (netif_carrier_ok(priv->netdev))
130 netif_carrier_off(priv->netdev); 129 netif_carrier_off(priv->netdev);
131} 130}
@@ -197,8 +196,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
197 dev_dbg(adapter->dev, "event: LINK_SENSED\n"); 196 dev_dbg(adapter->dev, "event: LINK_SENSED\n");
198 if (!netif_carrier_ok(priv->netdev)) 197 if (!netif_carrier_ok(priv->netdev))
199 netif_carrier_on(priv->netdev); 198 netif_carrier_on(priv->netdev);
200 if (netif_queue_stopped(priv->netdev)) 199 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
201 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
202 break; 200 break;
203 201
204 case EVENT_DEAUTHENTICATED: 202 case EVENT_DEAUTHENTICATED:
@@ -306,8 +304,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
306 dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n"); 304 dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n");
307 priv->adhoc_is_link_sensed = false; 305 priv->adhoc_is_link_sensed = false;
308 mwifiex_clean_txrx(priv); 306 mwifiex_clean_txrx(priv);
309 if (!netif_queue_stopped(priv->netdev)) 307 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
310 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
311 if (netif_carrier_ok(priv->netdev)) 308 if (netif_carrier_ok(priv->netdev))
312 netif_carrier_off(priv->netdev); 309 netif_carrier_off(priv->netdev);
313 break; 310 break;
@@ -424,7 +421,6 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
424 cfg80211_remain_on_channel_expired(priv->wdev, 421 cfg80211_remain_on_channel_expired(priv->wdev,
425 priv->roc_cfg.cookie, 422 priv->roc_cfg.cookie,
426 &priv->roc_cfg.chan, 423 &priv->roc_cfg.chan,
427 priv->roc_cfg.chan_type,
428 GFP_ATOMIC); 424 GFP_ATOMIC);
429 425
430 memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg)); 426 memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 552d72ed055..237c8d2ba9f 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -276,8 +276,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
276 dev_dbg(adapter->dev, "info: SSID found in scan list ... " 276 dev_dbg(adapter->dev, "info: SSID found in scan list ... "
277 "associating...\n"); 277 "associating...\n");
278 278
279 if (!netif_queue_stopped(priv->netdev)) 279 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
280 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
281 if (netif_carrier_ok(priv->netdev)) 280 if (netif_carrier_ok(priv->netdev))
282 netif_carrier_off(priv->netdev); 281 netif_carrier_off(priv->netdev);
283 282
@@ -318,8 +317,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
318 317
319 ret = mwifiex_check_network_compatibility(priv, bss_desc); 318 ret = mwifiex_check_network_compatibility(priv, bss_desc);
320 319
321 if (!netif_queue_stopped(priv->netdev)) 320 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
322 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
323 if (netif_carrier_ok(priv->netdev)) 321 if (netif_carrier_ok(priv->netdev))
324 netif_carrier_off(priv->netdev); 322 netif_carrier_off(priv->netdev);
325 323
@@ -1046,7 +1044,6 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv)
1046int 1044int
1047mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, 1045mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1048 struct ieee80211_channel *chan, 1046 struct ieee80211_channel *chan,
1049 enum nl80211_channel_type *ct,
1050 unsigned int duration) 1047 unsigned int duration)
1051{ 1048{
1052 struct host_cmd_ds_remain_on_chan roc_cfg; 1049 struct host_cmd_ds_remain_on_chan roc_cfg;
@@ -1056,7 +1053,7 @@ mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1056 roc_cfg.action = cpu_to_le16(action); 1053 roc_cfg.action = cpu_to_le16(action);
1057 if (action == HostCmd_ACT_GEN_SET) { 1054 if (action == HostCmd_ACT_GEN_SET) {
1058 roc_cfg.band_cfg = chan->band; 1055 roc_cfg.band_cfg = chan->band;
1059 sc = mwifiex_chan_type_to_sec_chan_offset(*ct); 1056 sc = mwifiex_chan_type_to_sec_chan_offset(NL80211_CHAN_NO_HT);
1060 roc_cfg.band_cfg |= (sc << 2); 1057 roc_cfg.band_cfg |= (sc << 2);
1061 1058
1062 roc_cfg.channel = 1059 roc_cfg.channel =
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 5cb3f7af874..8c80024c30f 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -121,13 +121,13 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
121 dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", 121 dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
122 ret); 122 ret);
123 adapter->dbg.num_tx_host_to_card_failure++; 123 adapter->dbg.num_tx_host_to_card_failure++;
124 mwifiex_write_data_complete(adapter, skb, ret); 124 mwifiex_write_data_complete(adapter, skb, 0, ret);
125 break; 125 break;
126 case -EINPROGRESS: 126 case -EINPROGRESS:
127 adapter->data_sent = false; 127 adapter->data_sent = false;
128 break; 128 break;
129 case 0: 129 case 0:
130 mwifiex_write_data_complete(adapter, skb, ret); 130 mwifiex_write_data_complete(adapter, skb, 0, ret);
131 break; 131 break;
132 default: 132 default:
133 break; 133 break;
@@ -144,11 +144,12 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
144 * wakes up stalled traffic queue if required, and then frees the buffer. 144 * wakes up stalled traffic queue if required, and then frees the buffer.
145 */ 145 */
146int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, 146int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
147 struct sk_buff *skb, int status) 147 struct sk_buff *skb, int aggr, int status)
148{ 148{
149 struct mwifiex_private *priv, *tpriv; 149 struct mwifiex_private *priv;
150 struct mwifiex_txinfo *tx_info; 150 struct mwifiex_txinfo *tx_info;
151 int i; 151 struct netdev_queue *txq;
152 int index;
152 153
153 if (!skb) 154 if (!skb)
154 return 0; 155 return 0;
@@ -172,15 +173,20 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
172 173
173 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) 174 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT)
174 atomic_dec_return(&adapter->pending_bridged_pkts); 175 atomic_dec_return(&adapter->pending_bridged_pkts);
175 if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING) 176
177 if (aggr)
178 /* For skb_aggr, do not wake up tx queue */
176 goto done; 179 goto done;
177 180
178 for (i = 0; i < adapter->priv_num; i++) { 181 atomic_dec(&adapter->tx_pending);
179 tpriv = adapter->priv[i];
180 182
181 if (tpriv->media_connected && 183 index = mwifiex_1d_to_wmm_queue[skb->priority];
182 netif_queue_stopped(tpriv->netdev)) 184 if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) {
183 mwifiex_wake_up_net_dev_queue(tpriv->netdev, adapter); 185 txq = netdev_get_tx_queue(priv->netdev, index);
186 if (netif_tx_queue_stopped(txq)) {
187 netif_tx_wake_queue(txq);
188 dev_dbg(adapter->dev, "wake queue: %d\n", index);
189 }
184 } 190 }
185done: 191done:
186 dev_kfree_skb_any(skb); 192 dev_kfree_skb_any(skb);
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index a33fa394e34..21c640d3b57 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -235,11 +235,18 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
235 break; 235 break;
236 case EVENT_UAP_BSS_IDLE: 236 case EVENT_UAP_BSS_IDLE:
237 priv->media_connected = false; 237 priv->media_connected = false;
238 if (netif_carrier_ok(priv->netdev))
239 netif_carrier_off(priv->netdev);
240 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
241
238 mwifiex_clean_txrx(priv); 242 mwifiex_clean_txrx(priv);
239 mwifiex_del_all_sta_list(priv); 243 mwifiex_del_all_sta_list(priv);
240 break; 244 break;
241 case EVENT_UAP_BSS_ACTIVE: 245 case EVENT_UAP_BSS_ACTIVE:
242 priv->media_connected = true; 246 priv->media_connected = true;
247 if (!netif_carrier_ok(priv->netdev))
248 netif_carrier_on(priv->netdev);
249 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
243 break; 250 break;
244 case EVENT_UAP_BSS_START: 251 case EVENT_UAP_BSS_START:
245 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause); 252 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 22a5916564b..bbe1f3518e4 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -238,7 +238,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
238 } else { 238 } else {
239 dev_dbg(adapter->dev, "%s: DATA\n", __func__); 239 dev_dbg(adapter->dev, "%s: DATA\n", __func__);
240 atomic_dec(&card->tx_data_urb_pending); 240 atomic_dec(&card->tx_data_urb_pending);
241 mwifiex_write_data_complete(adapter, context->skb, 241 mwifiex_write_data_complete(adapter, context->skb, 0,
242 urb->status ? -1 : 0); 242 urb->status ? -1 : 0);
243 } 243 }
244 244
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 600d8194610..818f871ae98 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -483,7 +483,7 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
483 struct sk_buff *skb, *tmp; 483 struct sk_buff *skb, *tmp;
484 484
485 skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) 485 skb_queue_walk_safe(&ra_list->skb_head, skb, tmp)
486 mwifiex_write_data_complete(adapter, skb, -1); 486 mwifiex_write_data_complete(adapter, skb, 0, -1);
487} 487}
488 488
489/* 489/*
@@ -650,7 +650,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
650 650
651 if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) { 651 if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) {
652 dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); 652 dev_dbg(adapter->dev, "data: drop packet in disconnect\n");
653 mwifiex_write_data_complete(adapter, skb, -1); 653 mwifiex_write_data_complete(adapter, skb, 0, -1);
654 return; 654 return;
655 } 655 }
656 656
@@ -680,7 +680,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
680 680
681 if (!ra_list) { 681 if (!ra_list) {
682 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); 682 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
683 mwifiex_write_data_complete(adapter, skb, -1); 683 mwifiex_write_data_complete(adapter, skb, 0, -1);
684 return; 684 return;
685 } 685 }
686 686
@@ -1090,7 +1090,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
1090 if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { 1090 if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
1091 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1091 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1092 ra_list_flags); 1092 ra_list_flags);
1093 mwifiex_write_data_complete(adapter, skb, -1); 1093 mwifiex_write_data_complete(adapter, skb, 0, -1);
1094 return; 1094 return;
1095 } 1095 }
1096 1096
@@ -1195,7 +1195,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1195 if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { 1195 if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
1196 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1196 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1197 ra_list_flags); 1197 ra_list_flags);
1198 mwifiex_write_data_complete(adapter, skb, -1); 1198 mwifiex_write_data_complete(adapter, skb, 0, -1);
1199 return; 1199 return;
1200 } 1200 }
1201 1201
@@ -1209,7 +1209,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1209 adapter->data_sent = false; 1209 adapter->data_sent = false;
1210 dev_err(adapter->dev, "host_to_card failed: %#x\n", ret); 1210 dev_err(adapter->dev, "host_to_card failed: %#x\n", ret);
1211 adapter->dbg.num_tx_host_to_card_failure++; 1211 adapter->dbg.num_tx_host_to_card_failure++;
1212 mwifiex_write_data_complete(adapter, skb, ret); 1212 mwifiex_write_data_complete(adapter, skb, 0, ret);
1213 break; 1213 break;
1214 case -EINPROGRESS: 1214 case -EINPROGRESS:
1215 adapter->data_sent = false; 1215 adapter->data_sent = false;
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index ec839952d2e..b92f39d8963 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -31,6 +31,8 @@ enum ieee_types_wmm_ecw_bitmasks {
31 MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)), 31 MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)),
32}; 32};
33 33
34static const u16 mwifiex_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
35
34/* 36/*
35 * This function retrieves the TID of the given RA list. 37 * This function retrieves the TID of the given RA list.
36 */ 38 */
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 5099e5375cb..0cdae663273 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1851,6 +1851,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
1851 bool start_ba_session = false; 1851 bool start_ba_session = false;
1852 bool mgmtframe = false; 1852 bool mgmtframe = false;
1853 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 1853 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1854 bool eapol_frame = false;
1854 1855
1855 wh = (struct ieee80211_hdr *)skb->data; 1856 wh = (struct ieee80211_hdr *)skb->data;
1856 if (ieee80211_is_data_qos(wh->frame_control)) 1857 if (ieee80211_is_data_qos(wh->frame_control))
@@ -1858,6 +1859,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
1858 else 1859 else
1859 qos = 0; 1860 qos = 0;
1860 1861
1862 if (skb->protocol == cpu_to_be16(ETH_P_PAE))
1863 eapol_frame = true;
1864
1861 if (ieee80211_is_mgmt(wh->frame_control)) 1865 if (ieee80211_is_mgmt(wh->frame_control))
1862 mgmtframe = true; 1866 mgmtframe = true;
1863 1867
@@ -1916,9 +1920,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
1916 1920
1917 txpriority = index; 1921 txpriority = index;
1918 1922
1919 if (priv->ap_fw && sta && sta->ht_cap.ht_supported 1923 if (priv->ap_fw && sta && sta->ht_cap.ht_supported && !eapol_frame &&
1920 && skb->protocol != cpu_to_be16(ETH_P_PAE) 1924 ieee80211_is_data_qos(wh->frame_control)) {
1921 && ieee80211_is_data_qos(wh->frame_control)) {
1922 tid = qos & 0xf; 1925 tid = qos & 0xf;
1923 mwl8k_tx_count_packet(sta, tid); 1926 mwl8k_tx_count_packet(sta, tid);
1924 spin_lock(&priv->stream_lock); 1927 spin_lock(&priv->stream_lock);
@@ -2005,6 +2008,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
2005 spin_unlock(&priv->stream_lock); 2008 spin_unlock(&priv->stream_lock);
2006 } 2009 }
2007 spin_unlock_bh(&priv->tx_lock); 2010 spin_unlock_bh(&priv->tx_lock);
2011 pci_unmap_single(priv->pdev, dma, skb->len,
2012 PCI_DMA_TODEVICE);
2008 dev_kfree_skb(skb); 2013 dev_kfree_skb(skb);
2009 return; 2014 return;
2010 } 2015 }
@@ -2025,9 +2030,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
2025 else 2030 else
2026 tx->peer_id = 0; 2031 tx->peer_id = 0;
2027 2032
2028 if (priv->ap_fw) 2033 if (priv->ap_fw && ieee80211_is_data(wh->frame_control) && !eapol_frame)
2029 tx->timestamp = cpu_to_le32(ioread32(priv->regs + 2034 tx->timestamp = cpu_to_le32(ioread32(priv->regs +
2030 MWL8K_HW_TIMER_REGISTER)); 2035 MWL8K_HW_TIMER_REGISTER));
2036 else
2037 tx->timestamp = 0;
2031 2038
2032 wmb(); 2039 wmb();
2033 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); 2040 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
@@ -3679,7 +3686,8 @@ struct mwl8k_cmd_bastream {
3679} __packed; 3686} __packed;
3680 3687
3681static int 3688static int
3682mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream) 3689mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
3690 struct ieee80211_vif *vif)
3683{ 3691{
3684 struct mwl8k_cmd_bastream *cmd; 3692 struct mwl8k_cmd_bastream *cmd;
3685 int rc; 3693 int rc;
@@ -3702,7 +3710,7 @@ mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
3702 cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) | 3710 cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) |
3703 cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM); 3711 cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM);
3704 3712
3705 rc = mwl8k_post_cmd(hw, &cmd->header); 3713 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
3706 3714
3707 kfree(cmd); 3715 kfree(cmd);
3708 3716
@@ -3711,7 +3719,7 @@ mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
3711 3719
3712static int 3720static int
3713mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, 3721mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
3714 u8 buf_size) 3722 u8 buf_size, struct ieee80211_vif *vif)
3715{ 3723{
3716 struct mwl8k_cmd_bastream *cmd; 3724 struct mwl8k_cmd_bastream *cmd;
3717 int rc; 3725 int rc;
@@ -3745,7 +3753,7 @@ mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
3745 cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE | 3753 cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE |
3746 BASTREAM_FLAG_DIRECTION_UPSTREAM); 3754 BASTREAM_FLAG_DIRECTION_UPSTREAM);
3747 3755
3748 rc = mwl8k_post_cmd(hw, &cmd->header); 3756 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
3749 3757
3750 wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n", 3758 wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n",
3751 stream->sta->addr, stream->tid); 3759 stream->sta->addr, stream->tid);
@@ -5085,6 +5093,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5085 struct mwl8k_priv *priv = hw->priv; 5093 struct mwl8k_priv *priv = hw->priv;
5086 struct mwl8k_ampdu_stream *stream; 5094 struct mwl8k_ampdu_stream *stream;
5087 u8 *addr = sta->addr; 5095 u8 *addr = sta->addr;
5096 struct mwl8k_sta *sta_info = MWL8K_STA(sta);
5088 5097
5089 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) 5098 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
5090 return -ENOTSUPP; 5099 return -ENOTSUPP;
@@ -5127,7 +5136,16 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5127 /* Release the lock before we do the time consuming stuff */ 5136 /* Release the lock before we do the time consuming stuff */
5128 spin_unlock(&priv->stream_lock); 5137 spin_unlock(&priv->stream_lock);
5129 for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) { 5138 for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) {
5130 rc = mwl8k_check_ba(hw, stream); 5139
5140 /* Check if link is still valid */
5141 if (!sta_info->is_ampdu_allowed) {
5142 spin_lock(&priv->stream_lock);
5143 mwl8k_remove_stream(hw, stream);
5144 spin_unlock(&priv->stream_lock);
5145 return -EBUSY;
5146 }
5147
5148 rc = mwl8k_check_ba(hw, stream, vif);
5131 5149
5132 /* If HW restart is in progress mwl8k_post_cmd will 5150 /* If HW restart is in progress mwl8k_post_cmd will
5133 * return -EBUSY. Avoid retrying mwl8k_check_ba in 5151 * return -EBUSY. Avoid retrying mwl8k_check_ba in
@@ -5167,7 +5185,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5167 BUG_ON(stream == NULL); 5185 BUG_ON(stream == NULL);
5168 BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS); 5186 BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS);
5169 spin_unlock(&priv->stream_lock); 5187 spin_unlock(&priv->stream_lock);
5170 rc = mwl8k_create_ba(hw, stream, buf_size); 5188 rc = mwl8k_create_ba(hw, stream, buf_size, vif);
5171 spin_lock(&priv->stream_lock); 5189 spin_lock(&priv->stream_lock);
5172 if (!rc) 5190 if (!rc)
5173 stream->state = AMPDU_STREAM_ACTIVE; 5191 stream->state = AMPDU_STREAM_ACTIVE;
@@ -5617,6 +5635,18 @@ fail:
5617 return rc; 5635 return rc;
5618} 5636}
5619 5637
5638static const struct ieee80211_iface_limit ap_if_limits[] = {
5639 { .max = 8, .types = BIT(NL80211_IFTYPE_AP) },
5640};
5641
5642static const struct ieee80211_iface_combination ap_if_comb = {
5643 .limits = ap_if_limits,
5644 .n_limits = ARRAY_SIZE(ap_if_limits),
5645 .max_interfaces = 8,
5646 .num_different_channels = 1,
5647};
5648
5649
5620static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) 5650static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
5621{ 5651{
5622 struct ieee80211_hw *hw = priv->hw; 5652 struct ieee80211_hw *hw = priv->hw;
@@ -5696,8 +5726,13 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
5696 goto err_free_cookie; 5726 goto err_free_cookie;
5697 5727
5698 hw->wiphy->interface_modes = 0; 5728 hw->wiphy->interface_modes = 0;
5699 if (priv->ap_macids_supported || priv->device_info->fw_image_ap) 5729
5730 if (priv->ap_macids_supported || priv->device_info->fw_image_ap) {
5700 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); 5731 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
5732 hw->wiphy->iface_combinations = &ap_if_comb;
5733 hw->wiphy->n_iface_combinations = 1;
5734 }
5735
5701 if (priv->sta_macids_supported || priv->device_info->fw_image_sta) 5736 if (priv->sta_macids_supported || priv->device_info->fw_image_sta)
5702 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); 5737 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
5703 5738
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 7b751fba7e1..d01edd2c50c 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -161,24 +161,23 @@ static int orinoco_scan(struct wiphy *wiphy,
161} 161}
162 162
163static int orinoco_set_monitor_channel(struct wiphy *wiphy, 163static int orinoco_set_monitor_channel(struct wiphy *wiphy,
164 struct ieee80211_channel *chan, 164 struct cfg80211_chan_def *chandef)
165 enum nl80211_channel_type channel_type)
166{ 165{
167 struct orinoco_private *priv = wiphy_priv(wiphy); 166 struct orinoco_private *priv = wiphy_priv(wiphy);
168 int err = 0; 167 int err = 0;
169 unsigned long flags; 168 unsigned long flags;
170 int channel; 169 int channel;
171 170
172 if (!chan) 171 if (!chandef->chan)
173 return -EINVAL; 172 return -EINVAL;
174 173
175 if (channel_type != NL80211_CHAN_NO_HT) 174 if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
176 return -EINVAL; 175 return -EINVAL;
177 176
178 if (chan->band != IEEE80211_BAND_2GHZ) 177 if (chandef->chan->band != IEEE80211_BAND_2GHZ)
179 return -EINVAL; 178 return -EINVAL;
180 179
181 channel = ieee80211_freq_to_dsss_chan(chan->center_freq); 180 channel = ieee80211_freq_to_dsss_chan(chandef->chan->center_freq);
182 181
183 if ((channel < 1) || (channel > NUM_CHANNELS) || 182 if ((channel < 1) || (channel > NUM_CHANNELS) ||
184 !(priv->channel_mask & (1 << (channel - 1)))) 183 !(priv->channel_mask & (1 << (channel - 1))))
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 5861e13a6fd..12f0a34477f 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -369,7 +369,11 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
369 rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32; 369 rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32;
370 priv->tsf_low32 = tsf32; 370 priv->tsf_low32 = tsf32;
371 371
372 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 372 /* LMAC API Page 10/29 - s_lm_data_in - clock
373 * "usec accurate timestamp of hardware clock
374 * at end of frame (before OFDM SIFS EOF padding"
375 */
376 rx_status->flag |= RX_FLAG_MACTIME_END;
373 377
374 if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN)) 378 if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
375 header_len += hdr->align[0]; 379 header_len += hdr->align[0];
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index bd1f0cb5608..abe1d039be8 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -490,9 +490,12 @@ static int rndis_scan(struct wiphy *wiphy,
490static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed); 490static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed);
491 491
492static int rndis_set_tx_power(struct wiphy *wiphy, 492static int rndis_set_tx_power(struct wiphy *wiphy,
493 struct wireless_dev *wdev,
493 enum nl80211_tx_power_setting type, 494 enum nl80211_tx_power_setting type,
494 int mbm); 495 int mbm);
495static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm); 496static int rndis_get_tx_power(struct wiphy *wiphy,
497 struct wireless_dev *wdev,
498 int *dbm);
496 499
497static int rndis_connect(struct wiphy *wiphy, struct net_device *dev, 500static int rndis_connect(struct wiphy *wiphy, struct net_device *dev,
498 struct cfg80211_connect_params *sme); 501 struct cfg80211_connect_params *sme);
@@ -1903,6 +1906,7 @@ static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1903} 1906}
1904 1907
1905static int rndis_set_tx_power(struct wiphy *wiphy, 1908static int rndis_set_tx_power(struct wiphy *wiphy,
1909 struct wireless_dev *wdev,
1906 enum nl80211_tx_power_setting type, 1910 enum nl80211_tx_power_setting type,
1907 int mbm) 1911 int mbm)
1908{ 1912{
@@ -1930,7 +1934,9 @@ static int rndis_set_tx_power(struct wiphy *wiphy,
1930 return -ENOTSUPP; 1934 return -ENOTSUPP;
1931} 1935}
1932 1936
1933static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm) 1937static int rndis_get_tx_power(struct wiphy *wiphy,
1938 struct wireless_dev *wdev,
1939 int *dbm)
1934{ 1940{
1935 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 1941 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
1936 struct usbnet *usbdev = priv->usbdev; 1942 struct usbnet *usbdev = priv->usbdev;
@@ -2287,7 +2293,7 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
2287{ 2293{
2288 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 2294 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2289 struct usbnet *usbdev = priv->usbdev; 2295 struct usbnet *usbdev = priv->usbdev;
2290 struct ieee80211_channel *channel = params->channel; 2296 struct ieee80211_channel *channel = params->chandef.chan;
2291 struct ndis_80211_ssid ssid; 2297 struct ndis_80211_ssid ssid;
2292 enum nl80211_auth_type auth_type; 2298 enum nl80211_auth_type auth_type;
2293 int ret, alg, length, chan = -1; 2299 int ret, alg, length, chan = -1;
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 3b8fb5a603f..023081286e0 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1096,6 +1096,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
1096 { USB_DEVICE(0x177f, 0x0153) }, 1096 { USB_DEVICE(0x177f, 0x0153) },
1097 { USB_DEVICE(0x177f, 0x0302) }, 1097 { USB_DEVICE(0x177f, 0x0302) },
1098 { USB_DEVICE(0x177f, 0x0313) }, 1098 { USB_DEVICE(0x177f, 0x0313) },
1099 { USB_DEVICE(0x177f, 0x0323) },
1099 /* U-Media */ 1100 /* U-Media */
1100 { USB_DEVICE(0x157e, 0x300e) }, 1101 { USB_DEVICE(0x157e, 0x300e) },
1101 { USB_DEVICE(0x157e, 0x3013) }, 1102 { USB_DEVICE(0x157e, 0x3013) },
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 69097d1faeb..67d167993d4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -157,6 +157,7 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)
157 * requested configurations. 157 * requested configurations.
158 */ 158 */
159 ieee80211_iterate_active_interfaces(rt2x00dev->hw, 159 ieee80211_iterate_active_interfaces(rt2x00dev->hw,
160 IEEE80211_IFACE_ITER_RESUME_ALL,
160 rt2x00lib_intf_scheduled_iter, 161 rt2x00lib_intf_scheduled_iter,
161 rt2x00dev); 162 rt2x00dev);
162} 163}
@@ -225,9 +226,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
225 return; 226 return;
226 227
227 /* send buffered bc/mc frames out for every bssid */ 228 /* send buffered bc/mc frames out for every bssid */
228 ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, 229 ieee80211_iterate_active_interfaces_atomic(
229 rt2x00lib_bc_buffer_iter, 230 rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
230 rt2x00dev); 231 rt2x00lib_bc_buffer_iter, rt2x00dev);
231 /* 232 /*
232 * Devices with pre tbtt interrupt don't need to update the beacon 233 * Devices with pre tbtt interrupt don't need to update the beacon
233 * here as they will fetch the next beacon directly prior to 234 * here as they will fetch the next beacon directly prior to
@@ -237,9 +238,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
237 return; 238 return;
238 239
239 /* fetch next beacon */ 240 /* fetch next beacon */
240 ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, 241 ieee80211_iterate_active_interfaces_atomic(
241 rt2x00lib_beaconupdate_iter, 242 rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
242 rt2x00dev); 243 rt2x00lib_beaconupdate_iter, rt2x00dev);
243} 244}
244EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); 245EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
245 246
@@ -249,9 +250,9 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
249 return; 250 return;
250 251
251 /* fetch next beacon */ 252 /* fetch next beacon */
252 ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, 253 ieee80211_iterate_active_interfaces_atomic(
253 rt2x00lib_beaconupdate_iter, 254 rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
254 rt2x00dev); 255 rt2x00lib_beaconupdate_iter, rt2x00dev);
255} 256}
256EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); 257EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
257 258
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 98a9e48f8e4..ed7a1bb3f24 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -424,9 +424,9 @@ int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
424 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) 424 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
425 return 0; 425 return 0;
426 426
427 ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, 427 ieee80211_iterate_active_interfaces_atomic(
428 rt2x00mac_set_tim_iter, 428 rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
429 rt2x00dev); 429 rt2x00mac_set_tim_iter, rt2x00dev);
430 430
431 /* queue work to upodate the beacon template */ 431 /* queue work to upodate the beacon template */
432 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work); 432 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work);
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 021d83e1b1d..b4218a5f206 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -150,7 +150,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
150 rx_status.freq = dev->conf.channel->center_freq; 150 rx_status.freq = dev->conf.channel->center_freq;
151 rx_status.band = dev->conf.channel->band; 151 rx_status.band = dev->conf.channel->band;
152 rx_status.mactime = le64_to_cpu(entry->tsft); 152 rx_status.mactime = le64_to_cpu(entry->tsft);
153 rx_status.flag |= RX_FLAG_MACTIME_MPDU; 153 rx_status.flag |= RX_FLAG_MACTIME_START;
154 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) 154 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
155 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 155 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
156 156
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index 7811b631597..52e6bebcf08 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -381,7 +381,7 @@ static void rtl8187_rx_cb(struct urb *urb)
381 rx_status.rate_idx = rate; 381 rx_status.rate_idx = rate;
382 rx_status.freq = dev->conf.channel->center_freq; 382 rx_status.freq = dev->conf.channel->center_freq;
383 rx_status.band = dev->conf.channel->band; 383 rx_status.band = dev->conf.channel->band;
384 rx_status.flag |= RX_FLAG_MACTIME_MPDU; 384 rx_status.flag |= RX_FLAG_MACTIME_START;
385 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) 385 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
386 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 386 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
387 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); 387 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig
index 6b28e92d1d2..21b1bbb93a7 100644
--- a/drivers/net/wireless/rtlwifi/Kconfig
+++ b/drivers/net/wireless/rtlwifi/Kconfig
@@ -32,6 +32,17 @@ config RTL8192DE
32 32
33 If you choose to build it as a module, it will be called rtl8192de 33 If you choose to build it as a module, it will be called rtl8192de
34 34
35config RTL8723AE
36 tristate "Realtek RTL8723AE PCIe Wireless Network Adapter"
37 depends on MAC80211 && PCI && EXPERIMENTAL
38 select FW_LOADER
39 select RTLWIFI
40 ---help---
41 This is the driver for Realtek RTL8723AE 802.11n PCIe
42 wireless network adapters.
43
44 If you choose to build it as a module, it will be called rtl8723ae
45
35config RTL8192CU 46config RTL8192CU
36 tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" 47 tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
37 depends on MAC80211 && USB 48 depends on MAC80211 && USB
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile
index 97935c565ba..3b1cbac741e 100644
--- a/drivers/net/wireless/rtlwifi/Makefile
+++ b/drivers/net/wireless/rtlwifi/Makefile
@@ -7,7 +7,8 @@ rtlwifi-objs := \
7 efuse.o \ 7 efuse.o \
8 ps.o \ 8 ps.o \
9 rc.o \ 9 rc.o \
10 regd.o 10 regd.o \
11 stats.o
11 12
12rtl8192c_common-objs += \ 13rtl8192c_common-objs += \
13 14
@@ -24,5 +25,6 @@ obj-$(CONFIG_RTL8192CE) += rtl8192ce/
24obj-$(CONFIG_RTL8192CU) += rtl8192cu/ 25obj-$(CONFIG_RTL8192CU) += rtl8192cu/
25obj-$(CONFIG_RTL8192SE) += rtl8192se/ 26obj-$(CONFIG_RTL8192SE) += rtl8192se/
26obj-$(CONFIG_RTL8192DE) += rtl8192de/ 27obj-$(CONFIG_RTL8192DE) += rtl8192de/
28obj-$(CONFIG_RTL8723AE) += rtl8723ae/
27 29
28ccflags-y += -D__CHECK_ENDIAN__ 30ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 59381fe8ed0..4494d130b37 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -826,6 +826,30 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
826} 826}
827EXPORT_SYMBOL(rtlwifi_rate_mapping); 827EXPORT_SYMBOL(rtlwifi_rate_mapping);
828 828
829bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
830{
831 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
832 struct rtl_priv *rtlpriv = rtl_priv(hw);
833 __le16 fc = rtl_get_fc(skb);
834
835 if (rtlpriv->dm.supp_phymode_switch &&
836 mac->link_state < MAC80211_LINKED &&
837 (ieee80211_is_auth(fc) || ieee80211_is_probe_req(fc))) {
838 if (rtlpriv->cfg->ops->check_switch_to_dmdp)
839 rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
840 }
841 if (ieee80211_is_auth(fc)) {
842 RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
843 rtl_ips_nic_on(hw);
844
845 mac->link_state = MAC80211_LINKING;
846 /* Dual mac */
847 rtlpriv->phy.need_iqk = true;
848 }
849
850 return true;
851}
852
829void rtl_get_tcb_desc(struct ieee80211_hw *hw, 853void rtl_get_tcb_desc(struct ieee80211_hw *hw,
830 struct ieee80211_tx_info *info, 854 struct ieee80211_tx_info *info,
831 struct ieee80211_sta *sta, 855 struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index f35af0fdaaf..5a8c80e259f 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -142,4 +142,6 @@ u8 rtl_tid_to_ac(u8 tid);
142extern struct attribute_group rtl_attribute_group; 142extern struct attribute_group rtl_attribute_group;
143int rtlwifi_rate_mapping(struct ieee80211_hw *hw, 143int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
144 bool isht, u8 desc_rate, bool first_ampdu); 144 bool isht, u8 desc_rate, bool first_ampdu);
145bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
146
145#endif 147#endif
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c
index ca69e35e50f..0e510f73041 100644
--- a/drivers/net/wireless/rtlwifi/cam.c
+++ b/drivers/net/wireless/rtlwifi/cam.c
@@ -337,7 +337,7 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
337 if (((bitmap & BIT(0)) == BIT(0)) && 337 if (((bitmap & BIT(0)) == BIT(0)) &&
338 (memcmp(addr, sta_addr, ETH_ALEN) == 0)) { 338 (memcmp(addr, sta_addr, ETH_ALEN) == 0)) {
339 /* Remove from HW Security CAM */ 339 /* Remove from HW Security CAM */
340 memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN); 340 eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]);
341 rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); 341 rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
342 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, 342 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
343 "del CAM entry %d\n", i); 343 "del CAM entry %d\n", i);
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index a7c0e52869b..be33aa14c8a 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -962,7 +962,6 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
962 int err = 0; 962 int err = 0;
963 u8 mac_addr[ETH_ALEN]; 963 u8 mac_addr[ETH_ALEN];
964 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 964 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
965 u8 zero_addr[ETH_ALEN] = { 0 };
966 965
967 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { 966 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
968 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 967 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
@@ -1057,7 +1056,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1057 memcpy(rtlpriv->sec.key_buf[key_idx], 1056 memcpy(rtlpriv->sec.key_buf[key_idx],
1058 key->key, key->keylen); 1057 key->key, key->keylen);
1059 rtlpriv->sec.key_len[key_idx] = key->keylen; 1058 rtlpriv->sec.key_len[key_idx] = key->keylen;
1060 memcpy(mac_addr, zero_addr, ETH_ALEN); 1059 eth_zero_addr(mac_addr);
1061 } else if (group_key) { /* group key */ 1060 } else if (group_key) { /* group key */
1062 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 1061 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1063 "set group key\n"); 1062 "set group key\n");
@@ -1108,7 +1107,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1108 } 1107 }
1109 memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); 1108 memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);
1110 rtlpriv->sec.key_len[key_idx] = 0; 1109 rtlpriv->sec.key_len[key_idx] = 0;
1111 memcpy(mac_addr, zero_addr, ETH_ALEN); 1110 eth_zero_addr(mac_addr);
1112 /* 1111 /*
1113 *mac80211 will delete entrys one by one, 1112 *mac80211 will delete entrys one by one,
1114 *so don't use rtl_cam_reset_all_entry 1113 *so don't use rtl_cam_reset_all_entry
diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h
index 07493d2957f..fd3269f4768 100644
--- a/drivers/net/wireless/rtlwifi/debug.h
+++ b/drivers/net/wireless/rtlwifi/debug.h
@@ -106,6 +106,8 @@
106#define COMP_REGD BIT(27) 106#define COMP_REGD BIT(27)
107#define COMP_CHAN BIT(28) 107#define COMP_CHAN BIT(28)
108#define COMP_USB BIT(29) 108#define COMP_USB BIT(29)
109#define COMP_EASY_CONCURRENT COMP_USB /* reuse of this bit is OK */
110#define COMP_BT_COEXIST BIT(30)
109 111
110/*-------------------------------------------------------------- 112/*--------------------------------------------------------------
111 Define the rt_print components 113 Define the rt_print components
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index abc306b502a..f38e30a947b 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1309,6 +1309,7 @@ static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw,
1309 struct rtl_priv *rtlpriv = rtl_priv(hw); 1309 struct rtl_priv *rtlpriv = rtl_priv(hw);
1310 struct rtl_sta_info *sta_entry = NULL; 1310 struct rtl_sta_info *sta_entry = NULL;
1311 u8 tid = rtl_get_tid(skb); 1311 u8 tid = rtl_get_tid(skb);
1312 __le16 fc = rtl_get_fc(skb);
1312 1313
1313 if (!sta) 1314 if (!sta)
1314 return false; 1315 return false;
@@ -1316,6 +1317,12 @@ static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw,
1316 1317
1317 if (!rtlpriv->rtlhal.earlymode_enable) 1318 if (!rtlpriv->rtlhal.earlymode_enable)
1318 return false; 1319 return false;
1320 if (ieee80211_is_nullfunc(fc))
1321 return false;
1322 if (ieee80211_is_qos_nullfunc(fc))
1323 return false;
1324 if (ieee80211_is_pspoll(fc))
1325 return false;
1319 if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL) 1326 if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL)
1320 return false; 1327 return false;
1321 if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE) 1328 if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE)
@@ -1357,10 +1364,8 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
1357 u8 own; 1364 u8 own;
1358 u8 temp_one = 1; 1365 u8 temp_one = 1;
1359 1366
1360 if (ieee80211_is_auth(fc)) { 1367 if (ieee80211_is_mgmt(fc))
1361 RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); 1368 rtl_tx_mgmt_proc(hw, skb);
1362 rtl_ips_nic_on(hw);
1363 }
1364 1369
1365 if (rtlpriv->psc.sw_ps_enabled) { 1370 if (rtlpriv->psc.sw_ps_enabled) {
1366 if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && 1371 if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) &&
@@ -1628,7 +1633,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
1628 "8192 PCI-E is found - vid/did=%x/%x\n", 1633 "8192 PCI-E is found - vid/did=%x/%x\n",
1629 venderid, deviceid); 1634 venderid, deviceid);
1630 rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; 1635 rtlhal->hw_type = HARDWARE_TYPE_RTL8192E;
1631 break; 1636 return false;
1632 case RTL_PCI_REVISION_ID_8192SE: 1637 case RTL_PCI_REVISION_ID_8192SE:
1633 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, 1638 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1634 "8192SE is found - vid/did=%x/%x\n", 1639 "8192SE is found - vid/did=%x/%x\n",
@@ -1643,6 +1648,11 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
1643 break; 1648 break;
1644 1649
1645 } 1650 }
1651 } else if (deviceid == RTL_PCI_8723AE_DID) {
1652 rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE;
1653 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1654 "8723AE PCI-E is found - "
1655 "vid/did=%x/%x\n", venderid, deviceid);
1646 } else if (deviceid == RTL_PCI_8192CET_DID || 1656 } else if (deviceid == RTL_PCI_8192CET_DID ||
1647 deviceid == RTL_PCI_8192CE_DID || 1657 deviceid == RTL_PCI_8192CE_DID ||
1648 deviceid == RTL_PCI_8191CE_DID || 1658 deviceid == RTL_PCI_8191CE_DID ||
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index 241448fc9ed..f71b12aa8cb 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -79,6 +79,7 @@
79#define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */ 79#define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */
80#define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */ 80#define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */
81#define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */ 81#define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */
82#define RTL_PCI_8723AE_DID 0x8723 /*8723AE */
82#define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */ 83#define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */
83#define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */ 84#define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */
84#define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */ 85#define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */
@@ -152,6 +153,7 @@ struct rtl8192_rx_ring {
152 153
153struct rtl_pci { 154struct rtl_pci {
154 struct pci_dev *pdev; 155 struct pci_dev *pdev;
156 bool irq_enabled;
155 157
156 bool driver_is_goingto_unload; 158 bool driver_is_goingto_unload;
157 bool up_first_time; 159 bool up_first_time;
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c
index d5cbf01da8a..c1e065f136b 100644
--- a/drivers/net/wireless/rtlwifi/rc.c
+++ b/drivers/net/wireless/rtlwifi/rc.c
@@ -55,7 +55,8 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
55 * 1M we will not use FW rate but user rate. 55 * 1M we will not use FW rate but user rate.
56 */ 56 */
57 if (rtlmac->opmode == NL80211_IFTYPE_AP || 57 if (rtlmac->opmode == NL80211_IFTYPE_AP ||
58 rtlmac->opmode == NL80211_IFTYPE_ADHOC) { 58 rtlmac->opmode == NL80211_IFTYPE_ADHOC ||
59 rtlmac->opmode == NL80211_IFTYPE_MESH_POINT) {
59 if (sta) { 60 if (sta) {
60 sta_entry = (struct rtl_sta_info *) sta->drv_priv; 61 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
61 wireless_mode = sta_entry->wireless_mode; 62 wireless_mode = sta_entry->wireless_mode;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index d7e1f0a7e48..17342475614 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -559,7 +559,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
559 if (GET_RX_DESC_RXHT(pdesc)) 559 if (GET_RX_DESC_RXHT(pdesc))
560 rx_status->flag |= RX_FLAG_HT; 560 rx_status->flag |= RX_FLAG_HT;
561 561
562 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 562 rx_status->flag |= RX_FLAG_MACTIME_START;
563 563
564 if (stats->decrypted) 564 if (stats->decrypted)
565 rx_status->flag |= RX_FLAG_DECRYPTED; 565 rx_status->flag |= RX_FLAG_DECRYPTED;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index 6e66f04c363..b6222eedb83 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -334,7 +334,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
334 rx_status->flag |= RX_FLAG_40MHZ; 334 rx_status->flag |= RX_FLAG_40MHZ;
335 if (GET_RX_DESC_RX_HT(pdesc)) 335 if (GET_RX_DESC_RX_HT(pdesc))
336 rx_status->flag |= RX_FLAG_HT; 336 rx_status->flag |= RX_FLAG_HT;
337 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 337 rx_status->flag |= RX_FLAG_MACTIME_START;
338 if (stats->decrypted) 338 if (stats->decrypted)
339 rx_status->flag |= RX_FLAG_DECRYPTED; 339 rx_status->flag |= RX_FLAG_DECRYPTED;
340 rx_status->rate_idx = rtlwifi_rate_mapping(hw, 340 rx_status->rate_idx = rtlwifi_rate_mapping(hw,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
index 35bb9da6196..f9f3861046c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
@@ -509,7 +509,7 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
509 rx_status->flag |= RX_FLAG_40MHZ; 509 rx_status->flag |= RX_FLAG_40MHZ;
510 if (GET_RX_DESC_RXHT(pdesc)) 510 if (GET_RX_DESC_RXHT(pdesc))
511 rx_status->flag |= RX_FLAG_HT; 511 rx_status->flag |= RX_FLAG_HT;
512 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 512 rx_status->flag |= RX_FLAG_MACTIME_START;
513 if (stats->decrypted) 513 if (stats->decrypted)
514 rx_status->flag |= RX_FLAG_DECRYPTED; 514 rx_status->flag |= RX_FLAG_DECRYPTED;
515 rx_status->rate_idx = rtlwifi_rate_mapping(hw, 515 rx_status->rate_idx = rtlwifi_rate_mapping(hw,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index 1ad51e711a3..0e9f6ebf078 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -553,7 +553,7 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
553 if (stats->is_ht) 553 if (stats->is_ht)
554 rx_status->flag |= RX_FLAG_HT; 554 rx_status->flag |= RX_FLAG_HT;
555 555
556 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 556 rx_status->flag |= RX_FLAG_MACTIME_START;
557 557
558 /* hw will set stats->decrypted true, if it finds the 558 /* hw will set stats->decrypted true, if it finds the
559 * frame is open data frame or mgmt frame, 559 * frame is open data frame or mgmt frame,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile b/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile
new file mode 100644
index 00000000000..4ed731f09b1
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile
@@ -0,0 +1,22 @@
1obj-m := rtl8723ae.o
2
3
4rtl8723ae-objs := \
5 dm.o \
6 fw.o \
7 hal_btc.o \
8 hal_bt_coexist.o\
9 hw.o \
10 led.o \
11 phy.o \
12 pwrseq.o \
13 pwrseqcmd.o \
14 rf.o \
15 sw.o \
16 table.o \
17 trx.o \
18
19
20obj-$(CONFIG_RTL8723AE) += rtl8723ae.o
21
22ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h b/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h
new file mode 100644
index 00000000000..417afeed36a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h
@@ -0,0 +1,41 @@
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 ** You should have received a copy of the GNU General Public License along with
15 ** this program; if not, write to the Free Software Foundation, Inc.,
16 ** 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 **
18 ** The full GNU General Public License is included in this distribution in the
19 ** file called LICENSE.
20 **
21 ** Contact Information:
22 ** wlanfae <wlanfae@realtek.com>
23 ** Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 ** Hsinchu 300, Taiwan.
25 ** Larry Finger <Larry.Finger@lwfinger.net>
26 **
27 *****************************************************************************
28 */
29
30#ifndef __RTL8723E_BTC_H__
31#define __RTL8723E_BTC_H__
32
33#include "../wifi.h"
34#include "hal_bt_coexist.h"
35
36struct bt_coexist_c2h_info {
37 u8 no_parse_c2h;
38 u8 has_c2h;
39};
40
41#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
new file mode 100644
index 00000000000..8c110356dff
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
@@ -0,0 +1,163 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 ****************************************************************************
29 */
30
31#ifndef __RTL8723E_DEF_H__
32#define __RTL8723E_DEF_H__
33
34#define HAL_PRIME_CHNL_OFFSET_LOWER 1
35
36#define RX_MPDU_QUEUE 0
37
38#define CHIP_8723 BIT(0)
39#define NORMAL_CHIP BIT(3)
40#define RF_TYPE_1T2R BIT(4)
41#define RF_TYPE_2T2R BIT(5)
42#define CHIP_VENDOR_UMC BIT(7)
43#define B_CUT_VERSION BIT(12)
44#define C_CUT_VERSION BIT(13)
45#define D_CUT_VERSION ((BIT(12)|BIT(13)))
46#define E_CUT_VERSION BIT(14)
47#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28))
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
55/* MASK */
56#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2))
57#define CHIP_TYPE_MASK BIT(3)
58#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6))
59#define MANUFACTUER_MASK BIT(7)
60#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8))
61#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12))
62
63/* Get element */
64#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK)
65#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK)
66#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK)
67
68#define IS_81XXC(version) ((GET_CVID_IC_TYPE(version) == 0) ?\
69 true : false)
70#define IS_8723_SERIES(version) \
71 ((GET_CVID_IC_TYPE(version) == CHIP_8723) ? true : false)
72#define IS_CHIP_VENDOR_UMC(version) \
73 ((GET_CVID_MANUFACTUER(version)) ? true : false)
74
75#define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? \
76 ((GET_CVID_CUT_VERSION(version)) ? false : true) : false)
77#define IS_VENDOR_8723_A_CUT(version) ((IS_8723_SERIES(version)) ? \
78 ((GET_CVID_CUT_VERSION(version)) ? false : true) : false)
79#define IS_81xxC_VENDOR_UMC_B_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) \
80 ? ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? \
81 true : false) : false)
82
83enum rf_optype {
84 RF_OP_BY_SW_3WIRE = 0,
85 RF_OP_BY_FW,
86 RF_OP_MAX
87};
88
89enum rf_power_state {
90 RF_ON,
91 RF_OFF,
92 RF_SLEEP,
93 RF_SHUT_DOWN,
94};
95
96enum power_save_mode {
97 POWER_SAVE_MODE_ACTIVE,
98 POWER_SAVE_MODE_SAVE,
99};
100
101enum power_polocy_config {
102 POWERCFG_MAX_POWER_SAVINGS,
103 POWERCFG_GLOBAL_POWER_SAVINGS,
104 POWERCFG_LOCAL_POWER_SAVINGS,
105 POWERCFG_LENOVO,
106};
107
108enum interface_select_pci {
109 INTF_SEL1_MINICARD = 0,
110 INTF_SEL0_PCIE = 1,
111 INTF_SEL2_RSV = 2,
112 INTF_SEL3_RSV = 3,
113};
114
115enum hal_fw_c2h_cmd_id {
116 HAL_FW_C2H_CMD_Read_MACREG = 0,
117 HAL_FW_C2H_CMD_Read_BBREG = 1,
118 HAL_FW_C2H_CMD_Read_RFREG = 2,
119 HAL_FW_C2H_CMD_Read_EEPROM = 3,
120 HAL_FW_C2H_CMD_Read_EFUSE = 4,
121 HAL_FW_C2H_CMD_Read_CAM = 5,
122 HAL_FW_C2H_CMD_Get_BasicRate = 6,
123 HAL_FW_C2H_CMD_Get_DataRate = 7,
124 HAL_FW_C2H_CMD_Survey = 8,
125 HAL_FW_C2H_CMD_SurveyDone = 9,
126 HAL_FW_C2H_CMD_JoinBss = 10,
127 HAL_FW_C2H_CMD_AddSTA = 11,
128 HAL_FW_C2H_CMD_DelSTA = 12,
129 HAL_FW_C2H_CMD_AtimDone = 13,
130 HAL_FW_C2H_CMD_TX_Report = 14,
131 HAL_FW_C2H_CMD_CCX_Report = 15,
132 HAL_FW_C2H_CMD_DTM_Report = 16,
133 HAL_FW_C2H_CMD_TX_Rate_Statistics = 17,
134 HAL_FW_C2H_CMD_C2HLBK = 18,
135 HAL_FW_C2H_CMD_C2HDBG = 19,
136 HAL_FW_C2H_CMD_C2HFEEDBACK = 20,
137 HAL_FW_C2H_CMD_MAX
138};
139
140enum rtl_desc_qsel {
141 QSLT_BK = 0x2,
142 QSLT_BE = 0x0,
143 QSLT_VI = 0x5,
144 QSLT_VO = 0x7,
145 QSLT_BEACON = 0x10,
146 QSLT_HIGH = 0x11,
147 QSLT_MGNT = 0x12,
148 QSLT_CMD = 0x13,
149};
150
151struct phy_sts_cck_8723e_t {
152 u8 adc_pwdb_X[4];
153 u8 sq_rpt;
154 u8 cck_agc_rpt;
155};
156
157struct h2c_cmd_8723e {
158 u8 element_id;
159 u32 cmd_len;
160 u8 *p_cmdbuffer;
161};
162
163#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
new file mode 100644
index 00000000000..12e2a3cb070
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
@@ -0,0 +1,920 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 ****************************************************************************
29 */
30
31#include "../wifi.h"
32#include "../base.h"
33#include "../pci.h"
34#include "reg.h"
35#include "def.h"
36#include "phy.h"
37#include "dm.h"
38#include "fw.h"
39#include "hal_btc.h"
40
41static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
42 0x7f8001fe,
43 0x788001e2,
44 0x71c001c7,
45 0x6b8001ae,
46 0x65400195,
47 0x5fc0017f,
48 0x5a400169,
49 0x55400155,
50 0x50800142,
51 0x4c000130,
52 0x47c0011f,
53 0x43c0010f,
54 0x40000100,
55 0x3c8000f2,
56 0x390000e4,
57 0x35c000d7,
58 0x32c000cb,
59 0x300000c0,
60 0x2d4000b5,
61 0x2ac000ab,
62 0x288000a2,
63 0x26000098,
64 0x24000090,
65 0x22000088,
66 0x20000080,
67 0x1e400079,
68 0x1c800072,
69 0x1b00006c,
70 0x19800066,
71 0x18000060,
72 0x16c0005b,
73 0x15800056,
74 0x14400051,
75 0x1300004c,
76 0x12000048,
77 0x11000044,
78 0x10000040,
79};
80
81static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
82 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
83 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
84 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
85 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
86 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
87 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
88 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
89 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
90 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
91 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
92 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
93 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
94 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
95 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
96 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
97 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
98 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
99 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
100 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
101 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
102 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
103 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
104 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
105 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
106 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
107 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
108 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
109 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
110 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
111 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
112 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
113 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
114 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
115};
116
117static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
118 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
119 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
120 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
121 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
122 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
123 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
124 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
125 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
126 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
127 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
128 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
129 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
130 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
131 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
132 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
133 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
134 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
135 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
136 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
137 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
138 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
139 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
140 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
141 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
142 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
143 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
144 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
145 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
146 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
147 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
148 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
149 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
150 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
151};
152
153static void rtl8723ae_dm_diginit(struct ieee80211_hw *hw)
154{
155 struct rtl_priv *rtlpriv = rtl_priv(hw);
156 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
157
158 dm_digtable->dig_enable_flag = true;
159 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
160 dm_digtable->cur_igvalue = 0x20;
161 dm_digtable->pre_igvalue = 0x0;
162 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
163 dm_digtable->presta_cstate = DIG_STA_DISCONNECT;
164 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
165 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
166 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
167 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
168 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
169 dm_digtable->rx_gain_range_max = DM_DIG_MAX;
170 dm_digtable->rx_gain_range_min = DM_DIG_MIN;
171 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
172 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
173 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
174 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
175 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
176}
177
178static u8 rtl_init_gain_min_pwdb(struct ieee80211_hw *hw)
179{
180 struct rtl_priv *rtlpriv = rtl_priv(hw);
181 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
182 long rssi_val_min = 0;
183
184 if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
185 (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) {
186 if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
187 rssi_val_min =
188 (rtlpriv->dm.entry_min_undec_sm_pwdb >
189 rtlpriv->dm.undec_sm_pwdb) ?
190 rtlpriv->dm.undec_sm_pwdb :
191 rtlpriv->dm.entry_min_undec_sm_pwdb;
192 else
193 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
194 } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT ||
195 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) {
196 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
197 } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
198 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
199 }
200
201 return (u8) rssi_val_min;
202}
203
204static void rtl8723ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
205{
206 u32 ret_value;
207 struct rtl_priv *rtlpriv = rtl_priv(hw);
208 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
209
210 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
211 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
212
213 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
214 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
215 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
216
217 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
218 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
219 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
220 falsealm_cnt->cnt_rate_illegal +
221 falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
222
223 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
224 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
225 falsealm_cnt->cnt_cck_fail = ret_value;
226
227 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
228 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
229 falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
230 falsealm_cnt->cnt_rate_illegal +
231 falsealm_cnt->cnt_crc8_fail +
232 falsealm_cnt->cnt_mcs_fail +
233 falsealm_cnt->cnt_cck_fail);
234
235 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
236 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
237 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
238 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
239
240 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
241 "cnt_parity_fail = %d, cnt_rate_illegal = %d, "
242 "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
243 falsealm_cnt->cnt_parity_fail,
244 falsealm_cnt->cnt_rate_illegal,
245 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
246
247 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
248 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
249 falsealm_cnt->cnt_ofdm_fail,
250 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
251}
252
253static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
254{
255 struct rtl_priv *rtlpriv = rtl_priv(hw);
256 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
257 u8 value_igi = dm_digtable->cur_igvalue;
258
259 if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
260 value_igi--;
261 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
262 value_igi += 0;
263 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
264 value_igi++;
265 else
266 value_igi += 2;
267
268 value_igi = clamp(value_igi, (u8)DM_DIG_FA_LOWER, (u8)DM_DIG_FA_UPPER);
269 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
270 value_igi = 0x32;
271
272 dm_digtable->cur_igvalue = value_igi;
273 rtl8723ae_dm_write_dig(hw);
274}
275
276static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
277{
278 struct rtl_priv *rtlpriv = rtl_priv(hw);
279 struct dig_t *dgtbl = &rtlpriv->dm_digtable;
280
281 if (rtlpriv->falsealm_cnt.cnt_all > dgtbl->fa_highthresh) {
282 if ((dgtbl->back_val - 2) < dgtbl->back_range_min)
283 dgtbl->back_val = dgtbl->back_range_min;
284 else
285 dgtbl->back_val -= 2;
286 } else if (rtlpriv->falsealm_cnt.cnt_all < dgtbl->fa_lowthresh) {
287 if ((dgtbl->back_val + 2) > dgtbl->back_range_max)
288 dgtbl->back_val = dgtbl->back_range_max;
289 else
290 dgtbl->back_val += 2;
291 }
292
293 if ((dgtbl->rssi_val_min + 10 - dgtbl->back_val) >
294 dgtbl->rx_gain_range_max)
295 dgtbl->cur_igvalue = dgtbl->rx_gain_range_max;
296 else if ((dgtbl->rssi_val_min + 10 -
297 dgtbl->back_val) < dgtbl->rx_gain_range_min)
298 dgtbl->cur_igvalue = dgtbl->rx_gain_range_min;
299 else
300 dgtbl->cur_igvalue = dgtbl->rssi_val_min + 10 - dgtbl->back_val;
301
302 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
303 "rssi_val_min = %x back_val %x\n",
304 dgtbl->rssi_val_min, dgtbl->back_val);
305
306 rtl8723ae_dm_write_dig(hw);
307}
308
309static void rtl8723ae_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
310{
311 struct rtl_priv *rtlpriv = rtl_priv(hw);
312 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
313 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
314 long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb;
315 bool multi_sta = false;
316
317 if (mac->opmode == NL80211_IFTYPE_ADHOC)
318 multi_sta = true;
319
320 if ((!multi_sta) ||
321 (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) {
322 rtlpriv->initialized = false;
323 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
324 return;
325 } else if (!rtlpriv->initialized) {
326 rtlpriv->initialized = true;
327 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
328 dm_digtable->cur_igvalue = 0x20;
329 rtl8723ae_dm_write_dig(hw);
330 }
331
332 if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
333 if ((rssi_strength < dm_digtable->rssi_lowthresh) &&
334 (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
335
336 if (dm_digtable->dig_ext_port_stage ==
337 DIG_EXT_PORT_STAGE_2) {
338 dm_digtable->cur_igvalue = 0x20;
339 rtl8723ae_dm_write_dig(hw);
340 }
341
342 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
343 } else if (rssi_strength > dm_digtable->rssi_highthresh) {
344 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
345 rtl92c_dm_ctrl_initgain_by_fa(hw);
346 }
347 } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
348 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
349 dm_digtable->cur_igvalue = 0x20;
350 rtl8723ae_dm_write_dig(hw);
351 }
352
353 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
354 "curmultista_cstate = %x dig_ext_port_stage %x\n",
355 dm_digtable->curmultista_cstate,
356 dm_digtable->dig_ext_port_stage);
357}
358
359static void rtl8723ae_dm_initial_gain_sta(struct ieee80211_hw *hw)
360{
361 struct rtl_priv *rtlpriv = rtl_priv(hw);
362 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
363
364 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
365 "presta_cstate = %x, cursta_cstate = %x\n",
366 dm_digtable->presta_cstate,
367 dm_digtable->cursta_cstate);
368
369 if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
370 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
371 dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
372
373 if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
374 dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw);
375 rtl92c_dm_ctrl_initgain_by_rssi(hw);
376 }
377 } else {
378 dm_digtable->rssi_val_min = 0;
379 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
380 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
381 dm_digtable->cur_igvalue = 0x20;
382 dm_digtable->pre_igvalue = 0;
383 rtl8723ae_dm_write_dig(hw);
384 }
385}
386static void rtl8723ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
387{
388 struct rtl_priv *rtlpriv = rtl_priv(hw);
389 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
390
391 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
392 dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw);
393
394 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
395 if (dm_digtable->rssi_val_min <= 25)
396 dm_digtable->cur_cck_pd_state =
397 CCK_PD_STAGE_LowRssi;
398 else
399 dm_digtable->cur_cck_pd_state =
400 CCK_PD_STAGE_HighRssi;
401 } else {
402 if (dm_digtable->rssi_val_min <= 20)
403 dm_digtable->cur_cck_pd_state =
404 CCK_PD_STAGE_LowRssi;
405 else
406 dm_digtable->cur_cck_pd_state =
407 CCK_PD_STAGE_HighRssi;
408 }
409 } else {
410 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
411 }
412
413 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
414 if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) {
415 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
416 dm_digtable->cur_cck_fa_state =
417 CCK_FA_STAGE_High;
418 else
419 dm_digtable->cur_cck_fa_state =
420 CCK_FA_STAGE_Low;
421
422 if (dm_digtable->pre_cck_fa_state !=
423 dm_digtable->cur_cck_fa_state) {
424 if (dm_digtable->cur_cck_fa_state ==
425 CCK_FA_STAGE_Low)
426 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
427 0x83);
428 else
429 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
430 0xcd);
431
432 dm_digtable->pre_cck_fa_state =
433 dm_digtable->cur_cck_fa_state;
434 }
435
436 rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
437
438 } else {
439 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
440 rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
441
442 }
443 dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
444 }
445
446 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
447 "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state);
448
449}
450
451static void rtl8723ae_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
452{
453 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
454 struct rtl_priv *rtlpriv = rtl_priv(hw);
455 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
456
457 if (mac->act_scanning == true)
458 return;
459
460 if (mac->link_state >= MAC80211_LINKED)
461 dm_digtable->cursta_cstate = DIG_STA_CONNECT;
462 else
463 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
464
465 rtl8723ae_dm_initial_gain_sta(hw);
466 rtl8723ae_dm_initial_gain_multi_sta(hw);
467 rtl8723ae_dm_cck_packet_detection_thresh(hw);
468
469 dm_digtable->presta_cstate = dm_digtable->cursta_cstate;
470
471}
472
473static void rtl8723ae_dm_dig(struct ieee80211_hw *hw)
474{
475 struct rtl_priv *rtlpriv = rtl_priv(hw);
476 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
477
478 if (rtlpriv->dm.dm_initialgain_enable == false)
479 return;
480 if (dm_digtable->dig_enable_flag == false)
481 return;
482
483 rtl8723ae_dm_ctrl_initgain_by_twoport(hw);
484}
485
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)
497{
498 struct rtl_priv *rtlpriv = rtl_priv(hw);
499 struct rtl_phy *rtlphy = &(rtlpriv->phy);
500 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
501 long undec_sm_pwdb;
502
503 if (!rtlpriv->dm.dynamic_txpower_enable)
504 return;
505
506 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
507 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
508 return;
509 }
510
511 if ((mac->link_state < MAC80211_LINKED) &&
512 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
513 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
514 "Not connected\n");
515
516 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
517
518 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
519 return;
520 }
521
522 if (mac->link_state >= MAC80211_LINKED) {
523 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
524 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
525 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
526 "AP Client PWDB = 0x%lx\n",
527 undec_sm_pwdb);
528 } else {
529 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
530 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
531 "STA Default Port PWDB = 0x%lx\n",
532 undec_sm_pwdb);
533 }
534 } else {
535 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
536
537 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
538 "AP Ext Port PWDB = 0x%lx\n",
539 undec_sm_pwdb);
540 }
541
542 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
543 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
544 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
545 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
546 } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
547 (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
548 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
549 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
550 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
551 } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
552 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
553 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
554 "TXHIGHPWRLEVEL_NORMAL\n");
555 }
556
557 if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
558 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
559 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
560 rtlphy->current_channel);
561 rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
562 }
563
564 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
565}
566
567void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw)
568{
569 struct rtl_priv *rtlpriv = rtl_priv(hw);
570 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
571
572 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
573 "cur_igvalue = 0x%x, "
574 "pre_igvalue = 0x%x, back_val = %d\n",
575 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
576 dm_digtable->back_val);
577
578 if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
579 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
580 dm_digtable->cur_igvalue);
581 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
582 dm_digtable->cur_igvalue);
583
584 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
585 }
586}
587
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)
602{
603 struct rtl_priv *rtlpriv = rtl_priv(hw);
604 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
605 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
606
607 u64 cur_txok_cnt = 0;
608 u64 cur_rxok_cnt = 0;
609 u32 edca_be_ul = 0x5ea42b;
610 u32 edca_be_dl = 0x5ea42b;
611 bool bt_change_edca = false;
612
613 if ((mac->last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) ||
614 (mac->last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) {
615 rtlpriv->dm.current_turbo_edca = false;
616 mac->last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
617 mac->last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl;
618 }
619
620 if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) {
621 edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
622 bt_change_edca = true;
623 }
624
625 if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) {
626 edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl;
627 bt_change_edca = true;
628 }
629
630 if (mac->link_state != MAC80211_LINKED) {
631 rtlpriv->dm.current_turbo_edca = false;
632 return;
633 }
634
635 if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) {
636 if (!(edca_be_ul & 0xffff0000))
637 edca_be_ul |= 0x005e0000;
638
639 if (!(edca_be_dl & 0xffff0000))
640 edca_be_dl |= 0x005e0000;
641 }
642
643 if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
644 (!rtlpriv->dm.disable_framebursting))) {
645
646 cur_txok_cnt = rtlpriv->stats.txbytesunicast -
647 mac->last_txok_cnt;
648 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast -
649 mac->last_rxok_cnt;
650
651 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
652 if (!rtlpriv->dm.is_cur_rdlstate ||
653 !rtlpriv->dm.current_turbo_edca) {
654 rtl_write_dword(rtlpriv,
655 REG_EDCA_BE_PARAM,
656 edca_be_dl);
657 rtlpriv->dm.is_cur_rdlstate = true;
658 }
659 } else {
660 if (rtlpriv->dm.is_cur_rdlstate ||
661 !rtlpriv->dm.current_turbo_edca) {
662 rtl_write_dword(rtlpriv,
663 REG_EDCA_BE_PARAM,
664 edca_be_ul);
665 rtlpriv->dm.is_cur_rdlstate = false;
666 }
667 }
668 rtlpriv->dm.current_turbo_edca = true;
669 } else {
670 if (rtlpriv->dm.current_turbo_edca) {
671 u8 tmp = AC0_BE;
672 rtlpriv->cfg->ops->set_hw_reg(hw,
673 HW_VAR_AC_PARAM,
674 (u8 *) (&tmp));
675 rtlpriv->dm.current_turbo_edca = false;
676 }
677 }
678
679 rtlpriv->dm.is_any_nonbepkts = false;
680 mac->last_txok_cnt = rtlpriv->stats.txbytesunicast;
681 mac->last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
682}
683
684static void rtl8723ae_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
685{
686 struct rtl_priv *rtlpriv = rtl_priv(hw);
687
688 rtlpriv->dm.txpower_tracking = true;
689 rtlpriv->dm.txpower_trackinginit = false;
690
691 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
692 "pMgntInfo->txpower_tracking = %d\n",
693 rtlpriv->dm.txpower_tracking);
694}
695
696void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
697{
698 struct rtl_priv *rtlpriv = rtl_priv(hw);
699 struct rate_adaptive *p_ra = &(rtlpriv->ra);
700
701 p_ra->ratr_state = DM_RATR_STA_INIT;
702 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
703
704 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
705 rtlpriv->dm.useramask = true;
706 else
707 rtlpriv->dm.useramask = false;
708}
709
710static void rtl8723ae_dm_init_dynamic_bpowersaving(struct ieee80211_hw *hw)
711{
712 struct rtl_priv *rtlpriv = rtl_priv(hw);
713
714 rtlpriv->dm_pstable.pre_ccastate = CCA_MAX;
715 rtlpriv->dm_pstable.cur_ccasate = CCA_MAX;
716 rtlpriv->dm_pstable.pre_rfstate = RF_MAX;
717 rtlpriv->dm_pstable.cur_rfstate = RF_MAX;
718 rtlpriv->dm_pstable.rssi_val_min = 0;
719}
720
721void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal)
722{
723 struct rtl_priv *rtlpriv = rtl_priv(hw);
724 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
725
726 if (!rtlpriv->reg_init) {
727 rtlpriv->reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
728 MASKDWORD) & 0x1CC000) >> 14;
729
730 rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
731 MASKDWORD) & BIT(3)) >> 3;
732
733 rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
734 MASKDWORD) & 0xFF000000) >> 24;
735
736 rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) &
737 0xF000) >> 12;
738
739 rtlpriv->reg_init = true;
740 }
741
742 if (!force_in_normal) {
743 if (dm_pstable->rssi_val_min != 0) {
744 if (dm_pstable->pre_rfstate == RF_NORMAL) {
745 if (dm_pstable->rssi_val_min >= 30)
746 dm_pstable->cur_rfstate = RF_SAVE;
747 else
748 dm_pstable->cur_rfstate = RF_NORMAL;
749 } else {
750 if (dm_pstable->rssi_val_min <= 25)
751 dm_pstable->cur_rfstate = RF_NORMAL;
752 else
753 dm_pstable->cur_rfstate = RF_SAVE;
754 }
755 } else {
756 dm_pstable->cur_rfstate = RF_MAX;
757 }
758 } else {
759 dm_pstable->cur_rfstate = RF_NORMAL;
760 }
761
762 if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) {
763 if (dm_pstable->cur_rfstate == RF_SAVE) {
764
765 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
766 BIT(5), 0x1);
767 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
768 0x1C0000, 0x2);
769 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
770 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
771 0xFF000000, 0x63);
772 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
773 0xC000, 0x2);
774 rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
775 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
776 rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
777 } else {
778 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
779 0x1CC000, rtlpriv->reg_874);
780 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
781 rtlpriv->reg_c70);
782 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
783 rtlpriv->reg_85c);
784 rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74);
785 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
786 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
787 BIT(5), 0x0);
788 }
789
790 dm_pstable->pre_rfstate = dm_pstable->cur_rfstate;
791 }
792}
793
794static void rtl8723ae_dm_dynamic_bpowersaving(struct ieee80211_hw *hw)
795{
796 struct rtl_priv *rtlpriv = rtl_priv(hw);
797 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
798 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
799
800 if (((mac->link_state == MAC80211_NOLINK)) &&
801 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
802 dm_pstable->rssi_val_min = 0;
803 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
804 "Not connected to any\n");
805 }
806
807 if (mac->link_state == MAC80211_LINKED) {
808 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
809 dm_pstable->rssi_val_min =
810 rtlpriv->dm.entry_min_undec_sm_pwdb;
811 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
812 "AP Client PWDB = 0x%lx\n",
813 dm_pstable->rssi_val_min);
814 } else {
815 dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
816 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
817 "STA Default Port PWDB = 0x%lx\n",
818 dm_pstable->rssi_val_min);
819 }
820 } else {
821 dm_pstable->rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
822
823 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
824 "AP Ext Port PWDB = 0x%lx\n",
825 dm_pstable->rssi_val_min);
826 }
827
828 rtl8723ae_dm_rf_saving(hw, false);
829}
830
831void rtl8723ae_dm_init(struct ieee80211_hw *hw)
832{
833 struct rtl_priv *rtlpriv = rtl_priv(hw);
834
835 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
836 rtl8723ae_dm_diginit(hw);
837 rtl8723ae_dm_init_dynamic_txpower(hw);
838 rtl8723ae_dm_init_edca_turbo(hw);
839 rtl8723ae_dm_init_rate_adaptive_mask(hw);
840 rtl8723ae_dm_initialize_txpower_tracking(hw);
841 rtl8723ae_dm_init_dynamic_bpowersaving(hw);
842}
843
844void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw)
845{
846 struct rtl_priv *rtlpriv = rtl_priv(hw);
847 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
848 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
849 bool fw_current_inpsmode = false;
850 bool fw_ps_awake = true;
851 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
852 (u8 *) (&fw_current_inpsmode));
853 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
854 (u8 *) (&fw_ps_awake));
855
856 if ((ppsc->rfpwr_state == ERFON) &&
857 ((!fw_current_inpsmode) && fw_ps_awake) &&
858 (!ppsc->rfchange_inprogress)) {
859 rtl8723ae_dm_pwdmonitor(hw);
860 rtl8723ae_dm_dig(hw);
861 rtl8723ae_dm_false_alarm_counter_statistics(hw);
862 rtl8723ae_dm_dynamic_bpowersaving(hw);
863 rtl8723ae_dm_dynamic_txpower(hw);
864 /* rtl92c_dm_refresh_rate_adaptive_mask(hw); */
865 rtl8723ae_dm_bt_coexist(hw);
866 rtl8723ae_dm_check_edca_turbo(hw);
867 }
868 if (rtlpcipriv->bt_coexist.init_set)
869 rtl_write_byte(rtlpriv, 0x76e, 0xc);
870}
871
872static void rtl8723ae_dm_init_bt_coexist(struct ieee80211_hw *hw)
873{
874 struct rtl_priv *rtlpriv = rtl_priv(hw);
875 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
876
877 rtlpcipriv->bt_coexist.bt_rfreg_origin_1e
878 = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff);
879 rtlpcipriv->bt_coexist.bt_rfreg_origin_1f
880 = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0);
881
882 rtlpcipriv->bt_coexist.cstate = 0;
883 rtlpcipriv->bt_coexist.previous_state = 0;
884 rtlpcipriv->bt_coexist.cstate_h = 0;
885 rtlpcipriv->bt_coexist.previous_state_h = 0;
886 rtlpcipriv->bt_coexist.lps_counter = 0;
887
888 /* Enable counter statistics */
889 rtl_write_byte(rtlpriv, 0x76e, 0x4);
890 rtl_write_byte(rtlpriv, 0x778, 0x3);
891 rtl_write_byte(rtlpriv, 0x40, 0x20);
892
893 rtlpcipriv->bt_coexist.init_set = true;
894}
895
896void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw)
897{
898 struct rtl_priv *rtlpriv = rtl_priv(hw);
899 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
900 u8 tmp_byte = 0;
901 if (!rtlpcipriv->bt_coexist.bt_coexistence) {
902 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
903 "[DM]{BT], BT not exist!!\n");
904 return;
905 }
906
907 if (!rtlpcipriv->bt_coexist.init_set) {
908 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
909 "[DM][BT], rtl8723ae_dm_bt_coexist()\n");
910
911 rtl8723ae_dm_init_bt_coexist(hw);
912 }
913
914 tmp_byte = rtl_read_byte(rtlpriv, 0x40);
915 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
916 "[DM][BT], 0x40 is 0x%x", tmp_byte);
917 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
918 "[DM][BT], bt_dm_coexist start");
919 rtl8723ae_dm_bt_coexist_8723(hw);
920}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
new file mode 100644
index 00000000000..39d24619624
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
@@ -0,0 +1,149 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 ****************************************************************************
29 */
30
31#ifndef __RTL8723E_DM_H__
32#define __RTL8723E_DM_H__
33
34#define HAL_DM_HIPWR_DISABLE BIT(1)
35
36#define OFDM_TABLE_SIZE 37
37#define CCK_TABLE_SIZE 33
38
39#define DM_DIG_THRESH_HIGH 40
40#define DM_DIG_THRESH_LOW 35
41
42#define DM_FALSEALARM_THRESH_LOW 400
43#define DM_FALSEALARM_THRESH_HIGH 1000
44
45#define DM_DIG_MAX 0x3e
46#define DM_DIG_MIN 0x1e
47
48#define DM_DIG_FA_UPPER 0x32
49#define DM_DIG_FA_LOWER 0x20
50#define DM_DIG_FA_TH0 0x20
51#define DM_DIG_FA_TH1 0x100
52#define DM_DIG_FA_TH2 0x200
53
54#define DM_DIG_BACKOFF_MAX 12
55#define DM_DIG_BACKOFF_MIN -4
56#define DM_DIG_BACKOFF_DEFAULT 10
57
58#define DM_RATR_STA_INIT 0
59
60#define TXHIGHPWRLEVEL_NORMAL 0
61#define TXHIGHPWRLEVEL_LEVEL1 1
62#define TXHIGHPWRLEVEL_LEVEL2 2
63#define TXHIGHPWRLEVEL_BT1 3
64#define TXHIGHPWRLEVEL_BT2 4
65
66#define DM_TYPE_BYDRIVER 1
67
68#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
69#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
70
71struct swat_t {
72 u8 failure_cnt;
73 u8 try_flag;
74 u8 stop_trying;
75 long pre_rssi;
76 long trying_threshold;
77 u8 cur_antenna;
78 u8 pre_antenna;
79};
80
81enum tag_dynamic_init_gain_operation_type_definition {
82 DIG_TYPE_THRESH_HIGH = 0,
83 DIG_TYPE_THRESH_LOW = 1,
84 DIG_TYPE_BACKOFF = 2,
85 DIG_TYPE_RX_GAIN_MIN = 3,
86 DIG_TYPE_RX_GAIN_MAX = 4,
87 DIG_TYPE_ENABLE = 5,
88 DIG_TYPE_DISABLE = 6,
89 DIG_OP_TYPE_MAX
90};
91
92enum tag_cck_packet_detection_threshold_type_definition {
93 CCK_PD_STAGE_LowRssi = 0,
94 CCK_PD_STAGE_HighRssi = 1,
95 CCK_FA_STAGE_Low = 2,
96 CCK_FA_STAGE_High = 3,
97 CCK_PD_STAGE_MAX = 4,
98};
99
100enum dm_1r_cca_e {
101 CCA_1R = 0,
102 CCA_2R = 1,
103 CCA_MAX = 2,
104};
105
106enum dm_rf_e {
107 RF_SAVE = 0,
108 RF_NORMAL = 1,
109 RF_MAX = 2,
110};
111
112enum dm_sw_ant_switch_e {
113 ANS_ANTENNA_B = 1,
114 ANS_ANTENNA_A = 2,
115 ANS_ANTENNA_MAX = 3,
116};
117
118enum dm_dig_ext_port_alg_e {
119 DIG_EXT_PORT_STAGE_0 = 0,
120 DIG_EXT_PORT_STAGE_1 = 1,
121 DIG_EXT_PORT_STAGE_2 = 2,
122 DIG_EXT_PORT_STAGE_3 = 3,
123 DIG_EXT_PORT_STAGE_MAX = 4,
124};
125
126enum dm_dig_connect_e {
127 DIG_STA_DISCONNECT = 0,
128 DIG_STA_CONNECT = 1,
129 DIG_STA_BEFORE_CONNECT = 2,
130 DIG_MULTISTA_DISCONNECT = 3,
131 DIG_MULTISTA_CONNECT = 4,
132 DIG_CONNECT_MAX
133};
134
135#define GET_UNDECORATED_AVERAGE_RSSI(_priv) \
136 ((((struct rtl_priv *)(_priv))->mac80211.opmode == \
137 NL80211_IFTYPE_ADHOC) ? \
138 (((struct rtl_priv *)(_priv))->dm.entry_min_undec_sm_pwdb) \
139 : (((struct rtl_priv *)(_priv))->dm.undec_sm_pwdb))
140
141void rtl8723ae_dm_init(struct ieee80211_hw *hw);
142void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw);
143void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw);
144void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw);
145void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
146void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
147void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw);
148
149#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
new file mode 100644
index 00000000000..f55b1767ef5
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
@@ -0,0 +1,745 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 ****************************************************************************
29 */
30
31#include "../wifi.h"
32#include "../pci.h"
33#include "../base.h"
34#include "reg.h"
35#include "def.h"
36#include "fw.h"
37
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
231static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
232{
233 struct rtl_priv *rtlpriv = rtl_priv(hw);
234 u8 val_hmetfr, val_mcutst_1;
235 bool result = false;
236
237 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
238 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
239
240 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
241 result = true;
242 return result;
243}
244
245static void _rtl8723ae_fill_h2c_command(struct ieee80211_hw *hw,
246 u8 element_id, u32 cmd_len,
247 u8 *p_cmdbuffer)
248{
249 struct rtl_priv *rtlpriv = rtl_priv(hw);
250 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
251 u8 boxnum;
252 u16 box_reg = 0, box_extreg = 0;
253 u8 u1tmp;
254 bool isfw_rd = false;
255 bool bwrite_sucess = false;
256 u8 wait_h2c_limmit = 100;
257 u8 wait_writeh2c_limmit = 100;
258 u8 boxcontent[4], boxextcontent[2];
259 u32 h2c_waitcounter = 0;
260 unsigned long flag;
261 u8 idx;
262
263 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
264
265 while (true) {
266 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
267 if (rtlhal->h2c_setinprogress) {
268 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
269 "H2C set in progress! Wait to set..element_id(%d).\n",
270 element_id);
271
272 while (rtlhal->h2c_setinprogress) {
273 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
274 flag);
275 h2c_waitcounter++;
276 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
277 "Wait 100 us (%d times)...\n",
278 h2c_waitcounter);
279 udelay(100);
280
281 if (h2c_waitcounter > 1000)
282 return;
283 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
284 flag);
285 }
286 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
287 } else {
288 rtlhal->h2c_setinprogress = true;
289 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
290 break;
291 }
292 }
293
294 while (!bwrite_sucess) {
295 wait_writeh2c_limmit--;
296 if (wait_writeh2c_limmit == 0) {
297 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
298 "Write H2C fail because no trigger "
299 "for FW INT!\n");
300 break;
301 }
302
303 boxnum = rtlhal->last_hmeboxnum;
304 switch (boxnum) {
305 case 0:
306 box_reg = REG_HMEBOX_0;
307 box_extreg = REG_HMEBOX_EXT_0;
308 break;
309 case 1:
310 box_reg = REG_HMEBOX_1;
311 box_extreg = REG_HMEBOX_EXT_1;
312 break;
313 case 2:
314 box_reg = REG_HMEBOX_2;
315 box_extreg = REG_HMEBOX_EXT_2;
316 break;
317 case 3:
318 box_reg = REG_HMEBOX_3;
319 box_extreg = REG_HMEBOX_EXT_3;
320 break;
321 default:
322 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
323 "switch case not processed\n");
324 break;
325 }
326
327 isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum);
328 while (!isfw_rd) {
329
330 wait_h2c_limmit--;
331 if (wait_h2c_limmit == 0) {
332 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
333 "Wating too long for FW read clear HMEBox(%d)!\n",
334 boxnum);
335 break;
336 }
337
338 udelay(10);
339
340 isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum);
341 u1tmp = rtl_read_byte(rtlpriv, 0x1BF);
342 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
343 "Wating for FW read clear HMEBox(%d)!!! "
344 "0x1BF = %2x\n", boxnum, u1tmp);
345 }
346
347 if (!isfw_rd) {
348 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
349 "Write H2C register BOX[%d] fail!!!!! "
350 "Fw do not read.\n", boxnum);
351 break;
352 }
353
354 memset(boxcontent, 0, sizeof(boxcontent));
355 memset(boxextcontent, 0, sizeof(boxextcontent));
356 boxcontent[0] = element_id;
357 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
358 "Write element_id box_reg(%4x) = %2x\n",
359 box_reg, element_id);
360
361 switch (cmd_len) {
362 case 1:
363 boxcontent[0] &= ~(BIT(7));
364 memcpy((u8 *) (boxcontent) + 1,
365 p_cmdbuffer, 1);
366
367 for (idx = 0; idx < 4; idx++) {
368 rtl_write_byte(rtlpriv, box_reg + idx,
369 boxcontent[idx]);
370 }
371 break;
372 case 2:
373 boxcontent[0] &= ~(BIT(7));
374 memcpy((u8 *) (boxcontent) + 1,
375 p_cmdbuffer, 2);
376
377 for (idx = 0; idx < 4; idx++) {
378 rtl_write_byte(rtlpriv, box_reg + idx,
379 boxcontent[idx]);
380 }
381 break;
382 case 3:
383 boxcontent[0] &= ~(BIT(7));
384 memcpy((u8 *) (boxcontent) + 1,
385 p_cmdbuffer, 3);
386
387 for (idx = 0; idx < 4; idx++) {
388 rtl_write_byte(rtlpriv, box_reg + idx,
389 boxcontent[idx]);
390 }
391 break;
392 case 4:
393 boxcontent[0] |= (BIT(7));
394 memcpy((u8 *) (boxextcontent),
395 p_cmdbuffer, 2);
396 memcpy((u8 *) (boxcontent) + 1,
397 p_cmdbuffer + 2, 2);
398
399 for (idx = 0; idx < 2; idx++) {
400 rtl_write_byte(rtlpriv, box_extreg + idx,
401 boxextcontent[idx]);
402 }
403
404 for (idx = 0; idx < 4; idx++) {
405 rtl_write_byte(rtlpriv, box_reg + idx,
406 boxcontent[idx]);
407 }
408 break;
409 case 5:
410 boxcontent[0] |= (BIT(7));
411 memcpy((u8 *) (boxextcontent),
412 p_cmdbuffer, 2);
413 memcpy((u8 *) (boxcontent) + 1,
414 p_cmdbuffer + 2, 3);
415
416 for (idx = 0; idx < 2; idx++) {
417 rtl_write_byte(rtlpriv, box_extreg + idx,
418 boxextcontent[idx]);
419 }
420
421 for (idx = 0; idx < 4; idx++) {
422 rtl_write_byte(rtlpriv, box_reg + idx,
423 boxcontent[idx]);
424 }
425 break;
426 default:
427 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
428 "switch case not process\n");
429 break;
430 }
431
432 bwrite_sucess = true;
433
434 rtlhal->last_hmeboxnum = boxnum + 1;
435 if (rtlhal->last_hmeboxnum == 4)
436 rtlhal->last_hmeboxnum = 0;
437
438 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
439 "pHalData->last_hmeboxnum = %d\n",
440 rtlhal->last_hmeboxnum);
441 }
442
443 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
444 rtlhal->h2c_setinprogress = false;
445 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
446
447 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
448}
449
450void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw,
451 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
452{
453 struct rtl_priv *rtlpriv = rtl_priv(hw);
454 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
455
456 if (rtlhal->fw_ready == false) {
457 RT_ASSERT(false,
458 "return H2C cmd because of Fw download fail!!!\n");
459 return;
460 }
461
462 _rtl8723ae_fill_h2c_command(hw, element_id, cmd_len, p_cmdbuffer);
463 return;
464}
465
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, 1);
498 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
499 ppsc->reg_max_lps_awakeintvl);
500
501 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
502 "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
503 u1_h2c_set_pwrmode, 3);
504 rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
505
506}
507
508static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw,
509 struct sk_buff *skb)
510{
511 struct rtl_priv *rtlpriv = rtl_priv(hw);
512 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
513 struct rtl8192_tx_ring *ring;
514 struct rtl_tx_desc *pdesc;
515 u8 own;
516 unsigned long flags;
517 struct sk_buff *pskb = NULL;
518
519 ring = &rtlpci->tx_ring[BEACON_QUEUE];
520
521 pskb = __skb_dequeue(&ring->queue);
522 if (pskb)
523 kfree_skb(pskb);
524
525 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
526
527 pdesc = &ring->desc[0];
528 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
529
530 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
531
532 __skb_queue_tail(&ring->queue, skb);
533
534 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
535
536 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
537
538 return true;
539}
540
541static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
542 /* page 0 beacon */
543 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
544 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
545 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
548 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
549 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
550 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
551 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
552 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
553 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
557 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559
560 /* page 1 beacon */
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577
578 /* page 2 ps-poll */
579 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
580 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
593 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595
596 /* page 3 null */
597 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
598 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
599 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
611 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613
614 /* page 4 probe_resp */
615 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
616 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
617 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
618 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
619 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
620 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
621 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
622 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
623 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
624 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
625 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
629 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631
632 /* page 5 probe_resp */
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649};
650
651void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
652{
653 struct rtl_priv *rtlpriv = rtl_priv(hw);
654 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
655 struct sk_buff *skb = NULL;
656
657 u32 totalpacketlen;
658 bool rtstatus;
659 u8 u1RsvdPageLoc[3] = { 0 };
660 bool dlok = false;
661
662 u8 *beacon;
663 u8 *p_pspoll;
664 u8 *nullfunc;
665 u8 *p_probersp;
666 /*---------------------------------------------------------
667 (1) beacon
668 ---------------------------------------------------------
669 */
670 beacon = &reserved_page_packet[BEACON_PG * 128];
671 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
672 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
673
674 /*-------------------------------------------------------
675 (2) ps-poll
676 --------------------------------------------------------
677 */
678 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
679 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
680 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
681 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
682
683 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
684
685 /*--------------------------------------------------------
686 (3) null data
687 ---------------------------------------------------------i
688 */
689 nullfunc = &reserved_page_packet[NULL_PG * 128];
690 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
691 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
692 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
693
694 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
695
696 /*---------------------------------------------------------
697 (4) probe response
698 ----------------------------------------------------------
699 */
700 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
701 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
702 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
703 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
704
705 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
706
707 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
708
709 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
710 "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
711 &reserved_page_packet[0], totalpacketlen);
712 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
713 "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
714 u1RsvdPageLoc, 3);
715
716 skb = dev_alloc_skb(totalpacketlen);
717 memcpy((u8 *) skb_put(skb, totalpacketlen),
718 &reserved_page_packet, totalpacketlen);
719
720 rtstatus = _rtl8723ae_cmd_send_packet(hw, skb);
721
722 if (rtstatus)
723 dlok = true;
724
725 if (dlok) {
726 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
727 "Set RSVD page location to Fw.\n");
728 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
729 "H2C_RSVDPAGE:\n",
730 u1RsvdPageLoc, 3);
731 rtl8723ae_fill_h2c_cmd(hw, H2C_RSVDPAGE,
732 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
733 } else
734 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
735 "Set RSVD page location to Fw FAIL!!!!!!.\n");
736}
737
738void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
739{
740 u8 u1_joinbssrpt_parm[1] = { 0 };
741
742 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
743
744 rtl8723ae_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
745}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
new file mode 100644
index 00000000000..89994e16dc8
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
@@ -0,0 +1,101 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 * Larry Finger <Larry.Finger@lwfinger.net>
26 *
27 ****************************************************************************
28 */
29
30#ifndef __RTL92C__FW__H__
31#define __RTL92C__FW__H__
32
33#define FW_8192C_START_ADDRESS 0x1000
34#define FW_8192C_END_ADDRESS 0x3FFF
35#define FW_8192C_PAGE_SIZE 4096
36#define FW_8192C_POLLING_DELAY 5
37#define FW_8192C_POLLING_TIMEOUT_COUNT 1000
38
39#define BEACON_PG 0
40#define PSPOLL_PG 2
41#define NULL_PG 3
42#define PROBERSP_PG 4 /* ->5 */
43
44#define TOTAL_RESERVED_PKT_LEN 768
45
46#define IS_FW_HEADER_EXIST(_pfwhdr) \
47 ((_pfwhdr->signature&0xFF00) == 0x2300)
48
49struct rtl8723ae_firmware_header {
50 u16 signature;
51 u8 category;
52 u8 function;
53 u16 version;
54 u8 subversion;
55 u8 rsvd1;
56 u8 month;
57 u8 date;
58 u8 hour;
59 u8 minute;
60 u16 ramcodeSize;
61 u16 rsvd2;
62 u32 svnindex;
63 u32 rsvd3;
64 u32 rsvd4;
65 u32 rsvd5;
66};
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 = 5,
74 H2C_RA_MASK = 6,
75 MAX_H2CCMD
76};
77
78#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
79 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
80#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
81 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
82#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \
83 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
84#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
85 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
86#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
87 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
88#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
89 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
90#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
91 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
92
93int rtl8723ae_download_fw(struct ieee80211_hw *hw);
94void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
95 u32 cmd_len, u8 *p_cmdbuffer);
96void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw);
97void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
98void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
99void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
100
101#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
new file mode 100644
index 00000000000..3d092e4b0b7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
@@ -0,0 +1,542 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "hal_bt_coexist.h"
31#include "../pci.h"
32#include "dm.h"
33#include "fw.h"
34#include "phy.h"
35#include "reg.h"
36#include "hal_btc.h"
37
38void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw,
39 bool reject)
40{
41}
42
43void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw)
44{
45 struct rtl_priv *rtlpriv = rtl_priv(hw);
46 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
47 struct rtl_phy *rtlphy = &(rtlpriv->phy);
48
49 if (rtlpriv->link_info.busytraffic) {
50 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_IDLE;
51
52 if (rtlpriv->link_info.tx_busy_traffic)
53 rtlpcipriv->bt_coexist.cstate |=
54 BT_COEX_STATE_WIFI_UPLINK;
55 else
56 rtlpcipriv->bt_coexist.cstate &=
57 ~BT_COEX_STATE_WIFI_UPLINK;
58
59 if (rtlpriv->link_info.rx_busy_traffic)
60 rtlpcipriv->bt_coexist.cstate |=
61 BT_COEX_STATE_WIFI_DOWNLINK;
62 else
63 rtlpcipriv->bt_coexist.cstate &=
64 ~BT_COEX_STATE_WIFI_DOWNLINK;
65 } else {
66 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_IDLE;
67 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_UPLINK;
68 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_DOWNLINK;
69 }
70
71 if (rtlpriv->mac80211.mode == WIRELESS_MODE_G ||
72 rtlpriv->mac80211.mode == WIRELESS_MODE_B) {
73 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_LEGACY;
74 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT20;
75 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT40;
76 } else {
77 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_LEGACY;
78 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
79 rtlpcipriv->bt_coexist.cstate |=
80 BT_COEX_STATE_WIFI_HT40;
81 rtlpcipriv->bt_coexist.cstate &=
82 ~BT_COEX_STATE_WIFI_HT20;
83 } else {
84 rtlpcipriv->bt_coexist.cstate |=
85 BT_COEX_STATE_WIFI_HT20;
86 rtlpcipriv->bt_coexist.cstate &=
87 ~BT_COEX_STATE_WIFI_HT40;
88 }
89 }
90
91 if (rtlpriv->bt_operation_on)
92 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT30;
93 else
94 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT30;
95}
96
97u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw,
98 u8 level_num, u8 rssi_thresh,
99 u8 rssi_thresh1)
100
101{
102 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
103 struct rtl_priv *rtlpriv = rtl_priv(hw);
104 long smooth;
105 u8 bt_rssi_state = 0;
106
107 smooth = rtl8723ae_dm_bt_get_rx_ss(hw);
108
109 if (level_num == 2) {
110 rtlpcipriv->bt_coexist.cstate &=
111 ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
112
113 if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
114 BT_RSSI_STATE_LOW) ||
115 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
116 BT_RSSI_STATE_STAY_LOW)) {
117 if (smooth >= (rssi_thresh +
118 BT_FW_COEX_THRESH_TOL)) {
119 bt_rssi_state = BT_RSSI_STATE_HIGH;
120 rtlpcipriv->bt_coexist.cstate |=
121 BT_COEX_STATE_WIFI_RSSI_1_HIGH;
122 rtlpcipriv->bt_coexist.cstate &=
123 ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
124 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
125 "[DM][BT], RSSI_1 state switch to High\n");
126 } else {
127 bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
128 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
129 "[DM][BT], RSSI_1 state stay at Low\n");
130 }
131 } else {
132 if (smooth < rssi_thresh) {
133 bt_rssi_state = BT_RSSI_STATE_LOW;
134 rtlpcipriv->bt_coexist.cstate |=
135 BT_COEX_STATE_WIFI_RSSI_1_LOW;
136 rtlpcipriv->bt_coexist.cstate &=
137 ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
138 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
139 "[DM][BT], RSSI_1 state switch to Low\n");
140 } else {
141 bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
142 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
143 "[DM][BT], RSSI_1 state stay at High\n");
144 }
145 }
146 } else if (level_num == 3) {
147 if (rssi_thresh > rssi_thresh1) {
148 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
149 "[DM][BT], RSSI_1 thresh error!!\n");
150 return rtlpcipriv->bt_coexist.bt_pre_rssi_state;
151 }
152
153 if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
154 BT_RSSI_STATE_LOW) ||
155 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
156 BT_RSSI_STATE_STAY_LOW)) {
157 if (smooth >=
158 (rssi_thresh+BT_FW_COEX_THRESH_TOL)) {
159 bt_rssi_state = BT_RSSI_STATE_MEDIUM;
160 rtlpcipriv->bt_coexist.cstate |=
161 BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
162 rtlpcipriv->bt_coexist.cstate &=
163 ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
164 rtlpcipriv->bt_coexist.cstate &=
165 ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
166 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
167 "[DM][BT], RSSI_1 state switch to Medium\n");
168 } else {
169 bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
170 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
171 "[DM][BT], RSSI_1 state stay at Low\n");
172 }
173 } else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
174 BT_RSSI_STATE_MEDIUM) ||
175 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
176 BT_RSSI_STATE_STAY_MEDIUM)) {
177 if (smooth >= (rssi_thresh1 +
178 BT_FW_COEX_THRESH_TOL)) {
179 bt_rssi_state = BT_RSSI_STATE_HIGH;
180 rtlpcipriv->bt_coexist.cstate |=
181 BT_COEX_STATE_WIFI_RSSI_1_HIGH;
182 rtlpcipriv->bt_coexist.cstate &=
183 ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
184 rtlpcipriv->bt_coexist.cstate &=
185 ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
186 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
187 "[DM][BT], RSSI_1 state switch to High\n");
188 } else if (smooth < rssi_thresh) {
189 bt_rssi_state = BT_RSSI_STATE_LOW;
190 rtlpcipriv->bt_coexist.cstate |=
191 BT_COEX_STATE_WIFI_RSSI_1_LOW;
192 rtlpcipriv->bt_coexist.cstate &=
193 ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
194 rtlpcipriv->bt_coexist.cstate &=
195 ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
196 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
197 "[DM][BT], RSSI_1 state switch to Low\n");
198 } else {
199 bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
200 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
201 "[DM][BT], RSSI_1 state stay at Medium\n");
202 }
203 } else {
204 if (smooth < rssi_thresh1) {
205 bt_rssi_state = BT_RSSI_STATE_MEDIUM;
206 rtlpcipriv->bt_coexist.cstate |=
207 BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
208 rtlpcipriv->bt_coexist.cstate &=
209 ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
210 rtlpcipriv->bt_coexist.cstate &=
211 ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
212 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
213 "[DM][BT], RSSI_1 state switch to Medium\n");
214 } else {
215 bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
216 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
217 "[DM][BT], RSSI_1 state stay at High\n");
218 }
219 }
220 }
221
222 rtlpcipriv->bt_coexist.bt_pre_rssi_state1 = bt_rssi_state;
223
224 return bt_rssi_state;
225}
226
227u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw,
228 u8 level_num, u8 rssi_thresh,
229 u8 rssi_thresh1)
230{
231 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
232 struct rtl_priv *rtlpriv = rtl_priv(hw);
233 long smooth;
234 u8 bt_rssi_state = 0;
235
236 smooth = rtl8723ae_dm_bt_get_rx_ss(hw);
237
238 if (level_num == 2) {
239 rtlpcipriv->bt_coexist.cstate &=
240 ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
241
242 if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
243 BT_RSSI_STATE_LOW) ||
244 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
245 BT_RSSI_STATE_STAY_LOW)){
246 if (smooth >=
247 (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
248 bt_rssi_state = BT_RSSI_STATE_HIGH;
249 rtlpcipriv->bt_coexist.cstate |=
250 BT_COEX_STATE_WIFI_RSSI_HIGH;
251 rtlpcipriv->bt_coexist.cstate &=
252 ~BT_COEX_STATE_WIFI_RSSI_LOW;
253 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
254 "[DM][BT], RSSI state switch to High\n");
255 } else {
256 bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
257 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
258 "[DM][BT], RSSI state stay at Low\n");
259 }
260 } else {
261 if (smooth < rssi_thresh) {
262 bt_rssi_state = BT_RSSI_STATE_LOW;
263 rtlpcipriv->bt_coexist.cstate |=
264 BT_COEX_STATE_WIFI_RSSI_LOW;
265 rtlpcipriv->bt_coexist.cstate &=
266 ~BT_COEX_STATE_WIFI_RSSI_HIGH;
267 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
268 "[DM][BT], RSSI state switch to Low\n");
269 } else {
270 bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
271 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
272 "[DM][BT], RSSI state stay at High\n");
273 }
274 }
275 } else if (level_num == 3) {
276 if (rssi_thresh > rssi_thresh1) {
277 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
278 "[DM][BT], RSSI thresh error!!\n");
279 return rtlpcipriv->bt_coexist.bt_pre_rssi_state;
280 }
281 if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
282 BT_RSSI_STATE_LOW) ||
283 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
284 BT_RSSI_STATE_STAY_LOW)) {
285 if (smooth >=
286 (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
287 bt_rssi_state = BT_RSSI_STATE_MEDIUM;
288 rtlpcipriv->bt_coexist.cstate
289 |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
290 rtlpcipriv->bt_coexist.cstate
291 &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
292 rtlpcipriv->bt_coexist.cstate
293 &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
294 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
295 "[DM][BT], RSSI state switch to Medium\n");
296 } else {
297 bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
298 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
299 "[DM][BT], RSSI state stay at Low\n");
300 }
301 } else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
302 BT_RSSI_STATE_MEDIUM) ||
303 (rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
304 BT_RSSI_STATE_STAY_MEDIUM)) {
305 if (smooth >=
306 (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) {
307 bt_rssi_state = BT_RSSI_STATE_HIGH;
308 rtlpcipriv->bt_coexist.cstate
309 |= BT_COEX_STATE_WIFI_RSSI_HIGH;
310 rtlpcipriv->bt_coexist.cstate
311 &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
312 rtlpcipriv->bt_coexist.cstate
313 &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
314 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
315 "[DM][BT], RSSI state switch to High\n");
316 } else if (smooth < rssi_thresh) {
317 bt_rssi_state = BT_RSSI_STATE_LOW;
318 rtlpcipriv->bt_coexist.cstate
319 |= BT_COEX_STATE_WIFI_RSSI_LOW;
320 rtlpcipriv->bt_coexist.cstate
321 &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
322 rtlpcipriv->bt_coexist.cstate
323 &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
324 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
325 "[DM][BT], RSSI state switch to Low\n");
326 } else {
327 bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
328 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
329 "[DM][BT], RSSI state stay at Medium\n");
330 }
331 } else {
332 if (smooth < rssi_thresh1) {
333 bt_rssi_state = BT_RSSI_STATE_MEDIUM;
334 rtlpcipriv->bt_coexist.cstate
335 |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
336 rtlpcipriv->bt_coexist.cstate
337 &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
338 rtlpcipriv->bt_coexist.cstate
339 &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
340 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
341 "[DM][BT], RSSI state switch to Medium\n");
342 } else {
343 bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
344 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
345 "[DM][BT], RSSI state stay at High\n");
346 }
347 }
348 }
349
350 rtlpcipriv->bt_coexist.bt_pre_rssi_state = bt_rssi_state;
351 return bt_rssi_state;
352}
353
354long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw)
355{
356 struct rtl_priv *rtlpriv = rtl_priv(hw);
357 long smooth = 0;
358
359 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
360 smooth = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
361 else
362 smooth = rtlpriv->dm.entry_min_undec_sm_pwdb;
363
364 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
365 "rtl8723ae_dm_bt_get_rx_ss() = %ld\n", smooth);
366
367 return smooth;
368}
369
370void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw,
371 bool balance_on, u8 ms0, u8 ms1)
372{
373 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
374 struct rtl_priv *rtlpriv = rtl_priv(hw);
375 u8 h2c_parameter[3] = {0};
376
377 if (balance_on) {
378 h2c_parameter[2] = 1;
379 h2c_parameter[1] = ms1;
380 h2c_parameter[0] = ms0;
381 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
382 } else {
383 h2c_parameter[2] = 0;
384 h2c_parameter[1] = 0;
385 h2c_parameter[0] = 0;
386 }
387 rtlpcipriv->bt_coexist.balance_on = balance_on;
388
389 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
390 "[DM][BT], Balance=[%s:%dms:%dms], write 0xc=0x%x\n",
391 balance_on ? "ON" : "OFF", ms0, ms1,
392 h2c_parameter[0]<<16 | h2c_parameter[1]<<8 | h2c_parameter[2]);
393
394 rtl8723ae_fill_h2c_cmd(hw, 0xc, 3, h2c_parameter);
395}
396
397
398void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type)
399{
400 struct rtl_priv *rtlpriv = rtl_priv(hw);
401 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
402
403 if (type == BT_AGCTABLE_OFF) {
404 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
405 "[BT]AGCTable Off!\n");
406 rtl_write_dword(rtlpriv, 0xc78, 0x641c0001);
407 rtl_write_dword(rtlpriv, 0xc78, 0x631d0001);
408 rtl_write_dword(rtlpriv, 0xc78, 0x621e0001);
409 rtl_write_dword(rtlpriv, 0xc78, 0x611f0001);
410 rtl_write_dword(rtlpriv, 0xc78, 0x60200001);
411
412 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
413 RF_RX_AGC_HP, 0xfffff, 0x32000);
414 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
415 RF_RX_AGC_HP, 0xfffff, 0x71000);
416 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
417 RF_RX_AGC_HP, 0xfffff, 0xb0000);
418 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
419 RF_RX_AGC_HP, 0xfffff, 0xfc000);
420 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
421 RF_RX_G1, 0xfffff, 0x30355);
422 } else if (type == BT_AGCTABLE_ON) {
423 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
424 "[BT]AGCTable On!\n");
425 rtl_write_dword(rtlpriv, 0xc78, 0x4e1c0001);
426 rtl_write_dword(rtlpriv, 0xc78, 0x4d1d0001);
427 rtl_write_dword(rtlpriv, 0xc78, 0x4c1e0001);
428 rtl_write_dword(rtlpriv, 0xc78, 0x4b1f0001);
429 rtl_write_dword(rtlpriv, 0xc78, 0x4a200001);
430
431 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
432 RF_RX_AGC_HP, 0xfffff, 0xdc000);
433 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
434 RF_RX_AGC_HP, 0xfffff, 0x90000);
435 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
436 RF_RX_AGC_HP, 0xfffff, 0x51000);
437 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
438 RF_RX_AGC_HP, 0xfffff, 0x12000);
439 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
440 RF_RX_G1, 0xfffff, 0x00355);
441
442 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
443 }
444}
445
446void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type)
447{
448 struct rtl_priv *rtlpriv = rtl_priv(hw);
449 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
450
451 if (type == BT_BB_BACKOFF_OFF) {
452 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
453 "[BT]BBBackOffLevel Off!\n");
454 rtl_write_dword(rtlpriv, 0xc04, 0x3a05611);
455 } else if (type == BT_BB_BACKOFF_ON) {
456 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
457 "[BT]BBBackOffLevel On!\n");
458 rtl_write_dword(rtlpriv, 0xc04, 0x3a07611);
459 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
460 }
461}
462
463void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw)
464{
465 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
466 struct rtl_priv *rtlpriv = rtl_priv(hw);
467 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
468 "rtl8723ae_dm_bt_fw_coex_all_off()\n");
469
470 if (rtlpcipriv->bt_coexist.fw_coexist_all_off)
471 return;
472
473 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
474 "rtl8723ae_dm_bt_fw_coex_all_off(), real Do\n");
475 rtl8723ae_dm_bt_fw_coex_all_off_8723a(hw);
476 rtlpcipriv->bt_coexist.fw_coexist_all_off = true;
477}
478
479void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw)
480{
481 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
482 struct rtl_priv *rtlpriv = rtl_priv(hw);
483
484 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
485 "rtl8723ae_dm_bt_sw_coex_all_off()\n");
486
487 if (rtlpcipriv->bt_coexist.sw_coexist_all_off)
488 return;
489
490 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
491 "rtl8723ae_dm_bt_sw_coex_all_off(), real Do\n");
492 rtl8723ae_dm_bt_sw_coex_all_off_8723a(hw);
493 rtlpcipriv->bt_coexist.sw_coexist_all_off = true;
494}
495
496void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw)
497{
498 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
499 struct rtl_priv *rtlpriv = rtl_priv(hw);
500
501 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
502 "rtl8723ae_dm_bt_hw_coex_all_off()\n");
503
504 if (rtlpcipriv->bt_coexist.hw_coexist_all_off)
505 return;
506 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
507 "rtl8723ae_dm_bt_hw_coex_all_off(), real Do\n");
508
509 rtl8723ae_dm_bt_hw_coex_all_off_8723a(hw);
510
511 rtlpcipriv->bt_coexist.hw_coexist_all_off = true;
512}
513
514void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw)
515{
516 rtl8723ae_dm_bt_fw_coex_all_off(hw);
517 rtl8723ae_dm_bt_sw_coex_all_off(hw);
518 rtl8723ae_dm_bt_hw_coex_all_off(hw);
519}
520
521bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw)
522{
523 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
524
525 if ((rtlpcipriv->bt_coexist.previous_state ==
526 rtlpcipriv->bt_coexist.cstate) &&
527 (rtlpcipriv->bt_coexist.previous_state_h ==
528 rtlpcipriv->bt_coexist.cstate_h))
529 return false;
530 else
531 return true;
532}
533
534bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw)
535{
536 struct rtl_priv *rtlpriv = rtl_priv(hw);
537
538 if (rtlpriv->link_info.tx_busy_traffic)
539 return true;
540 else
541 return false;
542}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h
new file mode 100644
index 00000000000..76f4d122dbc
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h
@@ -0,0 +1,160 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 * Larry Finger <Larry.Finger@lwfinger.net>
26 *
27 *****************************************************************************/
28
29#ifndef __RTL8723E_HAL_BT_COEXIST_H__
30#define __RTL8723E_HAL_BT_COEXIST_H__
31
32#include "../wifi.h"
33
34/* The reg define is for 8723 */
35#define REG_HIGH_PRIORITY_TXRX 0x770
36#define REG_LOW_PRIORITY_TXRX 0x774
37
38#define BT_FW_COEX_THRESH_TOL 6
39#define BT_FW_COEX_THRESH_20 20
40#define BT_FW_COEX_THRESH_23 23
41#define BT_FW_COEX_THRESH_25 25
42#define BT_FW_COEX_THRESH_30 30
43#define BT_FW_COEX_THRESH_35 35
44#define BT_FW_COEX_THRESH_40 40
45#define BT_FW_COEX_THRESH_45 45
46#define BT_FW_COEX_THRESH_47 47
47#define BT_FW_COEX_THRESH_50 50
48#define BT_FW_COEX_THRESH_55 55
49
50#define BT_COEX_STATE_BT30 BIT(0)
51#define BT_COEX_STATE_WIFI_HT20 BIT(1)
52#define BT_COEX_STATE_WIFI_HT40 BIT(2)
53#define BT_COEX_STATE_WIFI_LEGACY BIT(3)
54
55#define BT_COEX_STATE_WIFI_RSSI_LOW BIT(4)
56#define BT_COEX_STATE_WIFI_RSSI_MEDIUM BIT(5)
57#define BT_COEX_STATE_WIFI_RSSI_HIGH BIT(6)
58#define BT_COEX_STATE_DEC_BT_POWER BIT(7)
59
60#define BT_COEX_STATE_WIFI_IDLE BIT(8)
61#define BT_COEX_STATE_WIFI_UPLINK BIT(9)
62#define BT_COEX_STATE_WIFI_DOWNLINK BIT(10)
63
64#define BT_COEX_STATE_BT_INQ_PAGE BIT(11)
65#define BT_COEX_STATE_BT_IDLE BIT(12)
66#define BT_COEX_STATE_BT_UPLINK BIT(13)
67#define BT_COEX_STATE_BT_DOWNLINK BIT(14)
68
69#define BT_COEX_STATE_HOLD_FOR_BT_OPERATION BIT(15)
70#define BT_COEX_STATE_BT_RSSI_LOW BIT(19)
71
72#define BT_COEX_STATE_PROFILE_HID BIT(20)
73#define BT_COEX_STATE_PROFILE_A2DP BIT(21)
74#define BT_COEX_STATE_PROFILE_PAN BIT(22)
75#define BT_COEX_STATE_PROFILE_SCO BIT(23)
76
77#define BT_COEX_STATE_WIFI_RSSI_1_LOW BIT(24)
78#define BT_COEX_STATE_WIFI_RSSI_1_MEDIUM BIT(25)
79#define BT_COEX_STATE_WIFI_RSSI_1_HIGH BIT(26)
80
81#define BT_COEX_STATE_BTINFO_COMMON BIT(30)
82#define BT_COEX_STATE_BTINFO_B_HID_SCOESCO BIT(31)
83#define BT_COEX_STATE_BTINFO_B_FTP_A2DP BIT(29)
84
85#define BT_COEX_STATE_BT_CNT_LEVEL_0 BIT(0)
86#define BT_COEX_STATE_BT_CNT_LEVEL_1 BIT(1)
87#define BT_COEX_STATE_BT_CNT_LEVEL_2 BIT(2)
88#define BT_COEX_STATE_BT_CNT_LEVEL_3 BIT(3)
89
90#define BT_RSSI_STATE_HIGH 0
91#define BT_RSSI_STATE_MEDIUM 1
92#define BT_RSSI_STATE_LOW 2
93#define BT_RSSI_STATE_STAY_HIGH 3
94#define BT_RSSI_STATE_STAY_MEDIUM 4
95#define BT_RSSI_STATE_STAY_LOW 5
96
97#define BT_AGCTABLE_OFF 0
98#define BT_AGCTABLE_ON 1
99#define BT_BB_BACKOFF_OFF 0
100#define BT_BB_BACKOFF_ON 1
101#define BT_FW_NAV_OFF 0
102#define BT_FW_NAV_ON 1
103
104#define BT_COEX_MECH_NONE 0
105#define BT_COEX_MECH_SCO 1
106#define BT_COEX_MECH_HID 2
107#define BT_COEX_MECH_A2DP 3
108#define BT_COEX_MECH_PAN 4
109#define BT_COEX_MECH_HID_A2DP 5
110#define BT_COEX_MECH_HID_PAN 6
111#define BT_COEX_MECH_PAN_A2DP 7
112#define BT_COEX_MECH_HID_SCO_ESCO 8
113#define BT_COEX_MECH_FTP_A2DP 9
114#define BT_COEX_MECH_COMMON 10
115#define BT_COEX_MECH_MAX 11
116
117#define BT_DBG_PROFILE_NONE 0
118#define BT_DBG_PROFILE_SCO 1
119#define BT_DBG_PROFILE_HID 2
120#define BT_DBG_PROFILE_A2DP 3
121#define BT_DBG_PROFILE_PAN 4
122#define BT_DBG_PROFILE_HID_A2DP 5
123#define BT_DBG_PROFILE_HID_PAN 6
124#define BT_DBG_PROFILE_PAN_A2DP 7
125#define BT_DBG_PROFILE_MAX 9
126
127#define BTINFO_B_FTP BIT(7)
128#define BTINFO_B_A2DP BIT(6)
129#define BTINFO_B_HID BIT(5)
130#define BTINFO_B_SCO_BUSY BIT(4)
131#define BTINFO_B_ACL_BUSY BIT(3)
132#define BTINFO_B_INQ_PAGE BIT(2)
133#define BTINFO_B_SCO_ESCO BIT(1)
134#define BTINFO_B_CONNECTION BIT(0)
135
136
137void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw);
138void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw);
139
140void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw);
141void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw);
142long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw);
143void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw,
144 bool balance_on, u8 ms0, u8 ms1);
145void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type);
146void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type);
147u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw,
148 u8 level_num, u8 rssi_thresh,
149 u8 rssi_thresh1);
150u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw,
151 u8 level_num, u8 rssi_thresh,
152 u8 rssi_thresh1);
153void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw);
154void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw,
155 bool reject);
156
157bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw);
158bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw);
159
160#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
new file mode 100644
index 00000000000..887d521fe69
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
@@ -0,0 +1,1786 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 ****************************************************************************
29 */
30#include "hal_btc.h"
31#include "../pci.h"
32#include "phy.h"
33#include "fw.h"
34#include "reg.h"
35#include "def.h"
36
37void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw)
38{
39 struct rtl_priv *rtlpriv = rtl_priv(hw);
40 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
41 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
42
43 if (!rtlpcipriv->bt_coexist.bt_coexistence)
44 return;
45
46 if (ppsc->inactiveps) {
47 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
48 "[BT][DM], Before enter IPS, turn off all Coexist DM\n");
49 rtlpcipriv->bt_coexist.cstate = 0;
50 rtlpcipriv->bt_coexist.previous_state = 0;
51 rtlpcipriv->bt_coexist.cstate_h = 0;
52 rtlpcipriv->bt_coexist.previous_state_h = 0;
53 rtl8723ae_btdm_coex_all_off(hw);
54 }
55}
56
57static enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw)
58{
59 struct rtl_priv *rtlpriv = rtl_priv(hw);
60 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
61 enum _RT_MEDIA_STATUS m_status = RT_MEDIA_DISCONNECT;
62
63 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
64
65 if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED)
66 m_status = RT_MEDIA_CONNECT;
67
68 return m_status;
69}
70
71void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw,
72 bool mstatus)
73{
74 struct rtl_priv *rtlpriv = rtl_priv(hw);
75 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
76 struct rtl_phy *rtlphy = &(rtlpriv->phy);
77 u8 h2c_parameter[3] = {0};
78 u8 chnl;
79
80 if (!rtlpcipriv->bt_coexist.bt_coexistence)
81 return;
82
83 if (RT_MEDIA_CONNECT == mstatus)
84 h2c_parameter[0] = 0x1; /* 0: disconnected, 1:connected */
85 else
86 h2c_parameter[0] = 0x0;
87
88 if (mgnt_link_status_query(hw)) {
89 chnl = rtlphy->current_channel;
90 h2c_parameter[1] = chnl;
91 }
92
93 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
94 h2c_parameter[2] = 0x30;
95 else
96 h2c_parameter[2] = 0x20;
97
98 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
99 "[BTCoex], FW write 0x19 = 0x%x\n",
100 h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]);
101
102 rtl8723ae_fill_h2c_cmd(hw, 0x19, 3, h2c_parameter);
103
104}
105
106static bool rtl8723ae_dm_bt_is_wifi_busy(struct ieee80211_hw *hw)
107{
108 struct rtl_priv *rtlpriv = rtl_priv(hw);
109 if (rtlpriv->link_info.busytraffic ||
110 rtlpriv->link_info.rx_busy_traffic ||
111 rtlpriv->link_info.tx_busy_traffic)
112 return true;
113 else
114 return false;
115}
116
117static void rtl8723ae_dm_bt_set_fw_3a(struct ieee80211_hw *hw,
118 u8 byte1, u8 byte2, u8 byte3,
119 u8 byte4, u8 byte5)
120{
121 struct rtl_priv *rtlpriv = rtl_priv(hw);
122 u8 h2c_parameter[5] = {0};
123
124 h2c_parameter[0] = byte1;
125 h2c_parameter[1] = byte2;
126 h2c_parameter[2] = byte3;
127 h2c_parameter[3] = byte4;
128 h2c_parameter[4] = byte5;
129 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
130 "[BTCoex], FW write 0x3a(4bytes) = 0x%x%8x\n",
131 h2c_parameter[0], h2c_parameter[1]<<24 | h2c_parameter[2]<<16 |
132 h2c_parameter[3]<<8 | h2c_parameter[4]);
133 rtl8723ae_fill_h2c_cmd(hw, 0x3a, 5, h2c_parameter);
134}
135
136static bool rtl8723ae_dm_bt_need_to_dec_bt_pwr(struct ieee80211_hw *hw)
137{
138 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
139 struct rtl_priv *rtlpriv = rtl_priv(hw);
140
141 if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) {
142 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
143 "Need to decrease bt power\n");
144 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_DEC_BT_POWER;
145 return true;
146 }
147
148 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_DEC_BT_POWER;
149 return false;
150}
151
152static bool rtl8723ae_dm_bt_is_same_coexist_state(struct ieee80211_hw *hw)
153{
154 struct rtl_priv *rtlpriv = rtl_priv(hw);
155 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
156
157 if ((rtlpcipriv->bt_coexist.previous_state ==
158 rtlpcipriv->bt_coexist.cstate) &&
159 (rtlpcipriv->bt_coexist.previous_state_h ==
160 rtlpcipriv->bt_coexist.cstate_h)) {
161 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
162 "[DM][BT], Coexist state do not chang!!\n");
163 return true;
164 } else {
165 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
166 "[DM][BT], Coexist state changed!!\n");
167 return false;
168 }
169}
170
171static void rtl8723ae_dm_bt_set_coex_table(struct ieee80211_hw *hw,
172 u32 val_0x6c0, u32 val_0x6c8,
173 u32 val_0x6cc)
174{
175 struct rtl_priv *rtlpriv = rtl_priv(hw);
176
177 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
178 "set coex table, set 0x6c0 = 0x%x\n", val_0x6c0);
179 rtl_write_dword(rtlpriv, 0x6c0, val_0x6c0);
180
181 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
182 "set coex table, set 0x6c8 = 0x%x\n", val_0x6c8);
183 rtl_write_dword(rtlpriv, 0x6c8, val_0x6c8);
184
185 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
186 "set coex table, set 0x6cc = 0x%x\n", val_0x6cc);
187 rtl_write_byte(rtlpriv, 0x6cc, val_0x6cc);
188}
189
190static void rtl8723ae_dm_bt_set_hw_pta_mode(struct ieee80211_hw *hw, bool mode)
191{
192 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
193 struct rtl_priv *rtlpriv = rtl_priv(hw);
194
195 if (BT_PTA_MODE_ON == mode) {
196 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode on, ");
197 /* Enable GPIO 0/1/2/3/8 pins for bt */
198 rtl_write_byte(rtlpriv, 0x40, 0x20);
199 rtlpcipriv->bt_coexist.hw_coexist_all_off = false;
200 } else {
201 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode off\n");
202 rtl_write_byte(rtlpriv, 0x40, 0x0);
203 }
204}
205
206static void rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(struct ieee80211_hw *hw,
207 u8 type)
208{
209 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
210 struct rtl_priv *rtlpriv = rtl_priv(hw);
211
212 if (BT_RF_RX_LPF_CORNER_SHRINK == type) {
213 /* Shrink RF Rx LPF corner, 0x1e[7:4]=1111 ==> [11:4] by Jenyu*/
214 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
215 "Shrink RF Rx LPF corner!!\n");
216 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff,
217 0xf0ff7);
218 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
219 } else if (BT_RF_RX_LPF_CORNER_RESUME == type) {
220 /*Resume RF Rx LPF corner*/
221 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
222 "Resume RF Rx LPF corner!!\n");
223 rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff,
224 rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
225 }
226}
227
228static void rtl8723ae_bt_set_penalty_tx_rate_adap(struct ieee80211_hw *hw,
229 u8 ra_type)
230{
231 struct rtl_priv *rtlpriv = rtl_priv(hw);
232 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
233 u8 tmu1;
234
235 tmu1 = rtl_read_byte(rtlpriv, 0x4fd);
236 tmu1 |= BIT(0);
237 if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == ra_type) {
238 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
239 "Tx rate adaptive, set low penalty!!\n");
240 tmu1 &= ~BIT(2);
241 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
242 } else if (BT_TX_RATE_ADAPTIVE_NORMAL == ra_type) {
243 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
244 "Tx rate adaptive, set normal!!\n");
245 tmu1 |= BIT(2);
246 }
247 rtl_write_byte(rtlpriv, 0x4fd, tmu1);
248}
249
250static void rtl8723ae_dm_bt_btdm_structure_reload(struct ieee80211_hw *hw,
251 struct btdm_8723 *btdm)
252{
253 btdm->all_off = false;
254 btdm->agc_table_en = false;
255 btdm->adc_back_off_on = false;
256 btdm->b2_ant_hid_en = false;
257 btdm->low_penalty_rate_adaptive = false;
258 btdm->rf_rx_lpf_shrink = false;
259 btdm->reject_aggre_pkt = false;
260
261 btdm->tdma_on = false;
262 btdm->tdma_ant = TDMA_2ANT;
263 btdm->tdma_nav = TDMA_NAV_OFF;
264 btdm->tdma_dac_swing = TDMA_DAC_SWING_OFF;
265 btdm->fw_dac_swing_lvl = 0x20;
266
267 btdm->tra_tdma_on = false;
268 btdm->tra_tdma_ant = TDMA_2ANT;
269 btdm->tra_tdma_nav = TDMA_NAV_OFF;
270 btdm->ignore_wlan_act = false;
271
272 btdm->ps_tdma_on = false;
273 btdm->ps_tdma_byte[0] = 0x0;
274 btdm->ps_tdma_byte[1] = 0x0;
275 btdm->ps_tdma_byte[2] = 0x0;
276 btdm->ps_tdma_byte[3] = 0x8;
277 btdm->ps_tdma_byte[4] = 0x0;
278
279 btdm->pta_on = true;
280 btdm->val_0x6c0 = 0x5a5aaaaa;
281 btdm->val_0x6c8 = 0xcc;
282 btdm->val_0x6cc = 0x3;
283
284 btdm->sw_dac_swing_on = false;
285 btdm->sw_dac_swing_lvl = 0xc0;
286 btdm->wlan_act_hi = 0x20;
287 btdm->wlan_act_lo = 0x10;
288 btdm->bt_retry_index = 2;
289
290 btdm->dec_bt_pwr = false;
291}
292
293static void dm_bt_btdm_structure_reload_all_off(struct ieee80211_hw *hw,
294 struct btdm_8723 *btdm)
295{
296 rtl8723ae_dm_bt_btdm_structure_reload(hw, btdm);
297 btdm->all_off = true;
298 btdm->pta_on = false;
299 btdm->wlan_act_hi = 0x10;
300}
301
302static bool rtl8723ae_dm_bt_is_2_ant_common_action(struct ieee80211_hw *hw)
303{
304 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
305 struct rtl_priv *rtlpriv = rtl_priv(hw);
306 struct btdm_8723 btdm8723;
307 bool common = false;
308
309 rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723);
310
311 if (!rtl8723ae_dm_bt_is_wifi_busy(hw)
312 && !rtlpcipriv->bt_coexist.bt_busy) {
313 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
314 "Wifi idle + Bt idle, bt coex mechanism always off!!\n");
315 dm_bt_btdm_structure_reload_all_off(hw, &btdm8723);
316 common = true;
317 } else if (rtl8723ae_dm_bt_is_wifi_busy(hw)
318 && !rtlpcipriv->bt_coexist.bt_busy) {
319 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
320 "Wifi non-idle + Bt disabled/idle!!\n");
321 btdm8723.low_penalty_rate_adaptive = true;
322 btdm8723.rf_rx_lpf_shrink = false;
323 btdm8723.reject_aggre_pkt = false;
324
325 /* sw mechanism */
326 btdm8723.agc_table_en = false;
327 btdm8723.adc_back_off_on = false;
328 btdm8723.sw_dac_swing_on = false;
329
330 btdm8723.pta_on = true;
331 btdm8723.val_0x6c0 = 0x5a5aaaaa;
332 btdm8723.val_0x6c8 = 0xcccc;
333 btdm8723.val_0x6cc = 0x3;
334
335 btdm8723.tdma_on = false;
336 btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF;
337 btdm8723.b2_ant_hid_en = false;
338
339 common = true;
340 } else if (rtlpcipriv->bt_coexist.bt_busy) {
341 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
342 "Bt non-idle!\n");
343 if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) {
344 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
345 "Wifi connection exist\n");
346 common = false;
347 } else {
348 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
349 "No Wifi connection!\n");
350 btdm8723.rf_rx_lpf_shrink = true;
351 btdm8723.low_penalty_rate_adaptive = false;
352 btdm8723.reject_aggre_pkt = false;
353
354 /* sw mechanism */
355 btdm8723.agc_table_en = false;
356 btdm8723.adc_back_off_on = false;
357 btdm8723.sw_dac_swing_on = false;
358
359 btdm8723.pta_on = true;
360 btdm8723.val_0x6c0 = 0x55555555;
361 btdm8723.val_0x6c8 = 0x0000ffff;
362 btdm8723.val_0x6cc = 0x3;
363
364 btdm8723.tdma_on = false;
365 btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF;
366 btdm8723.b2_ant_hid_en = false;
367
368 common = true;
369 }
370 }
371
372 if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw))
373 btdm8723.dec_bt_pwr = true;
374
375 if (common)
376 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BTINFO_COMMON;
377
378 if (common && rtl8723ae_dm_bt_is_coexist_state_changed(hw))
379 rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723);
380
381 return common;
382}
383
384static void rtl8723ae_dm_bt_set_sw_full_time_dac_swing(struct ieee80211_hw *hw,
385 bool sw_dac_swing_on,
386 u32 sw_dac_swing_lvl)
387{
388 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
389 struct rtl_priv *rtlpriv = rtl_priv(hw);
390
391 if (sw_dac_swing_on) {
392 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
393 "[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl);
394 rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000,
395 sw_dac_swing_lvl);
396 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
397 } else {
398 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
399 "[BTCoex], SwDacSwing Off!\n");
400 rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0);
401 }
402}
403
404static void rtl8723ae_dm_bt_set_fw_dec_bt_pwr(struct ieee80211_hw *hw,
405 bool dec_bt_pwr)
406{
407 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
408 struct rtl_priv *rtlpriv = rtl_priv(hw);
409 u8 h2c_parameter[1] = {0};
410
411 h2c_parameter[0] = 0;
412
413 if (dec_bt_pwr) {
414 h2c_parameter[0] |= BIT(1);
415 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
416 }
417
418 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
419 "[BTCoex], decrease Bt Power : %s, write 0x21 = 0x%x\n",
420 (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]);
421
422 rtl8723ae_fill_h2c_cmd(hw, 0x21, 1, h2c_parameter);
423}
424
425static void rtl8723ae_dm_bt_set_fw_2_ant_hid(struct ieee80211_hw *hw,
426 bool enable, bool dac_swing_on)
427{
428 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
429 struct rtl_priv *rtlpriv = rtl_priv(hw);
430 u8 h2c_parameter[1] = {0};
431
432 if (enable) {
433 h2c_parameter[0] |= BIT(0);
434 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
435 }
436 if (dac_swing_on)
437 h2c_parameter[0] |= BIT(1); /* Dac Swing default enable */
438 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
439 "[BTCoex], turn 2-Ant+HID mode %s, DACSwing:%s, write 0x15 = 0x%x\n",
440 (enable ? "ON!!" : "OFF!!"), (dac_swing_on ? "ON" : "OFF"),
441 h2c_parameter[0]);
442
443 rtl8723ae_fill_h2c_cmd(hw, 0x15, 1, h2c_parameter);
444}
445
446static void rtl8723ae_dm_bt_set_fw_tdma_ctrl(struct ieee80211_hw *hw,
447 bool enable, u8 ant_num, u8 nav_en,
448 u8 dac_swing_en)
449{
450 struct rtl_priv *rtlpriv = rtl_priv(hw);
451 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
452 u8 h2c_parameter[1] = {0};
453 u8 h2c_parameter1[1] = {0};
454
455 h2c_parameter[0] = 0;
456 h2c_parameter1[0] = 0;
457
458 if (enable) {
459 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
460 "[BTCoex], set BT PTA update manager to trigger update!!\n");
461 h2c_parameter1[0] |= BIT(0);
462
463 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
464 "[BTCoex], turn TDMA mode ON!!\n");
465 h2c_parameter[0] |= BIT(0); /* function enable */
466 if (TDMA_1ANT == ant_num) {
467 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
468 "[BTCoex], TDMA_1ANT\n");
469 h2c_parameter[0] |= BIT(1);
470 } else if (TDMA_2ANT == ant_num) {
471 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
472 "[BTCoex], TDMA_2ANT\n");
473 } else {
474 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
475 "[BTCoex], Unknown Ant\n");
476 }
477
478 if (TDMA_NAV_OFF == nav_en) {
479 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
480 "[BTCoex], TDMA_NAV_OFF\n");
481 } else if (TDMA_NAV_ON == nav_en) {
482 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
483 "[BTCoex], TDMA_NAV_ON\n");
484 h2c_parameter[0] |= BIT(2);
485 }
486
487 if (TDMA_DAC_SWING_OFF == dac_swing_en) {
488 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
489 "[BTCoex], TDMA_DAC_SWING_OFF\n");
490 } else if (TDMA_DAC_SWING_ON == dac_swing_en) {
491 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
492 "[BTCoex], TDMA_DAC_SWING_ON\n");
493 h2c_parameter[0] |= BIT(4);
494 }
495 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
496 } else {
497 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
498 "[BTCoex], set BT PTA update manager to no update!!\n");
499 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
500 "[BTCoex], turn TDMA mode OFF!!\n");
501 }
502
503 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
504 "[BTCoex], FW2AntTDMA, write 0x26 = 0x%x\n",
505 h2c_parameter1[0]);
506 rtl8723ae_fill_h2c_cmd(hw, 0x26, 1, h2c_parameter1);
507
508 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
509 "[BTCoex], FW2AntTDMA, write 0x14 = 0x%x\n", h2c_parameter[0]);
510 rtl8723ae_fill_h2c_cmd(hw, 0x14, 1, h2c_parameter);
511}
512
513static void rtl8723ae_dm_bt_set_fw_ignore_wlan_act(struct ieee80211_hw *hw,
514 bool enable)
515{
516 struct rtl_priv *rtlpriv = rtl_priv(hw);
517 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
518 u8 h2c_parameter[1] = {0};
519
520 if (enable) {
521 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
522 "[BTCoex], BT Ignore Wlan_Act !!\n");
523 h2c_parameter[0] |= BIT(0); /* function enable */
524 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
525 } else {
526 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
527 "[BTCoex], BT don't ignore Wlan_Act !!\n");
528 }
529
530 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
531 "[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25 = 0x%x\n",
532 h2c_parameter[0]);
533
534 rtl8723ae_fill_h2c_cmd(hw, 0x25, 1, h2c_parameter);
535}
536
537static void rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(struct ieee80211_hw *hw,
538 bool enable, u8 ant_num,
539 u8 nav_en)
540{
541 struct rtl_priv *rtlpriv = rtl_priv(hw);
542 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
543 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
544 u8 h2c_parameter[2] = {0};
545
546 /* Only 8723 B cut should do this */
547 if (IS_VENDOR_8723_A_CUT(rtlhal->version)) {
548 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
549 "[BTCoex], not 8723B cut, don't set Traditional TDMA!!\n");
550 return;
551 }
552
553 if (enable) {
554 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
555 "[BTCoex], turn TTDMA mode ON!!\n");
556 h2c_parameter[0] |= BIT(0); /* function enable */
557 if (TDMA_1ANT == ant_num) {
558 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
559 "[BTCoex], TTDMA_1ANT\n");
560 h2c_parameter[0] |= BIT(1);
561 } else if (TDMA_2ANT == ant_num) {
562 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
563 "[BTCoex], TTDMA_2ANT\n");
564 } else {
565 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
566 "[BTCoex], Unknown Ant\n");
567 }
568
569 if (TDMA_NAV_OFF == nav_en) {
570 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
571 "[BTCoex], TTDMA_NAV_OFF\n");
572 } else if (TDMA_NAV_ON == nav_en) {
573 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
574 "[BTCoex], TTDMA_NAV_ON\n");
575 h2c_parameter[1] |= BIT(0);
576 }
577
578 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
579 } else {
580 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
581 "[BTCoex], turn TTDMA mode OFF!!\n");
582 }
583
584 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
585 "[BTCoex], FW Traditional TDMA, write 0x33 = 0x%x\n",
586 h2c_parameter[0] << 8 | h2c_parameter[1]);
587
588 rtl8723ae_fill_h2c_cmd(hw, 0x33, 2, h2c_parameter);
589}
590
591static void rtl8723ae_dm_bt_set_fw_dac_swing_level(struct ieee80211_hw *hw,
592 u8 dac_swing_lvl)
593{
594 struct rtl_priv *rtlpriv = rtl_priv(hw);
595 u8 h2c_parameter[1] = {0};
596
597 h2c_parameter[0] = dac_swing_lvl;
598
599 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
600 "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swing_lvl);
601 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
602 "[BTCoex], write 0x29 = 0x%x\n", h2c_parameter[0]);
603
604 rtl8723ae_fill_h2c_cmd(hw, 0x29, 1, h2c_parameter);
605}
606
607static void rtl8723ae_dm_bt_set_fw_bt_hid_info(struct ieee80211_hw *hw,
608 bool enable)
609{
610 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
611 struct rtl_priv *rtlpriv = rtl_priv(hw);
612 u8 h2c_parameter[1] = {0};
613
614 h2c_parameter[0] = 0;
615
616 if (enable) {
617 h2c_parameter[0] |= BIT(0);
618 rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
619 }
620 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
621 "[BTCoex], Set BT HID information = 0x%x\n", enable);
622 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
623 "[BTCoex], write 0x24 = 0x%x\n", h2c_parameter[0]);
624
625 rtl8723ae_fill_h2c_cmd(hw, 0x24, 1, h2c_parameter);
626}
627
628static void rtl8723ae_dm_bt_set_fw_bt_retry_index(struct ieee80211_hw *hw,
629 u8 retry_index)
630{
631 struct rtl_priv *rtlpriv = rtl_priv(hw);
632 u8 h2c_parameter[1] = {0};
633
634 h2c_parameter[0] = retry_index;
635
636 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
637 "[BTCoex], Set BT Retry Index=%d\n", retry_index);
638 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
639 "[BTCoex], write 0x23 = 0x%x\n", h2c_parameter[0]);
640
641 rtl8723ae_fill_h2c_cmd(hw, 0x23, 1, h2c_parameter);
642}
643
644static void rtl8723ae_dm_bt_set_fw_wlan_act(struct ieee80211_hw *hw,
645 u8 wlan_act_hi, u8 wlan_act_lo)
646{
647 struct rtl_priv *rtlpriv = rtl_priv(hw);
648 u8 h2c_parameter_hi[1] = {0};
649 u8 h2c_parameter_lo[1] = {0};
650
651 h2c_parameter_hi[0] = wlan_act_hi;
652 h2c_parameter_lo[0] = wlan_act_lo;
653
654 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
655 "[BTCoex], Set WLAN_ACT Hi:Lo = 0x%x/0x%x\n", wlan_act_hi,
656 wlan_act_lo);
657 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
658 "[BTCoex], write 0x22 = 0x%x\n", h2c_parameter_hi[0]);
659 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
660 "[BTCoex], write 0x11 = 0x%x\n", h2c_parameter_lo[0]);
661
662 /* WLAN_ACT = High duration, unit:ms */
663 rtl8723ae_fill_h2c_cmd(hw, 0x22, 1, h2c_parameter_hi);
664 /* WLAN_ACT = Low duration, unit:3*625us */
665 rtl8723ae_fill_h2c_cmd(hw, 0x11, 1, h2c_parameter_lo);
666}
667
668void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, struct btdm_8723 *btdm)
669{
670 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
671 struct rtl_priv *rtlpriv = rtl_priv(hw);
672 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
673 struct btdm_8723 *btdm_8723 = &rtlhal->hal_coex_8723.btdm;
674 u8 i;
675 bool fw_current_inpsmode = false;
676 bool fw_ps_awake = true;
677
678 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
679 (u8 *)(&fw_current_inpsmode));
680 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
681 (u8 *)(&fw_ps_awake));
682
683 /* check new setting is different than the old one,
684 * if all the same, don't do the setting again.
685 */
686 if (memcmp(btdm_8723, btdm, sizeof(struct btdm_8723)) == 0) {
687 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
688 "[BTCoex], the same coexist setting, return!!\n");
689 return;
690 } else { /* save the new coexist setting */
691 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
692 "[BTCoex], UPDATE TO NEW COEX SETTING!!\n");
693 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
694 "[BTCoex], original/new bAllOff = 0x%x/ 0x%x\n",
695 btdm_8723->all_off, btdm->all_off);
696 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
697 "[BTCoex], original/new agc_table_en = 0x%x/ 0x%x\n",
698 btdm_8723->agc_table_en, btdm->agc_table_en);
699 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
700 "[BTCoex], original/new adc_back_off_on = 0x%x/ 0x%x\n",
701 btdm_8723->adc_back_off_on, btdm->adc_back_off_on);
702 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
703 "[BTCoex], original/new b2_ant_hid_en = 0x%x/ 0x%x\n",
704 btdm_8723->b2_ant_hid_en, btdm->b2_ant_hid_en);
705 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
706 "[BTCoex], original/new bLowPenaltyRateAdaptive = 0x%x/ 0x%x\n",
707 btdm_8723->low_penalty_rate_adaptive,
708 btdm->low_penalty_rate_adaptive);
709 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
710 "[BTCoex], original/new bRfRxLpfShrink = 0x%x/ 0x%x\n",
711 btdm_8723->rf_rx_lpf_shrink, btdm->rf_rx_lpf_shrink);
712 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
713 "[BTCoex], original/new bRejectAggrePkt = 0x%x/ 0x%x\n",
714 btdm_8723->reject_aggre_pkt, btdm->reject_aggre_pkt);
715 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
716 "[BTCoex], original/new tdma_on = 0x%x/ 0x%x\n",
717 btdm_8723->tdma_on, btdm->tdma_on);
718 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
719 "[BTCoex], original/new tdmaAnt = 0x%x/ 0x%x\n",
720 btdm_8723->tdma_ant, btdm->tdma_ant);
721 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
722 "[BTCoex], original/new tdmaNav = 0x%x/ 0x%x\n",
723 btdm_8723->tdma_nav, btdm->tdma_nav);
724 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
725 "[BTCoex], original/new tdma_dac_swing = 0x%x/ 0x%x\n",
726 btdm_8723->tdma_dac_swing, btdm->tdma_dac_swing);
727 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
728 "[BTCoex], original/new fwDacSwingLvl = 0x%x/ 0x%x\n",
729 btdm_8723->fw_dac_swing_lvl, btdm->fw_dac_swing_lvl);
730
731 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
732 "[BTCoex], original/new bTraTdmaOn = 0x%x/ 0x%x\n",
733 btdm_8723->tra_tdma_on, btdm->tra_tdma_on);
734 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
735 "[BTCoex], original/new traTdmaAnt = 0x%x/ 0x%x\n",
736 btdm_8723->tra_tdma_ant, btdm->tra_tdma_ant);
737 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
738 "[BTCoex], original/new traTdmaNav = 0x%x/ 0x%x\n",
739 btdm_8723->tra_tdma_nav, btdm->tra_tdma_nav);
740 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
741 "[BTCoex], original/new bPsTdmaOn = 0x%x/ 0x%x\n",
742 btdm_8723->ps_tdma_on, btdm->ps_tdma_on);
743 for (i = 0; i < 5; i++) {
744 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
745 "[BTCoex], original/new psTdmaByte[i] = 0x%x/ 0x%x\n",
746 btdm_8723->ps_tdma_byte[i],
747 btdm->ps_tdma_byte[i]);
748 }
749 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
750 "[BTCoex], original/new bIgnoreWlanAct = 0x%x/ 0x%x\n",
751 btdm_8723->ignore_wlan_act, btdm->ignore_wlan_act);
752
753 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
754 "[BTCoex], original/new bPtaOn = 0x%x/ 0x%x\n",
755 btdm_8723->pta_on, btdm->pta_on);
756 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
757 "[BTCoex], original/new val_0x6c0 = 0x%x/ 0x%x\n",
758 btdm_8723->val_0x6c0, btdm->val_0x6c0);
759 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
760 "[BTCoex], original/new val_0x6c8 = 0x%x/ 0x%x\n",
761 btdm_8723->val_0x6c8, btdm->val_0x6c8);
762 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
763 "[BTCoex], original/new val_0x6cc = 0x%x/ 0x%x\n",
764 btdm_8723->val_0x6cc, btdm->val_0x6cc);
765 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
766 "[BTCoex], original/new sw_dac_swing_on = 0x%x/ 0x%x\n",
767 btdm_8723->sw_dac_swing_on, btdm->sw_dac_swing_on);
768 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
769 "[BTCoex], original/new sw_dac_swing_lvl = 0x%x/ 0x%x\n",
770 btdm_8723->sw_dac_swing_lvl,
771 btdm->sw_dac_swing_lvl);
772 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
773 "[BTCoex], original/new wlanActHi = 0x%x/ 0x%x\n",
774 btdm_8723->wlan_act_hi, btdm->wlan_act_hi);
775 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
776 "[BTCoex], original/new wlanActLo = 0x%x/ 0x%x\n",
777 btdm_8723->wlan_act_lo, btdm->wlan_act_lo);
778 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
779 "[BTCoex], original/new btRetryIndex = 0x%x/ 0x%x\n",
780 btdm_8723->bt_retry_index, btdm->bt_retry_index);
781
782 memcpy(btdm_8723, btdm, sizeof(struct btdm_8723));
783 }
784 /*
785 * Here we only consider when Bt Operation
786 * inquiry/paging/pairing is ON
787 * we only need to turn off TDMA
788 */
789
790 if (rtlpcipriv->bt_coexist.hold_for_bt_operation) {
791 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
792 "[BTCoex], set to ignore wlanAct for BT OP!!\n");
793 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, true);
794 return;
795 }
796
797 if (btdm->all_off) {
798 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
799 "[BTCoex], disable all coexist mechanism !!\n");
800 rtl8723ae_btdm_coex_all_off(hw);
801 return;
802 }
803
804 rtl8723ae_dm_bt_reject_ap_aggregated_packet(hw, btdm->reject_aggre_pkt);
805
806 if (btdm->low_penalty_rate_adaptive)
807 rtl8723ae_bt_set_penalty_tx_rate_adap(hw,
808 BT_TX_RATE_ADAPTIVE_LOW_PENALTY);
809 else
810 rtl8723ae_bt_set_penalty_tx_rate_adap(hw,
811 BT_TX_RATE_ADAPTIVE_NORMAL);
812
813 if (btdm->rf_rx_lpf_shrink)
814 rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw,
815 BT_RF_RX_LPF_CORNER_SHRINK);
816 else
817 rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw,
818 BT_RF_RX_LPF_CORNER_RESUME);
819
820 if (btdm->agc_table_en)
821 rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_ON);
822 else
823 rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF);
824
825 if (btdm->adc_back_off_on)
826 rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_ON);
827 else
828 rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_OFF);
829
830 rtl8723ae_dm_bt_set_fw_bt_retry_index(hw, btdm->bt_retry_index);
831
832 rtl8723ae_dm_bt_set_fw_dac_swing_level(hw, btdm->fw_dac_swing_lvl);
833 rtl8723ae_dm_bt_set_fw_wlan_act(hw, btdm->wlan_act_hi,
834 btdm->wlan_act_lo);
835
836 rtl8723ae_dm_bt_set_coex_table(hw, btdm->val_0x6c0,
837 btdm->val_0x6c8, btdm->val_0x6cc);
838 rtl8723ae_dm_bt_set_hw_pta_mode(hw, btdm->pta_on);
839
840 /* Note: There is a constraint between TDMA and 2AntHID
841 * Only one of 2AntHid and tdma can be turned on
842 * We should turn off those mechanisms first
843 * and then turn on them on.
844 */
845 if (btdm->b2_ant_hid_en) {
846 /* turn off tdma */
847 rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
848 btdm->tra_tdma_ant,
849 btdm->tra_tdma_nav);
850 rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant,
851 btdm->tdma_nav,
852 btdm->tdma_dac_swing);
853
854 /* turn off Pstdma */
855 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw,
856 btdm->ignore_wlan_act);
857 /* Antenna control by PTA, 0x870 = 0x300. */
858 rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
859
860 /* turn on 2AntHid */
861 rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, true);
862 rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, true, true);
863 } else if (btdm->tdma_on) {
864 /* turn off 2AntHid */
865 rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false);
866 rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
867
868 /* turn off pstdma */
869 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw,
870 btdm->ignore_wlan_act);
871 /* Antenna control by PTA, 0x870 = 0x300. */
872 rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
873
874 /* turn on tdma */
875 rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
876 btdm->tra_tdma_ant, btdm->tra_tdma_nav);
877 rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, true, btdm->tdma_ant,
878 btdm->tdma_nav, btdm->tdma_dac_swing);
879 } else if (btdm->ps_tdma_on) {
880 /* turn off 2AntHid */
881 rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false);
882 rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
883
884 /* turn off tdma */
885 rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
886 btdm->tra_tdma_ant, btdm->tra_tdma_nav);
887 rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant,
888 btdm->tdma_nav, btdm->tdma_dac_swing);
889
890 /* turn on pstdma */
891 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw,
892 btdm->ignore_wlan_act);
893 rtl8723ae_dm_bt_set_fw_3a(hw,
894 btdm->ps_tdma_byte[0],
895 btdm->ps_tdma_byte[1],
896 btdm->ps_tdma_byte[2],
897 btdm->ps_tdma_byte[3],
898 btdm->ps_tdma_byte[4]);
899 } else {
900 /* turn off 2AntHid */
901 rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false);
902 rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
903
904 /* turn off tdma */
905 rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
906 btdm->tra_tdma_ant, btdm->tra_tdma_nav);
907 rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant,
908 btdm->tdma_nav, btdm->tdma_dac_swing);
909
910 /* turn off pstdma */
911 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw,
912 btdm->ignore_wlan_act);
913 /* Antenna control by PTA, 0x870 = 0x300. */
914 rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
915 }
916
917 /* Note:
918 * We should add delay for making sure sw DacSwing can be set
919 * sucessfully. Because of that rtl8723ae_dm_bt_set_fw_2_ant_hid()
920 * and rtl8723ae_dm_bt_set_fw_tdma_ctrl()
921 * will overwrite the reg 0x880.
922 */
923 mdelay(30);
924 rtl8723ae_dm_bt_set_sw_full_time_dac_swing(hw,
925 btdm->sw_dac_swing_on, btdm->sw_dac_swing_lvl);
926 rtl8723ae_dm_bt_set_fw_dec_bt_pwr(hw, btdm->dec_bt_pwr);
927}
928
929/*============================================================
930 * extern function start with BTDM_
931 *============================================================
932 */
933static u32 rtl8723ae_dm_bt_tx_rx_couter_h(struct ieee80211_hw *hw)
934{
935 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
936 u32 counters = 0;
937
938 counters = rtlhal->hal_coex_8723.high_priority_tx +
939 rtlhal->hal_coex_8723.high_priority_rx;
940 return counters;
941}
942
943static u32 rtl8723ae_dm_bt_tx_rx_couter_l(struct ieee80211_hw *hw)
944{
945 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
946
947 return rtlhal->hal_coex_8723.low_priority_tx +
948 rtlhal->hal_coex_8723.low_priority_rx;
949}
950
951static u8 rtl8723ae_dm_bt_bt_tx_rx_counter_level(struct ieee80211_hw *hw)
952{
953 struct rtl_priv *rtlpriv = rtl_priv(hw);
954 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
955 u32 bt_tx_rx_cnt = 0;
956 u8 bt_tx_rx_cnt_lvl = 0;
957
958 bt_tx_rx_cnt = rtl8723ae_dm_bt_tx_rx_couter_h(hw) +
959 rtl8723ae_dm_bt_tx_rx_couter_l(hw);
960 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
961 "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt);
962
963 rtlpcipriv->bt_coexist.cstate_h &=
964 ~(BT_COEX_STATE_BT_CNT_LEVEL_0 | BT_COEX_STATE_BT_CNT_LEVEL_1 |
965 BT_COEX_STATE_BT_CNT_LEVEL_2);
966
967 if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_3) {
968 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
969 "[BTCoex], BT TxRx Counters at level 3\n");
970 bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_3;
971 rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_3;
972 } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_2) {
973 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
974 "[BTCoex], BT TxRx Counters at level 2\n");
975 bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_2;
976 rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_2;
977 } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_1) {
978 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
979 "[BTCoex], BT TxRx Counters at level 1\n");
980 bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_1;
981 rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_1;
982 } else {
983 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
984 "[BTCoex], BT TxRx Counters at level 0\n");
985 bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_0;
986 rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_0;
987 }
988 return bt_tx_rx_cnt_lvl;
989}
990
991static void rtl8723ae_dm_bt_2_ant_hid_sco_esco(struct ieee80211_hw *hw)
992{
993 struct rtl_priv *rtlpriv = rtl_priv(hw);
994 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
995 struct rtl_phy *rtlphy = &(rtlpriv->phy);
996 struct btdm_8723 btdm8723;
997 u8 bt_rssi_state, bt_rssi_state1;
998 u8 bt_tx_rx_cnt_lvl;
999
1000 rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723);
1001
1002 btdm8723.rf_rx_lpf_shrink = true;
1003 btdm8723.low_penalty_rate_adaptive = true;
1004 btdm8723.reject_aggre_pkt = false;
1005
1006 bt_tx_rx_cnt_lvl = rtl8723ae_dm_bt_bt_tx_rx_counter_level(hw);
1007 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1008 "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl);
1009
1010 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
1011 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n");
1012 /* coex table */
1013 btdm8723.val_0x6c0 = 0x55555555;
1014 btdm8723.val_0x6c8 = 0xffff;
1015 btdm8723.val_0x6cc = 0x3;
1016
1017 /* sw mechanism */
1018 btdm8723.agc_table_en = false;
1019 btdm8723.adc_back_off_on = false;
1020 btdm8723.sw_dac_swing_on = false;
1021
1022 /* fw mechanism */
1023 btdm8723.ps_tdma_on = true;
1024 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1025 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1026 "[BTCoex], BT TxRx Counters >= 1400\n");
1027 btdm8723.ps_tdma_byte[0] = 0xa3;
1028 btdm8723.ps_tdma_byte[1] = 0x5;
1029 btdm8723.ps_tdma_byte[2] = 0x5;
1030 btdm8723.ps_tdma_byte[3] = 0x2;
1031 btdm8723.ps_tdma_byte[4] = 0x80;
1032 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1033 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1034 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1035 btdm8723.ps_tdma_byte[0] = 0xa3;
1036 btdm8723.ps_tdma_byte[1] = 0xa;
1037 btdm8723.ps_tdma_byte[2] = 0xa;
1038 btdm8723.ps_tdma_byte[3] = 0x2;
1039 btdm8723.ps_tdma_byte[4] = 0x80;
1040 } else {
1041 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1042 "[BTCoex], BT TxRx Counters < 1200\n");
1043 btdm8723.ps_tdma_byte[0] = 0xa3;
1044 btdm8723.ps_tdma_byte[1] = 0xf;
1045 btdm8723.ps_tdma_byte[2] = 0xf;
1046 btdm8723.ps_tdma_byte[3] = 0x2;
1047 btdm8723.ps_tdma_byte[4] = 0x80;
1048 }
1049 } else {
1050 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1051 "HT20 or Legacy\n");
1052 bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2,
1053 47, 0);
1054 bt_rssi_state1 = rtl8723ae_dm_bt_check_coex_rssi_state1(hw, 2,
1055 27, 0);
1056
1057 /* coex table */
1058 btdm8723.val_0x6c0 = 0x55555555;
1059 btdm8723.val_0x6c8 = 0xffff;
1060 btdm8723.val_0x6cc = 0x3;
1061
1062 /* sw mechanism */
1063 if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
1064 (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) {
1065 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1066 "Wifi rssi high\n");
1067 btdm8723.agc_table_en = true;
1068 btdm8723.adc_back_off_on = true;
1069 btdm8723.sw_dac_swing_on = false;
1070 } else {
1071 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1072 "Wifi rssi low\n");
1073 btdm8723.agc_table_en = false;
1074 btdm8723.adc_back_off_on = false;
1075 btdm8723.sw_dac_swing_on = false;
1076 }
1077
1078 /* fw mechanism */
1079 btdm8723.ps_tdma_on = true;
1080 if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) ||
1081 (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) {
1082 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1083 "Wifi rssi-1 high\n");
1084 /* only rssi high we need to do this,
1085 * when rssi low, the value will modified by fw
1086 */
1087 rtl_write_byte(rtlpriv, 0x883, 0x40);
1088 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1089 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1090 "[BTCoex], BT TxRx Counters >= 1400\n");
1091 btdm8723.ps_tdma_byte[0] = 0xa3;
1092 btdm8723.ps_tdma_byte[1] = 0x5;
1093 btdm8723.ps_tdma_byte[2] = 0x5;
1094 btdm8723.ps_tdma_byte[3] = 0x83;
1095 btdm8723.ps_tdma_byte[4] = 0x80;
1096 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1097 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1098 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1099 btdm8723.ps_tdma_byte[0] = 0xa3;
1100 btdm8723.ps_tdma_byte[1] = 0xa;
1101 btdm8723.ps_tdma_byte[2] = 0xa;
1102 btdm8723.ps_tdma_byte[3] = 0x83;
1103 btdm8723.ps_tdma_byte[4] = 0x80;
1104 } else {
1105 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1106 "[BTCoex], BT TxRx Counters < 1200\n");
1107 btdm8723.ps_tdma_byte[0] = 0xa3;
1108 btdm8723.ps_tdma_byte[1] = 0xf;
1109 btdm8723.ps_tdma_byte[2] = 0xf;
1110 btdm8723.ps_tdma_byte[3] = 0x83;
1111 btdm8723.ps_tdma_byte[4] = 0x80;
1112 }
1113 } else {
1114 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1115 "Wifi rssi-1 low\n");
1116 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1117 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1118 "[BTCoex], BT TxRx Counters >= 1400\n");
1119 btdm8723.ps_tdma_byte[0] = 0xa3;
1120 btdm8723.ps_tdma_byte[1] = 0x5;
1121 btdm8723.ps_tdma_byte[2] = 0x5;
1122 btdm8723.ps_tdma_byte[3] = 0x2;
1123 btdm8723.ps_tdma_byte[4] = 0x80;
1124 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1125 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1126 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1127 btdm8723.ps_tdma_byte[0] = 0xa3;
1128 btdm8723.ps_tdma_byte[1] = 0xa;
1129 btdm8723.ps_tdma_byte[2] = 0xa;
1130 btdm8723.ps_tdma_byte[3] = 0x2;
1131 btdm8723.ps_tdma_byte[4] = 0x80;
1132 } else {
1133 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1134 "[BTCoex], BT TxRx Counters < 1200\n");
1135 btdm8723.ps_tdma_byte[0] = 0xa3;
1136 btdm8723.ps_tdma_byte[1] = 0xf;
1137 btdm8723.ps_tdma_byte[2] = 0xf;
1138 btdm8723.ps_tdma_byte[3] = 0x2;
1139 btdm8723.ps_tdma_byte[4] = 0x80;
1140 }
1141 }
1142 }
1143
1144 if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw))
1145 btdm8723.dec_bt_pwr = true;
1146
1147 /* Always ignore WlanAct if bHid|bSCOBusy|bSCOeSCO */
1148
1149 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1150 "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n",
1151 rtlhal->hal_coex_8723.bt_inq_page_start_time,
1152 bt_tx_rx_cnt_lvl);
1153 if ((rtlhal->hal_coex_8723.bt_inq_page_start_time) ||
1154 (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) {
1155 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1156 "[BTCoex], Set BT inquiry / page scan 0x3a setting\n");
1157 btdm8723.ps_tdma_on = true;
1158 btdm8723.ps_tdma_byte[0] = 0xa3;
1159 btdm8723.ps_tdma_byte[1] = 0x5;
1160 btdm8723.ps_tdma_byte[2] = 0x5;
1161 btdm8723.ps_tdma_byte[3] = 0x2;
1162 btdm8723.ps_tdma_byte[4] = 0x80;
1163 }
1164
1165 if (rtl8723ae_dm_bt_is_coexist_state_changed(hw))
1166 rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723);
1167}
1168
1169static void rtl8723ae_dm_bt_2_ant_fta2dp(struct ieee80211_hw *hw)
1170{
1171 struct rtl_priv *rtlpriv = rtl_priv(hw);
1172 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1173 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1174 struct btdm_8723 btdm8723;
1175 u8 bt_rssi_state, bt_rssi_state1;
1176 u32 bt_tx_rx_cnt_lvl;
1177
1178 rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723);
1179 btdm8723.rf_rx_lpf_shrink = true;
1180 btdm8723.low_penalty_rate_adaptive = true;
1181 btdm8723.reject_aggre_pkt = false;
1182
1183 bt_tx_rx_cnt_lvl = rtl8723ae_dm_bt_bt_tx_rx_counter_level(hw);
1184
1185 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1186 "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl);
1187
1188 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
1189 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n");
1190 bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2,
1191 37, 0);
1192
1193 /* coex table */
1194 btdm8723.val_0x6c0 = 0x55555555;
1195 btdm8723.val_0x6c8 = 0xffff;
1196 btdm8723.val_0x6cc = 0x3;
1197
1198 /* sw mechanism */
1199 btdm8723.agc_table_en = false;
1200 btdm8723.adc_back_off_on = true;
1201 btdm8723.sw_dac_swing_on = false;
1202
1203 /* fw mechanism */
1204 btdm8723.ps_tdma_on = true;
1205 if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
1206 (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) {
1207 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1208 "Wifi rssi high\n");
1209 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1210 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1211 "[BTCoex], BT TxRx Counters >= 1400\n");
1212 btdm8723.ps_tdma_byte[0] = 0xa3;
1213 btdm8723.ps_tdma_byte[1] = 0x5;
1214 btdm8723.ps_tdma_byte[2] = 0x5;
1215 btdm8723.ps_tdma_byte[3] = 0x81;
1216 btdm8723.ps_tdma_byte[4] = 0x80;
1217 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1218 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1219 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1220 btdm8723.ps_tdma_byte[0] = 0xa3;
1221 btdm8723.ps_tdma_byte[1] = 0xa;
1222 btdm8723.ps_tdma_byte[2] = 0xa;
1223 btdm8723.ps_tdma_byte[3] = 0x81;
1224 btdm8723.ps_tdma_byte[4] = 0x80;
1225 } else {
1226 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1227 "[BTCoex], BT TxRx Counters < 1200\n");
1228 btdm8723.ps_tdma_byte[0] = 0xa3;
1229 btdm8723.ps_tdma_byte[1] = 0xf;
1230 btdm8723.ps_tdma_byte[2] = 0xf;
1231 btdm8723.ps_tdma_byte[3] = 0x81;
1232 btdm8723.ps_tdma_byte[4] = 0x80;
1233 }
1234 } else {
1235 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1236 "Wifi rssi low\n");
1237 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1238 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1239 "[BTCoex], BT TxRx Counters >= 1400\n");
1240 btdm8723.ps_tdma_byte[0] = 0xa3;
1241 btdm8723.ps_tdma_byte[1] = 0x5;
1242 btdm8723.ps_tdma_byte[2] = 0x5;
1243 btdm8723.ps_tdma_byte[3] = 0x0;
1244 btdm8723.ps_tdma_byte[4] = 0x80;
1245 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1246 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1247 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1248 btdm8723.ps_tdma_byte[0] = 0xa3;
1249 btdm8723.ps_tdma_byte[1] = 0xa;
1250 btdm8723.ps_tdma_byte[2] = 0xa;
1251 btdm8723.ps_tdma_byte[3] = 0x0;
1252 btdm8723.ps_tdma_byte[4] = 0x80;
1253 } else {
1254 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1255 "[BTCoex], BT TxRx Counters < 1200\n");
1256 btdm8723.ps_tdma_byte[0] = 0xa3;
1257 btdm8723.ps_tdma_byte[1] = 0xf;
1258 btdm8723.ps_tdma_byte[2] = 0xf;
1259 btdm8723.ps_tdma_byte[3] = 0x0;
1260 btdm8723.ps_tdma_byte[4] = 0x80;
1261 }
1262 }
1263 } else {
1264 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1265 "HT20 or Legacy\n");
1266 bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2,
1267 47, 0);
1268 bt_rssi_state1 = rtl8723ae_dm_bt_check_coex_rssi_state1(hw, 2,
1269 27, 0);
1270
1271 /* coex table */
1272 btdm8723.val_0x6c0 = 0x55555555;
1273 btdm8723.val_0x6c8 = 0xffff;
1274 btdm8723.val_0x6cc = 0x3;
1275
1276 /* sw mechanism */
1277 if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
1278 (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) {
1279 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1280 "Wifi rssi high\n");
1281 btdm8723.agc_table_en = true;
1282 btdm8723.adc_back_off_on = true;
1283 btdm8723.sw_dac_swing_on = false;
1284 } else {
1285 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1286 "Wifi rssi low\n");
1287 btdm8723.agc_table_en = false;
1288 btdm8723.adc_back_off_on = false;
1289 btdm8723.sw_dac_swing_on = false;
1290 }
1291
1292 /* fw mechanism */
1293 btdm8723.ps_tdma_on = true;
1294 if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) ||
1295 (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) {
1296 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1297 "Wifi rssi-1 high\n");
1298 /* only rssi high we need to do this,
1299 * when rssi low, the value will modified by fw
1300 */
1301 rtl_write_byte(rtlpriv, 0x883, 0x40);
1302 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1303 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1304 "[BTCoex], BT TxRx Counters >= 1400\n");
1305 btdm8723.ps_tdma_byte[0] = 0xa3;
1306 btdm8723.ps_tdma_byte[1] = 0x5;
1307 btdm8723.ps_tdma_byte[2] = 0x5;
1308 btdm8723.ps_tdma_byte[3] = 0x81;
1309 btdm8723.ps_tdma_byte[4] = 0x80;
1310 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1311 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1312 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1313 btdm8723.ps_tdma_byte[0] = 0xa3;
1314 btdm8723.ps_tdma_byte[1] = 0xa;
1315 btdm8723.ps_tdma_byte[2] = 0xa;
1316 btdm8723.ps_tdma_byte[3] = 0x81;
1317 btdm8723.ps_tdma_byte[4] = 0x80;
1318 } else {
1319 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1320 "[BTCoex], BT TxRx Counters < 1200\n");
1321 btdm8723.ps_tdma_byte[0] = 0xa3;
1322 btdm8723.ps_tdma_byte[1] = 0xf;
1323 btdm8723.ps_tdma_byte[2] = 0xf;
1324 btdm8723.ps_tdma_byte[3] = 0x81;
1325 btdm8723.ps_tdma_byte[4] = 0x80;
1326 }
1327 } else {
1328 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1329 "Wifi rssi-1 low\n");
1330 if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1331 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1332 "[BTCoex], BT TxRx Counters >= 1400\n");
1333 btdm8723.ps_tdma_byte[0] = 0xa3;
1334 btdm8723.ps_tdma_byte[1] = 0x5;
1335 btdm8723.ps_tdma_byte[2] = 0x5;
1336 btdm8723.ps_tdma_byte[3] = 0x0;
1337 btdm8723.ps_tdma_byte[4] = 0x80;
1338 } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1339 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1340 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1341 btdm8723.ps_tdma_byte[0] = 0xa3;
1342 btdm8723.ps_tdma_byte[1] = 0xa;
1343 btdm8723.ps_tdma_byte[2] = 0xa;
1344 btdm8723.ps_tdma_byte[3] = 0x0;
1345 btdm8723.ps_tdma_byte[4] = 0x80;
1346 } else {
1347 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1348 "[BTCoex], BT TxRx Counters < 1200\n");
1349 btdm8723.ps_tdma_byte[0] = 0xa3;
1350 btdm8723.ps_tdma_byte[1] = 0xf;
1351 btdm8723.ps_tdma_byte[2] = 0xf;
1352 btdm8723.ps_tdma_byte[3] = 0x0;
1353 btdm8723.ps_tdma_byte[4] = 0x80;
1354 }
1355 }
1356 }
1357
1358 if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw))
1359 btdm8723.dec_bt_pwr = true;
1360
1361 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1362 "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n",
1363 rtlhal->hal_coex_8723.bt_inq_page_start_time,
1364 bt_tx_rx_cnt_lvl);
1365
1366 if ((rtlhal->hal_coex_8723.bt_inq_page_start_time) ||
1367 (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) {
1368 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1369 "[BTCoex], Set BT inquiry / page scan 0x3a setting\n");
1370 btdm8723.ps_tdma_on = true;
1371 btdm8723.ps_tdma_byte[0] = 0xa3;
1372 btdm8723.ps_tdma_byte[1] = 0x5;
1373 btdm8723.ps_tdma_byte[2] = 0x5;
1374 btdm8723.ps_tdma_byte[3] = 0x83;
1375 btdm8723.ps_tdma_byte[4] = 0x80;
1376 }
1377
1378 if (rtl8723ae_dm_bt_is_coexist_state_changed(hw))
1379 rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723);
1380}
1381
1382static void rtl8723ae_dm_bt_inq_page_monitor(struct ieee80211_hw *hw)
1383{
1384 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1385 struct rtl_priv *rtlpriv = rtl_priv(hw);
1386 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1387 u32 cur_time = jiffies;
1388
1389 if (rtlhal->hal_coex_8723.c2h_bt_inquiry_page) {
1390 /* bt inquiry or page is started. */
1391 if (rtlhal->hal_coex_8723.bt_inq_page_start_time == 0) {
1392 rtlpcipriv->bt_coexist.cstate |=
1393 BT_COEX_STATE_BT_INQ_PAGE;
1394 rtlhal->hal_coex_8723.bt_inq_page_start_time = cur_time;
1395 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1396 "[BTCoex], BT Inquiry/page is started at time : 0x%x\n",
1397 rtlhal->hal_coex_8723.bt_inq_page_start_time);
1398 }
1399 }
1400 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1401 "[BTCoex], BT Inquiry/page started time : 0x%x, cur_time : 0x%x\n",
1402 rtlhal->hal_coex_8723.bt_inq_page_start_time, cur_time);
1403
1404 if (rtlhal->hal_coex_8723.bt_inq_page_start_time) {
1405 if ((((long)cur_time -
1406 (long)rtlhal->hal_coex_8723.bt_inq_page_start_time) / HZ) >=
1407 10) {
1408 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1409 "[BTCoex], BT Inquiry/page >= 10sec!!!");
1410 rtlhal->hal_coex_8723.bt_inq_page_start_time = 0;
1411 rtlpcipriv->bt_coexist.cstate &=
1412 ~BT_COEX_STATE_BT_INQ_PAGE;
1413 }
1414 }
1415}
1416
1417static void rtl8723ae_dm_bt_reset_action_profile_state(struct ieee80211_hw *hw)
1418{
1419 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1420
1421 rtlpcipriv->bt_coexist.cstate &=
1422 ~(BT_COEX_STATE_PROFILE_HID | BT_COEX_STATE_PROFILE_A2DP |
1423 BT_COEX_STATE_PROFILE_PAN | BT_COEX_STATE_PROFILE_SCO);
1424
1425 rtlpcipriv->bt_coexist.cstate &=
1426 ~(BT_COEX_STATE_BTINFO_COMMON |
1427 BT_COEX_STATE_BTINFO_B_HID_SCOESCO |
1428 BT_COEX_STATE_BTINFO_B_FTP_A2DP);
1429}
1430
1431static void _rtl8723ae_dm_bt_coexist_2_ant(struct ieee80211_hw *hw)
1432{
1433 struct rtl_priv *rtlpriv = rtl_priv(hw);
1434 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1435 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1436 u8 bt_retry_cnt;
1437 u8 bt_info_original;
1438 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1439 "[BTCoex] Get bt info by fw!!\n");
1440
1441 _rtl8723_dm_bt_check_wifi_state(hw);
1442
1443 if (rtlhal->hal_coex_8723.c2h_bt_info_req_sent) {
1444 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1445 "[BTCoex] c2h for btInfo not rcvd yet!!\n");
1446 }
1447
1448 bt_retry_cnt = rtlhal->hal_coex_8723.bt_retry_cnt;
1449 bt_info_original = rtlhal->hal_coex_8723.c2h_bt_info_original;
1450
1451 /* when bt inquiry or page scan, we have to set h2c 0x25
1452 * ignore wlanact for continuous 4x2secs
1453 */
1454 rtl8723ae_dm_bt_inq_page_monitor(hw);
1455 rtl8723ae_dm_bt_reset_action_profile_state(hw);
1456
1457 if (rtl8723ae_dm_bt_is_2_ant_common_action(hw)) {
1458 rtlpcipriv->bt_coexist.bt_profile_case = BT_COEX_MECH_COMMON;
1459 rtlpcipriv->bt_coexist.bt_profile_action = BT_COEX_MECH_COMMON;
1460
1461 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1462 "Action 2-Ant common.\n");
1463 } else {
1464 if ((bt_info_original & BTINFO_B_HID) ||
1465 (bt_info_original & BTINFO_B_SCO_BUSY) ||
1466 (bt_info_original & BTINFO_B_SCO_ESCO)) {
1467 rtlpcipriv->bt_coexist.cstate |=
1468 BT_COEX_STATE_BTINFO_B_HID_SCOESCO;
1469 rtlpcipriv->bt_coexist.bt_profile_case =
1470 BT_COEX_MECH_HID_SCO_ESCO;
1471 rtlpcipriv->bt_coexist.bt_profile_action =
1472 BT_COEX_MECH_HID_SCO_ESCO;
1473 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1474 "[BTCoex], BTInfo: bHid|bSCOBusy|bSCOeSCO\n");
1475 rtl8723ae_dm_bt_2_ant_hid_sco_esco(hw);
1476 } else if ((bt_info_original & BTINFO_B_FTP) ||
1477 (bt_info_original & BTINFO_B_A2DP)) {
1478 rtlpcipriv->bt_coexist.cstate |=
1479 BT_COEX_STATE_BTINFO_B_FTP_A2DP;
1480 rtlpcipriv->bt_coexist.bt_profile_case =
1481 BT_COEX_MECH_FTP_A2DP;
1482 rtlpcipriv->bt_coexist.bt_profile_action =
1483 BT_COEX_MECH_FTP_A2DP;
1484 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1485 "BTInfo: bFTP|bA2DP\n");
1486 rtl8723ae_dm_bt_2_ant_fta2dp(hw);
1487 } else {
1488 rtlpcipriv->bt_coexist.cstate |=
1489 BT_COEX_STATE_BTINFO_B_HID_SCOESCO;
1490 rtlpcipriv->bt_coexist.bt_profile_case =
1491 BT_COEX_MECH_NONE;
1492 rtlpcipriv->bt_coexist.bt_profile_action =
1493 BT_COEX_MECH_NONE;
1494 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1495 "[BTCoex], BTInfo: undefined case!!!!\n");
1496 rtl8723ae_dm_bt_2_ant_hid_sco_esco(hw);
1497 }
1498 }
1499}
1500
1501static void _rtl8723ae_dm_bt_coexist_1_ant(struct ieee80211_hw *hw)
1502{
1503}
1504
1505void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw)
1506{
1507 rtl8723ae_dm_bt_set_coex_table(hw, 0x5a5aaaaa, 0xcc, 0x3);
1508 rtl8723ae_dm_bt_set_hw_pta_mode(hw, true);
1509}
1510
1511void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw)
1512{
1513 rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, false);
1514 rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
1515 rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
1516 rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, false,
1517 TDMA_2ANT, TDMA_NAV_OFF);
1518 rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, TDMA_2ANT,
1519 TDMA_NAV_OFF, TDMA_DAC_SWING_OFF);
1520 rtl8723ae_dm_bt_set_fw_dac_swing_level(hw, 0);
1521 rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false);
1522 rtl8723ae_dm_bt_set_fw_bt_retry_index(hw, 2);
1523 rtl8723ae_dm_bt_set_fw_wlan_act(hw, 0x10, 0x10);
1524 rtl8723ae_dm_bt_set_fw_dec_bt_pwr(hw, false);
1525}
1526
1527void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw)
1528{
1529 rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF);
1530 rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_OFF);
1531 rtl8723ae_dm_bt_reject_ap_aggregated_packet(hw, false);
1532
1533 rtl8723ae_bt_set_penalty_tx_rate_adap(hw, BT_TX_RATE_ADAPTIVE_NORMAL);
1534 rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, BT_RF_RX_LPF_CORNER_RESUME);
1535 rtl8723ae_dm_bt_set_sw_full_time_dac_swing(hw, false, 0xc0);
1536}
1537
1538static void rtl8723ae_dm_bt_query_bt_information(struct ieee80211_hw *hw)
1539{
1540 struct rtl_priv *rtlpriv = rtl_priv(hw);
1541 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1542 u8 h2c_parameter[1] = {0};
1543
1544 rtlhal->hal_coex_8723.c2h_bt_info_req_sent = true;
1545
1546 h2c_parameter[0] |= BIT(0);
1547
1548 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1549 "Query Bt information, write 0x38 = 0x%x\n",
1550 h2c_parameter[0]);
1551
1552 rtl8723ae_fill_h2c_cmd(hw, 0x38, 1, h2c_parameter);
1553}
1554
1555static void rtl8723ae_dm_bt_bt_hw_counters_monitor(struct ieee80211_hw *hw)
1556{
1557 struct rtl_priv *rtlpriv = rtl_priv(hw);
1558 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1559 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1560 u32 reg_htx_rx, reg_ltx_rx, u32_tmp;
1561 u32 reg_htx, reg_hrx, reg_ltx, reg_lrx;
1562
1563 reg_htx_rx = REG_HIGH_PRIORITY_TXRX;
1564 reg_ltx_rx = REG_LOW_PRIORITY_TXRX;
1565
1566 u32_tmp = rtl_read_dword(rtlpriv, reg_htx_rx);
1567 reg_htx = u32_tmp & MASKLWORD;
1568 reg_hrx = (u32_tmp & MASKHWORD)>>16;
1569
1570 u32_tmp = rtl_read_dword(rtlpriv, reg_ltx_rx);
1571 reg_ltx = u32_tmp & MASKLWORD;
1572 reg_lrx = (u32_tmp & MASKHWORD)>>16;
1573
1574 if (rtlpcipriv->bt_coexist.lps_counter > 1) {
1575 reg_htx %= rtlpcipriv->bt_coexist.lps_counter;
1576 reg_hrx %= rtlpcipriv->bt_coexist.lps_counter;
1577 reg_ltx %= rtlpcipriv->bt_coexist.lps_counter;
1578 reg_lrx %= rtlpcipriv->bt_coexist.lps_counter;
1579 }
1580
1581 rtlhal->hal_coex_8723.high_priority_tx = reg_htx;
1582 rtlhal->hal_coex_8723.high_priority_rx = reg_hrx;
1583 rtlhal->hal_coex_8723.low_priority_tx = reg_ltx;
1584 rtlhal->hal_coex_8723.low_priority_rx = reg_lrx;
1585
1586 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1587 "High Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n",
1588 reg_htx_rx, reg_htx, reg_htx, reg_hrx, reg_hrx);
1589 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1590 "Low Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n",
1591 reg_ltx_rx, reg_ltx, reg_ltx, reg_lrx, reg_lrx);
1592 rtlpcipriv->bt_coexist.lps_counter = 0;
1593}
1594
1595static void rtl8723ae_dm_bt_bt_enable_disable_check(struct ieee80211_hw *hw)
1596{
1597 struct rtl_priv *rtlpriv = rtl_priv(hw);
1598 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1599 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1600 bool bt_alife = true;
1601
1602 if (rtlhal->hal_coex_8723.high_priority_tx == 0 &&
1603 rtlhal->hal_coex_8723.high_priority_rx == 0 &&
1604 rtlhal->hal_coex_8723.low_priority_tx == 0 &&
1605 rtlhal->hal_coex_8723.low_priority_rx == 0)
1606 bt_alife = false;
1607 if (rtlhal->hal_coex_8723.high_priority_tx == 0xeaea &&
1608 rtlhal->hal_coex_8723.high_priority_rx == 0xeaea &&
1609 rtlhal->hal_coex_8723.low_priority_tx == 0xeaea &&
1610 rtlhal->hal_coex_8723.low_priority_rx == 0xeaea)
1611 bt_alife = false;
1612 if (rtlhal->hal_coex_8723.high_priority_tx == 0xffff &&
1613 rtlhal->hal_coex_8723.high_priority_rx == 0xffff &&
1614 rtlhal->hal_coex_8723.low_priority_tx == 0xffff &&
1615 rtlhal->hal_coex_8723.low_priority_rx == 0xffff)
1616 bt_alife = false;
1617 if (bt_alife) {
1618 rtlpcipriv->bt_coexist.bt_active_zero_cnt = 0;
1619 rtlpcipriv->bt_coexist.cur_bt_disabled = false;
1620 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1621 "8723A BT is enabled !!\n");
1622 } else {
1623 rtlpcipriv->bt_coexist.bt_active_zero_cnt++;
1624 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1625 "8723A bt all counters = 0, %d times!!\n",
1626 rtlpcipriv->bt_coexist.bt_active_zero_cnt);
1627 if (rtlpcipriv->bt_coexist.bt_active_zero_cnt >= 2) {
1628 rtlpcipriv->bt_coexist.cur_bt_disabled = true;
1629 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1630 "8723A BT is disabled !!\n");
1631 }
1632 }
1633 if (rtlpcipriv->bt_coexist.pre_bt_disabled !=
1634 rtlpcipriv->bt_coexist.cur_bt_disabled) {
1635 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1636 "8723A BT is from %s to %s!!\n",
1637 (rtlpcipriv->bt_coexist.pre_bt_disabled ?
1638 "disabled" : "enabled"),
1639 (rtlpcipriv->bt_coexist.cur_bt_disabled ?
1640 "disabled" : "enabled"));
1641 rtlpcipriv->bt_coexist.pre_bt_disabled
1642 = rtlpcipriv->bt_coexist.cur_bt_disabled;
1643 }
1644}
1645
1646
1647void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw)
1648{
1649 struct rtl_priv *rtlpriv = rtl_priv(hw);
1650 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1651
1652 rtl8723ae_dm_bt_query_bt_information(hw);
1653 rtl8723ae_dm_bt_bt_hw_counters_monitor(hw);
1654 rtl8723ae_dm_bt_bt_enable_disable_check(hw);
1655
1656 if (rtlpcipriv->bt_coexist.bt_ant_num == ANT_X2) {
1657 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1658 "[BTCoex], 2 Ant mechanism\n");
1659 _rtl8723ae_dm_bt_coexist_2_ant(hw);
1660 } else {
1661 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1662 "[BTCoex], 1 Ant mechanism\n");
1663 _rtl8723ae_dm_bt_coexist_1_ant(hw);
1664 }
1665
1666 if (!rtl8723ae_dm_bt_is_same_coexist_state(hw)) {
1667 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1668 "[BTCoex], Coexist State[bitMap] change from 0x%x%8x to 0x%x%8x\n",
1669 rtlpcipriv->bt_coexist.previous_state_h,
1670 rtlpcipriv->bt_coexist.previous_state,
1671 rtlpcipriv->bt_coexist.cstate_h,
1672 rtlpcipriv->bt_coexist.cstate);
1673 rtlpcipriv->bt_coexist.previous_state
1674 = rtlpcipriv->bt_coexist.cstate;
1675 rtlpcipriv->bt_coexist.previous_state_h
1676 = rtlpcipriv->bt_coexist.cstate_h;
1677 }
1678}
1679
1680static void rtl8723ae_dm_bt_parse_bt_info(struct ieee80211_hw *hw,
1681 u8 *tmbuf, u8 len)
1682{
1683 struct rtl_priv *rtlpriv = rtl_priv(hw);
1684 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1685 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1686 u8 bt_info;
1687 u8 i;
1688
1689 rtlhal->hal_coex_8723.c2h_bt_info_req_sent = false;
1690 rtlhal->hal_coex_8723.bt_retry_cnt = 0;
1691 for (i = 0; i < len; i++) {
1692 if (i == 0)
1693 rtlhal->hal_coex_8723.c2h_bt_info_original = tmbuf[i];
1694 else if (i == 1)
1695 rtlhal->hal_coex_8723.bt_retry_cnt = tmbuf[i];
1696 if (i == len-1) {
1697 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1698 "0x%2x]", tmbuf[i]);
1699 } else {
1700 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1701 "0x%2x, ", tmbuf[i]);
1702 }
1703 }
1704 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1705 "BT info bt_info (Data)= 0x%x\n",
1706 rtlhal->hal_coex_8723.c2h_bt_info_original);
1707 bt_info = rtlhal->hal_coex_8723.c2h_bt_info_original;
1708
1709 if (bt_info & BIT(2))
1710 rtlhal->hal_coex_8723.c2h_bt_inquiry_page = true;
1711 else
1712 rtlhal->hal_coex_8723.c2h_bt_inquiry_page = false;
1713
1714 if (bt_info & BTINFO_B_CONNECTION) {
1715 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1716 "[BTC2H], BTInfo: bConnect=true\n");
1717 rtlpcipriv->bt_coexist.bt_busy = true;
1718 rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT_IDLE;
1719 } else {
1720 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1721 "[BTC2H], BTInfo: bConnect=false\n");
1722 rtlpcipriv->bt_coexist.bt_busy = false;
1723 rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT_IDLE;
1724 }
1725}
1726void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw)
1727{
1728 struct rtl_priv *rtlpriv = rtl_priv(hw);
1729 struct c2h_evt_hdr c2h_event;
1730 u8 *ptmbuf;
1731 u8 index;
1732 u8 u1tmp;
1733
1734 memset(&c2h_event, 0, sizeof(c2h_event));
1735 u1tmp = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL);
1736 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
1737 "&&&&&&: REG_C2HEVT_MSG_NORMAL is 0x%x\n", u1tmp);
1738 c2h_event.cmd_id = u1tmp & 0xF;
1739 c2h_event.cmd_len = (u1tmp & 0xF0) >> 4;
1740 c2h_event.cmd_seq = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + 1);
1741 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
1742 "cmd_id: %d, cmd_len: %d, cmd_seq: %d\n",
1743 c2h_event.cmd_id , c2h_event.cmd_len, c2h_event.cmd_seq);
1744 u1tmp = rtl_read_byte(rtlpriv, 0x01AF);
1745 if (u1tmp == C2H_EVT_HOST_CLOSE) {
1746 return;
1747 } else if (u1tmp != C2H_EVT_FW_CLOSE) {
1748 rtl_write_byte(rtlpriv, 0x1AF, 0x00);
1749 return;
1750 }
1751 ptmbuf = kmalloc(c2h_event.cmd_len, GFP_KERNEL);
1752 if (ptmbuf == NULL) {
1753 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1754 "malloc cmd buf failed\n");
1755 return;
1756 }
1757
1758 /* Read the content */
1759 for (index = 0; index < c2h_event.cmd_len; index++)
1760 ptmbuf[index] = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL +
1761 2 + index);
1762
1763 switch (c2h_event.cmd_id) {
1764 case C2H_BT_RSSI:
1765 break;
1766
1767 case C2H_BT_OP_MODE:
1768 break;
1769
1770 case BT_INFO:
1771 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1772 "BT info Byte[0] (ID) is 0x%x\n", c2h_event.cmd_id);
1773 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1774 "BT info Byte[1] (Seq) is 0x%x\n", c2h_event.cmd_seq);
1775 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1776 "BT info Byte[2] (Data)= 0x%x\n", ptmbuf[0]);
1777
1778 rtl8723ae_dm_bt_parse_bt_info(hw, ptmbuf, c2h_event.cmd_len);
1779 break;
1780 default:
1781 break;
1782 }
1783 kfree(ptmbuf);
1784
1785 rtl_write_byte(rtlpriv, 0x01AF, C2H_EVT_HOST_CLOSE);
1786}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h
new file mode 100644
index 00000000000..4325ecd58f0
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h
@@ -0,0 +1,151 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 * Larry Finger <Larry.Finger@lwfinger.net>
26 *
27 ****************************************************************************
28 */
29
30#ifndef __RTL8723E_HAL_BTC_H__
31#define __RTL8723E_HAL_BTC_H__
32
33#include "../wifi.h"
34#include "btc.h"
35#include "hal_bt_coexist.h"
36
37#define BT_TXRX_CNT_THRES_1 1200
38#define BT_TXRX_CNT_THRES_2 1400
39#define BT_TXRX_CNT_THRES_3 3000
40#define BT_TXRX_CNT_LEVEL_0 0 /* < 1200 */
41#define BT_TXRX_CNT_LEVEL_1 1 /* >= 1200 && < 1400 */
42#define BT_TXRX_CNT_LEVEL_2 2 /* >= 1400 */
43#define BT_TXRX_CNT_LEVEL_3 3
44
45/* TDMA mode definition */
46#define TDMA_2ANT 0
47#define TDMA_1ANT 1
48#define TDMA_NAV_OFF 0
49#define TDMA_NAV_ON 1
50#define TDMA_DAC_SWING_OFF 0
51#define TDMA_DAC_SWING_ON 1
52
53/* PTA mode related definition */
54#define BT_PTA_MODE_OFF 0
55#define BT_PTA_MODE_ON 1
56
57/* Penalty Tx Rate Adaptive */
58#define BT_TX_RATE_ADAPTIVE_NORMAL 0
59#define BT_TX_RATE_ADAPTIVE_LOW_PENALTY 1
60
61/* RF Corner */
62#define BT_RF_RX_LPF_CORNER_RESUME 0
63#define BT_RF_RX_LPF_CORNER_SHRINK 1
64
65#define C2H_EVT_HOST_CLOSE 0x00
66#define C2H_EVT_FW_CLOSE 0xFF
67
68enum bt_traffic_mode {
69 BT_MOTOR_EXT_BE = 0x00,
70 BT_MOTOR_EXT_GUL = 0x01,
71 BT_MOTOR_EXT_GUB = 0x02,
72 BT_MOTOR_EXT_GULB = 0x03
73};
74
75enum bt_traffic_mode_profile {
76 BT_PROFILE_NONE,
77 BT_PROFILE_A2DP,
78 BT_PROFILE_PAN,
79 BT_PROFILE_HID,
80 BT_PROFILE_SCO
81};
82
83enum hci_ext_bt_operation {
84 HCI_BT_OP_NONE = 0x0,
85 HCI_BT_OP_INQUIRE_START = 0x1,
86 HCI_BT_OP_INQUIRE_FINISH = 0x2,
87 HCI_BT_OP_PAGING_START = 0x3,
88 HCI_BT_OP_PAGING_SUCCESS = 0x4,
89 HCI_BT_OP_PAGING_UNSUCCESS = 0x5,
90 HCI_BT_OP_PAIRING_START = 0x6,
91 HCI_BT_OP_PAIRING_FINISH = 0x7,
92 HCI_BT_OP_BT_DEV_ENABLE = 0x8,
93 HCI_BT_OP_BT_DEV_DISABLE = 0x9,
94 HCI_BT_OP_MAX,
95};
96
97enum bt_spec {
98 BT_SPEC_1_0_b = 0x00,
99 BT_SPEC_1_1 = 0x01,
100 BT_SPEC_1_2 = 0x02,
101 BT_SPEC_2_0_EDR = 0x03,
102 BT_SPEC_2_1_EDR = 0x04,
103 BT_SPEC_3_0_HS = 0x05,
104 BT_SPEC_4_0 = 0x06
105};
106
107struct c2h_evt_hdr {
108 u8 cmd_id;
109 u8 cmd_len;
110 u8 cmd_seq;
111};
112
113enum bt_state {
114 BT_INFO_STATE_DISABLED = 0,
115 BT_INFO_STATE_NO_CONNECTION = 1,
116 BT_INFO_STATE_CONNECT_IDLE = 2,
117 BT_INFO_STATE_INQ_OR_PAG = 3,
118 BT_INFO_STATE_ACL_ONLY_BUSY = 4,
119 BT_INFO_STATE_SCO_ONLY_BUSY = 5,
120 BT_INFO_STATE_ACL_SCO_BUSY = 6,
121 BT_INFO_STATE_HID_BUSY = 7,
122 BT_INFO_STATE_HID_SCO_BUSY = 8,
123 BT_INFO_STATE_MAX = 7
124};
125
126enum rtl8723ae_c2h_evt {
127 C2H_DBG = 0,
128 C2H_TSF = 1,
129 C2H_AP_RPT_RSP = 2,
130 C2H_CCX_TX_RPT = 3, /* The FW notify the report of the specific */
131 /* tx packet. */
132 C2H_BT_RSSI = 4,
133 C2H_BT_OP_MODE = 5,
134 C2H_HW_INFO_EXCH = 10,
135 C2H_C2H_H2C_TEST = 11,
136 BT_INFO = 12,
137 MAX_C2HEVENT
138};
139
140void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw);
141void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw);
142void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw);
143void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw);
144void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw,
145 struct btdm_8723 *p_btdm);
146void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw);
147void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw,
148 bool mstatus);
149void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw);
150
151#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
new file mode 100644
index 00000000000..0a8c03863fb
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -0,0 +1,2380 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
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#include "reg.h"
38#include "def.h"
39#include "phy.h"
40#include "dm.h"
41#include "fw.h"
42#include "led.h"
43#include "hw.h"
44#include "pwrseqcmd.h"
45#include "pwrseq.h"
46#include "btc.h"
47
48static void _rtl8723ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
49 u8 set_bits, u8 clear_bits)
50{
51 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
52 struct rtl_priv *rtlpriv = rtl_priv(hw);
53
54 rtlpci->reg_bcn_ctrl_val |= set_bits;
55 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
56
57 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
58}
59
60static void _rtl8723ae_stop_tx_beacon(struct ieee80211_hw *hw)
61{
62 struct rtl_priv *rtlpriv = rtl_priv(hw);
63 u8 tmp1byte;
64
65 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
66 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
67 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
68 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
69 tmp1byte &= ~(BIT(0));
70 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
71}
72
73static void _rtl8723ae_resume_tx_beacon(struct ieee80211_hw *hw)
74{
75 struct rtl_priv *rtlpriv = rtl_priv(hw);
76 u8 tmp1byte;
77
78 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
79 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
80 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
81 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
82 tmp1byte |= BIT(1);
83 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
84}
85
86static void _rtl8723ae_enable_bcn_sufunc(struct ieee80211_hw *hw)
87{
88 _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(1));
89}
90
91static void _rtl8723ae_disable_bcn_sufunc(struct ieee80211_hw *hw)
92{
93 _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(1), 0);
94}
95
96void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
97{
98 struct rtl_priv *rtlpriv = rtl_priv(hw);
99 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
100 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
101
102 switch (variable) {
103 case HW_VAR_RCR:
104 *((u32 *) (val)) = rtlpci->receive_config;
105 break;
106 case HW_VAR_RF_STATE:
107 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
108 break;
109 case HW_VAR_FWLPS_RF_ON:{
110 enum rf_pwrstate rfState;
111 u32 val_rcr;
112
113 rtlpriv->cfg->ops->get_hw_reg(hw,
114 HW_VAR_RF_STATE,
115 (u8 *) (&rfState));
116 if (rfState == ERFOFF) {
117 *((bool *) (val)) = true;
118 } else {
119 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
120 val_rcr &= 0x00070000;
121 if (val_rcr)
122 *((bool *) (val)) = false;
123 else
124 *((bool *) (val)) = true;
125 }
126 break; }
127 case HW_VAR_FW_PSMODE_STATUS:
128 *((bool *) (val)) = ppsc->fw_current_inpsmode;
129 break;
130 case HW_VAR_CORRECT_TSF:{
131 u64 tsf;
132 u32 *ptsf_low = (u32 *)&tsf;
133 u32 *ptsf_high = ((u32 *)&tsf) + 1;
134
135 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
136 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
137
138 *((u64 *) (val)) = tsf;
139
140 break; }
141 default:
142 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
143 "switch case not process\n");
144 break;
145 }
146}
147
148void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
149{
150 struct rtl_priv *rtlpriv = rtl_priv(hw);
151 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
152 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
153 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
154 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
155 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
156 u8 idx;
157
158 switch (variable) {
159 case HW_VAR_ETHER_ADDR:
160 for (idx = 0; idx < ETH_ALEN; idx++) {
161 rtl_write_byte(rtlpriv, (REG_MACID + idx),
162 val[idx]);
163 }
164 break;
165 case HW_VAR_BASIC_RATE:{
166 u16 rate_cfg = ((u16 *) val)[0];
167 u8 rate_index = 0;
168 rate_cfg = rate_cfg & 0x15f;
169 rate_cfg |= 0x01;
170 rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
171 rtl_write_byte(rtlpriv, REG_RRSR + 1,
172 (rate_cfg >> 8) & 0xff);
173 while (rate_cfg > 0x1) {
174 rate_cfg = (rate_cfg >> 1);
175 rate_index++;
176 }
177 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL,
178 rate_index);
179 break; }
180 case HW_VAR_BSSID:
181 for (idx = 0; idx < ETH_ALEN; idx++) {
182 rtl_write_byte(rtlpriv, (REG_BSSID + idx),
183 val[idx]);
184 }
185 break;
186 case HW_VAR_SIFS:
187 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
188 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
189
190 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
191 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
192
193 if (!mac->ht_enable)
194 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
195 0x0e0e);
196 else
197 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
198 *((u16 *) val));
199 break;
200 case HW_VAR_SLOT_TIME:{
201 u8 e_aci;
202
203 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
204 "HW_VAR_SLOT_TIME %x\n", val[0]);
205
206 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
207
208 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
209 rtlpriv->cfg->ops->set_hw_reg(hw,
210 HW_VAR_AC_PARAM,
211 (u8 *) (&e_aci));
212 }
213 break; }
214 case HW_VAR_ACK_PREAMBLE:{
215 u8 reg_tmp;
216 u8 short_preamble = (bool) (*(u8 *) val);
217 reg_tmp = (mac->cur_40_prime_sc) << 5;
218 if (short_preamble)
219 reg_tmp |= 0x80;
220
221 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp);
222 break; }
223 case HW_VAR_AMPDU_MIN_SPACE:{
224 u8 min_spacing_to_set;
225 u8 sec_min_space;
226
227 min_spacing_to_set = *((u8 *) val);
228 if (min_spacing_to_set <= 7) {
229 sec_min_space = 0;
230
231 if (min_spacing_to_set < sec_min_space)
232 min_spacing_to_set = sec_min_space;
233
234 mac->min_space_cfg = ((mac->min_space_cfg &
235 0xf8) |
236 min_spacing_to_set);
237
238 *val = min_spacing_to_set;
239
240 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
241 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
242 mac->min_space_cfg);
243
244 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
245 mac->min_space_cfg);
246 }
247 break; }
248 case HW_VAR_SHORTGI_DENSITY:{
249 u8 density_to_set;
250
251 density_to_set = *((u8 *) val);
252 mac->min_space_cfg |= (density_to_set << 3);
253
254 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
255 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
256 mac->min_space_cfg);
257
258 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
259 mac->min_space_cfg);
260
261 break; }
262 case HW_VAR_AMPDU_FACTOR:{
263 u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
264 u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97};
265 u8 factor_toset;
266 u8 *p_regtoset = NULL;
267 u8 index;
268
269 if ((pcipriv->bt_coexist.bt_coexistence) &&
270 (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4))
271 p_regtoset = regtoset_bt;
272 else
273 p_regtoset = regtoset_normal;
274
275 factor_toset = *((u8 *) val);
276 if (factor_toset <= 3) {
277 factor_toset = (1 << (factor_toset + 2));
278 if (factor_toset > 0xf)
279 factor_toset = 0xf;
280
281 for (index = 0; index < 4; index++) {
282 if ((p_regtoset[index] & 0xf0) >
283 (factor_toset << 4))
284 p_regtoset[index] =
285 (p_regtoset[index] & 0x0f) |
286 (factor_toset << 4);
287
288 if ((p_regtoset[index] & 0x0f) >
289 factor_toset)
290 p_regtoset[index] =
291 (p_regtoset[index] & 0xf0) |
292 (factor_toset);
293
294 rtl_write_byte(rtlpriv,
295 (REG_AGGLEN_LMT + index),
296 p_regtoset[index]);
297
298 }
299
300 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
301 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
302 factor_toset);
303 }
304 break; }
305 case HW_VAR_AC_PARAM:{
306 u8 e_aci = *((u8 *) val);
307 rtl8723ae_dm_init_edca_turbo(hw);
308
309 if (rtlpci->acm_method != eAcmWay2_SW)
310 rtlpriv->cfg->ops->set_hw_reg(hw,
311 HW_VAR_ACM_CTRL,
312 (u8 *) (&e_aci));
313 break; }
314 case HW_VAR_ACM_CTRL:{
315 u8 e_aci = *((u8 *) val);
316 union aci_aifsn *p_aci_aifsn =
317 (union aci_aifsn *)(&(mac->ac[0].aifs));
318 u8 acm = p_aci_aifsn->f.acm;
319 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
320
321 acm_ctrl |= ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
322
323 if (acm) {
324 switch (e_aci) {
325 case AC0_BE:
326 acm_ctrl |= AcmHw_BeqEn;
327 break;
328 case AC2_VI:
329 acm_ctrl |= AcmHw_ViqEn;
330 break;
331 case AC3_VO:
332 acm_ctrl |= AcmHw_VoqEn;
333 break;
334 default:
335 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
336 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
337 acm);
338 break;
339 }
340 } else {
341 switch (e_aci) {
342 case AC0_BE:
343 acm_ctrl &= (~AcmHw_BeqEn);
344 break;
345 case AC2_VI:
346 acm_ctrl &= (~AcmHw_ViqEn);
347 break;
348 case AC3_VO:
349 acm_ctrl &= (~AcmHw_BeqEn);
350 break;
351 default:
352 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
353 "switch case not processed\n");
354 break;
355 }
356 }
357
358 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
359 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
360 acm_ctrl);
361 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
362 break; }
363 case HW_VAR_RCR:
364 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]);
365 rtlpci->receive_config = ((u32 *) (val))[0];
366 break;
367 case HW_VAR_RETRY_LIMIT:{
368 u8 retry_limit = ((u8 *) (val))[0];
369
370 rtl_write_word(rtlpriv, REG_RL,
371 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
372 retry_limit << RETRY_LIMIT_LONG_SHIFT);
373 break; }
374 case HW_VAR_DUAL_TSF_RST:
375 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
376 break;
377 case HW_VAR_EFUSE_BYTES:
378 rtlefuse->efuse_usedbytes = *((u16 *) val);
379 break;
380 case HW_VAR_EFUSE_USAGE:
381 rtlefuse->efuse_usedpercentage = *((u8 *) val);
382 break;
383 case HW_VAR_IO_CMD:
384 rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val));
385 break;
386 case HW_VAR_WPA_CONFIG:
387 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val));
388 break;
389 case HW_VAR_SET_RPWM:{
390 u8 rpwm_val;
391
392 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
393 udelay(1);
394
395 if (rpwm_val & BIT(7)) {
396 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
397 (*(u8 *) val));
398 } else {
399 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
400 ((*(u8 *) val) | BIT(7)));
401 }
402
403 break; }
404 case HW_VAR_H2C_FW_PWRMODE:{
405 u8 psmode = (*(u8 *) val);
406
407 if (psmode != FW_PS_ACTIVE_MODE)
408 rtl8723ae_dm_rf_saving(hw, true);
409
410 rtl8723ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val));
411 break; }
412 case HW_VAR_FW_PSMODE_STATUS:
413 ppsc->fw_current_inpsmode = *((bool *) val);
414 break;
415 case HW_VAR_H2C_FW_JOINBSSRPT:{
416 u8 mstatus = (*(u8 *) val);
417 u8 tmp_regcr, tmp_reg422;
418 bool recover = false;
419
420 if (mstatus == RT_MEDIA_CONNECT) {
421 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
422
423 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
424 rtl_write_byte(rtlpriv, REG_CR + 1,
425 (tmp_regcr | BIT(0)));
426
427 _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(3));
428 _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(4), 0);
429
430 tmp_reg422 = rtl_read_byte(rtlpriv,
431 REG_FWHW_TXQ_CTRL + 2);
432 if (tmp_reg422 & BIT(6))
433 recover = true;
434 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
435 tmp_reg422 & (~BIT(6)));
436
437 rtl8723ae_set_fw_rsvdpagepkt(hw, 0);
438
439 _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(3), 0);
440 _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(4));
441
442 if (recover)
443 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
444 tmp_reg422);
445
446 rtl_write_byte(rtlpriv, REG_CR + 1,
447 (tmp_regcr & ~(BIT(0))));
448 }
449 rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val));
450
451 break; }
452 case HW_VAR_AID:{
453 u16 u2btmp;
454 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
455 u2btmp &= 0xC000;
456 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp |
457 mac->assoc_id));
458 break; }
459 case HW_VAR_CORRECT_TSF:{
460 u8 btype_ibss = ((u8 *) (val))[0];
461
462 if (btype_ibss == true)
463 _rtl8723ae_stop_tx_beacon(hw);
464
465 _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(3));
466
467 rtl_write_dword(rtlpriv, REG_TSFTR,
468 (u32) (mac->tsf & 0xffffffff));
469 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
470 (u32) ((mac->tsf >> 32) & 0xffffffff));
471
472 _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(3), 0);
473
474 if (btype_ibss == true)
475 _rtl8723ae_resume_tx_beacon(hw);
476 break; }
477 default:
478 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
479 "switch case not processed\n");
480 break;
481 }
482}
483
484static bool _rtl8723ae_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
485{
486 struct rtl_priv *rtlpriv = rtl_priv(hw);
487 bool status = true;
488 long count = 0;
489 u32 value = _LLT_INIT_ADDR(address) |
490 _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
491
492 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
493
494 do {
495 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
496 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
497 break;
498
499 if (count > POLLING_LLT_THRESHOLD) {
500 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
501 "Failed to polling write LLT done at address %d!\n",
502 address);
503 status = false;
504 break;
505 }
506 } while (++count);
507
508 return status;
509}
510
511static bool _rtl8723ae_llt_table_init(struct ieee80211_hw *hw)
512{
513 struct rtl_priv *rtlpriv = rtl_priv(hw);
514 unsigned short i;
515 u8 txpktbuf_bndy;
516 u8 maxPage;
517 bool status;
518 u8 ubyte;
519
520 maxPage = 255;
521 txpktbuf_bndy = 246;
522
523 rtl_write_byte(rtlpriv, REG_CR, 0x8B);
524
525 rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000);
526
527 rtl_write_dword(rtlpriv, REG_RQPN, 0x80ac1c29);
528 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x03);
529
530 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy));
531 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
532
533 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
534 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
535
536 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
537 rtl_write_byte(rtlpriv, REG_PBP, 0x11);
538 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
539
540 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
541 status = _rtl8723ae_llt_write(hw, i, i + 1);
542 if (true != status)
543 return status;
544 }
545
546 status = _rtl8723ae_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
547 if (true != status)
548 return status;
549
550 for (i = txpktbuf_bndy; i < maxPage; i++) {
551 status = _rtl8723ae_llt_write(hw, i, (i + 1));
552 if (true != status)
553 return status;
554 }
555
556 status = _rtl8723ae_llt_write(hw, maxPage, txpktbuf_bndy);
557 if (true != status)
558 return status;
559
560 rtl_write_byte(rtlpriv, REG_CR, 0xff);
561 ubyte = rtl_read_byte(rtlpriv, REG_RQPN + 3);
562 rtl_write_byte(rtlpriv, REG_RQPN + 3, ubyte | BIT(7));
563
564 return true;
565}
566
567static void _rtl8723ae_gen_refresh_led_state(struct ieee80211_hw *hw)
568{
569 struct rtl_priv *rtlpriv = rtl_priv(hw);
570 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
571 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
572 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
573
574 if (rtlpriv->rtlhal.up_first_time)
575 return;
576
577 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
578 rtl8723ae_sw_led_on(hw, pLed0);
579 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
580 rtl8723ae_sw_led_on(hw, pLed0);
581 else
582 rtl8723ae_sw_led_off(hw, pLed0);
583}
584
585static bool _rtl8712e_init_mac(struct ieee80211_hw *hw)
586{
587 struct rtl_priv *rtlpriv = rtl_priv(hw);
588 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
589 unsigned char bytetmp;
590 unsigned short wordtmp;
591 u16 retry = 0;
592 u16 tmpu2b;
593 bool mac_func_enable;
594
595 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
596 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
597 if (bytetmp == 0xFF)
598 mac_func_enable = true;
599 else
600 mac_func_enable = false;
601
602
603 /* HW Power on sequence */
604 if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
605 PWR_INTF_PCI_MSK, Rtl8723_NIC_ENABLE_FLOW))
606 return false;
607
608 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+2);
609 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+2, bytetmp | BIT(4));
610
611 /* eMAC time out function enable, 0x369[7]=1 */
612 bytetmp = rtl_read_byte(rtlpriv, 0x369);
613 rtl_write_byte(rtlpriv, 0x369, bytetmp | BIT(7));
614
615 /* ePHY reg 0x1e bit[4]=1 using MDIO interface,
616 * we should do this before Enabling ASPM backdoor.
617 */
618 do {
619 rtl_write_word(rtlpriv, 0x358, 0x5e);
620 udelay(100);
621 rtl_write_word(rtlpriv, 0x356, 0xc280);
622 rtl_write_word(rtlpriv, 0x354, 0xc290);
623 rtl_write_word(rtlpriv, 0x358, 0x3e);
624 udelay(100);
625 rtl_write_word(rtlpriv, 0x358, 0x5e);
626 udelay(100);
627 tmpu2b = rtl_read_word(rtlpriv, 0x356);
628 retry++;
629 } while (tmpu2b != 0xc290 && retry < 100);
630
631 if (retry >= 100) {
632 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
633 "InitMAC(): ePHY configure fail!!!\n");
634 return false;
635 }
636
637 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
638 rtl_write_word(rtlpriv, REG_CR + 1, 0x06);
639
640 if (!mac_func_enable) {
641 if (_rtl8723ae_llt_table_init(hw) == false)
642 return false;
643 }
644
645 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
646 rtl_write_byte(rtlpriv, REG_HISRE, 0xff);
647
648 rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff);
649
650 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0xf;
651 wordtmp |= 0xF771;
652 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
653
654 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
655 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
656 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
657 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
658
659 rtl_write_byte(rtlpriv, 0x4d0, 0x0);
660
661 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
662 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
663 DMA_BIT_MASK(32));
664 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
665 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
666 DMA_BIT_MASK(32));
667 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
668 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
669 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
670 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
671 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
672 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
673 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
674 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
675 rtl_write_dword(rtlpriv, REG_HQ_DESA,
676 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
677 DMA_BIT_MASK(32));
678 rtl_write_dword(rtlpriv, REG_RX_DESA,
679 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
680 DMA_BIT_MASK(32));
681
682 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x74);
683
684 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
685
686 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
687 rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6));
688 do {
689 retry++;
690 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
691 } while ((retry < 200) && (bytetmp & BIT(7)));
692
693 _rtl8723ae_gen_refresh_led_state(hw);
694
695 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
696
697 return true;
698}
699
700static void _rtl8723ae_hw_configure(struct ieee80211_hw *hw)
701{
702 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
703 struct rtl_priv *rtlpriv = rtl_priv(hw);
704 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
705 u8 reg_bw_opmode;
706 u32 reg_ratr, reg_prsr;
707
708 reg_bw_opmode = BW_OPMODE_20MHZ;
709 reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
710 RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
711 reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
712
713 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8);
714
715 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
716
717 rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr);
718
719 rtl_write_byte(rtlpriv, REG_SLOT, 0x09);
720
721 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0);
722
723 rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80);
724
725 rtl_write_word(rtlpriv, REG_RL, 0x0707);
726
727 rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802);
728
729 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
730
731 rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
732 rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
733 rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
734 rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
735
736 if ((pcipriv->bt_coexist.bt_coexistence) &&
737 (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4))
738 rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431);
739 else
740 rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841);
741
742 rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2);
743
744 rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff);
745
746 rtlpci->reg_bcn_ctrl_val = 0x1f;
747 rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
748
749 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
750
751 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
752
753 rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
754 rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
755
756 if ((pcipriv->bt_coexist.bt_coexistence) &&
757 (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) {
758 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
759 rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402);
760 } else {
761 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
762 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
763 }
764
765 if ((pcipriv->bt_coexist.bt_coexistence) &&
766 (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4))
767 rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
768 else
769 rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666);
770
771 rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
772
773 rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010);
774 rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010);
775
776 rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010);
777
778 rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010);
779
780 rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff);
781 rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff);
782
783 rtl_write_dword(rtlpriv, 0x394, 0x1);
784}
785
786static void _rtl8723ae_enable_aspm_back_door(struct ieee80211_hw *hw)
787{
788 struct rtl_priv *rtlpriv = rtl_priv(hw);
789 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
790
791 rtl_write_byte(rtlpriv, 0x34b, 0x93);
792 rtl_write_word(rtlpriv, 0x350, 0x870c);
793 rtl_write_byte(rtlpriv, 0x352, 0x1);
794
795 if (ppsc->support_backdoor)
796 rtl_write_byte(rtlpriv, 0x349, 0x1b);
797 else
798 rtl_write_byte(rtlpriv, 0x349, 0x03);
799
800 rtl_write_word(rtlpriv, 0x350, 0x2718);
801 rtl_write_byte(rtlpriv, 0x352, 0x1);
802}
803
804void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw)
805{
806 struct rtl_priv *rtlpriv = rtl_priv(hw);
807 u8 sec_reg_value;
808
809 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
810 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
811 rtlpriv->sec.pairwise_enc_algorithm,
812 rtlpriv->sec.group_enc_algorithm);
813
814 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
815 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
816 "not open hw encryption\n");
817 return;
818 }
819
820 sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable;
821
822 if (rtlpriv->sec.use_defaultkey) {
823 sec_reg_value |= SCR_TxUseDK;
824 sec_reg_value |= SCR_RxUseDK;
825 }
826
827 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
828
829 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
830
831 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
832 "The SECR-value %x\n", sec_reg_value);
833
834 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
835
836}
837
838int rtl8723ae_hw_init(struct ieee80211_hw *hw)
839{
840 struct rtl_priv *rtlpriv = rtl_priv(hw);
841 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
842 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
843 struct rtl_phy *rtlphy = &(rtlpriv->phy);
844 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
845 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
846 bool rtstatus = true;
847 int err;
848 u8 tmp_u1b;
849
850 rtlpriv->rtlhal.being_init_adapter = true;
851 rtlpriv->intf_ops->disable_aspm(hw);
852 rtstatus = _rtl8712e_init_mac(hw);
853 if (rtstatus != true) {
854 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
855 err = 1;
856 return err;
857 }
858
859 err = rtl8723ae_download_fw(hw);
860 if (err) {
861 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
862 "Failed to download FW. Init HW without FW now..\n");
863 err = 1;
864 rtlhal->fw_ready = false;
865 return err;
866 } else {
867 rtlhal->fw_ready = true;
868 }
869
870 rtlhal->last_hmeboxnum = 0;
871 rtl8723ae_phy_mac_config(hw);
872 /* because the last function modifies RCR, we update
873 * rcr var here, or TP will be unstable as ther receive_config
874 * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx
875 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
876 */
877 rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
878 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
879 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
880
881 rtl8723ae_phy_bb_config(hw);
882 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
883 rtl8723ae_phy_rf_config(hw);
884 if (IS_VENDOR_UMC_A_CUT(rtlhal->version)) {
885 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255);
886 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00);
887 } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
888 rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE);
889 rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31);
890 rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425);
891 rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200);
892 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053);
893 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201);
894 }
895 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
896 RF_CHNLBW, RFREG_OFFSET_MASK);
897 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
898 RF_CHNLBW, RFREG_OFFSET_MASK);
899 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
900 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
901 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
902 _rtl8723ae_hw_configure(hw);
903 rtl_cam_reset_all_entry(hw);
904 rtl8723ae_enable_hw_security_config(hw);
905
906 ppsc->rfpwr_state = ERFON;
907
908 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
909 _rtl8723ae_enable_aspm_back_door(hw);
910 rtlpriv->intf_ops->enable_aspm(hw);
911
912 rtl8723ae_bt_hw_init(hw);
913
914 if (ppsc->rfpwr_state == ERFON) {
915 rtl8723ae_phy_set_rfpath_switch(hw, 1);
916 if (rtlphy->iqk_initialized) {
917 rtl8723ae_phy_iq_calibrate(hw, true);
918 } else {
919 rtl8723ae_phy_iq_calibrate(hw, false);
920 rtlphy->iqk_initialized = true;
921 }
922
923 rtl8723ae_phy_lc_calibrate(hw);
924 }
925
926 tmp_u1b = efuse_read_1byte(hw, 0x1FA);
927 if (!(tmp_u1b & BIT(0))) {
928 rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
929 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n");
930 }
931
932 if (!(tmp_u1b & BIT(4))) {
933 tmp_u1b = rtl_read_byte(rtlpriv, 0x16) & 0x0F;
934 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
935 udelay(10);
936 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
937 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
938 }
939 rtl8723ae_dm_init(hw);
940 rtlpriv->rtlhal.being_init_adapter = false;
941 return err;
942}
943
944static enum version_8723e _rtl8723ae_read_chip_version(struct ieee80211_hw *hw)
945{
946 struct rtl_priv *rtlpriv = rtl_priv(hw);
947 struct rtl_phy *rtlphy = &(rtlpriv->phy);
948 enum version_8723e version = 0x0000;
949 u32 value32;
950
951 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
952 if (value32 & TRP_VAUX_EN) {
953 version = (enum version_8723e)(version |
954 ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0));
955 /* RTL8723 with BT function. */
956 version = (enum version_8723e)(version |
957 ((value32 & BT_FUNC) ? CHIP_8723 : 0));
958
959 } else {
960 /* Normal mass production chip. */
961 version = (enum version_8723e) NORMAL_CHIP;
962 version = (enum version_8723e)(version |
963 ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0));
964 /* RTL8723 with BT function. */
965 version = (enum version_8723e)(version |
966 ((value32 & BT_FUNC) ? CHIP_8723 : 0));
967 if (IS_CHIP_VENDOR_UMC(version))
968 version = (enum version_8723e)(version |
969 ((value32 & CHIP_VER_RTL_MASK)));/* IC version (CUT) */
970 if (IS_8723_SERIES(version)) {
971 value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS);
972 /* ROM code version */
973 version = (enum version_8723e)(version |
974 ((value32 & RF_RL_ID)>>20));
975 }
976 }
977
978 if (IS_8723_SERIES(version)) {
979 value32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
980 rtlphy->polarity_ctl = ((value32 & WL_HWPDN_SL) ?
981 RT_POLARITY_HIGH_ACT :
982 RT_POLARITY_LOW_ACT);
983 }
984 switch (version) {
985 case VERSION_TEST_UMC_CHIP_8723:
986 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
987 "Chip Version ID: VERSION_TEST_UMC_CHIP_8723.\n");
988 break;
989 case VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT:
990 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
991 "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT.\n");
992 break;
993 case VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT:
994 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
995 "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT.\n");
996 break;
997 default:
998 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
999 "Chip Version ID: Unknown. Bug?\n");
1000 break;
1001 }
1002
1003 if (IS_8723_SERIES(version))
1004 rtlphy->rf_type = RF_1T1R;
1005
1006 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n",
1007 (rtlphy->rf_type == RF_2T2R) ? "RF_2T2R" : "RF_1T1R");
1008
1009 return version;
1010}
1011
1012static int _rtl8723ae_set_media_status(struct ieee80211_hw *hw,
1013 enum nl80211_iftype type)
1014{
1015 struct rtl_priv *rtlpriv = rtl_priv(hw);
1016 u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1017 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1018
1019 rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0);
1020 RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
1021 "clear 0x550 when set HW_VAR_MEDIA_STATUS\n");
1022
1023 if (type == NL80211_IFTYPE_UNSPECIFIED ||
1024 type == NL80211_IFTYPE_STATION) {
1025 _rtl8723ae_stop_tx_beacon(hw);
1026 _rtl8723ae_enable_bcn_sufunc(hw);
1027 } else if (type == NL80211_IFTYPE_ADHOC ||
1028 type == NL80211_IFTYPE_AP) {
1029 _rtl8723ae_resume_tx_beacon(hw);
1030 _rtl8723ae_disable_bcn_sufunc(hw);
1031 } else {
1032 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1033 "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1034 type);
1035 }
1036
1037 switch (type) {
1038 case NL80211_IFTYPE_UNSPECIFIED:
1039 bt_msr |= MSR_NOLINK;
1040 ledaction = LED_CTL_LINK;
1041 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1042 "Set Network type to NO LINK!\n");
1043 break;
1044 case NL80211_IFTYPE_ADHOC:
1045 bt_msr |= MSR_ADHOC;
1046 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1047 "Set Network type to Ad Hoc!\n");
1048 break;
1049 case NL80211_IFTYPE_STATION:
1050 bt_msr |= MSR_INFRA;
1051 ledaction = LED_CTL_LINK;
1052 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1053 "Set Network type to STA!\n");
1054 break;
1055 case NL80211_IFTYPE_AP:
1056 bt_msr |= MSR_AP;
1057 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1058 "Set Network type to AP!\n");
1059 break;
1060 default:
1061 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1062 "Network type %d not supported!\n",
1063 type);
1064 return 1;
1065 break;
1066
1067 }
1068
1069 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1070 rtlpriv->cfg->ops->led_control(hw, ledaction);
1071 if ((bt_msr & 0x03) == MSR_AP)
1072 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1073 else
1074 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1075 return 0;
1076}
1077
1078void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1079{
1080 struct rtl_priv *rtlpriv = rtl_priv(hw);
1081 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1082 u32 reg_rcr = rtlpci->receive_config;
1083
1084 if (rtlpriv->psc.rfpwr_state != ERFON)
1085 return;
1086
1087 if (check_bssid == true) {
1088 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1089 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1090 (u8 *)(&reg_rcr));
1091 _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(4));
1092 } else if (check_bssid == false) {
1093 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1094 _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(4), 0);
1095 rtlpriv->cfg->ops->set_hw_reg(hw,
1096 HW_VAR_RCR, (u8 *) (&reg_rcr));
1097 }
1098}
1099
1100int rtl8723ae_set_network_type(struct ieee80211_hw *hw,
1101 enum nl80211_iftype type)
1102{
1103 struct rtl_priv *rtlpriv = rtl_priv(hw);
1104
1105 if (_rtl8723ae_set_media_status(hw, type))
1106 return -EOPNOTSUPP;
1107
1108 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1109 if (type != NL80211_IFTYPE_AP)
1110 rtl8723ae_set_check_bssid(hw, true);
1111 } else {
1112 rtl8723ae_set_check_bssid(hw, false);
1113 }
1114 return 0;
1115}
1116
1117/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
1118void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci)
1119{
1120 struct rtl_priv *rtlpriv = rtl_priv(hw);
1121
1122 rtl8723ae_dm_init_edca_turbo(hw);
1123 switch (aci) {
1124 case AC1_BK:
1125 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1126 break;
1127 case AC0_BE:
1128 /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4ac_param); */
1129 break;
1130 case AC2_VI:
1131 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1132 break;
1133 case AC3_VO:
1134 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1135 break;
1136 default:
1137 RT_ASSERT(false, "invalid aci: %d !\n", aci);
1138 break;
1139 }
1140}
1141
1142void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw)
1143{
1144 struct rtl_priv *rtlpriv = rtl_priv(hw);
1145 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1146
1147 rtl_write_dword(rtlpriv, 0x3a8, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1148 rtl_write_dword(rtlpriv, 0x3ac, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1149 rtlpci->irq_enabled = true;
1150}
1151
1152void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw)
1153{
1154 struct rtl_priv *rtlpriv = rtl_priv(hw);
1155 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1156
1157 rtl_write_dword(rtlpriv, 0x3a8, IMR8190_DISABLED);
1158 rtl_write_dword(rtlpriv, 0x3ac, IMR8190_DISABLED);
1159 rtlpci->irq_enabled = false;
1160 synchronize_irq(rtlpci->pdev->irq);
1161}
1162
1163static void _rtl8723ae_poweroff_adapter(struct ieee80211_hw *hw)
1164{
1165 struct rtl_priv *rtlpriv = rtl_priv(hw);
1166 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1167 u8 u1tmp;
1168
1169 /* Combo (PCIe + USB) Card and PCIe-MF Card */
1170 /* 1. Run LPS WL RFOFF flow */
1171 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1172 PWR_INTF_PCI_MSK, Rtl8723_NIC_LPS_ENTER_FLOW);
1173
1174 /* 2. 0x1F[7:0] = 0 */
1175 /* turn off RF */
1176 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
1177 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready)
1178 rtl8723ae_firmware_selfreset(hw);
1179
1180 /* Reset MCU. Suggested by Filen. */
1181 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
1182 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1tmp & (~BIT(2))));
1183
1184 /* g. MCUFWDL 0x80[1:0]=0 */
1185 /* reset MCU ready status */
1186 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1187
1188 /* HW card disable configuration. */
1189 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1190 PWR_INTF_PCI_MSK, Rtl8723_NIC_DISABLE_FLOW);
1191
1192 /* Reset MCU IO Wrapper */
1193 u1tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1194 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1tmp & (~BIT(0))));
1195 u1tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1196 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1tmp | BIT(0));
1197
1198 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1199 /* lock ISO/CLK/Power control register */
1200 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1201}
1202
1203void rtl8723ae_card_disable(struct ieee80211_hw *hw)
1204{
1205 struct rtl_priv *rtlpriv = rtl_priv(hw);
1206 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1207 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1208 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1209 enum nl80211_iftype opmode;
1210
1211 mac->link_state = MAC80211_NOLINK;
1212 opmode = NL80211_IFTYPE_UNSPECIFIED;
1213 _rtl8723ae_set_media_status(hw, opmode);
1214 if (rtlpci->driver_is_goingto_unload ||
1215 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1216 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1217 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1218 _rtl8723ae_poweroff_adapter(hw);
1219
1220 /* after power off we should do iqk again */
1221 rtlpriv->phy.iqk_initialized = false;
1222}
1223
1224void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw,
1225 u32 *p_inta, u32 *p_intb)
1226{
1227 struct rtl_priv *rtlpriv = rtl_priv(hw);
1228 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1229
1230 *p_inta = rtl_read_dword(rtlpriv, 0x3a0) & rtlpci->irq_mask[0];
1231 rtl_write_dword(rtlpriv, 0x3a0, *p_inta);
1232}
1233
1234void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw)
1235{
1236
1237 struct rtl_priv *rtlpriv = rtl_priv(hw);
1238 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1239 u16 bcn_interval, atim_window;
1240
1241 bcn_interval = mac->beacon_interval;
1242 atim_window = 2; /*FIX MERGE */
1243 rtl8723ae_disable_interrupt(hw);
1244 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1245 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1246 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1247 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1248 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1249 rtl_write_byte(rtlpriv, 0x606, 0x30);
1250 rtl8723ae_enable_interrupt(hw);
1251}
1252
1253void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw)
1254{
1255 struct rtl_priv *rtlpriv = rtl_priv(hw);
1256 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1257 u16 bcn_interval = mac->beacon_interval;
1258
1259 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1260 "beacon_interval:%d\n", bcn_interval);
1261 rtl8723ae_disable_interrupt(hw);
1262 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1263 rtl8723ae_enable_interrupt(hw);
1264}
1265
1266void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw,
1267 u32 add_msr, u32 rm_msr)
1268{
1269 struct rtl_priv *rtlpriv = rtl_priv(hw);
1270 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1271
1272 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1273 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1274
1275 if (add_msr)
1276 rtlpci->irq_mask[0] |= add_msr;
1277 if (rm_msr)
1278 rtlpci->irq_mask[0] &= (~rm_msr);
1279 rtl8723ae_disable_interrupt(hw);
1280 rtl8723ae_enable_interrupt(hw);
1281}
1282
1283static u8 _rtl8723ae_get_chnl_group(u8 chnl)
1284{
1285 u8 group;
1286
1287 if (chnl < 3)
1288 group = 0;
1289 else if (chnl < 9)
1290 group = 1;
1291 else
1292 group = 2;
1293 return group;
1294}
1295
1296static void _rtl8723ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1297 bool autoload_fail,
1298 u8 *hwinfo)
1299{
1300 struct rtl_priv *rtlpriv = rtl_priv(hw);
1301 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1302 u8 rf_path, index, tempval;
1303 u16 i;
1304
1305 for (rf_path = 0; rf_path < 1; rf_path++) {
1306 for (i = 0; i < 3; i++) {
1307 if (!autoload_fail) {
1308 rtlefuse->eeprom_chnlarea_txpwr_cck
1309 [rf_path][i] =
1310 hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i];
1311 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1312 [rf_path][i] =
1313 hwinfo[EEPROM_TXPOWERHT40_1S + rf_path *
1314 3 + i];
1315 } else {
1316 rtlefuse->eeprom_chnlarea_txpwr_cck
1317 [rf_path][i] =
1318 EEPROM_DEFAULT_TXPOWERLEVEL;
1319 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1320 [rf_path][i] =
1321 EEPROM_DEFAULT_TXPOWERLEVEL;
1322 }
1323 }
1324 }
1325
1326 for (i = 0; i < 3; i++) {
1327 if (!autoload_fail)
1328 tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i];
1329 else
1330 tempval = EEPROM_DEFAULT_HT40_2SDIFF;
1331 rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] =
1332 (tempval & 0xf);
1333 rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] =
1334 ((tempval & 0xf0) >> 4);
1335 }
1336
1337 for (rf_path = 0; rf_path < 2; rf_path++)
1338 for (i = 0; i < 3; i++)
1339 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1340 "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
1341 i, rtlefuse->eeprom_chnlarea_txpwr_cck
1342 [rf_path][i]);
1343 for (rf_path = 0; rf_path < 2; rf_path++)
1344 for (i = 0; i < 3; i++)
1345 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1346 "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
1347 rf_path, i,
1348 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1349 [rf_path][i]);
1350 for (rf_path = 0; rf_path < 2; rf_path++)
1351 for (i = 0; i < 3; i++)
1352 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1353 "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
1354 rf_path, i,
1355 rtlefuse->eprom_chnl_txpwr_ht40_2sdf
1356 [rf_path][i]);
1357
1358 for (rf_path = 0; rf_path < 2; rf_path++) {
1359 for (i = 0; i < 14; i++) {
1360 index = _rtl8723ae_get_chnl_group((u8) i);
1361
1362 rtlefuse->txpwrlevel_cck[rf_path][i] =
1363 rtlefuse->eeprom_chnlarea_txpwr_cck
1364 [rf_path][index];
1365 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1366 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1367 [rf_path][index];
1368
1369 if ((rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1370 [rf_path][index] -
1371 rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path]
1372 [index]) > 0) {
1373 rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
1374 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1375 [rf_path][index] -
1376 rtlefuse->eprom_chnl_txpwr_ht40_2sdf
1377 [rf_path][index];
1378 } else {
1379 rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0;
1380 }
1381 }
1382
1383 for (i = 0; i < 14; i++) {
1384 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1385 "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
1386 "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
1387 rtlefuse->txpwrlevel_cck[rf_path][i],
1388 rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
1389 rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
1390 }
1391 }
1392
1393 for (i = 0; i < 3; i++) {
1394 if (!autoload_fail) {
1395 rtlefuse->eeprom_pwrlimit_ht40[i] =
1396 hwinfo[EEPROM_TXPWR_GROUP + i];
1397 rtlefuse->eeprom_pwrlimit_ht20[i] =
1398 hwinfo[EEPROM_TXPWR_GROUP + 3 + i];
1399 } else {
1400 rtlefuse->eeprom_pwrlimit_ht40[i] = 0;
1401 rtlefuse->eeprom_pwrlimit_ht20[i] = 0;
1402 }
1403 }
1404
1405 for (rf_path = 0; rf_path < 2; rf_path++) {
1406 for (i = 0; i < 14; i++) {
1407 index = _rtl8723ae_get_chnl_group((u8) i);
1408
1409 if (rf_path == RF90_PATH_A) {
1410 rtlefuse->pwrgroup_ht20[rf_path][i] =
1411 (rtlefuse->eeprom_pwrlimit_ht20[index] &
1412 0xf);
1413 rtlefuse->pwrgroup_ht40[rf_path][i] =
1414 (rtlefuse->eeprom_pwrlimit_ht40[index] &
1415 0xf);
1416 } else if (rf_path == RF90_PATH_B) {
1417 rtlefuse->pwrgroup_ht20[rf_path][i] =
1418 ((rtlefuse->eeprom_pwrlimit_ht20[index] &
1419 0xf0) >> 4);
1420 rtlefuse->pwrgroup_ht40[rf_path][i] =
1421 ((rtlefuse->eeprom_pwrlimit_ht40[index] &
1422 0xf0) >> 4);
1423 }
1424
1425 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1426 "RF-%d pwrgroup_ht20[%d] = 0x%x\n", rf_path, i,
1427 rtlefuse->pwrgroup_ht20[rf_path][i]);
1428 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1429 "RF-%d pwrgroup_ht40[%d] = 0x%x\n", rf_path, i,
1430 rtlefuse->pwrgroup_ht40[rf_path][i]);
1431 }
1432 }
1433
1434 for (i = 0; i < 14; i++) {
1435 index = _rtl8723ae_get_chnl_group((u8) i);
1436
1437 if (!autoload_fail)
1438 tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index];
1439 else
1440 tempval = EEPROM_DEFAULT_HT20_DIFF;
1441
1442 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF);
1443 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] =
1444 ((tempval >> 4) & 0xF);
1445
1446 if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3))
1447 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0;
1448
1449 if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3))
1450 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0;
1451
1452 index = _rtl8723ae_get_chnl_group((u8) i);
1453
1454 if (!autoload_fail)
1455 tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index];
1456 else
1457 tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF;
1458
1459 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF);
1460 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] =
1461 ((tempval >> 4) & 0xF);
1462 }
1463
1464 rtlefuse->legacy_ht_txpowerdiff =
1465 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7];
1466
1467 for (i = 0; i < 14; i++)
1468 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1469 "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
1470 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
1471 for (i = 0; i < 14; i++)
1472 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1473 "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
1474 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
1475 for (i = 0; i < 14; i++)
1476 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1477 "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
1478 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
1479 for (i = 0; i < 14; i++)
1480 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1481 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
1482 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
1483
1484 if (!autoload_fail)
1485 rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
1486 else
1487 rtlefuse->eeprom_regulatory = 0;
1488 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1489 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
1490
1491 if (!autoload_fail)
1492 rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
1493 else
1494 rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI;
1495 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1496 "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
1497 rtlefuse->eeprom_tssi[RF90_PATH_A],
1498 rtlefuse->eeprom_tssi[RF90_PATH_B]);
1499
1500 if (!autoload_fail)
1501 tempval = hwinfo[EEPROM_THERMAL_METER];
1502 else
1503 tempval = EEPROM_DEFAULT_THERMALMETER;
1504 rtlefuse->eeprom_thermalmeter = (tempval & 0x1f);
1505
1506 if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail)
1507 rtlefuse->apk_thermalmeterignore = true;
1508
1509 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
1510 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1511 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1512}
1513
1514static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,
1515 bool pseudo_test)
1516{
1517 struct rtl_priv *rtlpriv = rtl_priv(hw);
1518 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1519 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1520 u16 i, usvalue;
1521 u8 hwinfo[HWSET_MAX_SIZE];
1522 u16 eeprom_id;
1523
1524 if (pseudo_test) {
1525 /* need add */
1526 return;
1527 }
1528 if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
1529 rtl_efuse_shadow_map_update(hw);
1530
1531 memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
1532 HWSET_MAX_SIZE);
1533 } else if (rtlefuse->epromtype == EEPROM_93C46) {
1534 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1535 "RTL819X Not boot from eeprom, check it !!");
1536 }
1537
1538 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
1539 hwinfo, HWSET_MAX_SIZE);
1540
1541 eeprom_id = *((u16 *)&hwinfo[0]);
1542 if (eeprom_id != RTL8190_EEPROM_ID) {
1543 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1544 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
1545 rtlefuse->autoload_failflag = true;
1546 } else {
1547 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1548 rtlefuse->autoload_failflag = false;
1549 }
1550
1551 if (rtlefuse->autoload_failflag == true)
1552 return;
1553
1554 rtlefuse->eeprom_vid = *(u16 *) &hwinfo[EEPROM_VID];
1555 rtlefuse->eeprom_did = *(u16 *) &hwinfo[EEPROM_DID];
1556 rtlefuse->eeprom_svid = *(u16 *) &hwinfo[EEPROM_SVID];
1557 rtlefuse->eeprom_smid = *(u16 *) &hwinfo[EEPROM_SMID];
1558 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1559 "EEPROMId = 0x%4x\n", eeprom_id);
1560 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1561 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
1562 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1563 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
1564 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1565 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
1566 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1567 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
1568
1569 for (i = 0; i < 6; i += 2) {
1570 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
1571 *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
1572 }
1573
1574 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1575 "dev_addr: %pM\n", rtlefuse->dev_addr);
1576
1577 _rtl8723ae_read_txpower_info_from_hwpg(hw,
1578 rtlefuse->autoload_failflag, hwinfo);
1579
1580 rtl8723ae_read_bt_coexist_info_from_hwpg(hw,
1581 rtlefuse->autoload_failflag, hwinfo);
1582
1583 rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
1584 rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
1585 rtlefuse->txpwr_fromeprom = true;
1586 rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
1587
1588 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1589 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
1590
1591 /* set channel paln to world wide 13 */
1592 rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
1593
1594 if (rtlhal->oem_id == RT_CID_DEFAULT) {
1595 switch (rtlefuse->eeprom_oemid) {
1596 case EEPROM_CID_DEFAULT:
1597 if (rtlefuse->eeprom_did == 0x8176) {
1598 if (CHK_SVID_SMID(0x10EC, 0x6151) ||
1599 CHK_SVID_SMID(0x10EC, 0x6152) ||
1600 CHK_SVID_SMID(0x10EC, 0x6154) ||
1601 CHK_SVID_SMID(0x10EC, 0x6155) ||
1602 CHK_SVID_SMID(0x10EC, 0x6177) ||
1603 CHK_SVID_SMID(0x10EC, 0x6178) ||
1604 CHK_SVID_SMID(0x10EC, 0x6179) ||
1605 CHK_SVID_SMID(0x10EC, 0x6180) ||
1606 CHK_SVID_SMID(0x10EC, 0x8151) ||
1607 CHK_SVID_SMID(0x10EC, 0x8152) ||
1608 CHK_SVID_SMID(0x10EC, 0x8154) ||
1609 CHK_SVID_SMID(0x10EC, 0x8155) ||
1610 CHK_SVID_SMID(0x10EC, 0x8181) ||
1611 CHK_SVID_SMID(0x10EC, 0x8182) ||
1612 CHK_SVID_SMID(0x10EC, 0x8184) ||
1613 CHK_SVID_SMID(0x10EC, 0x8185) ||
1614 CHK_SVID_SMID(0x10EC, 0x9151) ||
1615 CHK_SVID_SMID(0x10EC, 0x9152) ||
1616 CHK_SVID_SMID(0x10EC, 0x9154) ||
1617 CHK_SVID_SMID(0x10EC, 0x9155) ||
1618 CHK_SVID_SMID(0x10EC, 0x9181) ||
1619 CHK_SVID_SMID(0x10EC, 0x9182) ||
1620 CHK_SVID_SMID(0x10EC, 0x9184) ||
1621 CHK_SVID_SMID(0x10EC, 0x9185))
1622 rtlhal->oem_id = RT_CID_TOSHIBA;
1623 else if (rtlefuse->eeprom_svid == 0x1025)
1624 rtlhal->oem_id = RT_CID_819x_Acer;
1625 else if (CHK_SVID_SMID(0x10EC, 0x6191) ||
1626 CHK_SVID_SMID(0x10EC, 0x6192) ||
1627 CHK_SVID_SMID(0x10EC, 0x6193) ||
1628 CHK_SVID_SMID(0x10EC, 0x7191) ||
1629 CHK_SVID_SMID(0x10EC, 0x7192) ||
1630 CHK_SVID_SMID(0x10EC, 0x7193) ||
1631 CHK_SVID_SMID(0x10EC, 0x8191) ||
1632 CHK_SVID_SMID(0x10EC, 0x8192) ||
1633 CHK_SVID_SMID(0x10EC, 0x8193))
1634 rtlhal->oem_id = RT_CID_819x_SAMSUNG;
1635 else if (CHK_SVID_SMID(0x10EC, 0x8195) ||
1636 CHK_SVID_SMID(0x10EC, 0x9195) ||
1637 CHK_SVID_SMID(0x10EC, 0x7194) ||
1638 CHK_SVID_SMID(0x10EC, 0x8200) ||
1639 CHK_SVID_SMID(0x10EC, 0x8201) ||
1640 CHK_SVID_SMID(0x10EC, 0x8202) ||
1641 CHK_SVID_SMID(0x10EC, 0x9200))
1642 rtlhal->oem_id = RT_CID_819x_Lenovo;
1643 else if (CHK_SVID_SMID(0x10EC, 0x8197) ||
1644 CHK_SVID_SMID(0x10EC, 0x9196))
1645 rtlhal->oem_id = RT_CID_819x_CLEVO;
1646 else if (CHK_SVID_SMID(0x1028, 0x8194) ||
1647 CHK_SVID_SMID(0x1028, 0x8198) ||
1648 CHK_SVID_SMID(0x1028, 0x9197) ||
1649 CHK_SVID_SMID(0x1028, 0x9198))
1650 rtlhal->oem_id = RT_CID_819x_DELL;
1651 else if (CHK_SVID_SMID(0x103C, 0x1629))
1652 rtlhal->oem_id = RT_CID_819x_HP;
1653 else if (CHK_SVID_SMID(0x1A32, 0x2315))
1654 rtlhal->oem_id = RT_CID_819x_QMI;
1655 else if (CHK_SVID_SMID(0x10EC, 0x8203))
1656 rtlhal->oem_id = RT_CID_819x_PRONETS;
1657 else if (CHK_SVID_SMID(0x1043, 0x84B5))
1658 rtlhal->oem_id =
1659 RT_CID_819x_Edimax_ASUS;
1660 else
1661 rtlhal->oem_id = RT_CID_DEFAULT;
1662 } else if (rtlefuse->eeprom_did == 0x8178) {
1663 if (CHK_SVID_SMID(0x10EC, 0x6181) ||
1664 CHK_SVID_SMID(0x10EC, 0x6182) ||
1665 CHK_SVID_SMID(0x10EC, 0x6184) ||
1666 CHK_SVID_SMID(0x10EC, 0x6185) ||
1667 CHK_SVID_SMID(0x10EC, 0x7181) ||
1668 CHK_SVID_SMID(0x10EC, 0x7182) ||
1669 CHK_SVID_SMID(0x10EC, 0x7184) ||
1670 CHK_SVID_SMID(0x10EC, 0x7185) ||
1671 CHK_SVID_SMID(0x10EC, 0x8181) ||
1672 CHK_SVID_SMID(0x10EC, 0x8182) ||
1673 CHK_SVID_SMID(0x10EC, 0x8184) ||
1674 CHK_SVID_SMID(0x10EC, 0x8185) ||
1675 CHK_SVID_SMID(0x10EC, 0x9181) ||
1676 CHK_SVID_SMID(0x10EC, 0x9182) ||
1677 CHK_SVID_SMID(0x10EC, 0x9184) ||
1678 CHK_SVID_SMID(0x10EC, 0x9185))
1679 rtlhal->oem_id = RT_CID_TOSHIBA;
1680 else if (rtlefuse->eeprom_svid == 0x1025)
1681 rtlhal->oem_id = RT_CID_819x_Acer;
1682 else if (CHK_SVID_SMID(0x10EC, 0x8186))
1683 rtlhal->oem_id = RT_CID_819x_PRONETS;
1684 else if (CHK_SVID_SMID(0x1043, 0x8486))
1685 rtlhal->oem_id =
1686 RT_CID_819x_Edimax_ASUS;
1687 else
1688 rtlhal->oem_id = RT_CID_DEFAULT;
1689 } else {
1690 rtlhal->oem_id = RT_CID_DEFAULT;
1691 }
1692 break;
1693 case EEPROM_CID_TOSHIBA:
1694 rtlhal->oem_id = RT_CID_TOSHIBA;
1695 break;
1696 case EEPROM_CID_CCX:
1697 rtlhal->oem_id = RT_CID_CCX;
1698 break;
1699 case EEPROM_CID_QMI:
1700 rtlhal->oem_id = RT_CID_819x_QMI;
1701 break;
1702 case EEPROM_CID_WHQL:
1703 break;
1704 default:
1705 rtlhal->oem_id = RT_CID_DEFAULT;
1706 break;
1707
1708 }
1709 }
1710}
1711
1712static void _rtl8723ae_hal_customized_behavior(struct ieee80211_hw *hw)
1713{
1714 struct rtl_priv *rtlpriv = rtl_priv(hw);
1715 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1716 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1717
1718 switch (rtlhal->oem_id) {
1719 case RT_CID_819x_HP:
1720 pcipriv->ledctl.led_opendrain = true;
1721 break;
1722 case RT_CID_819x_Lenovo:
1723 case RT_CID_DEFAULT:
1724 case RT_CID_TOSHIBA:
1725 case RT_CID_CCX:
1726 case RT_CID_819x_Acer:
1727 case RT_CID_WHQL:
1728 default:
1729 break;
1730 }
1731 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1732 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
1733}
1734
1735void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw)
1736{
1737 struct rtl_priv *rtlpriv = rtl_priv(hw);
1738 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1739 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1740 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1741 u8 tmp_u1b;
1742 u32 value32;
1743
1744 value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST]);
1745 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1746 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST], value32);
1747
1748 rtlhal->version = _rtl8723ae_read_chip_version(hw);
1749
1750 if (get_rf_type(rtlphy) == RF_1T1R)
1751 rtlpriv->dm.rfpath_rxenable[0] = true;
1752 else
1753 rtlpriv->dm.rfpath_rxenable[0] =
1754 rtlpriv->dm.rfpath_rxenable[1] = true;
1755 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
1756 rtlhal->version);
1757
1758 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
1759 if (tmp_u1b & BIT(4)) {
1760 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
1761 rtlefuse->epromtype = EEPROM_93C46;
1762 } else {
1763 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
1764 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
1765 }
1766 if (tmp_u1b & BIT(5)) {
1767 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1768 rtlefuse->autoload_failflag = false;
1769 _rtl8723ae_read_adapter_info(hw, false);
1770 } else {
1771 rtlefuse->autoload_failflag = true;
1772 _rtl8723ae_read_adapter_info(hw, false);
1773 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
1774 }
1775 _rtl8723ae_hal_customized_behavior(hw);
1776}
1777
1778static void rtl8723ae_update_hal_rate_table(struct ieee80211_hw *hw,
1779 struct ieee80211_sta *sta)
1780{
1781 struct rtl_priv *rtlpriv = rtl_priv(hw);
1782 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1783 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1784 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1785 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1786 u32 ratr_value;
1787 u8 ratr_index = 0;
1788 u8 nmode = mac->ht_enable;
1789 u8 mimo_ps = IEEE80211_SMPS_OFF;
1790 u8 curtxbw_40mhz = mac->bw_40;
1791 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
1792 1 : 0;
1793 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1794 1 : 0;
1795 enum wireless_mode wirelessmode = mac->mode;
1796
1797 if (rtlhal->current_bandtype == BAND_ON_5G)
1798 ratr_value = sta->supp_rates[1] << 4;
1799 else
1800 ratr_value = sta->supp_rates[0];
1801 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1802 ratr_value = 0xfff;
1803 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
1804 sta->ht_cap.mcs.rx_mask[0] << 12);
1805 switch (wirelessmode) {
1806 case WIRELESS_MODE_B:
1807 if (ratr_value & 0x0000000c)
1808 ratr_value &= 0x0000000d;
1809 else
1810 ratr_value &= 0x0000000f;
1811 break;
1812 case WIRELESS_MODE_G:
1813 ratr_value &= 0x00000FF5;
1814 break;
1815 case WIRELESS_MODE_N_24G:
1816 case WIRELESS_MODE_N_5G:
1817 nmode = 1;
1818 if (mimo_ps == IEEE80211_SMPS_STATIC) {
1819 ratr_value &= 0x0007F005;
1820 } else {
1821 u32 ratr_mask;
1822
1823 if (get_rf_type(rtlphy) == RF_1T2R ||
1824 get_rf_type(rtlphy) == RF_1T1R)
1825 ratr_mask = 0x000ff005;
1826 else
1827 ratr_mask = 0x0f0ff005;
1828
1829 ratr_value &= ratr_mask;
1830 }
1831 break;
1832 default:
1833 if (rtlphy->rf_type == RF_1T2R)
1834 ratr_value &= 0x000ff0ff;
1835 else
1836 ratr_value &= 0x0f0ff0ff;
1837
1838 break;
1839 }
1840
1841 if ((pcipriv->bt_coexist.bt_coexistence) &&
1842 (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) &&
1843 (pcipriv->bt_coexist.bt_cur_state) &&
1844 (pcipriv->bt_coexist.bt_ant_isolation) &&
1845 ((pcipriv->bt_coexist.bt_service == BT_SCO) ||
1846 (pcipriv->bt_coexist.bt_service == BT_BUSY)))
1847 ratr_value &= 0x0fffcfc0;
1848 else
1849 ratr_value &= 0x0FFFFFFF;
1850
1851 if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
1852 (!curtxbw_40mhz && curshortgi_20mhz)))
1853 ratr_value |= 0x10000000;
1854
1855 rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
1856
1857 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
1858 "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0));
1859}
1860
1861static void rtl8723ae_update_hal_rate_mask(struct ieee80211_hw *hw,
1862 struct ieee80211_sta *sta, u8 rssi_level)
1863{
1864 struct rtl_priv *rtlpriv = rtl_priv(hw);
1865 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1866 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1867 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1868 struct rtl_sta_info *sta_entry = NULL;
1869 u32 ratr_bitmap;
1870 u8 ratr_index;
1871 u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
1872 ? 1 : 0;
1873 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
1874 1 : 0;
1875 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1876 1 : 0;
1877 enum wireless_mode wirelessmode = 0;
1878 bool shortgi = false;
1879 u8 rate_mask[5];
1880 u8 macid = 0;
1881 u8 mimo_ps = IEEE80211_SMPS_OFF;
1882
1883 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
1884 wirelessmode = sta_entry->wireless_mode;
1885 if (mac->opmode == NL80211_IFTYPE_STATION)
1886 curtxbw_40mhz = mac->bw_40;
1887 else if (mac->opmode == NL80211_IFTYPE_AP ||
1888 mac->opmode == NL80211_IFTYPE_ADHOC)
1889 macid = sta->aid + 1;
1890
1891 if (rtlhal->current_bandtype == BAND_ON_5G)
1892 ratr_bitmap = sta->supp_rates[1] << 4;
1893 else
1894 ratr_bitmap = sta->supp_rates[0];
1895 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1896 ratr_bitmap = 0xfff;
1897 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
1898 sta->ht_cap.mcs.rx_mask[0] << 12);
1899 switch (wirelessmode) {
1900 case WIRELESS_MODE_B:
1901 ratr_index = RATR_INX_WIRELESS_B;
1902 if (ratr_bitmap & 0x0000000c)
1903 ratr_bitmap &= 0x0000000d;
1904 else
1905 ratr_bitmap &= 0x0000000f;
1906 break;
1907 case WIRELESS_MODE_G:
1908 ratr_index = RATR_INX_WIRELESS_GB;
1909
1910 if (rssi_level == 1)
1911 ratr_bitmap &= 0x00000f00;
1912 else if (rssi_level == 2)
1913 ratr_bitmap &= 0x00000ff0;
1914 else
1915 ratr_bitmap &= 0x00000ff5;
1916 break;
1917 case WIRELESS_MODE_A:
1918 ratr_index = RATR_INX_WIRELESS_A;
1919 ratr_bitmap &= 0x00000ff0;
1920 break;
1921 case WIRELESS_MODE_N_24G:
1922 case WIRELESS_MODE_N_5G:
1923 ratr_index = RATR_INX_WIRELESS_NGB;
1924
1925 if (mimo_ps == IEEE80211_SMPS_STATIC) {
1926 if (rssi_level == 1)
1927 ratr_bitmap &= 0x00070000;
1928 else if (rssi_level == 2)
1929 ratr_bitmap &= 0x0007f000;
1930 else
1931 ratr_bitmap &= 0x0007f005;
1932 } else {
1933 if (rtlphy->rf_type == RF_1T2R ||
1934 rtlphy->rf_type == RF_1T1R) {
1935 if (curtxbw_40mhz) {
1936 if (rssi_level == 1)
1937 ratr_bitmap &= 0x000f0000;
1938 else if (rssi_level == 2)
1939 ratr_bitmap &= 0x000ff000;
1940 else
1941 ratr_bitmap &= 0x000ff015;
1942 } else {
1943 if (rssi_level == 1)
1944 ratr_bitmap &= 0x000f0000;
1945 else if (rssi_level == 2)
1946 ratr_bitmap &= 0x000ff000;
1947 else
1948 ratr_bitmap &= 0x000ff005;
1949 }
1950 } else {
1951 if (curtxbw_40mhz) {
1952 if (rssi_level == 1)
1953 ratr_bitmap &= 0x0f0f0000;
1954 else if (rssi_level == 2)
1955 ratr_bitmap &= 0x0f0ff000;
1956 else
1957 ratr_bitmap &= 0x0f0ff015;
1958 } else {
1959 if (rssi_level == 1)
1960 ratr_bitmap &= 0x0f0f0000;
1961 else if (rssi_level == 2)
1962 ratr_bitmap &= 0x0f0ff000;
1963 else
1964 ratr_bitmap &= 0x0f0ff005;
1965 }
1966 }
1967 }
1968
1969 if ((curtxbw_40mhz && curshortgi_40mhz) ||
1970 (!curtxbw_40mhz && curshortgi_20mhz)) {
1971 if (macid == 0)
1972 shortgi = true;
1973 else if (macid == 1)
1974 shortgi = false;
1975 }
1976 break;
1977 default:
1978 ratr_index = RATR_INX_WIRELESS_NGB;
1979
1980 if (rtlphy->rf_type == RF_1T2R)
1981 ratr_bitmap &= 0x000ff0ff;
1982 else
1983 ratr_bitmap &= 0x0f0ff0ff;
1984 break;
1985 }
1986 sta_entry->ratr_index = ratr_index;
1987
1988 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
1989 "ratr_bitmap :%x\n", ratr_bitmap);
1990 /* convert ratr_bitmap to le byte array */
1991 rate_mask[0] = ratr_bitmap;
1992 rate_mask[1] = (ratr_bitmap >>= 8);
1993 rate_mask[2] = (ratr_bitmap >>= 8);
1994 rate_mask[3] = ((ratr_bitmap >> 8) & 0x0f) | (ratr_index << 4);
1995 rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
1996 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
1997 "Rate_index:%x, ratr_bitmap: %*phC\n",
1998 ratr_index, 5, rate_mask);
1999 rtl8723ae_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
2000}
2001
2002void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw,
2003 struct ieee80211_sta *sta, u8 rssi_level)
2004{
2005 struct rtl_priv *rtlpriv = rtl_priv(hw);
2006
2007 if (rtlpriv->dm.useramask)
2008 rtl8723ae_update_hal_rate_mask(hw, sta, rssi_level);
2009 else
2010 rtl8723ae_update_hal_rate_table(hw, sta);
2011}
2012
2013void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw)
2014{
2015 struct rtl_priv *rtlpriv = rtl_priv(hw);
2016 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2017 u16 sifs_timer;
2018
2019 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
2020 (u8 *)&mac->slot_time);
2021 if (!mac->ht_enable)
2022 sifs_timer = 0x0a0a;
2023 else
2024 sifs_timer = 0x1010;
2025 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2026}
2027
2028bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2029{
2030 struct rtl_priv *rtlpriv = rtl_priv(hw);
2031 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2032 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2033 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2034 u8 u1tmp;
2035 bool actuallyset = false;
2036
2037 if (rtlpriv->rtlhal.being_init_adapter)
2038 return false;
2039
2040 if (ppsc->swrf_processing)
2041 return false;
2042
2043 spin_lock(&rtlpriv->locks.rf_ps_lock);
2044 if (ppsc->rfchange_inprogress) {
2045 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2046 return false;
2047 } else {
2048 ppsc->rfchange_inprogress = true;
2049 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2050 }
2051
2052 cur_rfstate = ppsc->rfpwr_state;
2053
2054 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2055 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2)&~(BIT(1)));
2056
2057 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2058
2059 if (rtlphy->polarity_ctl)
2060 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2061 else
2062 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2063
2064 if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) {
2065 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2066 "GPIOChangeRF - HW Radio ON, RF ON\n");
2067
2068 e_rfpowerstate_toset = ERFON;
2069 ppsc->hwradiooff = false;
2070 actuallyset = true;
2071 } else if ((ppsc->hwradiooff == false)
2072 && (e_rfpowerstate_toset == ERFOFF)) {
2073 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2074 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2075
2076 e_rfpowerstate_toset = ERFOFF;
2077 ppsc->hwradiooff = true;
2078 actuallyset = true;
2079 }
2080
2081 if (actuallyset) {
2082 spin_lock(&rtlpriv->locks.rf_ps_lock);
2083 ppsc->rfchange_inprogress = false;
2084 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2085 } else {
2086 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2087 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2088
2089 spin_lock(&rtlpriv->locks.rf_ps_lock);
2090 ppsc->rfchange_inprogress = false;
2091 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2092 }
2093
2094 *valid = 1;
2095 return !ppsc->hwradiooff;
2096}
2097
2098void rtl8723ae_set_key(struct ieee80211_hw *hw, u32 key_index,
2099 u8 *p_macaddr, bool is_group, u8 enc_algo,
2100 bool is_wepkey, bool clear_all)
2101{
2102 struct rtl_priv *rtlpriv = rtl_priv(hw);
2103 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2104 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2105 u8 *macaddr = p_macaddr;
2106 u32 entry_id = 0;
2107 bool is_pairwise = false;
2108 static u8 cam_const_addr[4][6] = {
2109 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2110 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2111 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2112 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2113 };
2114 static u8 cam_const_broad[] = {
2115 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2116 };
2117
2118 if (clear_all) {
2119 u8 idx = 0;
2120 u8 cam_offset = 0;
2121 u8 clear_number = 5;
2122
2123 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2124
2125 for (idx = 0; idx < clear_number; idx++) {
2126 rtl_cam_mark_invalid(hw, cam_offset + idx);
2127 rtl_cam_empty_entry(hw, cam_offset + idx);
2128
2129 if (idx < 5) {
2130 memset(rtlpriv->sec.key_buf[idx], 0,
2131 MAX_KEY_LEN);
2132 rtlpriv->sec.key_len[idx] = 0;
2133 }
2134 }
2135 } else {
2136 switch (enc_algo) {
2137 case WEP40_ENCRYPTION:
2138 enc_algo = CAM_WEP40;
2139 break;
2140 case WEP104_ENCRYPTION:
2141 enc_algo = CAM_WEP104;
2142 break;
2143 case TKIP_ENCRYPTION:
2144 enc_algo = CAM_TKIP;
2145 break;
2146 case AESCCMP_ENCRYPTION:
2147 enc_algo = CAM_AES;
2148 break;
2149 default:
2150 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2151 "switch case not processed\n");
2152 enc_algo = CAM_TKIP;
2153 break;
2154 }
2155
2156 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2157 macaddr = cam_const_addr[key_index];
2158 entry_id = key_index;
2159 } else {
2160 if (is_group) {
2161 macaddr = cam_const_broad;
2162 entry_id = key_index;
2163 } else {
2164 if (mac->opmode == NL80211_IFTYPE_AP) {
2165 entry_id = rtl_cam_get_free_entry(hw,
2166 macaddr);
2167 if (entry_id >= TOTAL_CAM_ENTRY) {
2168 RT_TRACE(rtlpriv, COMP_SEC,
2169 DBG_EMERG,
2170 "Can not find free hw security cam entry\n");
2171 return;
2172 }
2173 } else {
2174 entry_id = CAM_PAIRWISE_KEY_POSITION;
2175 }
2176
2177 key_index = PAIRWISE_KEYIDX;
2178 is_pairwise = true;
2179 }
2180 }
2181
2182 if (rtlpriv->sec.key_len[key_index] == 0) {
2183 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2184 "delete one entry, entry_id is %d\n",
2185 entry_id);
2186 if (mac->opmode == NL80211_IFTYPE_AP)
2187 rtl_cam_del_entry(hw, p_macaddr);
2188 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2189 } else {
2190 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2191 "add one entry\n");
2192 if (is_pairwise) {
2193 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2194 "set Pairwiase key\n");
2195
2196 rtl_cam_add_one_entry(hw, macaddr, key_index,
2197 entry_id, enc_algo,
2198 CAM_CONFIG_NO_USEDK,
2199 rtlpriv->sec.key_buf[key_index]);
2200 } else {
2201 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2202 "set group key\n");
2203
2204 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2205 rtl_cam_add_one_entry(hw,
2206 rtlefuse->dev_addr,
2207 PAIRWISE_KEYIDX,
2208 CAM_PAIRWISE_KEY_POSITION,
2209 enc_algo,
2210 CAM_CONFIG_NO_USEDK,
2211 rtlpriv->sec.key_buf
2212 [entry_id]);
2213 }
2214
2215 rtl_cam_add_one_entry(hw, macaddr, key_index,
2216 entry_id, enc_algo,
2217 CAM_CONFIG_NO_USEDK,
2218 rtlpriv->sec.key_buf[entry_id]);
2219 }
2220
2221 }
2222 }
2223}
2224
2225static void rtl8723ae_bt_var_init(struct ieee80211_hw *hw)
2226{
2227 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2228 struct rtl_priv *rtlpriv = rtl_priv(hw);
2229
2230 pcipriv->bt_coexist.bt_coexistence =
2231 pcipriv->bt_coexist.eeprom_bt_coexist;
2232 pcipriv->bt_coexist.bt_ant_num =
2233 pcipriv->bt_coexist.eeprom_bt_ant_num;
2234 pcipriv->bt_coexist.bt_coexist_type =
2235 pcipriv->bt_coexist.eeprom_bt_type;
2236
2237 pcipriv->bt_coexist.bt_ant_isolation =
2238 pcipriv->bt_coexist.eeprom_bt_ant_isol;
2239
2240 pcipriv->bt_coexist.bt_radio_shared_type =
2241 pcipriv->bt_coexist.eeprom_bt_radio_shared;
2242
2243 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2244 "BT Coexistance = 0x%x\n",
2245 pcipriv->bt_coexist.bt_coexistence);
2246
2247 if (pcipriv->bt_coexist.bt_coexistence) {
2248 pcipriv->bt_coexist.bt_busy_traffic = false;
2249 pcipriv->bt_coexist.bt_traffic_mode_set = false;
2250 pcipriv->bt_coexist.bt_non_traffic_mode_set = false;
2251
2252 pcipriv->bt_coexist.cstate = 0;
2253 pcipriv->bt_coexist.previous_state = 0;
2254
2255 if (pcipriv->bt_coexist.bt_ant_num == ANT_X2) {
2256 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2257 "BlueTooth BT_Ant_Num = Antx2\n");
2258 } else if (pcipriv->bt_coexist.bt_ant_num == ANT_X1) {
2259 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2260 "BlueTooth BT_Ant_Num = Antx1\n");
2261 }
2262
2263 switch (pcipriv->bt_coexist.bt_coexist_type) {
2264 case BT_2WIRE:
2265 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2266 "BlueTooth BT_CoexistType = BT_2Wire\n");
2267 break;
2268 case BT_ISSC_3WIRE:
2269 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2270 "BlueTooth BT_CoexistType = BT_ISSC_3Wire\n");
2271 break;
2272 case BT_ACCEL:
2273 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2274 "BlueTooth BT_CoexistType = BT_ACCEL\n");
2275 break;
2276 case BT_CSR_BC4:
2277 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2278 "BlueTooth BT_CoexistType = BT_CSR_BC4\n");
2279 break;
2280 case BT_CSR_BC8:
2281 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2282 "BlueTooth BT_CoexistType = BT_CSR_BC8\n");
2283 break;
2284 case BT_RTL8756:
2285 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2286 "BlueTooth BT_CoexistType = BT_RTL8756\n");
2287 break;
2288 default:
2289 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2290 "BlueTooth BT_CoexistType = Unknown\n");
2291 break;
2292 }
2293 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2294 "BlueTooth BT_Ant_isolation = %d\n",
2295 pcipriv->bt_coexist.bt_ant_isolation);
2296 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
2297 "BT_RadioSharedType = 0x%x\n",
2298 pcipriv->bt_coexist.bt_radio_shared_type);
2299 pcipriv->bt_coexist.bt_active_zero_cnt = 0;
2300 pcipriv->bt_coexist.cur_bt_disabled = false;
2301 pcipriv->bt_coexist.pre_bt_disabled = false;
2302 }
2303}
2304
2305void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2306 bool auto_load_fail, u8 *hwinfo)
2307{
2308 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2309 struct rtl_priv *rtlpriv = rtl_priv(hw);
2310 u8 value;
2311 u32 tmpu_32;
2312
2313 if (!auto_load_fail) {
2314 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2315 if (tmpu_32 & BIT(18))
2316 pcipriv->bt_coexist.eeprom_bt_coexist = 1;
2317 else
2318 pcipriv->bt_coexist.eeprom_bt_coexist = 0;
2319 value = hwinfo[RF_OPTION4];
2320 pcipriv->bt_coexist.eeprom_bt_type = BT_RTL8723A;
2321 pcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1);
2322 pcipriv->bt_coexist.eeprom_bt_ant_isol = ((value & 0x10) >> 4);
2323 pcipriv->bt_coexist.eeprom_bt_radio_shared =
2324 ((value & 0x20) >> 5);
2325 } else {
2326 pcipriv->bt_coexist.eeprom_bt_coexist = 0;
2327 pcipriv->bt_coexist.eeprom_bt_type = BT_RTL8723A;
2328 pcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2;
2329 pcipriv->bt_coexist.eeprom_bt_ant_isol = 0;
2330 pcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED;
2331 }
2332
2333 rtl8723ae_bt_var_init(hw);
2334}
2335
2336void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw)
2337{
2338 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2339
2340 /* 0:Low, 1:High, 2:From Efuse. */
2341 pcipriv->bt_coexist.reg_bt_iso = 2;
2342 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2343 pcipriv->bt_coexist.reg_bt_sco = 3;
2344 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2345 pcipriv->bt_coexist.reg_bt_sco = 0;
2346}
2347
2348
2349void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw)
2350{
2351}
2352
2353void rtl8723ae_suspend(struct ieee80211_hw *hw)
2354{
2355}
2356
2357void rtl8723ae_resume(struct ieee80211_hw *hw)
2358{
2359}
2360
2361/* Turn on AAP (RCR:bit 0) for promicuous mode. */
2362void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw,
2363 bool allow_all_da, bool write_into_reg)
2364{
2365 struct rtl_priv *rtlpriv = rtl_priv(hw);
2366 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2367
2368 if (allow_all_da) /* Set BIT0 */
2369 rtlpci->receive_config |= RCR_AAP;
2370 else /* Clear BIT0 */
2371 rtlpci->receive_config &= ~RCR_AAP;
2372
2373 if (write_into_reg)
2374 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
2375
2376
2377 RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
2378 "receive_config=0x%08X, write_into_reg=%d\n",
2379 rtlpci->receive_config, write_into_reg);
2380}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h
new file mode 100644
index 00000000000..6fa24f79b1d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h
@@ -0,0 +1,73 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL8723E_HW_H__
31#define __RTL8723E_HW_H__
32
33#define CHK_SVID_SMID(_val1, _val2) \
34 ((rtlefuse->eeprom_svid == (_val1)) && \
35 (rtlefuse->eeprom_smid == (_val2)))
36
37void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
38void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw);
39
40void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw,
41 u32 *p_inta, u32 *p_intb);
42int rtl8723ae_hw_init(struct ieee80211_hw *hw);
43void rtl8723ae_card_disable(struct ieee80211_hw *hw);
44void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw);
45void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw);
46int rtl8723ae_set_network_type(struct ieee80211_hw *hw,
47 enum nl80211_iftype type);
48void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
49void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci);
50void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw);
51void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw);
52void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw,
53 u32 add_msr, u32 rm_msr);
54void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
55void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw,
56 struct ieee80211_sta *sta, u8 rssi_level);
57void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw);
58bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
59void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw);
60void rtl8723ae_set_key(struct ieee80211_hw *hw, u32 key_index,
61 u8 *p_macaddr, bool is_group, u8 enc_algo,
62 bool is_wepkey, bool clear_all);
63
64void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
65 bool autoload_fail, u8 *hwinfo);
66void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw);
67void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw);
68void rtl8723ae_suspend(struct ieee80211_hw *hw);
69void rtl8723ae_resume(struct ieee80211_hw *hw);
70void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw,
71 bool allow_all_da, bool write_into_reg);
72
73#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/led.c b/drivers/net/wireless/rtlwifi/rtl8723ae/led.c
new file mode 100644
index 00000000000..9c4e1d81118
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/led.c
@@ -0,0 +1,151 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "reg.h"
33#include "led.h"
34
35static void _rtl8723ae_init_led(struct ieee80211_hw *hw,
36 struct rtl_led *pled, enum rtl_led_pin ledpin)
37{
38 pled->hw = hw;
39 pled->ledpin = ledpin;
40 pled->ledon = false;
41}
42
43void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
44{
45 struct rtl_priv *rtlpriv = rtl_priv(hw);
46 u8 ledcfg;
47
48 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
49 "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
50
51 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
52
53 switch (pled->ledpin) {
54 case LED_PIN_GPIO0:
55 break;
56 case LED_PIN_LED0:
57 rtl_write_byte(rtlpriv,
58 REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6));
59 break;
60 case LED_PIN_LED1:
61 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
62 break;
63 default:
64 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
65 "switch case not processed\n");
66 break;
67 }
68 pled->ledon = true;
69}
70
71void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
72{
73 struct rtl_priv *rtlpriv = rtl_priv(hw);
74 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
75 u8 ledcfg;
76
77 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
78 "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
79
80 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
81
82 switch (pled->ledpin) {
83 case LED_PIN_GPIO0:
84 break;
85 case LED_PIN_LED0:
86 ledcfg &= 0xf0;
87 if (pcipriv->ledctl.led_opendrain)
88 rtl_write_byte(rtlpriv, REG_LEDCFG2,
89 (ledcfg | BIT(1) | BIT(5) | BIT(6)));
90 else
91 rtl_write_byte(rtlpriv, REG_LEDCFG2,
92 (ledcfg | BIT(3) | BIT(5) | BIT(6)));
93 break;
94 case LED_PIN_LED1:
95 ledcfg &= 0x0f;
96 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
97 break;
98 default:
99 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
100 "switch case not processed\n");
101 break;
102 }
103 pled->ledon = false;
104}
105
106void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw)
107{
108 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
109
110 _rtl8723ae_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
111 _rtl8723ae_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
112}
113
114static void _rtl8723ae_sw_led_control(struct ieee80211_hw *hw,
115 enum led_ctl_mode ledaction)
116{
117 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
118 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
119
120 switch (ledaction) {
121 case LED_CTL_POWER_ON:
122 case LED_CTL_LINK:
123 case LED_CTL_NO_LINK:
124 rtl8723ae_sw_led_on(hw, pLed0);
125 break;
126 case LED_CTL_POWER_OFF:
127 rtl8723ae_sw_led_off(hw, pLed0);
128 break;
129 default:
130 break;
131 }
132}
133
134void rtl8723ae_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
135{
136 struct rtl_priv *rtlpriv = rtl_priv(hw);
137 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
138
139 if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
140 (ledaction == LED_CTL_TX ||
141 ledaction == LED_CTL_RX ||
142 ledaction == LED_CTL_SITE_SURVEY ||
143 ledaction == LED_CTL_LINK ||
144 ledaction == LED_CTL_NO_LINK ||
145 ledaction == LED_CTL_START_TO_LINK ||
146 ledaction == LED_CTL_POWER_ON)) {
147 return;
148 }
149 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction);
150 _rtl8723ae_sw_led_control(hw, ledaction);
151}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/led.h b/drivers/net/wireless/rtlwifi/rtl8723ae/led.h
new file mode 100644
index 00000000000..2cb88e78f62
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/led.h
@@ -0,0 +1,39 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92CE_LED_H__
31#define __RTL92CE_LED_H__
32
33void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw);
34void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
35void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
36void rtl8723ae_led_control(struct ieee80211_hw *hw,
37 enum led_ctl_mode ledaction);
38
39#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
new file mode 100644
index 00000000000..39cc7938eed
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
@@ -0,0 +1,2044 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../ps.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "rf.h"
37#include "dm.h"
38#include "table.h"
39
40/* static forward definitions */
41static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
42 enum radio_path rfpath, u32 offset);
43static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
44 enum radio_path rfpath,
45 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);
52static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw);
53static 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);
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,
62 u8 *stage, u8 *step, u32 *delay);
63static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
64 enum wireless_mode wirelessmode,
65 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);
69
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,
113 enum radio_path rfpath, u32 regaddr, u32 bitmask)
114{
115 struct rtl_priv *rtlpriv = rtl_priv(hw);
116 u32 original_value, readback_value, bitshift;
117 struct rtl_phy *rtlphy = &(rtlpriv->phy);
118 unsigned long flags;
119
120 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
121 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
122 regaddr, rfpath, bitmask);
123
124 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
125
126 if (rtlphy->rf_mode != RF_OP_BY_FW)
127 original_value = _phy_rf_serial_read(hw, rfpath, regaddr);
128 else
129 original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr);
130
131 bitshift = _phy_calculate_bit_shift(bitmask);
132 readback_value = (original_value & bitmask) >> bitshift;
133
134 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
135
136 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
137 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
138 regaddr, rfpath, bitmask, original_value);
139
140 return readback_value;
141}
142
143void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,
144 enum radio_path rfpath,
145 u32 regaddr, u32 bitmask, u32 data)
146{
147 struct rtl_priv *rtlpriv = rtl_priv(hw);
148 struct rtl_phy *rtlphy = &(rtlpriv->phy);
149 u32 original_value, bitshift;
150 unsigned long flags;
151
152 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
153 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
154 regaddr, bitmask, data, rfpath);
155
156 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
157
158 if (rtlphy->rf_mode != RF_OP_BY_FW) {
159 if (bitmask != RFREG_OFFSET_MASK) {
160 original_value = _phy_rf_serial_read(hw, rfpath,
161 regaddr);
162 bitshift = _phy_calculate_bit_shift(bitmask);
163 data = ((original_value & (~bitmask)) |
164 (data << bitshift));
165 }
166
167 _phy_rf_serial_write(hw, rfpath, regaddr, data);
168 } else {
169 if (bitmask != RFREG_OFFSET_MASK) {
170 original_value = _phy_fw_rf_serial_read(hw, rfpath,
171 regaddr);
172 bitshift = _phy_calculate_bit_shift(bitmask);
173 data = ((original_value & (~bitmask)) |
174 (data << bitshift));
175 }
176 _phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
177 }
178
179 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
180
181 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
182 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
183 regaddr, bitmask, data, rfpath);
184}
185
186static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
187 enum radio_path rfpath, u32 offset)
188{
189 RT_ASSERT(false, "deprecated!\n");
190 return 0;
191}
192
193static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
194 enum radio_path rfpath,
195 u32 offset, u32 data)
196{
197 RT_ASSERT(false, "deprecated!\n");
198}
199
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)
282{
283 rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
284 rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
285 rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
286 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
287 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
288 rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
289 rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
290 rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
291 rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
292 rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
293}
294
295bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw)
296{
297 struct rtl_priv *rtlpriv = rtl_priv(hw);
298 bool rtstatus = _phy_cfg_mac_w_header(hw);
299 rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
300 return rtstatus;
301}
302
303bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw)
304{
305 bool rtstatus = true;
306 struct rtl_priv *rtlpriv = rtl_priv(hw);
307 u8 tmpu1b;
308 u8 reg_hwparafile = 1;
309
310 _phy_init_bb_rf_reg_def(hw);
311
312 /* 1. 0x28[1] = 1 */
313 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL);
314 udelay(2);
315 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1)));
316 udelay(2);
317 /* 2. 0x29[7:0] = 0xFF */
318 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff);
319 udelay(2);
320
321 /* 3. 0x02[1:0] = 2b'11 */
322 tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
323 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, (tmpu1b |
324 FEN_BB_GLB_RSTn | FEN_BBRSTB));
325
326 /* 4. 0x25[6] = 0 */
327 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1);
328 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b&(~BIT(6))));
329
330 /* 5. 0x24[20] = 0 Advised by SD3 Alex Wang. 2011.02.09. */
331 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2);
332 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b&(~BIT(4))));
333
334 /* 6. 0x1f[7:0] = 0x07 */
335 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07);
336
337 if (reg_hwparafile == 1)
338 rtstatus = _phy_bb8192c_config_parafile(hw);
339 return rtstatus;
340}
341
342bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw)
343{
344 return rtl8723ae_phy_rf6052_config(hw);
345}
346
347static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
348{
349 struct rtl_priv *rtlpriv = rtl_priv(hw);
350 struct rtl_phy *rtlphy = &(rtlpriv->phy);
351 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
352 bool rtstatus;
353
354 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
355 rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_PHY_REG);
356 if (rtstatus != true) {
357 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
358 return false;
359 }
360
361 if (rtlphy->rf_type == RF_1T2R) {
362 _rtl8723ae_phy_bb_config_1t(hw);
363 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
364 }
365 if (rtlefuse->autoload_failflag == false) {
366 rtlphy->pwrgroup_cnt = 0;
367 rtstatus = _phy_cfg_bb_w_pgheader(hw, BASEBAND_CONFIG_PHY_REG);
368 }
369 if (rtstatus != true) {
370 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
371 return false;
372 }
373 rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_AGC_TAB);
374 if (rtstatus != true) {
375 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
376 return false;
377 }
378 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
379 RFPGA0_XA_HSSIPARAMETER2, 0x200));
380 return true;
381}
382
383static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw)
384{
385 struct rtl_priv *rtlpriv = rtl_priv(hw);
386 u32 i;
387 u32 arraylength;
388 u32 *ptrarray;
389
390 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n");
391 arraylength = RTL8723E_MACARRAYLENGTH;
392 ptrarray = RTL8723EMAC_ARRAY;
393
394 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
395 "Img:RTL8192CEMAC_2T_ARRAY\n");
396 for (i = 0; i < arraylength; i = i + 2)
397 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
398 return true;
399}
400
401static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype)
402{
403 int i;
404 u32 *phy_regarray_table;
405 u32 *agctab_array_table;
406 u16 phy_reg_arraylen, agctab_arraylen;
407 struct rtl_priv *rtlpriv = rtl_priv(hw);
408
409 agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH;
410 agctab_array_table = RTL8723EAGCTAB_1TARRAY;
411 phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH;
412 phy_regarray_table = RTL8723EPHY_REG_1TARRAY;
413 if (configtype == BASEBAND_CONFIG_PHY_REG) {
414 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
415 if (phy_regarray_table[i] == 0xfe)
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,
428 phy_regarray_table[i + 1]);
429 udelay(1);
430 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
431 "The phy_regarray_table[0] is %x"
432 " Rtl819XPHY_REGArray[1] is %x\n",
433 phy_regarray_table[i],
434 phy_regarray_table[i + 1]);
435 }
436 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
437 for (i = 0; i < agctab_arraylen; i = i + 2) {
438 rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
439 agctab_array_table[i + 1]);
440 udelay(1);
441 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
442 "The agctab_array_table[0] is "
443 "%x Rtl819XPHY_REGArray[1] is %x\n",
444 agctab_array_table[i],
445 agctab_array_table[i + 1]);
446 }
447 }
448 return true;
449}
450
451static void _st_pwrIdx_dfrate_off(struct ieee80211_hw *hw, u32 regaddr,
452 u32 bitmask, u32 data)
453{
454 struct rtl_priv *rtlpriv = rtl_priv(hw);
455 struct rtl_phy *rtlphy = &(rtlpriv->phy);
456
457 switch (regaddr) {
458 case RTXAGC_A_RATE18_06:
459 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0] = data;
460 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
461 "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
462 rtlphy->pwrgroup_cnt,
463 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0]);
464 break;
465 case RTXAGC_A_RATE54_24:
466 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1] = data;
467 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
468 "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
469 rtlphy->pwrgroup_cnt,
470 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1]);
471 break;
472 case RTXAGC_A_CCK1_MCS32:
473 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6] = data;
474 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
475 "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
476 rtlphy->pwrgroup_cnt,
477 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6]);
478 break;
479 case RTXAGC_B_CCK11_A_CCK2_11:
480 if (bitmask == 0xffffff00) {
481 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7] = data;
482 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
483 "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
484 rtlphy->pwrgroup_cnt,
485 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7]);
486 }
487 if (bitmask == 0x000000ff) {
488 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15] = data;
489 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
490 "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
491 rtlphy->pwrgroup_cnt,
492 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15]);
493 }
494 break;
495 case RTXAGC_A_MCS03_MCS00:
496 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2] = data;
497 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
498 "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
499 rtlphy->pwrgroup_cnt,
500 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2]);
501 break;
502 case RTXAGC_A_MCS07_MCS04:
503 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3] = data;
504 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
505 "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
506 rtlphy->pwrgroup_cnt,
507 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3]);
508 break;
509 case RTXAGC_A_MCS11_MCS08:
510 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4] = data;
511 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
512 "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
513 rtlphy->pwrgroup_cnt,
514 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4]);
515 break;
516 case RTXAGC_A_MCS15_MCS12:
517 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5] = data;
518 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
519 "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
520 rtlphy->pwrgroup_cnt,
521 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5]);
522 break;
523 case RTXAGC_B_RATE18_06:
524 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8] = data;
525 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
526 "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
527 rtlphy->pwrgroup_cnt,
528 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8]);
529 break;
530 case RTXAGC_B_RATE54_24:
531 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9] = data;
532 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
533 "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
534 rtlphy->pwrgroup_cnt,
535 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9]);
536 break;
537 case RTXAGC_B_CCK1_55_MCS32:
538 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14] = data;
539 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
540 "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
541 rtlphy->pwrgroup_cnt,
542 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14]);
543 break;
544 case RTXAGC_B_MCS03_MCS00:
545 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10] = data;
546 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
547 "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
548 rtlphy->pwrgroup_cnt,
549 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10]);
550 break;
551 case RTXAGC_B_MCS07_MCS04:
552 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11] = data;
553 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
554 "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
555 rtlphy->pwrgroup_cnt,
556 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11]);
557 break;
558 case RTXAGC_B_MCS11_MCS08:
559 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12] = data;
560 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
561 "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
562 rtlphy->pwrgroup_cnt,
563 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12]);
564 break;
565 case RTXAGC_B_MCS15_MCS12:
566 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13] = data;
567 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
568 "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
569 rtlphy->pwrgroup_cnt,
570 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13]);
571 rtlphy->pwrgroup_cnt++;
572 break;
573 }
574}
575
576static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype)
577{
578 struct rtl_priv *rtlpriv = rtl_priv(hw);
579 int i;
580 u32 *phy_regarray_table_pg;
581 u16 phy_regarray_pg_len;
582
583 phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH;
584 phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG;
585
586 if (configtype == BASEBAND_CONFIG_PHY_REG) {
587 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
588 if (phy_regarray_table_pg[i] == 0xfe)
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
601 _st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i],
602 phy_regarray_table_pg[i + 1],
603 phy_regarray_table_pg[i + 2]);
604 }
605 } else {
606 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
607 "configtype != BaseBand_Config_PHY_REG\n");
608 }
609 return true;
610}
611
612bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
613 enum radio_path rfpath)
614{
615 struct rtl_priv *rtlpriv = rtl_priv(hw);
616 int i;
617 bool rtstatus = true;
618 u32 *radioa_array_table;
619 u32 *radiob_array_table;
620 u16 radioa_arraylen, radiob_arraylen;
621
622 radioa_arraylen = Rtl8723ERADIOA_1TARRAYLENGTH;
623 radioa_array_table = RTL8723E_RADIOA_1TARRAY;
624 radiob_arraylen = RTL8723E_RADIOB_1TARRAYLENGTH;
625 radiob_array_table = RTL8723E_RADIOB_1TARRAY;
626
627 rtstatus = true;
628
629 switch (rfpath) {
630 case RF90_PATH_A:
631 for (i = 0; i < radioa_arraylen; i = i + 2) {
632 if (radioa_array_table[i] == 0xfe)
633 mdelay(50);
634 else if (radioa_array_table[i] == 0xfd)
635 mdelay(5);
636 else if (radioa_array_table[i] == 0xfc)
637 mdelay(1);
638 else if (radioa_array_table[i] == 0xfb)
639 udelay(50);
640 else if (radioa_array_table[i] == 0xfa)
641 udelay(5);
642 else if (radioa_array_table[i] == 0xf9)
643 udelay(1);
644 else {
645 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
646 RFREG_OFFSET_MASK,
647 radioa_array_table[i + 1]);
648 udelay(1);
649 }
650 }
651 break;
652 case RF90_PATH_B:
653 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
654 "switch case not process\n");
655 break;
656 case RF90_PATH_C:
657 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
658 "switch case not process\n");
659 break;
660 case RF90_PATH_D:
661 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
662 "switch case not process\n");
663 break;
664 }
665 return true;
666}
667
668void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
669{
670 struct rtl_priv *rtlpriv = rtl_priv(hw);
671 struct rtl_phy *rtlphy = &(rtlpriv->phy);
672
673 rtlphy->default_initialgain[0] =
674 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
675 rtlphy->default_initialgain[1] =
676 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
677 rtlphy->default_initialgain[2] =
678 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
679 rtlphy->default_initialgain[3] =
680 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
681
682 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
683 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
684 rtlphy->default_initialgain[0],
685 rtlphy->default_initialgain[1],
686 rtlphy->default_initialgain[2],
687 rtlphy->default_initialgain[3]);
688
689 rtlphy->framesync = (u8) rtl_get_bbreg(hw,
690 ROFDM0_RXDETECTOR3, MASKBYTE0);
691 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
692 ROFDM0_RXDETECTOR2, MASKDWORD);
693
694 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
695 "Default framesync (0x%x) = 0x%x\n",
696 ROFDM0_RXDETECTOR3, rtlphy->framesync);
697}
698
699static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw)
700{
701 struct rtl_priv *rtlpriv = rtl_priv(hw);
702 struct rtl_phy *rtlphy = &(rtlpriv->phy);
703
704 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
705 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
706 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
707 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
708
709 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
710 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
711 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
712 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
713
714 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
715 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
716
717 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
718 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
719
720 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
721 RFPGA0_XA_LSSIPARAMETER;
722 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
723 RFPGA0_XB_LSSIPARAMETER;
724
725 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
726 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
727 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
728 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
729
730 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
731 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
732 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
733 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
734
735 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
736 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
737
738 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
739 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
740
741 rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
742 rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
743 rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
744 rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
745
746 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
747 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
748 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
749 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
750
751 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
752 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
753 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
754 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
755
756 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
757 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
758 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE;
759 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
760
761 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
762 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
763 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
764 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
765
766 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
767 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
768 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
769 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
770
771 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
772 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
773 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
774 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
775
776 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
777 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
778 rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
779 rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
780
781 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
782 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
783}
784
785void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
786{
787 struct rtl_priv *rtlpriv = rtl_priv(hw);
788 struct rtl_phy *rtlphy = &(rtlpriv->phy);
789 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
790 u8 txpwr_level;
791 long txpwr_dbm;
792
793 txpwr_level = rtlphy->cur_cck_txpwridx;
794 txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level);
795 txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
796 rtlefuse->legacy_ht_txpowerdiff;
797 if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm)
798 txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
799 txpwr_level);
800 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
801 if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) >
802 txpwr_dbm)
803 txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
804 txpwr_level);
805 *powerlevel = txpwr_dbm;
806}
807
808static void _rtl8723ae_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
809 u8 *cckpowerlevel, u8 *ofdmpowerlevel)
810{
811 struct rtl_priv *rtlpriv = rtl_priv(hw);
812 struct rtl_phy *rtlphy = &(rtlpriv->phy);
813 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
814 u8 index = (channel - 1);
815
816 cckpowerlevel[RF90_PATH_A] =
817 rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
818 cckpowerlevel[RF90_PATH_B] =
819 rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
820 if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
821 ofdmpowerlevel[RF90_PATH_A] =
822 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
823 ofdmpowerlevel[RF90_PATH_B] =
824 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
825 } else if (get_rf_type(rtlphy) == RF_2T2R) {
826 ofdmpowerlevel[RF90_PATH_A] =
827 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
828 ofdmpowerlevel[RF90_PATH_B] =
829 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
830 }
831}
832
833static void _rtl8723ae_ccxpower_index_check(struct ieee80211_hw *hw,
834 u8 channel, u8 *cckpowerlevel,
835 u8 *ofdmpowerlevel)
836{
837 struct rtl_priv *rtlpriv = rtl_priv(hw);
838 struct rtl_phy *rtlphy = &(rtlpriv->phy);
839
840 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
841 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
842}
843
844void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
845{
846 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
847 u8 cckpowerlevel[2], ofdmpowerlevel[2];
848
849 if (rtlefuse->txpwr_fromeprom == false)
850 return;
851 _rtl8723ae_get_txpower_index(hw, channel, &cckpowerlevel[0],
852 &ofdmpowerlevel[0]);
853 _rtl8723ae_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
854 &ofdmpowerlevel[0]);
855 rtl8723ae_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
856 rtl8723ae_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
857}
858
859bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
860{
861 struct rtl_priv *rtlpriv = rtl_priv(hw);
862 struct rtl_phy *rtlphy = &(rtlpriv->phy);
863 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
864 u8 idx;
865 u8 rf_path;
866 u8 ccktxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_B,
867 power_indbm);
868 u8 ofdmtxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_N_24G,
869 power_indbm);
870 if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
871 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
872 else
873 ofdmtxpwridx = 0;
874 RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
875 "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
876 power_indbm, ccktxpwridx, ofdmtxpwridx);
877 for (idx = 0; idx < 14; idx++) {
878 for (rf_path = 0; rf_path < 2; rf_path++) {
879 rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
880 rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
881 ofdmtxpwridx;
882 rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
883 ofdmtxpwridx;
884 }
885 }
886 rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
887 return true;
888}
889
890static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
891 enum wireless_mode wirelessmode,
892 long power_indbm)
893{
894 u8 txpwridx;
895 long offset;
896
897 switch (wirelessmode) {
898 case WIRELESS_MODE_B:
899 offset = -7;
900 break;
901 case WIRELESS_MODE_G:
902 case WIRELESS_MODE_N_24G:
903 offset = -8;
904 break;
905 default:
906 offset = -8;
907 break;
908 }
909
910 if ((power_indbm - offset) > 0)
911 txpwridx = (u8) ((power_indbm - offset) * 2);
912 else
913 txpwridx = 0;
914
915 if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
916 txpwridx = MAX_TXPWR_IDX_NMODE_92S;
917
918 return txpwridx;
919}
920
921static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
922 enum wireless_mode wirelessmode, u8 txpwridx)
923{
924 long offset;
925 long pwrout_dbm;
926
927 switch (wirelessmode) {
928 case WIRELESS_MODE_B:
929 offset = -7;
930 break;
931 case WIRELESS_MODE_G:
932 case WIRELESS_MODE_N_24G:
933 offset = -8;
934 break;
935 default:
936 offset = -8;
937 break;
938 }
939 pwrout_dbm = txpwridx / 2 + offset;
940 return pwrout_dbm;
941}
942
943void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
944{
945 struct rtl_priv *rtlpriv = rtl_priv(hw);
946 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
947 enum io_type iotype;
948
949 if (!is_hal_stop(rtlhal)) {
950 switch (operation) {
951 case SCAN_OPT_BACKUP:
952 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
953 rtlpriv->cfg->ops->set_hw_reg(hw,
954 HW_VAR_IO_CMD,
955 (u8 *)&iotype);
956
957 break;
958 case SCAN_OPT_RESTORE:
959 iotype = IO_CMD_RESUME_DM_BY_SCAN;
960 rtlpriv->cfg->ops->set_hw_reg(hw,
961 HW_VAR_IO_CMD,
962 (u8 *)&iotype);
963 break;
964 default:
965 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
966 "Unknown Scan Backup operation.\n");
967 break;
968 }
969 }
970}
971
972void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
973{
974 struct rtl_priv *rtlpriv = rtl_priv(hw);
975 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
976 struct rtl_phy *rtlphy = &(rtlpriv->phy);
977 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
978 u8 reg_bw_opmode;
979 u8 reg_prsr_rsc;
980
981 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
982 "Switch to %s bandwidth\n",
983 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
984 "20MHz" : "40MHz");
985
986 if (is_hal_stop(rtlhal)) {
987 rtlphy->set_bwmode_inprogress = false;
988 return;
989 }
990
991 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
992 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
993
994 switch (rtlphy->current_chan_bw) {
995 case HT_CHANNEL_WIDTH_20:
996 reg_bw_opmode |= BW_OPMODE_20MHZ;
997 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
998 break;
999 case HT_CHANNEL_WIDTH_20_40:
1000 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1001 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1002 reg_prsr_rsc =
1003 (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
1004 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1005 break;
1006 default:
1007 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1008 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1009 break;
1010 }
1011
1012 switch (rtlphy->current_chan_bw) {
1013 case HT_CHANNEL_WIDTH_20:
1014 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1015 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1016 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
1017 break;
1018 case HT_CHANNEL_WIDTH_20_40:
1019 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1020 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1021
1022 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1023 (mac->cur_40_prime_sc >> 1));
1024 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1025 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
1026
1027 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1028 (mac->cur_40_prime_sc ==
1029 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1030 break;
1031 default:
1032 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1033 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1034 break;
1035 }
1036 rtl8723ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1037 rtlphy->set_bwmode_inprogress = false;
1038 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
1039}
1040
1041void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw,
1042 enum nl80211_channel_type ch_type)
1043{
1044 struct rtl_priv *rtlpriv = rtl_priv(hw);
1045 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1046 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1047 u8 tmp_bw = rtlphy->current_chan_bw;
1048
1049 if (rtlphy->set_bwmode_inprogress)
1050 return;
1051 rtlphy->set_bwmode_inprogress = true;
1052 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1053 rtl8723ae_phy_set_bw_mode_callback(hw);
1054 } else {
1055 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1056 "FALSE driver sleep or unload\n");
1057 rtlphy->set_bwmode_inprogress = false;
1058 rtlphy->current_chan_bw = tmp_bw;
1059 }
1060}
1061
1062void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1063{
1064 struct rtl_priv *rtlpriv = rtl_priv(hw);
1065 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1066 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1067 u32 delay;
1068
1069 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1070 "switch to channel%d\n", rtlphy->current_channel);
1071 if (is_hal_stop(rtlhal))
1072 return;
1073 do {
1074 if (!rtlphy->sw_chnl_inprogress)
1075 break;
1076 if (!_phy_sw_chnl_step_by_step
1077 (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
1078 &rtlphy->sw_chnl_step, &delay)) {
1079 if (delay > 0)
1080 mdelay(delay);
1081 else
1082 continue;
1083 } else {
1084 rtlphy->sw_chnl_inprogress = false;
1085 }
1086 break;
1087 } while (true);
1088 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
1089}
1090
1091u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw)
1092{
1093 struct rtl_priv *rtlpriv = rtl_priv(hw);
1094 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1095 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1096
1097 if (rtlphy->sw_chnl_inprogress)
1098 return 0;
1099 if (rtlphy->set_bwmode_inprogress)
1100 return 0;
1101 RT_ASSERT((rtlphy->current_channel <= 14),
1102 "WIRELESS_MODE_G but channel>14");
1103 rtlphy->sw_chnl_inprogress = true;
1104 rtlphy->sw_chnl_stage = 0;
1105 rtlphy->sw_chnl_step = 0;
1106 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1107 rtl8723ae_phy_sw_chnl_callback(hw);
1108 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1109 "sw_chnl_inprogress false schdule workitem\n");
1110 rtlphy->sw_chnl_inprogress = false;
1111 } else {
1112 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1113 "sw_chnl_inprogress false driver sleep or unload\n");
1114 rtlphy->sw_chnl_inprogress = false;
1115 }
1116 return 1;
1117}
1118
1119static void _rtl8723ae_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel)
1120{
1121 struct rtl_priv *rtlpriv = rtl_priv(hw);
1122 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1123 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1124
1125 if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
1126 if (channel == 6 && rtlphy->current_chan_bw ==
1127 HT_CHANNEL_WIDTH_20)
1128 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
1129 0x00255);
1130 else{
1131 u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A,
1132 RF_RX_G1, RFREG_OFFSET_MASK);
1133 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
1134 backupRF0x1A);
1135 }
1136 }
1137}
1138
1139static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
1140 u8 *stage, u8 *step, u32 *delay)
1141{
1142 struct rtl_priv *rtlpriv = rtl_priv(hw);
1143 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1144 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1145 u32 precommoncmdcnt;
1146 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1147 u32 postcommoncmdcnt;
1148 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1149 u32 rfdependcmdcnt;
1150 struct swchnlcmd *currentcmd = NULL;
1151 u8 rfpath;
1152 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1153
1154 precommoncmdcnt = 0;
1155 _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1156 MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL,
1157 0, 0, 0);
1158 _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1159 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1160 postcommoncmdcnt = 0;
1161
1162 _phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1163 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
1164 rfdependcmdcnt = 0;
1165
1166 RT_ASSERT((channel >= 1 && channel <= 14),
1167 "illegal channel for Zebra: %d\n", channel);
1168
1169 _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1170 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
1171 RF_CHNLBW, channel, 10);
1172
1173 _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1174 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
1175
1176 do {
1177 switch (*stage) {
1178 case 0:
1179 currentcmd = &precommoncmd[*step];
1180 break;
1181 case 1:
1182 currentcmd = &rfdependcmd[*step];
1183 break;
1184 case 2:
1185 currentcmd = &postcommoncmd[*step];
1186 break;
1187 }
1188
1189 if (currentcmd->cmdid == CMDID_END) {
1190 if ((*stage) == 2) {
1191 return true;
1192 } else {
1193 (*stage)++;
1194 (*step) = 0;
1195 continue;
1196 }
1197 }
1198
1199 switch (currentcmd->cmdid) {
1200 case CMDID_SET_TXPOWEROWER_LEVEL:
1201 rtl8723ae_phy_set_txpower_level(hw, channel);
1202 break;
1203 case CMDID_WRITEPORT_ULONG:
1204 rtl_write_dword(rtlpriv, currentcmd->para1,
1205 currentcmd->para2);
1206 break;
1207 case CMDID_WRITEPORT_USHORT:
1208 rtl_write_word(rtlpriv, currentcmd->para1,
1209 (u16) currentcmd->para2);
1210 break;
1211 case CMDID_WRITEPORT_UCHAR:
1212 rtl_write_byte(rtlpriv, currentcmd->para1,
1213 (u8) currentcmd->para2);
1214 break;
1215 case CMDID_RF_WRITEREG:
1216 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1217 rtlphy->rfreg_chnlval[rfpath] =
1218 ((rtlphy->rfreg_chnlval[rfpath] &
1219 0xfffffc00) | currentcmd->para2);
1220
1221 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1222 currentcmd->para1,
1223 RFREG_OFFSET_MASK,
1224 rtlphy->rfreg_chnlval[rfpath]);
1225 }
1226 _rtl8723ae_phy_sw_rf_seting(hw, channel);
1227 break;
1228 default:
1229 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1230 "switch case not process\n");
1231 break;
1232 }
1233
1234 break;
1235 } while (true);
1236
1237 (*delay) = currentcmd->msdelay;
1238 (*step)++;
1239 return false;
1240}
1241
1242static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
1243 u32 cmdtableidx, u32 cmdtablesz,
1244 enum swchnlcmd_id cmdid, u32 para1,
1245 u32 para2, u32 msdelay)
1246{
1247 struct swchnlcmd *pcmd;
1248
1249 if (cmdtable == NULL) {
1250 RT_ASSERT(false, "cmdtable cannot be NULL.\n");
1251 return false;
1252 }
1253
1254 if (cmdtableidx >= cmdtablesz)
1255 return false;
1256
1257 pcmd = cmdtable + cmdtableidx;
1258 pcmd->cmdid = cmdid;
1259 pcmd->para1 = para1;
1260 pcmd->para2 = para2;
1261 pcmd->msdelay = msdelay;
1262 return true;
1263}
1264
1265static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1266{
1267 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1268 u8 result = 0x00;
1269
1270 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
1271 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
1272 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
1273 rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
1274 config_pathb ? 0x28160202 : 0x28160502);
1275
1276 if (config_pathb) {
1277 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
1278 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
1279 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
1280 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
1281 }
1282
1283 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
1284 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1285 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1286
1287 mdelay(IQK_DELAY_TIME);
1288
1289 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1290 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1291 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1292 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1293
1294 if (!(reg_eac & BIT(28)) &&
1295 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1296 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1297 result |= 0x01;
1298 else
1299 return result;
1300
1301 if (!(reg_eac & BIT(27)) &&
1302 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1303 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1304 result |= 0x02;
1305 return result;
1306}
1307
1308static u8 _rtl8723ae_phy_path_b_iqk(struct ieee80211_hw *hw)
1309{
1310 u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
1311 u8 result = 0x00;
1312
1313 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
1314 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
1315 mdelay(IQK_DELAY_TIME);
1316 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1317 reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1318 reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1319 reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1320 reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1321
1322 if (!(reg_eac & BIT(31)) &&
1323 (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
1324 (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
1325 result |= 0x01;
1326 else
1327 return result;
1328 if (!(reg_eac & BIT(30)) &&
1329 (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
1330 (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
1331 result |= 0x02;
1332 return result;
1333}
1334
1335static void phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, bool iqk_ok,
1336 long result[][8], u8 final_candidate,
1337 bool btxonly)
1338{
1339 u32 oldval_0, x, tx0_a, reg;
1340 long y, tx0_c;
1341
1342 if (final_candidate == 0xFF) {
1343 return;
1344 } else if (iqk_ok) {
1345 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1346 MASKDWORD) >> 22) & 0x3FF;
1347 x = result[final_candidate][0];
1348 if ((x & 0x00000200) != 0)
1349 x = x | 0xFFFFFC00;
1350 tx0_a = (x * oldval_0) >> 8;
1351 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
1352 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
1353 ((x * oldval_0 >> 7) & 0x1));
1354 y = result[final_candidate][1];
1355 if ((y & 0x00000200) != 0)
1356 y = y | 0xFFFFFC00;
1357 tx0_c = (y * oldval_0) >> 8;
1358 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1359 ((tx0_c & 0x3C0) >> 6));
1360 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
1361 (tx0_c & 0x3F));
1362 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
1363 ((y * oldval_0 >> 7) & 0x1));
1364 if (btxonly)
1365 return;
1366 reg = result[final_candidate][2];
1367 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1368 reg = result[final_candidate][3] & 0x3F;
1369 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1370 reg = (result[final_candidate][3] >> 6) & 0xF;
1371 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1372 }
1373}
1374
1375static void phy_save_adda_regs(struct ieee80211_hw *hw,
1376 u32 *addareg, u32 *addabackup,
1377 u32 registernum)
1378{
1379 u32 i;
1380
1381 for (i = 0; i < registernum; i++)
1382 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1383}
1384
1385static void phy_save_mac_regs(struct ieee80211_hw *hw, u32 *macreg,
1386 u32 *macbackup)
1387{
1388 struct rtl_priv *rtlpriv = rtl_priv(hw);
1389 u32 i;
1390
1391 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1392 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1393 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1394}
1395
1396static void phy_reload_adda_regs(struct ieee80211_hw *hw, u32 *addareg,
1397 u32 *addabackup, u32 regiesternum)
1398{
1399 u32 i;
1400
1401 for (i = 0; i < regiesternum; i++)
1402 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
1403}
1404
1405static void phy_reload_mac_regs(struct ieee80211_hw *hw, u32 *macreg,
1406 u32 *macbackup)
1407{
1408 struct rtl_priv *rtlpriv = rtl_priv(hw);
1409 u32 i;
1410
1411 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1412 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1413 rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1414}
1415
1416static void _rtl8723ae_phy_path_adda_on(struct ieee80211_hw *hw,
1417 u32 *addareg, bool is_patha_on,
1418 bool is2t)
1419{
1420 u32 pathOn;
1421 u32 i;
1422
1423 pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1424 if (false == is2t) {
1425 pathOn = 0x0bdb25a0;
1426 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1427 } else {
1428 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn);
1429 }
1430
1431 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1432 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn);
1433}
1434
1435static void _rtl8723ae_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1436 u32 *macreg, u32 *macbackup)
1437{
1438 struct rtl_priv *rtlpriv = rtl_priv(hw);
1439 u32 i = 0;
1440
1441 rtl_write_byte(rtlpriv, macreg[i], 0x3F);
1442
1443 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1444 rtl_write_byte(rtlpriv, macreg[i],
1445 (u8) (macbackup[i] & (~BIT(3))));
1446 rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1447}
1448
1449static void _rtl8723ae_phy_path_a_standby(struct ieee80211_hw *hw)
1450{
1451 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1452 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1453 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1454}
1455
1456static void _rtl8723ae_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1457{
1458 u32 mode;
1459
1460 mode = pi_mode ? 0x01000100 : 0x01000000;
1461 rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1462 rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1463}
1464
1465static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8],
1466 u8 c1, u8 c2)
1467{
1468 u32 i, j, diff, simularity_bitmap, bound;
1469
1470 u8 final_candidate[2] = { 0xFF, 0xFF };
1471 bool bresult = true;
1472
1473 bound = 4;
1474
1475 simularity_bitmap = 0;
1476
1477 for (i = 0; i < bound; i++) {
1478 diff = (result[c1][i] > result[c2][i]) ?
1479 (result[c1][i] - result[c2][i]) :
1480 (result[c2][i] - result[c1][i]);
1481
1482 if (diff > MAX_TOLERANCE) {
1483 if ((i == 2 || i == 6) && !simularity_bitmap) {
1484 if (result[c1][i] + result[c1][i + 1] == 0)
1485 final_candidate[(i / 4)] = c2;
1486 else if (result[c2][i] + result[c2][i + 1] == 0)
1487 final_candidate[(i / 4)] = c1;
1488 else
1489 simularity_bitmap = simularity_bitmap |
1490 (1 << i);
1491 } else
1492 simularity_bitmap =
1493 simularity_bitmap | (1 << i);
1494 }
1495 }
1496
1497 if (simularity_bitmap == 0) {
1498 for (i = 0; i < (bound / 4); i++) {
1499 if (final_candidate[i] != 0xFF) {
1500 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1501 result[3][j] =
1502 result[final_candidate[i]][j];
1503 bresult = false;
1504 }
1505 }
1506 return bresult;
1507 } else if (!(simularity_bitmap & 0x0F)) {
1508 for (i = 0; i < 4; i++)
1509 result[3][i] = result[c1][i];
1510 return false;
1511 } else {
1512 return false;
1513 }
1514
1515}
1516
1517static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
1518 long result[][8], u8 t, bool is2t)
1519{
1520 struct rtl_priv *rtlpriv = rtl_priv(hw);
1521 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1522 u32 i;
1523 u8 patha_ok, pathb_ok;
1524 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1525 0x85c, 0xe6c, 0xe70, 0xe74,
1526 0xe78, 0xe7c, 0xe80, 0xe84,
1527 0xe88, 0xe8c, 0xed0, 0xed4,
1528 0xed8, 0xedc, 0xee0, 0xeec
1529 };
1530 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1531 0x522, 0x550, 0x551, 0x040
1532 };
1533 const u32 retrycount = 2;
1534 u32 bbvalue;
1535
1536 if (t == 0) {
1537 bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD);
1538
1539 phy_save_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16);
1540 phy_save_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup);
1541 }
1542 _rtl8723ae_phy_path_adda_on(hw, adda_reg, true, is2t);
1543 if (t == 0) {
1544 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1545 RFPGA0_XA_HSSIPARAMETER1,
1546 BIT(8));
1547 }
1548
1549 if (!rtlphy->rfpi_enable)
1550 _rtl8723ae_phy_pi_mode_switch(hw, true);
1551 if (t == 0) {
1552 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1553 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1554 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1555 }
1556 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1557 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1558 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1559 if (is2t) {
1560 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1561 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1562 }
1563 _rtl8723ae_phy_mac_setting_calibration(hw, iqk_mac_reg,
1564 rtlphy->iqk_mac_backup);
1565 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1566 if (is2t)
1567 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1568 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1569 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1570 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1571 for (i = 0; i < retrycount; i++) {
1572 patha_ok = _rtl8723ae_phy_path_a_iqk(hw, is2t);
1573 if (patha_ok == 0x03) {
1574 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1575 0x3FF0000) >> 16;
1576 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1577 0x3FF0000) >> 16;
1578 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1579 0x3FF0000) >> 16;
1580 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1581 0x3FF0000) >> 16;
1582 break;
1583 } else if (i == (retrycount - 1) && patha_ok == 0x01)
1584
1585 result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1586 MASKDWORD) & 0x3FF0000) >> 16;
1587 result[t][1] =
1588 (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1589
1590 }
1591
1592 if (is2t) {
1593 _rtl8723ae_phy_path_a_standby(hw);
1594 _rtl8723ae_phy_path_adda_on(hw, adda_reg, false, is2t);
1595 for (i = 0; i < retrycount; i++) {
1596 pathb_ok = _rtl8723ae_phy_path_b_iqk(hw);
1597 if (pathb_ok == 0x03) {
1598 result[t][4] =
1599 (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
1600 0x3FF0000) >> 16;
1601 result[t][5] =
1602 (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1603 0x3FF0000) >> 16;
1604 result[t][6] =
1605 (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1606 0x3FF0000) >> 16;
1607 result[t][7] =
1608 (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1609 0x3FF0000) >> 16;
1610 break;
1611 } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1612 result[t][4] =
1613 (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
1614 0x3FF0000) >> 16;
1615 }
1616 result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1617 0x3FF0000) >> 16;
1618 }
1619 }
1620 rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1621 rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1622 rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1623 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1624 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1625 if (is2t)
1626 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1627 if (t != 0) {
1628 if (!rtlphy->rfpi_enable)
1629 _rtl8723ae_phy_pi_mode_switch(hw, false);
1630 phy_reload_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16);
1631 phy_reload_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup);
1632 }
1633}
1634
1635static void _rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1636{
1637 struct rtl_priv *rtlpriv = rtl_priv(hw);
1638 u8 tmpreg;
1639 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1640
1641 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1642
1643 if ((tmpreg & 0x70) != 0)
1644 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1645 else
1646 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1647
1648 if ((tmpreg & 0x70) != 0) {
1649 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1650
1651 if (is2t)
1652 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1653 MASK12BITS);
1654
1655 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1656 (rf_a_mode & 0x8FFFF) | 0x10000);
1657
1658 if (is2t)
1659 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1660 (rf_b_mode & 0x8FFFF) | 0x10000);
1661 }
1662 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1663
1664 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
1665
1666 mdelay(100);
1667
1668 if ((tmpreg & 0x70) != 0) {
1669 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1670 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1671
1672 if (is2t)
1673 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1674 rf_b_mode);
1675 } else {
1676 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1677 }
1678}
1679
1680static void _rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1681 bool bmain, bool is2t)
1682{
1683 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1684
1685 if (is_hal_stop(rtlhal)) {
1686 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
1687 rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1688 }
1689 if (is2t) {
1690 if (bmain)
1691 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1692 BIT(5) | BIT(6), 0x1);
1693 else
1694 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1695 BIT(5) | BIT(6), 0x2);
1696 } else {
1697 if (bmain)
1698 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
1699 else
1700 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
1701
1702 }
1703}
1704
1705#undef IQK_ADDA_REG_NUM
1706#undef IQK_DELAY_TIME
1707
1708void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1709{
1710 struct rtl_priv *rtlpriv = rtl_priv(hw);
1711 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1712 long result[4][8];
1713 u8 i, final_candidate;
1714 bool patha_ok, pathb_ok;
1715 long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
1716 reg_ecc, reg_tmp = 0;
1717 bool is12simular, is13simular, is23simular;
1718 bool start_conttx = false, singletone = false;
1719 u32 iqk_bb_reg[10] = {
1720 ROFDM0_XARXIQIMBALANCE,
1721 ROFDM0_XBRXIQIMBALANCE,
1722 ROFDM0_ECCATHRESHOLD,
1723 ROFDM0_AGCRSSITABLE,
1724 ROFDM0_XATXIQIMBALANCE,
1725 ROFDM0_XBTXIQIMBALANCE,
1726 ROFDM0_XCTXIQIMBALANCE,
1727 ROFDM0_XCTXAFE,
1728 ROFDM0_XDTXAFE,
1729 ROFDM0_RXIQEXTANTA
1730 };
1731
1732 if (recovery) {
1733 phy_reload_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10);
1734 return;
1735 }
1736 if (start_conttx || singletone)
1737 return;
1738 for (i = 0; i < 8; i++) {
1739 result[0][i] = 0;
1740 result[1][i] = 0;
1741 result[2][i] = 0;
1742 result[3][i] = 0;
1743 }
1744 final_candidate = 0xff;
1745 patha_ok = false;
1746 pathb_ok = false;
1747 is12simular = false;
1748 is23simular = false;
1749 is13simular = false;
1750 for (i = 0; i < 3; i++) {
1751 _rtl8723ae_phy_iq_calibrate(hw, result, i, false);
1752 if (i == 1) {
1753 is12simular = phy_simularity_comp(hw, result, 0, 1);
1754 if (is12simular) {
1755 final_candidate = 0;
1756 break;
1757 }
1758 }
1759 if (i == 2) {
1760 is13simular = phy_simularity_comp(hw, result, 0, 2);
1761 if (is13simular) {
1762 final_candidate = 0;
1763 break;
1764 }
1765 is23simular = phy_simularity_comp(hw, result, 1, 2);
1766 if (is23simular) {
1767 final_candidate = 1;
1768 } else {
1769 for (i = 0; i < 8; i++)
1770 reg_tmp += result[3][i];
1771
1772 if (reg_tmp != 0)
1773 final_candidate = 3;
1774 else
1775 final_candidate = 0xFF;
1776 }
1777 }
1778 }
1779 for (i = 0; i < 4; i++) {
1780 reg_e94 = result[i][0];
1781 reg_e9c = result[i][1];
1782 reg_ea4 = result[i][2];
1783 reg_eac = result[i][3];
1784 reg_eb4 = result[i][4];
1785 reg_ebc = result[i][5];
1786 reg_ec4 = result[i][6];
1787 reg_ecc = result[i][7];
1788 }
1789 if (final_candidate != 0xff) {
1790 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1791 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1792 reg_ea4 = result[final_candidate][2];
1793 reg_eac = result[final_candidate][3];
1794 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1795 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1796 reg_ec4 = result[final_candidate][6];
1797 reg_ecc = result[final_candidate][7];
1798 patha_ok = pathb_ok = true;
1799 } else {
1800 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
1801 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1802 }
1803 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1804 phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1805 final_candidate, (reg_ea4 == 0));
1806 phy_save_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10);
1807}
1808
1809void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw)
1810{
1811 bool start_conttx = false, singletone = false;
1812
1813 if (start_conttx || singletone)
1814 return;
1815 _rtl8723ae_phy_lc_calibrate(hw, false);
1816}
1817
1818void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1819{
1820 _rtl8723ae_phy_set_rfpath_switch(hw, bmain, false);
1821}
1822
1823bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1824{
1825 struct rtl_priv *rtlpriv = rtl_priv(hw);
1826 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1827 bool postprocessing = false;
1828
1829 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1830 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1831 iotype, rtlphy->set_io_inprogress);
1832 do {
1833 switch (iotype) {
1834 case IO_CMD_RESUME_DM_BY_SCAN:
1835 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1836 "[IO CMD] Resume DM after scan.\n");
1837 postprocessing = true;
1838 break;
1839 case IO_CMD_PAUSE_DM_BY_SCAN:
1840 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1841 "[IO CMD] Pause DM before scan.\n");
1842 postprocessing = true;
1843 break;
1844 default:
1845 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1846 "switch case not process\n");
1847 break;
1848 }
1849 } while (false);
1850 if (postprocessing && !rtlphy->set_io_inprogress) {
1851 rtlphy->set_io_inprogress = true;
1852 rtlphy->current_io_type = iotype;
1853 } else {
1854 return false;
1855 }
1856 rtl8723ae_phy_set_io(hw);
1857 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
1858 return true;
1859}
1860
1861static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw)
1862{
1863 struct rtl_priv *rtlpriv = rtl_priv(hw);
1864 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1865 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1866
1867 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1868 "--->Cmd(%#x), set_io_inprogress(%d)\n",
1869 rtlphy->current_io_type, rtlphy->set_io_inprogress);
1870 switch (rtlphy->current_io_type) {
1871 case IO_CMD_RESUME_DM_BY_SCAN:
1872 dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
1873 rtl8723ae_dm_write_dig(hw);
1874 rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
1875 break;
1876 case IO_CMD_PAUSE_DM_BY_SCAN:
1877 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
1878 dm_digtable->cur_igvalue = 0x17;
1879 rtl8723ae_dm_write_dig(hw);
1880 break;
1881 default:
1882 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1883 "switch case not process\n");
1884 break;
1885 }
1886 rtlphy->set_io_inprogress = false;
1887 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1888 "<---(%#x)\n", rtlphy->current_io_type);
1889}
1890
1891static void rtl8723ae_phy_set_rf_on(struct ieee80211_hw *hw)
1892{
1893 struct rtl_priv *rtlpriv = rtl_priv(hw);
1894
1895 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
1896 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1897 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1898 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1899 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1900 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1901}
1902
1903static void _rtl8723ae_phy_set_rf_sleep(struct ieee80211_hw *hw)
1904{
1905 struct rtl_priv *rtlpriv = rtl_priv(hw);
1906 u32 u4b_tmp;
1907 u8 delay = 5;
1908
1909 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1910 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1911 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1912 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1913 while (u4b_tmp != 0 && delay > 0) {
1914 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
1915 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1916 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1917 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1918 delay--;
1919 }
1920 if (delay == 0) {
1921 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1922 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1923 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1924 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1925 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1926 "Switch RF timeout !!!.\n");
1927 return;
1928 }
1929 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1930 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
1931}
1932
1933static bool _rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
1934 enum rf_pwrstate rfpwr_state)
1935{
1936 struct rtl_priv *rtlpriv = rtl_priv(hw);
1937 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1938 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1939 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1940 struct rtl8192_tx_ring *ring = NULL;
1941 bool bresult = true;
1942 u8 i, queue_id;
1943
1944 switch (rfpwr_state) {
1945 case ERFON:
1946 if ((ppsc->rfpwr_state == ERFOFF) &&
1947 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
1948 bool rtstatus;
1949 u32 InitializeCount = 0;
1950 do {
1951 InitializeCount++;
1952 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1953 "IPS Set eRf nic enable\n");
1954 rtstatus = rtl_ps_enable_nic(hw);
1955 } while ((rtstatus != true) && (InitializeCount < 10));
1956 RT_CLEAR_PS_LEVEL(ppsc,
1957 RT_RF_OFF_LEVL_HALT_NIC);
1958 } else {
1959 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1960 "Set ERFON sleeped:%d ms\n",
1961 jiffies_to_msecs(jiffies -
1962 ppsc->last_sleep_jiffies));
1963 ppsc->last_awake_jiffies = jiffies;
1964 rtl8723ae_phy_set_rf_on(hw);
1965 }
1966 if (mac->link_state == MAC80211_LINKED) {
1967 rtlpriv->cfg->ops->led_control(hw,
1968 LED_CTL_LINK);
1969 } else {
1970 rtlpriv->cfg->ops->led_control(hw,
1971 LED_CTL_NO_LINK);
1972 }
1973 break;
1974 case ERFOFF:
1975 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
1976 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1977 "IPS Set eRf nic disable\n");
1978 rtl_ps_disable_nic(hw);
1979 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1980 } else {
1981 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
1982 rtlpriv->cfg->ops->led_control(hw,
1983 LED_CTL_NO_LINK);
1984 } else {
1985 rtlpriv->cfg->ops->led_control(hw,
1986 LED_CTL_POWER_OFF);
1987 }
1988 }
1989 break;
1990 case ERFSLEEP:
1991 if (ppsc->rfpwr_state == ERFOFF)
1992 break;
1993 for (queue_id = 0, i = 0;
1994 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
1995 ring = &pcipriv->dev.tx_ring[queue_id];
1996 if (skb_queue_len(&ring->queue) == 0) {
1997 queue_id++;
1998 continue;
1999 } else {
2000 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2001 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2002 (i + 1), queue_id,
2003 skb_queue_len(&ring->queue));
2004
2005 udelay(10);
2006 i++;
2007 }
2008 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2009 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2010 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2011 MAX_DOZE_WAITING_TIMES_9x,
2012 queue_id,
2013 skb_queue_len(&ring->queue));
2014 break;
2015 }
2016 }
2017 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2018 "Set ERFSLEEP awaked:%d ms\n",
2019 jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
2020 ppsc->last_sleep_jiffies = jiffies;
2021 _rtl8723ae_phy_set_rf_sleep(hw);
2022 break;
2023 default:
2024 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2025 "switch case not processed\n");
2026 bresult = false;
2027 break;
2028 }
2029 if (bresult)
2030 ppsc->rfpwr_state = rfpwr_state;
2031 return bresult;
2032}
2033
2034bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
2035 enum rf_pwrstate rfpwr_state)
2036{
2037 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2038 bool bresult = false;
2039
2040 if (rfpwr_state == ppsc->rfpwr_state)
2041 return bresult;
2042 bresult = _rtl8723ae_phy_set_rf_power_state(hw, rfpwr_state);
2043 return bresult;
2044}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
new file mode 100644
index 00000000000..e7a59eba351
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
@@ -0,0 +1,224 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C_PHY_H__
31#define __RTL92C_PHY_H__
32
33#define MAX_PRECMD_CNT 16
34#define MAX_RFDEPENDCMD_CNT 16
35#define MAX_POSTCMD_CNT 16
36
37#define MAX_DOZE_WAITING_TIMES_9x 64
38
39#define RT_CANNOT_IO(hw) false
40#define HIGHPOWER_RADIOA_ARRAYLEN 22
41
42#define MAX_TOLERANCE 5
43#define IQK_DELAY_TIME 1
44
45#define APK_BB_REG_NUM 5
46#define APK_AFE_REG_NUM 16
47#define APK_CURVE_REG_NUM 4
48#define PATH_NUM 2
49
50#define LOOP_LIMIT 5
51#define MAX_STALL_TIME 50
52#define AntennaDiversityValue 0x80
53#define MAX_TXPWR_IDX_NMODE_92S 63
54#define Reset_Cnt_Limit 3
55
56#define IQK_MAC_REG_NUM 4
57
58#define RF6052_MAX_PATH 2
59
60#define CT_OFFSET_MAC_ADDR 0X16
61
62#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
63#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
64#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66
65#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
66#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
67
68#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
69#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
70
71#define CT_OFFSET_CHANNEL_PLAH 0x75
72#define CT_OFFSET_THERMAL_METER 0x78
73#define CT_OFFSET_RF_OPTION 0x79
74#define CT_OFFSET_VERSION 0x7E
75#define CT_OFFSET_CUSTOMER_ID 0x7F
76
77#define RTL92C_MAX_PATH_NUM 2
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 {
97 HW90_BLOCK_MAC = 0,
98 HW90_BLOCK_PHY0 = 1,
99 HW90_BLOCK_PHY1 = 2,
100 HW90_BLOCK_RF = 3,
101 HW90_BLOCK_MAXIMUM = 4,
102};
103
104enum baseband_config_type {
105 BASEBAND_CONFIG_PHY_REG = 0,
106 BASEBAND_CONFIG_AGC_TAB = 1,
107};
108
109enum ra_offset_area {
110 RA_OFFSET_LEGACY_OFDM1,
111 RA_OFFSET_LEGACY_OFDM2,
112 RA_OFFSET_HT_OFDM1,
113 RA_OFFSET_HT_OFDM2,
114 RA_OFFSET_HT_OFDM3,
115 RA_OFFSET_HT_OFDM4,
116 RA_OFFSET_HT_CCK,
117};
118
119enum antenna_path {
120 ANTENNA_NONE,
121 ANTENNA_D,
122 ANTENNA_C,
123 ANTENNA_CD,
124 ANTENNA_B,
125 ANTENNA_BD,
126 ANTENNA_BC,
127 ANTENNA_BCD,
128 ANTENNA_A,
129 ANTENNA_AD,
130 ANTENNA_AC,
131 ANTENNA_ACD,
132 ANTENNA_AB,
133 ANTENNA_ABD,
134 ANTENNA_ABC,
135 ANTENNA_ABCD
136};
137
138struct r_antenna_select_ofdm {
139 u32 r_tx_antenna:4;
140 u32 r_ant_l:4;
141 u32 r_ant_non_ht:4;
142 u32 r_ant_ht1:4;
143 u32 r_ant_ht2:4;
144 u32 r_ant_ht_s1:4;
145 u32 r_ant_non_ht_s1:4;
146 u32 ofdm_txsc:2;
147 u32 reserved:2;
148};
149
150struct r_antenna_select_cck {
151 u8 r_cckrx_enable_2:2;
152 u8 r_cckrx_enable:2;
153 u8 r_ccktx_enable:4;
154};
155
156struct efuse_contents {
157 u8 mac_addr[ETH_ALEN];
158 u8 cck_tx_power_idx[6];
159 u8 ht40_1s_tx_power_idx[6];
160 u8 ht40_2s_tx_power_idx_diff[3];
161 u8 ht20_tx_power_idx_diff[3];
162 u8 ofdm_tx_power_idx_diff[3];
163 u8 ht40_max_power_offset[3];
164 u8 ht20_max_power_offset[3];
165 u8 channel_plan;
166 u8 thermal_meter;
167 u8 rf_option[5];
168 u8 version;
169 u8 oem_id;
170 u8 regulatory;
171};
172
173struct tx_power_struct {
174 u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
175 u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
176 u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
177 u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
178 u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
179 u8 legacy_ht_txpowerdiff;
180 u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
181 u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
182 u8 pwrgroup_cnt;
183 u32 mcs_original_offset[4][16];
184};
185
186extern u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw,
187 u32 regaddr, u32 bitmask);
188extern void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw,
189 u32 regaddr, u32 bitmask, u32 data);
190extern u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
191 enum radio_path rfpath, u32 regaddr,
192 u32 bitmask);
193extern void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,
194 enum radio_path rfpath, u32 regaddr,
195 u32 bitmask, u32 data);
196extern bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw);
197extern bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw);
198extern bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw);
199extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
200 enum radio_path rfpath);
201extern void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
202extern void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw,
203 long *powerlevel);
204extern void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw,
205 u8 channel);
206extern bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw,
207 long power_indbm);
208extern void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw,
209 u8 operation);
210extern void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
211extern void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw,
212 enum nl80211_channel_type ch_type);
213extern void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw);
214extern u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw);
215extern void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
216void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw);
217void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
218bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
219 enum radio_path rfpath);
220bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
221extern bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
222 enum rf_pwrstate rfpwr_state);
223
224#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c
new file mode 100644
index 00000000000..df6ca9a57f7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c
@@ -0,0 +1,109 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "pwrseqcmd.h"
31#include "pwrseq.h"
32
33/* drivers should parse arrays below and do the corresponding actions */
34
35/*3 Power on Array*/
36struct wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS
37 + RTL8723A_TRANS_END_STPS] = {
38 RTL8723A_TRANS_CARDEMU_TO_ACT,
39 RTL8723A_TRANS_END
40};
41
42/*3Radio off GPIO Array */
43struct wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
44 + RTL8723A_TRANS_END_STPS] = {
45 RTL8723A_TRANS_ACT_TO_CARDEMU,
46 RTL8723A_TRANS_END
47};
48
49/*3Card Disable Array*/
50struct wlan_pwr_cfg
51rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
52 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
53 + RTL8723A_TRANS_END_STPS] = {
54 RTL8723A_TRANS_ACT_TO_CARDEMU,
55 RTL8723A_TRANS_CARDEMU_TO_CARDDIS,
56 RTL8723A_TRANS_END
57};
58
59/*3 Card Enable Array*/
60struct wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
61 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
62 + RTL8723A_TRANS_END_STPS] = {
63 RTL8723A_TRANS_CARDDIS_TO_CARDEMU,
64 RTL8723A_TRANS_CARDEMU_TO_ACT,
65 RTL8723A_TRANS_END
66};
67
68/*3Suspend Array*/
69struct wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
70 + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS
71 + RTL8723A_TRANS_END_STPS] = {
72 RTL8723A_TRANS_ACT_TO_CARDEMU,
73 RTL8723A_TRANS_CARDEMU_TO_SUS,
74 RTL8723A_TRANS_END
75};
76
77/*3 Resume Array*/
78struct wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
79 + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS
80 + RTL8723A_TRANS_END_STPS] = {
81 RTL8723A_TRANS_SUS_TO_CARDEMU,
82 RTL8723A_TRANS_CARDEMU_TO_ACT,
83 RTL8723A_TRANS_END
84};
85
86/*3HWPDN Array*/
87struct wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
88 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
89 + RTL8723A_TRANS_END_STPS] = {
90 RTL8723A_TRANS_ACT_TO_CARDEMU,
91 RTL8723A_TRANS_CARDEMU_TO_PDN,
92 RTL8723A_TRANS_END
93};
94
95/*3 Enter LPS */
96struct wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS
97 + RTL8723A_TRANS_END_STPS] = {
98 /*FW behavior*/
99 RTL8723A_TRANS_ACT_TO_LPS,
100 RTL8723A_TRANS_END
101};
102
103/*3 Leave LPS */
104struct wlan_pwr_cfg rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STPS
105 + RTL8723A_TRANS_END_STPS] = {
106 /*FW behavior*/
107 RTL8723A_TRANS_LPS_TO_ACT,
108 RTL8723A_TRANS_END
109};
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h
new file mode 100644
index 00000000000..7a46f9fdf55
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h
@@ -0,0 +1,322 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL8723E_PWRSEQ_H__
31#define __RTL8723E_PWRSEQ_H__
32
33#include "pwrseqcmd.h"
34/*
35 Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd
36 There are 6 HW Power States:
37 0: POFF--Power Off
38 1: PDN--Power Down
39 2: CARDEMU--Card Emulation
40 3: ACT--Active Mode
41 4: LPS--Low Power State
42 5: SUS--Suspend
43
44 The transision from different states are defined below
45 TRANS_CARDEMU_TO_ACT
46 TRANS_ACT_TO_CARDEMU
47 TRANS_CARDEMU_TO_SUS
48 TRANS_SUS_TO_CARDEMU
49 TRANS_CARDEMU_TO_PDN
50 TRANS_ACT_TO_LPS
51 TRANS_LPS_TO_ACT
52
53 TRANS_END
54*/
55
56#define RTL8723A_TRANS_CARDEMU_TO_ACT_STPS 10
57#define RTL8723A_TRANS_ACT_TO_CARDEMU_STPS 10
58#define RTL8723A_TRANS_CARDEMU_TO_SUS_STPS 10
59#define RTL8723A_TRANS_SUS_TO_CARDEMU_STPS 10
60#define RTL8723A_TRANS_CARDEMU_TO_PDN_STPS 10
61#define RTL8723A_TRANS_PDN_TO_CARDEMU_STPS 10
62#define RTL8723A_TRANS_ACT_TO_LPS_STPS 15
63#define RTL8723A_TRANS_LPS_TO_ACT_STPS 15
64#define RTL8723A_TRANS_END_STPS 1
65
66
67#define RTL8723A_TRANS_CARDEMU_TO_ACT \
68 /* format */ \
69 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \
70 * comments here*/ \
71 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
72 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), 0}, \
73 /* disable SW LPS 0x04[10]=0*/ \
74 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
75 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
76 /* wait till 0x04[17] = 1 power ready*/ \
77 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
78 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
79 /* release WLON reset 0x04[16]=1*/ \
80 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
81 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \
82 /* disable HWPDN 0x04[15]=0*/ \
83 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
84 PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0}, \
85 /* disable WL suspend*/ \
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 /* polling until return 0*/ \
89 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
90 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0}
91
92#define RTL8723A_TRANS_ACT_TO_CARDEMU \
93 /* format */ \
94 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \
95 * comments here*/ \
96 {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
97 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, \
98 /*0x1F[7:0] = 0 turn off RF*/ \
99 {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
100 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \
101 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
102 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
103 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
104 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}
105
106#define RTL8723A_TRANS_CARDEMU_TO_SUS \
107 /* format */ \
108 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \
109 * comments here*/ \
110 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
111 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), \
112 (BIT(4)|BIT(3))}, \
113 /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \
114 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK | \
115 PWR_INTF_SDIO_MSK, \
116 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},\
117 /*0x04[12:11] = 2b'01 enable WL suspend*/ \
118 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
119 PWR_BASEADDR_MAC, \
120 PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4)}, \
121 /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \
122 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
123 PWR_BASEADDR_SDIO, \
124 PWR_CMD_WRITE, BIT(0), BIT(0)}, \
125 /*Set SDIO suspend local register*/ \
126 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
127 PWR_BASEADDR_SDIO, \
128 PWR_CMD_POLLING, BIT(1), 0} \
129 /*wait power state to suspend*/
130
131#define RTL8723A_TRANS_SUS_TO_CARDEMU \
132 /* format */ \
133 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
134 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
135 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \
136 /*Set SDIO suspend local register*/ \
137 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
138 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
139 /*wait power state to suspend*/ \
140 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
141 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0} \
142 /*0x04[12:11] = 2b'01enable WL suspend*/
143
144#define RTL8723A_TRANS_CARDEMU_TO_CARDDIS \
145 /* format */ \
146 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
147 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
148 PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
149 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},\
150 /*0x04[12:11] = 2b'01 enable WL suspend*/ \
151 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
152 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)}, \
153 /*0x04[10] = 1, enable SW LPS*/ \
154 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
155 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
156 /*Set SDIO suspend local register*/ \
157 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
158 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0} \
159 /*wait power state to suspend*/
160
161#define RTL8723A_TRANS_CARDDIS_TO_CARDEMU \
162 /* format */ \
163 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
164 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
165 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \
166 /*Set SDIO suspend local register*/ \
167 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
168 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
169 /*wait power state to suspend*/ \
170 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
171 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \
172 /*0x04[12:11] = 2b'00enable WL suspend*/ \
173 {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
174 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0} \
175 /*PCIe DMA start*/
176
177#define RTL8723A_TRANS_CARDEMU_TO_PDN \
178 /* format */ \
179 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
180 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
181 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
182 /* 0x04[16] = 0*/\
183 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
184 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)} \
185 /* 0x04[15] = 1*/
186
187#define RTL8723A_TRANS_PDN_TO_CARDEMU \
188 /* format */ \
189 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
190 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
191 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0} \
192 /* 0x04[15] = 0*/
193
194#define RTL8723A_TRANS_ACT_TO_LPS \
195 /* format */ \
196 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
197 {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
198 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
199 /*PCIe DMA stop*/ \
200 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
201 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F}, \
202 /*Tx Pause*/ \
203 {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
204 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
205 /*Should be zero if no packet is transmitting*/ \
206 {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
207 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
208 /*Should be zero if no packet is transmitting*/ \
209 {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
210 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
211 /*Should be zero if no packet is transmitting*/ \
212 {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
213 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
214 /*Should be zero if no packet is transmitting*/ \
215 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
216 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
217 /*CCK and OFDM are disabled,and clock are gated*/ \
218 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
219 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, \
220 /*Delay 1us*/ \
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 /*Whole BB is reset*/ \
224 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
225 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F}, \
226 /*Reset MAC TRX*/ \
227 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
228 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
229 /*check if removed later*/ \
230 {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
231 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)} \
232 /*Respond TxOK to scheduler*/
233
234#define RTL8723A_TRANS_LPS_TO_ACT \
235 /* format */ \
236 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
237 {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
238 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, \
239 /*SDIO RPWM*/ \
240 {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
241 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \
242 /*USB RPWM*/ \
243 {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
244 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \
245 /*PCIe RPWM*/ \
246 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
247 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, \
248 /*Delay*/ \
249 {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
250 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
251 /* 0x08[4] = 0 switch TSF to 40M*/ \
252 {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
253 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, \
254 /*Polling 0x109[7]=0 TSF in 40M*/ \
255 {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
256 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, \
257 /*. 0x29[7:6] = 2b'00 enable BB clock*/ \
258 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
259 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
260 /*. 0x101[1] = 1*/ \
261 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
262 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
263 /* 0x100[7:0] = 0xFF enable WMAC TRX*/ \
264 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
265 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), \
266 BIT(1)|BIT(0)}, \
267 /* 0x02[1:0] = 2b'11 enable BB macro*/ \
268 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
269 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0} \
270 /*. 0x522 = 0*/
271
272#define RTL8723A_TRANS_END \
273 /* format */ \
274 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
275 {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
276 0, PWR_CMD_END, 0, 0}
277
278extern struct
279wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS
280 + RTL8723A_TRANS_END_STPS];
281extern struct
282wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
283 + RTL8723A_TRANS_END_STPS];
284extern struct
285wlan_pwr_cfg rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
286 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
287 + RTL8723A_TRANS_END_STPS];
288extern struct
289wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
290 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
291 + RTL8723A_TRANS_END_STPS];
292extern struct
293wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
294 + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS
295 + RTL8723A_TRANS_END_STPS];
296extern struct
297wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
298 + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS
299 + RTL8723A_TRANS_END_STPS];
300extern struct
301wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS
302 + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS
303 + RTL8723A_TRANS_END_STPS];
304extern struct
305wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS
306 + RTL8723A_TRANS_END_STPS];
307extern struct
308wlan_pwr_cfg rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STPS
309 + RTL8723A_TRANS_END_STPS];
310
311/* RTL8723 Power Configuration CMDs for PCIe interface */
312#define Rtl8723_NIC_PWR_ON_FLOW rtl8723A_power_on_flow
313#define Rtl8723_NIC_RF_OFF_FLOW rtl8723A_radio_off_flow
314#define Rtl8723_NIC_DISABLE_FLOW rtl8723A_card_disable_flow
315#define Rtl8723_NIC_ENABLE_FLOW rtl8723A_card_enable_flow
316#define Rtl8723_NIC_SUSPEND_FLOW rtl8723A_suspend_flow
317#define Rtl8723_NIC_RESUME_FLOW rtl8723A_resume_flow
318#define Rtl8723_NIC_PDN_FLOW rtl8723A_hwpdn_flow
319#define Rtl8723_NIC_LPS_ENTER_FLOW rtl8723A_enter_lps_flow
320#define Rtl8723_NIC_LPS_LEAVE_FLOW rtl8723A_leave_lps_flow
321
322#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c
new file mode 100644
index 00000000000..2044b5936b7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c
@@ -0,0 +1,129 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "pwrseq.h"
31
32/* Description:
33 * This routine deals with the Power Configuration CMD
34 * parsing for RTL8723/RTL8188E Series IC.
35 * Assumption:
36 * We should follow specific format that was released from HW SD.
37 */
38bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
39 u8 faversion, u8 interface_type,
40 struct wlan_pwr_cfg pwrcfgcmd[])
41{
42 struct wlan_pwr_cfg cfg_cmd = {0};
43 bool polling_bit = false;
44 u32 ary_idx = 0;
45 u8 value = 0;
46 u32 offset = 0;
47 u32 polling_count = 0;
48 u32 max_polling_cnt = 5000;
49
50 do {
51 cfg_cmd = pwrcfgcmd[ary_idx];
52 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
53 "rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x),"
54 "interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n",
55 GET_PWR_CFG_OFFSET(cfg_cmd),
56 GET_PWR_CFG_CUT_MASK(cfg_cmd),
57 GET_PWR_CFG_FAB_MASK(cfg_cmd),
58 GET_PWR_CFG_INTF_MASK(cfg_cmd),
59 GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd),
60 GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd));
61
62 if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) &&
63 (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) &&
64 (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) {
65 switch (GET_PWR_CFG_CMD(cfg_cmd)) {
66 case PWR_CMD_READ:
67 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
68 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n");
69 break;
70 case PWR_CMD_WRITE:
71 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
72 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n");
73 offset = GET_PWR_CFG_OFFSET(cfg_cmd);
74
75 /*Read the value from system register*/
76 value = rtl_read_byte(rtlpriv, offset);
77 value &= (~(GET_PWR_CFG_MASK(cfg_cmd)));
78 value |= (GET_PWR_CFG_VALUE(cfg_cmd) &
79 GET_PWR_CFG_MASK(cfg_cmd));
80
81 /*Write the value back to sytem register*/
82 rtl_write_byte(rtlpriv, offset, value);
83 break;
84 case PWR_CMD_POLLING:
85 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
86 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n");
87 polling_bit = false;
88 offset = GET_PWR_CFG_OFFSET(cfg_cmd);
89
90 do {
91 value = rtl_read_byte(rtlpriv, offset);
92
93 value &= GET_PWR_CFG_MASK(cfg_cmd);
94 if (value ==
95 (GET_PWR_CFG_VALUE(cfg_cmd)
96 & GET_PWR_CFG_MASK(cfg_cmd)))
97 polling_bit = true;
98 else
99 udelay(10);
100
101 if (polling_count++ > max_polling_cnt)
102 return false;
103 } while (!polling_bit);
104 break;
105 case PWR_CMD_DELAY:
106 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
107 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n");
108 if (GET_PWR_CFG_VALUE(cfg_cmd) ==
109 PWRSEQ_DELAY_US)
110 udelay(GET_PWR_CFG_OFFSET(cfg_cmd));
111 else
112 mdelay(GET_PWR_CFG_OFFSET(cfg_cmd));
113 break;
114 case PWR_CMD_END:
115 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
116 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n");
117 return true;
118 default:
119 RT_ASSERT(false,
120 "rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n");
121 break;
122 }
123
124 }
125 ary_idx++;
126 } while (1);
127
128 return true;
129}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h
new file mode 100644
index 00000000000..6e0f3ea37ec
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h
@@ -0,0 +1,98 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL8723E_PWRSEQCMD_H__
31#define __RTL8723E_PWRSEQCMD_H__
32
33#include "../wifi.h"
34/*---------------------------------------------
35 * 3 The value of cmd: 4 bits
36 *---------------------------------------------
37 */
38#define PWR_CMD_READ 0x00
39#define PWR_CMD_WRITE 0x01
40#define PWR_CMD_POLLING 0x02
41#define PWR_CMD_DELAY 0x03
42#define PWR_CMD_END 0x04
43
44/* define the base address of each block */
45#define PWR_BASEADDR_MAC 0x00
46#define PWR_BASEADDR_USB 0x01
47#define PWR_BASEADDR_PCIE 0x02
48#define PWR_BASEADDR_SDIO 0x03
49
50#define PWR_INTF_SDIO_MSK BIT(0)
51#define PWR_INTF_USB_MSK BIT(1)
52#define PWR_INTF_PCI_MSK BIT(2)
53#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
54
55#define PWR_FAB_TSMC_MSK BIT(0)
56#define PWR_FAB_UMC_MSK BIT(1)
57#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
58
59#define PWR_CUT_TESTCHIP_MSK BIT(0)
60#define PWR_CUT_A_MSK BIT(1)
61#define PWR_CUT_B_MSK BIT(2)
62#define PWR_CUT_C_MSK BIT(3)
63#define PWR_CUT_D_MSK BIT(4)
64#define PWR_CUT_E_MSK BIT(5)
65#define PWR_CUT_F_MSK BIT(6)
66#define PWR_CUT_G_MSK BIT(7)
67#define PWR_CUT_ALL_MSK 0xFF
68
69enum pwrseq_delay_unit {
70 PWRSEQ_DELAY_US,
71 PWRSEQ_DELAY_MS,
72};
73
74struct wlan_pwr_cfg {
75 u16 offset;
76 u8 cut_msk;
77 u8 fab_msk:4;
78 u8 interface_msk:4;
79 u8 base:4;
80 u8 cmd:4;
81 u8 msk;
82 u8 value;
83};
84
85#define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset)
86#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk)
87#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk)
88#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk)
89#define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base)
90#define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd)
91#define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk)
92#define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value)
93
94bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
95 u8 fab_version, u8 interface_type,
96 struct wlan_pwr_cfg pwrcfgcmd[]);
97
98#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
new file mode 100644
index 00000000000..199da366c6d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
@@ -0,0 +1,2097 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL8723E_REG_H__
31#define __RTL8723E_REG_H__
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#define REG_AFE_PLL_CTRL 0x0028
50#define REG_EFUSE_CTRL 0x0030
51#define REG_EFUSE_TEST 0x0034
52#define REG_PWR_DATA 0x0038
53#define REG_CAL_TIMER 0x003C
54#define REG_ACLK_MON 0x003E
55#define REG_GPIO_MUXCFG 0x0040
56#define REG_GPIO_IO_SEL 0x0042
57#define REG_MAC_PINMUX_CFG 0x0043
58#define REG_GPIO_PIN_CTRL 0x0044
59#define REG_GPIO_INTM 0x0048
60#define REG_LEDCFG0 0x004C
61#define REG_LEDCFG1 0x004D
62#define REG_LEDCFG2 0x004E
63#define REG_LEDCFG3 0x004F
64#define REG_FSIMR 0x0050
65#define REG_FSISR 0x0054
66#define REG_GPIO_PIN_CTRL_2 0x0060
67#define REG_GPIO_IO_SEL_2 0x0062
68#define REG_MULTI_FUNC_CTRL 0x0068
69
70#define REG_MCUFWDL 0x0080
71
72#define REG_HMEBOX_EXT_0 0x0088
73#define REG_HMEBOX_EXT_1 0x008A
74#define REG_HMEBOX_EXT_2 0x008C
75#define REG_HMEBOX_EXT_3 0x008E
76
77#define REG_BIST_SCAN 0x00D0
78#define REG_BIST_RPT 0x00D4
79#define REG_BIST_ROM_RPT 0x00D8
80#define REG_USB_SIE_INTF 0x00E0
81#define REG_PCIE_MIO_INTF 0x00E4
82#define REG_PCIE_MIO_INTD 0x00E8
83#define REG_SYS_CFG 0x00F0
84#define REG_GPIO_OUTSTS 0x00F4
85
86#define REG_CR 0x0100
87#define REG_PBP 0x0104
88#define REG_TRXDMA_CTRL 0x010C
89#define REG_TRXFF_BNDY 0x0114
90#define REG_TRXFF_STATUS 0x0118
91#define REG_RXFF_PTR 0x011C
92#define REG_HIMR 0x0120
93#define REG_HISR 0x0124
94#define REG_HIMRE 0x0128
95#define REG_HISRE 0x012C
96#define REG_CPWM 0x012F
97#define REG_FWIMR 0x0130
98#define REG_FWISR 0x0134
99#define REG_PKTBUF_DBG_CTRL 0x0140
100#define REG_PKTBUF_DBG_DATA_L 0x0144
101#define REG_PKTBUF_DBG_DATA_H 0x0148
102
103#define REG_TC0_CTRL 0x0150
104#define REG_TC1_CTRL 0x0154
105#define REG_TC2_CTRL 0x0158
106#define REG_TC3_CTRL 0x015C
107#define REG_TC4_CTRL 0x0160
108#define REG_TCUNIT_BASE 0x0164
109#define REG_MBIST_START 0x0174
110#define REG_MBIST_DONE 0x0178
111#define REG_MBIST_FAIL 0x017C
112#define REG_C2HEVT_MSG_NORMAL 0x01A0
113#define REG_C2HEVT_MSG_TEST 0x01B8
114#define REG_MCUTST_1 0x01c0
115#define REG_FMETHR 0x01C8
116#define REG_HMETFR 0x01CC
117#define REG_HMEBOX_0 0x01D0
118#define REG_HMEBOX_1 0x01D4
119#define REG_HMEBOX_2 0x01D8
120#define REG_HMEBOX_3 0x01DC
121
122#define REG_LLT_INIT 0x01E0
123#define REG_BB_ACCEESS_CTRL 0x01E8
124#define REG_BB_ACCESS_DATA 0x01EC
125
126#define REG_RQPN 0x0200
127#define REG_FIFOPAGE 0x0204
128#define REG_TDECTRL 0x0208
129#define REG_TXDMA_OFFSET_CHK 0x020C
130#define REG_TXDMA_STATUS 0x0210
131#define REG_RQPN_NPQ 0x0214
132
133#define REG_RXDMA_AGG_PG_TH 0x0280
134#define REG_RXPKT_NUM 0x0284
135#define REG_RXDMA_STATUS 0x0288
136
137#define REG_PCIE_CTRL_REG 0x0300
138#define REG_INT_MIG 0x0304
139#define REG_BCNQ_DESA 0x0308
140#define REG_HQ_DESA 0x0310
141#define REG_MGQ_DESA 0x0318
142#define REG_VOQ_DESA 0x0320
143#define REG_VIQ_DESA 0x0328
144#define REG_BEQ_DESA 0x0330
145#define REG_BKQ_DESA 0x0338
146#define REG_RX_DESA 0x0340
147#define REG_DBI 0x0348
148#define REG_MDIO 0x0354
149#define REG_DBG_SEL 0x0360
150#define REG_PCIE_HRPWM 0x0361
151#define REG_PCIE_HCPWM 0x0363
152#define REG_UART_CTRL 0x0364
153#define REG_UART_TX_DESA 0x0370
154#define REG_UART_RX_DESA 0x0378
155
156#define REG_HDAQ_DESA_NODEF 0x0000
157#define REG_CMDQ_DESA_NODEF 0x0000
158
159#define REG_VOQ_INFORMATION 0x0400
160#define REG_VIQ_INFORMATION 0x0404
161#define REG_BEQ_INFORMATION 0x0408
162#define REG_BKQ_INFORMATION 0x040C
163#define REG_MGQ_INFORMATION 0x0410
164#define REG_HGQ_INFORMATION 0x0414
165#define REG_BCNQ_INFORMATION 0x0418
166
167#define REG_CPU_MGQ_INFORMATION 0x041C
168#define REG_FWHW_TXQ_CTRL 0x0420
169#define REG_HWSEQ_CTRL 0x0423
170#define REG_TXPKTBUF_BCNQ_BDNY 0x0424
171#define REG_TXPKTBUF_MGQ_BDNY 0x0425
172#define REG_MULTI_BCNQ_EN 0x0426
173#define REG_MULTI_BCNQ_OFFSET 0x0427
174#define REG_SPEC_SIFS 0x0428
175#define REG_RL 0x042A
176#define REG_DARFRC 0x0430
177#define REG_RARFRC 0x0438
178#define REG_RRSR 0x0440
179#define REG_ARFR0 0x0444
180#define REG_ARFR1 0x0448
181#define REG_ARFR2 0x044C
182#define REG_ARFR3 0x0450
183#define REG_AGGLEN_LMT 0x0458
184#define REG_AMPDU_MIN_SPACE 0x045C
185#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D
186#define REG_FAST_EDCA_CTRL 0x0460
187#define REG_RD_RESP_PKT_TH 0x0463
188#define REG_INIRTS_RATE_SEL 0x0480
189#define REG_INIDATA_RATE_SEL 0x0484
190#define REG_POWER_STATUS 0x04A4
191#define REG_POWER_STAGE1 0x04B4
192#define REG_POWER_STAGE2 0x04B8
193#define REG_PKT_LIFE_TIME 0x04C0
194#define REG_STBC_SETTING 0x04C4
195#define REG_PROT_MODE_CTRL 0x04C8
196#define REG_BAR_MODE_CTRL 0x04CC
197#define REG_RA_TRY_RATE_AGG_LMT 0x04CF
198#define REG_NQOS_SEQ 0x04DC
199#define REG_QOS_SEQ 0x04DE
200#define REG_NEED_CPU_HANDLE 0x04E0
201#define REG_PKT_LOSE_RPT 0x04E1
202#define REG_PTCL_ERR_STATUS 0x04E2
203#define REG_DUMMY 0x04FC
204
205#define REG_EDCA_VO_PARAM 0x0500
206#define REG_EDCA_VI_PARAM 0x0504
207#define REG_EDCA_BE_PARAM 0x0508
208#define REG_EDCA_BK_PARAM 0x050C
209#define REG_BCNTCFG 0x0510
210#define REG_PIFS 0x0512
211#define REG_RDG_PIFS 0x0513
212#define REG_SIFS_CTX 0x0514
213#define REG_SIFS_TRX 0x0516
214#define REG_AGGR_BREAK_TIME 0x051A
215#define REG_SLOT 0x051B
216#define REG_TX_PTCL_CTRL 0x0520
217#define REG_TXPAUSE 0x0522
218#define REG_DIS_TXREQ_CLR 0x0523
219#define REG_RD_CTRL 0x0524
220#define REG_TBTT_PROHIBIT 0x0540
221#define REG_RD_NAV_NXT 0x0544
222#define REG_NAV_PROT_LEN 0x0546
223#define REG_BCN_CTRL 0x0550
224#define REG_USTIME_TSF 0x0551
225#define REG_MBID_NUM 0x0552
226#define REG_DUAL_TSF_RST 0x0553
227#define REG_BCN_INTERVAL 0x0554
228#define REG_MBSSID_BCN_SPACE 0x0554
229#define REG_DRVERLYINT 0x0558
230#define REG_BCNDMATIM 0x0559
231#define REG_ATIMWND 0x055A
232#define REG_BCN_MAX_ERR 0x055D
233#define REG_RXTSF_OFFSET_CCK 0x055E
234#define REG_RXTSF_OFFSET_OFDM 0x055F
235#define REG_TSFTR 0x0560
236#define REG_INIT_TSFTR 0x0564
237#define REG_PSTIMER 0x0580
238#define REG_TIMER0 0x0584
239#define REG_TIMER1 0x0588
240#define REG_ACMHWCTRL 0x05C0
241#define REG_ACMRSTCTRL 0x05C1
242#define REG_ACMAVG 0x05C2
243#define REG_VO_ADMTIME 0x05C4
244#define REG_VI_ADMTIME 0x05C6
245#define REG_BE_ADMTIME 0x05C8
246#define REG_EDCA_RANDOM_GEN 0x05CC
247#define REG_SCH_TXCMD 0x05D0
248
249#define REG_APSD_CTRL 0x0600
250#define REG_BWOPMODE 0x0603
251#define REG_TCR 0x0604
252#define REG_RCR 0x0608
253#define REG_RX_PKT_LIMIT 0x060C
254#define REG_RX_DLK_TIME 0x060D
255#define REG_RX_DRVINFO_SZ 0x060F
256
257#define REG_MACID 0x0610
258#define REG_BSSID 0x0618
259#define REG_MAR 0x0620
260#define REG_MBIDCAMCFG 0x0628
261
262#define REG_USTIME_EDCA 0x0638
263#define REG_MAC_SPEC_SIFS 0x063A
264#define REG_RESP_SIFS_CCK 0x063C
265#define REG_RESP_SIFS_OFDM 0x063E
266#define REG_ACKTO 0x0640
267#define REG_CTS2TO 0x0641
268#define REG_EIFS 0x0642
269
270#define REG_NAV_CTRL 0x0650
271#define REG_BACAMCMD 0x0654
272#define REG_BACAMCONTENT 0x0658
273#define REG_LBDLY 0x0660
274#define REG_FWDLY 0x0661
275#define REG_RXERR_RPT 0x0664
276#define REG_WMAC_TRXPTCL_CTL 0x0668
277
278#define REG_CAMCMD 0x0670
279#define REG_CAMWRITE 0x0674
280#define REG_CAMREAD 0x0678
281#define REG_CAMDBG 0x067C
282#define REG_SECCFG 0x0680
283
284#define REG_WOW_CTRL 0x0690
285#define REG_PSSTATUS 0x0691
286#define REG_PS_RX_INFO 0x0692
287#define REG_LPNAV_CTRL 0x0694
288#define REG_WKFMCAM_CMD 0x0698
289#define REG_WKFMCAM_RWD 0x069C
290#define REG_RXFLTMAP0 0x06A0
291#define REG_RXFLTMAP1 0x06A2
292#define REG_RXFLTMAP2 0x06A4
293#define REG_BCN_PSR_RPT 0x06A8
294#define REG_CALB32K_CTRL 0x06AC
295#define REG_PKT_MON_CTRL 0x06B4
296#define REG_BT_COEX_TABLE 0x06C0
297#define REG_WMAC_RESP_TXINFO 0x06D8
298
299#define REG_USB_INFO 0xFE17
300#define REG_USB_SPECIAL_OPTION 0xFE55
301#define REG_USB_DMA_AGG_TO 0xFE5B
302#define REG_USB_AGG_TO 0xFE5C
303#define REG_USB_AGG_TH 0xFE5D
304
305#define REG_TEST_USB_TXQS 0xFE48
306#define REG_TEST_SIE_VID 0xFE60
307#define REG_TEST_SIE_PID 0xFE62
308#define REG_TEST_SIE_OPTIONAL 0xFE64
309#define REG_TEST_SIE_CHIRP_K 0xFE65
310#define REG_TEST_SIE_PHY 0xFE66
311#define REG_TEST_SIE_MAC_ADDR 0xFE70
312#define REG_TEST_SIE_STRING 0xFE80
313
314#define REG_NORMAL_SIE_VID 0xFE60
315#define REG_NORMAL_SIE_PID 0xFE62
316#define REG_NORMAL_SIE_OPTIONAL 0xFE64
317#define REG_NORMAL_SIE_EP 0xFE65
318#define REG_NORMAL_SIE_PHY 0xFE68
319#define REG_NORMAL_SIE_MAC_ADDR 0xFE70
320#define REG_NORMAL_SIE_STRING 0xFE80
321
322#define CR9346 REG_9346CR
323#define MSR (REG_CR + 2)
324#define ISR REG_HISR
325#define TSFR REG_TSFTR
326
327#define MACIDR0 REG_MACID
328#define MACIDR4 (REG_MACID + 4)
329
330#define PBP REG_PBP
331
332#define IDR0 MACIDR0
333#define IDR4 MACIDR4
334
335#define UNUSED_REGISTER 0x1BF
336#define DCAM UNUSED_REGISTER
337#define PSR UNUSED_REGISTER
338#define BBADDR UNUSED_REGISTER
339#define PHYDATAR UNUSED_REGISTER
340
341#define INVALID_BBRF_VALUE 0x12345678
342
343#define MAX_MSS_DENSITY_2T 0x13
344#define MAX_MSS_DENSITY_1T 0x0A
345
346#define CMDEEPROM_EN BIT(5)
347#define CMDEEPROM_SEL BIT(4)
348#define CMD9346CR_9356SEL BIT(4)
349#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL)
350#define AUTOLOAD_EFUSE CMDEEPROM_EN
351
352#define GPIOSEL_GPIO 0
353#define GPIOSEL_ENBT BIT(5)
354
355#define GPIO_IN REG_GPIO_PIN_CTRL
356#define GPIO_OUT (REG_GPIO_PIN_CTRL+1)
357#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2)
358#define GPIO_MOD (REG_GPIO_PIN_CTRL+3)
359
360#define MSR_NOLINK 0x00
361#define MSR_ADHOC 0x01
362#define MSR_INFRA 0x02
363#define MSR_AP 0x03
364
365#define RRSR_RSC_OFFSET 21
366#define RRSR_SHORT_OFFSET 23
367#define RRSR_RSC_BW_40M 0x600000
368#define RRSR_RSC_UPSUBCHNL 0x400000
369#define RRSR_RSC_LOWSUBCHNL 0x200000
370#define RRSR_SHORT 0x800000
371#define RRSR_1M BIT(0)
372#define RRSR_2M BIT(1)
373#define RRSR_5_5M BIT(2)
374#define RRSR_11M BIT(3)
375#define RRSR_6M BIT(4)
376#define RRSR_9M BIT(5)
377#define RRSR_12M BIT(6)
378#define RRSR_18M BIT(7)
379#define RRSR_24M BIT(8)
380#define RRSR_36M BIT(9)
381#define RRSR_48M BIT(10)
382#define RRSR_54M BIT(11)
383#define RRSR_MCS0 BIT(12)
384#define RRSR_MCS1 BIT(13)
385#define RRSR_MCS2 BIT(14)
386#define RRSR_MCS3 BIT(15)
387#define RRSR_MCS4 BIT(16)
388#define RRSR_MCS5 BIT(17)
389#define RRSR_MCS6 BIT(18)
390#define RRSR_MCS7 BIT(19)
391#define BRSR_ACKSHORTPMB BIT(23)
392
393#define RATR_1M 0x00000001
394#define RATR_2M 0x00000002
395#define RATR_55M 0x00000004
396#define RATR_11M 0x00000008
397#define RATR_6M 0x00000010
398#define RATR_9M 0x00000020
399#define RATR_12M 0x00000040
400#define RATR_18M 0x00000080
401#define RATR_24M 0x00000100
402#define RATR_36M 0x00000200
403#define RATR_48M 0x00000400
404#define RATR_54M 0x00000800
405#define RATR_MCS0 0x00001000
406#define RATR_MCS1 0x00002000
407#define RATR_MCS2 0x00004000
408#define RATR_MCS3 0x00008000
409#define RATR_MCS4 0x00010000
410#define RATR_MCS5 0x00020000
411#define RATR_MCS6 0x00040000
412#define RATR_MCS7 0x00080000
413#define RATR_MCS8 0x00100000
414#define RATR_MCS9 0x00200000
415#define RATR_MCS10 0x00400000
416#define RATR_MCS11 0x00800000
417#define RATR_MCS12 0x01000000
418#define RATR_MCS13 0x02000000
419#define RATR_MCS14 0x04000000
420#define RATR_MCS15 0x08000000
421
422#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
423#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\
424 RATR_24M | RATR_36M | RATR_48M | RATR_54M)
425#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\
426 RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\
427 RATR_MCS6 | RATR_MCS7)
428#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\
429 RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\
430 RATR_MCS14 | RATR_MCS15)
431
432#define BW_OPMODE_20MHZ BIT(2)
433#define BW_OPMODE_5G BIT(1)
434#define BW_OPMODE_11J BIT(0)
435
436#define CAM_VALID BIT(15)
437#define CAM_NOTVALID 0x0000
438#define CAM_USEDK BIT(5)
439
440#define CAM_NONE 0x0
441#define CAM_WEP40 0x01
442#define CAM_TKIP 0x02
443#define CAM_AES 0x04
444#define CAM_WEP104 0x05
445
446#define TOTAL_CAM_ENTRY 32
447#define HALF_CAM_ENTRY 16
448
449#define CAM_WRITE BIT(16)
450#define CAM_READ 0x00000000
451#define CAM_POLLINIG BIT(31)
452
453#define SCR_USEDK 0x01
454#define SCR_TXSEC_ENABLE 0x02
455#define SCR_RXSEC_ENABLE 0x04
456
457#define WOW_PMEN BIT(0)
458#define WOW_WOMEN BIT(1)
459#define WOW_MAGIC BIT(2)
460#define WOW_UWF BIT(3)
461
462#define IMR8190_DISABLED 0x0
463#define IMR_BCNDMAINT6 BIT(31)
464#define IMR_BCNDMAINT5 BIT(30)
465#define IMR_BCNDMAINT4 BIT(29)
466#define IMR_BCNDMAINT3 BIT(28)
467#define IMR_BCNDMAINT2 BIT(27)
468#define IMR_BCNDMAINT1 BIT(26)
469#define IMR_BCNDOK8 BIT(25)
470#define IMR_BCNDOK7 BIT(24)
471#define IMR_BCNDOK6 BIT(23)
472#define IMR_BCNDOK5 BIT(22)
473#define IMR_BCNDOK4 BIT(21)
474#define IMR_BCNDOK3 BIT(20)
475#define IMR_BCNDOK2 BIT(19)
476#define IMR_BCNDOK1 BIT(18)
477#define IMR_TIMEOUT2 BIT(17)
478#define IMR_TIMEOUT1 BIT(16)
479#define IMR_TXFOVW BIT(15)
480#define IMR_PSTIMEOUT BIT(14)
481#define IMR_BCNINT BIT(13)
482#define IMR_RXFOVW BIT(12)
483#define IMR_RDU BIT(11)
484#define IMR_ATIMEND BIT(10)
485#define IMR_BDOK BIT(9)
486#define IMR_HIGHDOK BIT(8)
487#define IMR_TBDOK BIT(7)
488#define IMR_MGNTDOK BIT(6)
489#define IMR_TBDER BIT(5)
490#define IMR_BKDOK BIT(4)
491#define IMR_BEDOK BIT(3)
492#define IMR_VIDOK BIT(2)
493#define IMR_VODOK BIT(1)
494#define IMR_ROK BIT(0)
495
496#define IMR_TXERR BIT(11)
497#define IMR_RXERR BIT(10)
498#define IMR_CPWM BIT(8)
499#define IMR_OCPINT BIT(1)
500#define IMR_WLANOFF BIT(0)
501
502/* 8723E series PCIE Host IMR/ISR bit */
503/* IMR DW0 Bit 0-31 */
504#define PHIMR_TIMEOUT2 BIT(31)
505#define PHIMR_TIMEOUT1 BIT(30)
506#define PHIMR_PSTIMEOUT BIT(29)
507#define PHIMR_GTINT4 BIT(28)
508#define PHIMR_GTINT3 BIT(27)
509#define PHIMR_TXBCNERR BIT(26)
510#define PHIMR_TXBCNOK BIT(25)
511#define PHIMR_TSF_BIT32_TOGGLE BIT(24)
512#define PHIMR_BCNDMAINT3 BIT(23)
513#define PHIMR_BCNDMAINT2 BIT(22)
514#define PHIMR_BCNDMAINT1 BIT(21)
515#define PHIMR_BCNDMAINT0 BIT(20)
516#define PHIMR_BCNDOK3 BIT(19)
517#define PHIMR_BCNDOK2 BIT(18)
518#define PHIMR_BCNDOK1 BIT(17)
519#define PHIMR_BCNDOK0 BIT(16)
520#define PHIMR_HSISR_IND_ON BIT(15)
521#define PHIMR_BCNDMAINT_E BIT(14)
522#define PHIMR_ATIMEND_E BIT(13)
523#define PHIMR_ATIM_CTW_END BIT(12)
524#define PHIMR_HISRE_IND BIT(11)
525#define PHIMR_C2HCMD BIT(10)
526#define PHIMR_CPWM2 BIT(9)
527#define PHIMR_CPWM BIT(8)
528#define PHIMR_HIGHDOK BIT(7)
529#define PHIMR_MGNTDOK BIT(6)
530#define PHIMR_BKDOK BIT(5)
531#define PHIMR_BEDOK BIT(4)
532#define PHIMR_VIDOK BIT(3)
533#define PHIMR_VODOK BIT(2)
534#define PHIMR_RDU BIT(1)
535#define PHIMR_ROK BIT(0)
536
537/* PCIE Host Interrupt Status Extension bit */
538#define PHIMR_BCNDMAINT7 BIT(23)
539#define PHIMR_BCNDMAINT6 BIT(22)
540#define PHIMR_BCNDMAINT5 BIT(21)
541#define PHIMR_BCNDMAINT4 BIT(20)
542#define PHIMR_BCNDOK7 BIT(19)
543#define PHIMR_BCNDOK6 BIT(18)
544#define PHIMR_BCNDOK5 BIT(17)
545#define PHIMR_BCNDOK4 BIT(16)
546/* bit12-15: RSVD */
547#define PHIMR_TXERR BIT(11)
548#define PHIMR_RXERR BIT(10)
549#define PHIMR_TXFOVW BIT(9)
550#define PHIMR_RXFOVW BIT(8)
551/* bit2-7: RSV */
552#define PHIMR_OCPINT BIT(1)
553
554#define HWSET_MAX_SIZE 256
555#define EFUSE_MAX_SECTION 32
556#define EFUSE_REAL_CONTENT_LEN 512
557#define EFUSE_OOB_PROTECT_BYTES 15
558
559#define EEPROM_DEFAULT_TSSI 0x0
560#define EEPROM_DEFAULT_TXPOWERDIFF 0x0
561#define EEPROM_DEFAULT_CRYSTALCAP 0x5
562#define EEPROM_DEFAULT_BOARDTYPE 0x02
563#define EEPROM_DEFAULT_TXPOWER 0x1010
564#define EEPROM_DEFAULT_HT2T_TXPWR 0x10
565
566#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
567#define EEPROM_DEFAULT_THERMALMETER 0x12
568#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0
569#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5
570#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22
571#define EEPROM_DEFAULT_HT40_2SDIFF 0x0
572#define EEPROM_DEFAULT_HT20_DIFF 2
573#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
574#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0
575#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0
576
577
578#define EEPROM_DEFAULT_PID 0x1234
579#define EEPROM_DEFAULT_VID 0x5678
580#define EEPROM_DEFAULT_CUSTOMERID 0xAB
581#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD
582#define EEPROM_DEFAULT_VERSION 0
583
584#define EEPROM_CHANNEL_PLAN_FCC 0x0
585#define EEPROM_CHANNEL_PLAN_IC 0x1
586#define EEPROM_CHANNEL_PLAN_ETSI 0x2
587#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
588#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
589#define EEPROM_CHANNEL_PLAN_MKK 0x5
590#define EEPROM_CHANNEL_PLAN_MKK1 0x6
591#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
592#define EEPROM_CHANNEL_PLAN_TELEC 0x8
593#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
594#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
595#define EEPROM_CHANNEL_PLAN_NCC 0xB
596#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
597
598#define EEPROM_CID_DEFAULT 0x0
599#define EEPROM_CID_TOSHIBA 0x4
600#define EEPROM_CID_CCX 0x10
601#define EEPROM_CID_QMI 0x0D
602#define EEPROM_CID_WHQL 0xFE
603
604#define RTL8192_EEPROM_ID 0x8129
605
606#define RTL8190_EEPROM_ID 0x8129
607#define EEPROM_HPON 0x02
608#define EEPROM_CLK 0x06
609#define EEPROM_TESTR 0x08
610
611#define EEPROM_VID 0x49
612#define EEPROM_DID 0x4B
613#define EEPROM_SVID 0x4D
614#define EEPROM_SMID 0x4F
615
616#define EEPROM_MAC_ADDR 0x67
617
618#define EEPROM_CCK_TX_PWR_INX 0x5A
619#define EEPROM_HT40_1S_TX_PWR_INX 0x60
620#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66
621#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69
622#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C
623#define EEPROM_HT40_MAX_PWR_OFFSET 0x25
624#define EEPROM_HT20_MAX_PWR_OFFSET 0x22
625
626#define EEPROM_THERMAL_METER 0x2a
627#define EEPROM_XTAL_K 0x78
628#define EEPROM_RF_OPT1 0x79
629#define EEPROM_RF_OPT2 0x7A
630#define EEPROM_RF_OPT3 0x7B
631#define EEPROM_RF_OPT4 0x7C
632#define EEPROM_CHANNEL_PLAN 0x28
633#define EEPROM_VERSION 0x30
634#define EEPROM_CUSTOMER_ID 0x31
635
636#define EEPROM_PWRDIFF 0x54
637
638#define EEPROM_TXPOWERCCK 0x10
639#define EEPROM_TXPOWERHT40_1S 0x16
640#define EEPROM_TXPOWERHT40_2SDIFF 0x66
641#define EEPROM_TXPOWERHT20DIFF 0x1C
642#define EEPROM_TXPOWER_OFDMDIFF 0x1F
643
644#define EEPROM_TXPWR_GROUP 0x22
645
646#define EEPROM_TSSI_A 0x29
647#define EEPROM_TSSI_B 0x77
648
649#define EEPROM_CHANNELPLAN 0x28
650
651#define RF_OPTION1 0x2B
652#define RF_OPTION2 0x2C
653#define RF_OPTION3 0x2D
654#define RF_OPTION4 0x2E
655
656#define STOPBECON BIT(6)
657#define STOPHIGHT BIT(5)
658#define STOPMGT BIT(4)
659#define STOPVO BIT(3)
660#define STOPVI BIT(2)
661#define STOPBE BIT(1)
662#define STOPBK BIT(0)
663
664#define RCR_APPFCS BIT(31)
665#define RCR_APP_MIC BIT(30)
666#define RCR_APP_ICV BIT(29)
667#define RCR_APP_PHYST_RXFF BIT(28)
668#define RCR_APP_BA_SSN BIT(27)
669#define RCR_ENMBID BIT(24)
670#define RCR_LSIGEN BIT(23)
671#define RCR_MFBEN BIT(22)
672#define RCR_HTC_LOC_CTRL BIT(14)
673#define RCR_AMF BIT(13)
674#define RCR_ACF BIT(12)
675#define RCR_ADF BIT(11)
676#define RCR_AICV BIT(9)
677#define RCR_ACRC32 BIT(8)
678#define RCR_CBSSID_BCN BIT(7)
679#define RCR_CBSSID_DATA BIT(6)
680#define RCR_CBSSID RCR_CBSSID_DATA
681#define RCR_APWRMGT BIT(5)
682#define RCR_ADD3 BIT(4)
683#define RCR_AB BIT(3)
684#define RCR_AM BIT(2)
685#define RCR_APM BIT(1)
686#define RCR_AAP BIT(0)
687#define RCR_MXDMA_OFFSET 8
688#define RCR_FIFO_OFFSET 13
689
690#define RSV_CTRL 0x001C
691#define RD_CTRL 0x0524
692
693#define REG_USB_INFO 0xFE17
694#define REG_USB_SPECIAL_OPTION 0xFE55
695#define REG_USB_DMA_AGG_TO 0xFE5B
696#define REG_USB_AGG_TO 0xFE5C
697#define REG_USB_AGG_TH 0xFE5D
698
699#define REG_USB_VID 0xFE60
700#define REG_USB_PID 0xFE62
701#define REG_USB_OPTIONAL 0xFE64
702#define REG_USB_CHIRP_K 0xFE65
703#define REG_USB_PHY 0xFE66
704#define REG_USB_MAC_ADDR 0xFE70
705#define REG_USB_HRPWM 0xFE58
706#define REG_USB_HCPWM 0xFE57
707
708#define SW18_FPWM BIT(3)
709
710#define ISO_MD2PP BIT(0)
711#define ISO_UA2USB BIT(1)
712#define ISO_UD2CORE BIT(2)
713#define ISO_PA2PCIE BIT(3)
714#define ISO_PD2CORE BIT(4)
715#define ISO_IP2MAC BIT(5)
716#define ISO_DIOP BIT(6)
717#define ISO_DIOE BIT(7)
718#define ISO_EB2CORE BIT(8)
719#define ISO_DIOR BIT(9)
720
721#define PWC_EV25V BIT(14)
722#define PWC_EV12V BIT(15)
723
724#define FEN_BBRSTB BIT(0)
725#define FEN_BB_GLB_RSTn BIT(1)
726#define FEN_USBA BIT(2)
727#define FEN_UPLL BIT(3)
728#define FEN_USBD BIT(4)
729#define FEN_DIO_PCIE BIT(5)
730#define FEN_PCIEA BIT(6)
731#define FEN_PPLL BIT(7)
732#define FEN_PCIED BIT(8)
733#define FEN_DIOE BIT(9)
734#define FEN_CPUEN BIT(10)
735#define FEN_DCORE BIT(11)
736#define FEN_ELDR BIT(12)
737#define FEN_DIO_RF BIT(13)
738#define FEN_HWPDN BIT(14)
739#define FEN_MREGEN BIT(15)
740
741#define PFM_LDALL BIT(0)
742#define PFM_ALDN BIT(1)
743#define PFM_LDKP BIT(2)
744#define PFM_WOWL BIT(3)
745#define EnPDN BIT(4)
746#define PDN_PL BIT(5)
747#define APFM_ONMAC BIT(8)
748#define APFM_OFF BIT(9)
749#define APFM_RSM BIT(10)
750#define AFSM_HSUS BIT(11)
751#define AFSM_PCIE BIT(12)
752#define APDM_MAC BIT(13)
753#define APDM_HOST BIT(14)
754#define APDM_HPDN BIT(15)
755#define RDY_MACON BIT(16)
756#define SUS_HOST BIT(17)
757#define ROP_ALD BIT(20)
758#define ROP_PWR BIT(21)
759#define ROP_SPS BIT(22)
760#define SOP_MRST BIT(25)
761#define SOP_FUSE BIT(26)
762#define SOP_ABG BIT(27)
763#define SOP_AMB BIT(28)
764#define SOP_RCK BIT(29)
765#define SOP_A8M BIT(30)
766#define XOP_BTCK BIT(31)
767
768#define ANAD16V_EN BIT(0)
769#define ANA8M BIT(1)
770#define MACSLP BIT(4)
771#define LOADER_CLK_EN BIT(5)
772#define _80M_SSC_DIS BIT(7)
773#define _80M_SSC_EN_HO BIT(8)
774#define PHY_SSC_RSTB BIT(9)
775#define SEC_CLK_EN BIT(10)
776#define MAC_CLK_EN BIT(11)
777#define SYS_CLK_EN BIT(12)
778#define RING_CLK_EN BIT(13)
779
780#define BOOT_FROM_EEPROM BIT(4)
781#define EEPROM_EN BIT(5)
782
783#define AFE_BGEN BIT(0)
784#define AFE_MBEN BIT(1)
785#define MAC_ID_EN BIT(7)
786
787#define WLOCK_ALL BIT(0)
788#define WLOCK_00 BIT(1)
789#define WLOCK_04 BIT(2)
790#define WLOCK_08 BIT(3)
791#define WLOCK_40 BIT(4)
792#define R_DIS_PRST_0 BIT(5)
793#define R_DIS_PRST_1 BIT(6)
794#define LOCK_ALL_EN BIT(7)
795
796#define RF_EN BIT(0)
797#define RF_RSTB BIT(1)
798#define RF_SDMRSTB BIT(2)
799
800#define LDA15_EN BIT(0)
801#define LDA15_STBY BIT(1)
802#define LDA15_OBUF BIT(2)
803#define LDA15_REG_VOS BIT(3)
804#define _LDA15_VOADJ(x) (((x) & 0x7) << 4)
805
806#define LDV12_EN BIT(0)
807#define LDV12_SDBY BIT(1)
808#define LPLDO_HSM BIT(2)
809#define LPLDO_LSM_DIS BIT(3)
810#define _LDV12_VADJ(x) (((x) & 0xF) << 4)
811
812#define XTAL_EN BIT(0)
813#define XTAL_BSEL BIT(1)
814#define _XTAL_BOSC(x) (((x) & 0x3) << 2)
815#define _XTAL_CADJ(x) (((x) & 0xF) << 4)
816#define XTAL_GATE_USB BIT(8)
817#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9)
818#define XTAL_GATE_AFE BIT(11)
819#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12)
820#define XTAL_RF_GATE BIT(14)
821#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15)
822#define XTAL_GATE_DIG BIT(17)
823#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18)
824#define XTAL_BT_GATE BIT(20)
825#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21)
826#define _XTAL_GPIO(x) (((x) & 0x7) << 23)
827
828#define CKDLY_AFE BIT(26)
829#define CKDLY_USB BIT(27)
830#define CKDLY_DIG BIT(28)
831#define CKDLY_BT BIT(29)
832
833#define APLL_EN BIT(0)
834#define APLL_320_EN BIT(1)
835#define APLL_FREF_SEL BIT(2)
836#define APLL_EDGE_SEL BIT(3)
837#define APLL_WDOGB BIT(4)
838#define APLL_LPFEN BIT(5)
839
840#define APLL_REF_CLK_13MHZ 0x1
841#define APLL_REF_CLK_19_2MHZ 0x2
842#define APLL_REF_CLK_20MHZ 0x3
843#define APLL_REF_CLK_25MHZ 0x4
844#define APLL_REF_CLK_26MHZ 0x5
845#define APLL_REF_CLK_38_4MHZ 0x6
846#define APLL_REF_CLK_40MHZ 0x7
847
848#define APLL_320EN BIT(14)
849#define APLL_80EN BIT(15)
850#define APLL_1MEN BIT(24)
851
852#define ALD_EN BIT(18)
853#define EF_PD BIT(19)
854#define EF_FLAG BIT(31)
855
856#define EF_TRPT BIT(7)
857#define LDOE25_EN BIT(31)
858
859#define RSM_EN BIT(0)
860#define Timer_EN BIT(4)
861
862#define TRSW0EN BIT(2)
863#define TRSW1EN BIT(3)
864#define EROM_EN BIT(4)
865#define EnBT BIT(5)
866#define EnUart BIT(8)
867#define Uart_910 BIT(9)
868#define EnPMAC BIT(10)
869#define SIC_SWRST BIT(11)
870#define EnSIC BIT(12)
871#define SIC_23 BIT(13)
872#define EnHDP BIT(14)
873#define SIC_LBK BIT(15)
874
875#define LED0PL BIT(4)
876#define LED1PL BIT(12)
877#define LED0DIS BIT(7)
878
879#define MCUFWDL_EN BIT(0)
880#define MCUFWDL_RDY BIT(1)
881#define FWDL_ChkSum_rpt BIT(2)
882#define MACINI_RDY BIT(3)
883#define BBINI_RDY BIT(4)
884#define RFINI_RDY BIT(5)
885#define WINTINI_RDY BIT(6)
886#define CPRST BIT(23)
887
888#define XCLK_VLD BIT(0)
889#define ACLK_VLD BIT(1)
890#define UCLK_VLD BIT(2)
891#define PCLK_VLD BIT(3)
892#define PCIRSTB BIT(4)
893#define V15_VLD BIT(5)
894#define TRP_B15V_EN BIT(7)
895#define SIC_IDLE BIT(8)
896#define BD_MAC2 BIT(9)
897#define BD_MAC1 BIT(10)
898#define IC_MACPHY_MODE BIT(11)
899#define BT_FUNC BIT(16)
900#define VENDOR_ID BIT(19)
901#define PAD_HWPD_IDN BIT(22)
902#define TRP_VAUX_EN BIT(23)
903#define TRP_BT_EN BIT(24)
904#define BD_PKG_SEL BIT(25)
905#define BD_HCI_SEL BIT(26)
906#define TYPE_ID BIT(27)
907
908#define CHIP_VER_RTL_MASK 0xF000
909#define CHIP_VER_RTL_SHIFT 12
910
911#define REG_LBMODE (REG_CR + 3)
912
913#define HCI_TXDMA_EN BIT(0)
914#define HCI_RXDMA_EN BIT(1)
915#define TXDMA_EN BIT(2)
916#define RXDMA_EN BIT(3)
917#define PROTOCOL_EN BIT(4)
918#define SCHEDULE_EN BIT(5)
919#define MACTXEN BIT(6)
920#define MACRXEN BIT(7)
921#define ENSWBCN BIT(8)
922#define ENSEC BIT(9)
923
924#define _NETTYPE(x) (((x) & 0x3) << 16)
925#define MASK_NETTYPE 0x30000
926#define NT_NO_LINK 0x0
927#define NT_LINK_AD_HOC 0x1
928#define NT_LINK_AP 0x2
929#define NT_AS_AP 0x3
930
931#define _LBMODE(x) (((x) & 0xF) << 24)
932#define MASK_LBMODE 0xF000000
933#define LOOPBACK_NORMAL 0x0
934#define LOOPBACK_IMMEDIATELY 0xB
935#define LOOPBACK_MAC_DELAY 0x3
936#define LOOPBACK_PHY 0x1
937#define LOOPBACK_DMA 0x7
938
939#define GET_RX_PAGE_SIZE(value) ((value) & 0xF)
940#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4)
941#define _PSRX_MASK 0xF
942#define _PSTX_MASK 0xF0
943#define _PSRX(x) (x)
944#define _PSTX(x) ((x) << 4)
945
946#define PBP_64 0x0
947#define PBP_128 0x1
948#define PBP_256 0x2
949#define PBP_512 0x3
950#define PBP_1024 0x4
951
952#define RXDMA_ARBBW_EN BIT(0)
953#define RXSHFT_EN BIT(1)
954#define RXDMA_AGG_EN BIT(2)
955#define QS_VO_QUEUE BIT(8)
956#define QS_VI_QUEUE BIT(9)
957#define QS_BE_QUEUE BIT(10)
958#define QS_BK_QUEUE BIT(11)
959#define QS_MANAGER_QUEUE BIT(12)
960#define QS_HIGH_QUEUE BIT(13)
961
962#define HQSEL_VOQ BIT(0)
963#define HQSEL_VIQ BIT(1)
964#define HQSEL_BEQ BIT(2)
965#define HQSEL_BKQ BIT(3)
966#define HQSEL_MGTQ BIT(4)
967#define HQSEL_HIQ BIT(5)
968
969#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14)
970#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12)
971#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10)
972#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8)
973#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6)
974#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4)
975
976#define QUEUE_LOW 1
977#define QUEUE_NORMAL 2
978#define QUEUE_HIGH 3
979
980#define _LLT_NO_ACTIVE 0x0
981#define _LLT_WRITE_ACCESS 0x1
982#define _LLT_READ_ACCESS 0x2
983
984#define _LLT_INIT_DATA(x) ((x) & 0xFF)
985#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8)
986#define _LLT_OP(x) (((x) & 0x3) << 30)
987#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3)
988
989#define BB_WRITE_READ_MASK (BIT(31) | BIT(30))
990#define BB_WRITE_EN BIT(30)
991#define BB_READ_EN BIT(31)
992
993#define _HPQ(x) ((x) & 0xFF)
994#define _LPQ(x) (((x) & 0xFF) << 8)
995#define _PUBQ(x) (((x) & 0xFF) << 16)
996#define _NPQ(x) ((x) & 0xFF)
997
998#define HPQ_PUBLIC_DIS BIT(24)
999#define LPQ_PUBLIC_DIS BIT(25)
1000#define LD_RQPN BIT(31)
1001
1002#define BCN_VALID BIT(16)
1003#define BCN_HEAD(x) (((x) & 0xFF) << 8)
1004#define BCN_HEAD_MASK 0xFF00
1005
1006#define BLK_DESC_NUM_SHIFT 4
1007#define BLK_DESC_NUM_MASK 0xF
1008
1009#define DROP_DATA_EN BIT(9)
1010
1011#define EN_AMPDU_RTY_NEW BIT(7)
1012
1013#define _INIRTSMCS_SEL(x) ((x) & 0x3F)
1014
1015#define _SPEC_SIFS_CCK(x) ((x) & 0xFF)
1016#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8)
1017
1018#define RATE_REG_BITMAP_ALL 0xFFFFF
1019
1020#define _RRSC_BITMAP(x) ((x) & 0xFFFFF)
1021
1022#define _RRSR_RSC(x) (((x) & 0x3) << 21)
1023#define RRSR_RSC_RESERVED 0x0
1024#define RRSR_RSC_UPPER_SUBCHANNEL 0x1
1025#define RRSR_RSC_LOWER_SUBCHANNEL 0x2
1026#define RRSR_RSC_DUPLICATE_MODE 0x3
1027
1028#define USE_SHORT_G1 BIT(20)
1029
1030#define _AGGLMT_MCS0(x) ((x) & 0xF)
1031#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4)
1032#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8)
1033#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12)
1034#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16)
1035#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20)
1036#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24)
1037#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28)
1038
1039#define RETRY_LIMIT_SHORT_SHIFT 8
1040#define RETRY_LIMIT_LONG_SHIFT 0
1041
1042#define _DARF_RC1(x) ((x) & 0x1F)
1043#define _DARF_RC2(x) (((x) & 0x1F) << 8)
1044#define _DARF_RC3(x) (((x) & 0x1F) << 16)
1045#define _DARF_RC4(x) (((x) & 0x1F) << 24)
1046#define _DARF_RC5(x) ((x) & 0x1F)
1047#define _DARF_RC6(x) (((x) & 0x1F) << 8)
1048#define _DARF_RC7(x) (((x) & 0x1F) << 16)
1049#define _DARF_RC8(x) (((x) & 0x1F) << 24)
1050
1051#define _RARF_RC1(x) ((x) & 0x1F)
1052#define _RARF_RC2(x) (((x) & 0x1F) << 8)
1053#define _RARF_RC3(x) (((x) & 0x1F) << 16)
1054#define _RARF_RC4(x) (((x) & 0x1F) << 24)
1055#define _RARF_RC5(x) ((x) & 0x1F)
1056#define _RARF_RC6(x) (((x) & 0x1F) << 8)
1057#define _RARF_RC7(x) (((x) & 0x1F) << 16)
1058#define _RARF_RC8(x) (((x) & 0x1F) << 24)
1059
1060#define AC_PARAM_TXOP_LIMIT_OFFSET 16
1061#define AC_PARAM_ECW_MAX_OFFSET 12
1062#define AC_PARAM_ECW_MIN_OFFSET 8
1063#define AC_PARAM_AIFS_OFFSET 0
1064
1065#define _AIFS(x) (x)
1066#define _ECW_MAX_MIN(x) ((x) << 8)
1067#define _TXOP_LIMIT(x) ((x) << 16)
1068
1069#define _BCNIFS(x) ((x) & 0xFF)
1070#define _BCNECW(x) ((((x) & 0xF)) << 8)
1071
1072#define _LRL(x) ((x) & 0x3F)
1073#define _SRL(x) (((x) & 0x3F) << 8)
1074
1075#define _SIFS_CCK_CTX(x) ((x) & 0xFF)
1076#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8);
1077
1078#define _SIFS_OFDM_CTX(x) ((x) & 0xFF)
1079#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8);
1080
1081#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8)
1082
1083#define DIS_EDCA_CNT_DWN BIT(11)
1084
1085#define EN_MBSSID BIT(1)
1086#define EN_TXBCN_RPT BIT(2)
1087#define EN_BCN_FUNCTION BIT(3)
1088
1089#define TSFTR_RST BIT(0)
1090#define TSFTR1_RST BIT(1)
1091
1092#define STOP_BCNQ BIT(6)
1093
1094#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4)
1095#define DIS_TSF_UDT0_TEST_CHIP BIT(5)
1096
1097#define AcmHw_HwEn BIT(0)
1098#define AcmHw_BeqEn BIT(1)
1099#define AcmHw_ViqEn BIT(2)
1100#define AcmHw_VoqEn BIT(3)
1101#define AcmHw_BeqStatus BIT(4)
1102#define AcmHw_ViqStatus BIT(5)
1103#define AcmHw_VoqStatus BIT(6)
1104
1105#define APSDOFF BIT(6)
1106#define APSDOFF_STATUS BIT(7)
1107
1108#define BW_20MHZ BIT(2)
1109
1110#define RATE_BITMAP_ALL 0xFFFFF
1111
1112#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1
1113
1114#define TSFRST BIT(0)
1115#define DIS_GCLK BIT(1)
1116#define PAD_SEL BIT(2)
1117#define PWR_ST BIT(6)
1118#define PWRBIT_OW_EN BIT(7)
1119#define ACRC BIT(8)
1120#define CFENDFORM BIT(9)
1121#define ICV BIT(10)
1122
1123#define AAP BIT(0)
1124#define APM BIT(1)
1125#define AM BIT(2)
1126#define AB BIT(3)
1127#define ADD3 BIT(4)
1128#define APWRMGT BIT(5)
1129#define CBSSID BIT(6)
1130#define CBSSID_DATA BIT(6)
1131#define CBSSID_BCN BIT(7)
1132#define ACRC32 BIT(8)
1133#define AICV BIT(9)
1134#define ADF BIT(11)
1135#define ACF BIT(12)
1136#define AMF BIT(13)
1137#define HTC_LOC_CTRL BIT(14)
1138#define UC_DATA_EN BIT(16)
1139#define BM_DATA_EN BIT(17)
1140#define MFBEN BIT(22)
1141#define LSIGEN BIT(23)
1142#define EnMBID BIT(24)
1143#define APP_BASSN BIT(27)
1144#define APP_PHYSTS BIT(28)
1145#define APP_ICV BIT(29)
1146#define APP_MIC BIT(30)
1147#define APP_FCS BIT(31)
1148
1149#define _MIN_SPACE(x) ((x) & 0x7)
1150#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3)
1151
1152#define RXERR_TYPE_OFDM_PPDU 0
1153#define RXERR_TYPE_OFDM_FALSE_ALARM 1
1154#define RXERR_TYPE_OFDM_MPDU_OK 2
1155#define RXERR_TYPE_OFDM_MPDU_FAIL 3
1156#define RXERR_TYPE_CCK_PPDU 4
1157#define RXERR_TYPE_CCK_FALSE_ALARM 5
1158#define RXERR_TYPE_CCK_MPDU_OK 6
1159#define RXERR_TYPE_CCK_MPDU_FAIL 7
1160#define RXERR_TYPE_HT_PPDU 8
1161#define RXERR_TYPE_HT_FALSE_ALARM 9
1162#define RXERR_TYPE_HT_MPDU_TOTAL 10
1163#define RXERR_TYPE_HT_MPDU_OK 11
1164#define RXERR_TYPE_HT_MPDU_FAIL 12
1165#define RXERR_TYPE_RX_FULL_DROP 15
1166
1167#define RXERR_COUNTER_MASK 0xFFFFF
1168#define RXERR_RPT_RST BIT(27)
1169#define _RXERR_RPT_SEL(type) ((type) << 28)
1170
1171#define SCR_TxUseDK BIT(0)
1172#define SCR_RxUseDK BIT(1)
1173#define SCR_TxEncEnable BIT(2)
1174#define SCR_RxDecEnable BIT(3)
1175#define SCR_SKByA2 BIT(4)
1176#define SCR_NoSKMC BIT(5)
1177#define SCR_TXBCUSEDK BIT(6)
1178#define SCR_RXBCUSEDK BIT(7)
1179
1180#define USB_IS_HIGH_SPEED 0
1181#define USB_IS_FULL_SPEED 1
1182#define USB_SPEED_MASK BIT(5)
1183
1184#define USB_NORMAL_SIE_EP_MASK 0xF
1185#define USB_NORMAL_SIE_EP_SHIFT 4
1186
1187#define USB_TEST_EP_MASK 0x30
1188#define USB_TEST_EP_SHIFT 4
1189
1190#define USB_AGG_EN BIT(3)
1191
1192#define MAC_ADDR_LEN 6
1193#define LAST_ENTRY_OF_TX_PKT_BUFFER 255
1194
1195#define POLLING_LLT_THRESHOLD 20
1196#define POLLING_READY_TIMEOUT_COUNT 1000
1197
1198#define MAX_MSS_DENSITY_2T 0x13
1199#define MAX_MSS_DENSITY_1T 0x0A
1200
1201#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
1202#define EPROM_CMD_CONFIG 0x3
1203#define EPROM_CMD_LOAD 1
1204
1205#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE
1206
1207#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
1208
1209#define RPMAC_RESET 0x100
1210#define RPMAC_TXSTART 0x104
1211#define RPMAC_TXLEGACYSIG 0x108
1212#define RPMAC_TXHTSIG1 0x10c
1213#define RPMAC_TXHTSIG2 0x110
1214#define RPMAC_PHYDEBUG 0x114
1215#define RPMAC_TXPACKETNUM 0x118
1216#define RPMAC_TXIDLE 0x11c
1217#define RPMAC_TXMACHEADER0 0x120
1218#define RPMAC_TXMACHEADER1 0x124
1219#define RPMAC_TXMACHEADER2 0x128
1220#define RPMAC_TXMACHEADER3 0x12c
1221#define RPMAC_TXMACHEADER4 0x130
1222#define RPMAC_TXMACHEADER5 0x134
1223#define RPMAC_TXDADATYPE 0x138
1224#define RPMAC_TXRANDOMSEED 0x13c
1225#define RPMAC_CCKPLCPPREAMBLE 0x140
1226#define RPMAC_CCKPLCPHEADER 0x144
1227#define RPMAC_CCKCRC16 0x148
1228#define RPMAC_OFDMRXCRC32OK 0x170
1229#define RPMAC_OFDMRXCRC32Er 0x174
1230#define RPMAC_OFDMRXPARITYER 0x178
1231#define RPMAC_OFDMRXCRC8ER 0x17c
1232#define RPMAC_CCKCRXRC16ER 0x180
1233#define RPMAC_CCKCRXRC32ER 0x184
1234#define RPMAC_CCKCRXRC32OK 0x188
1235#define RPMAC_TXSTATUS 0x18c
1236
1237#define RFPGA0_RFMOD 0x800
1238
1239#define RFPGA0_TXINFO 0x804
1240#define RFPGA0_PSDFUNCTION 0x808
1241
1242#define RFPGA0_TXGAINSTAGE 0x80c
1243
1244#define RFPGA0_RFTIMING1 0x810
1245#define RFPGA0_RFTIMING2 0x814
1246
1247#define RFPGA0_XA_HSSIPARAMETER1 0x820
1248#define RFPGA0_XA_HSSIPARAMETER2 0x824
1249#define RFPGA0_XB_HSSIPARAMETER1 0x828
1250#define RFPGA0_XB_HSSIPARAMETER2 0x82c
1251
1252#define RFPGA0_XA_LSSIPARAMETER 0x840
1253#define RFPGA0_XB_LSSIPARAMETER 0x844
1254
1255#define RFPGA0_RFWAKEUPPARAMETER 0x850
1256#define RFPGA0_RFSLEEPUPPARAMETER 0x854
1257
1258#define RFPGA0_XAB_SWITCHCONTROL 0x858
1259#define RFPGA0_XCD_SWITCHCONTROL 0x85c
1260
1261#define RFPGA0_XA_RFINTERFACEOE 0x860
1262#define RFPGA0_XB_RFINTERFACEOE 0x864
1263
1264#define RFPGA0_XAB_RFINTERFACESW 0x870
1265#define RFPGA0_XCD_RFINTERFACESW 0x874
1266
1267#define rFPGA0_XAB_RFPARAMETER 0x878
1268#define rFPGA0_XCD_RFPARAMETER 0x87c
1269
1270#define RFPGA0_ANALOGPARAMETER1 0x880
1271#define RFPGA0_ANALOGPARAMETER2 0x884
1272#define RFPGA0_ANALOGPARAMETER3 0x888
1273#define RFPGA0_ANALOGPARAMETER4 0x88c
1274
1275#define RFPGA0_XA_LSSIREADBACK 0x8a0
1276#define RFPGA0_XB_LSSIREADBACK 0x8a4
1277#define RFPGA0_XC_LSSIREADBACK 0x8a8
1278#define RFPGA0_XD_LSSIREADBACK 0x8ac
1279
1280#define RFPGA0_PSDREPORT 0x8b4
1281#define TRANSCEIVEA_HSPI_READBACK 0x8b8
1282#define TRANSCEIVEB_HSPI_READBACK 0x8bc
1283#define RFPGA0_XAB_RFINTERFACERB 0x8e0
1284#define RFPGA0_XCD_RFINTERFACERB 0x8e4
1285
1286#define RFPGA1_RFMOD 0x900
1287
1288#define RFPGA1_TXBLOCK 0x904
1289#define RFPGA1_DEBUGSELECT 0x908
1290#define RFPGA1_TXINFO 0x90c
1291
1292#define RCCK0_SYSTEM 0xa00
1293
1294#define RCCK0_AFESETTING 0xa04
1295#define RCCK0_CCA 0xa08
1296
1297#define RCCK0_RXAGC1 0xa0c
1298#define RCCK0_RXAGC2 0xa10
1299
1300#define RCCK0_RXHP 0xa14
1301
1302#define RCCK0_DSPPARAMETER1 0xa18
1303#define RCCK0_DSPPARAMETER2 0xa1c
1304
1305#define RCCK0_TXFILTER1 0xa20
1306#define RCCK0_TXFILTER2 0xa24
1307#define RCCK0_DEBUGPORT 0xa28
1308#define RCCK0_FALSEALARMREPORT 0xa2c
1309#define RCCK0_TRSSIREPORT 0xa50
1310#define RCCK0_RXREPORT 0xa54
1311#define RCCK0_FACOUNTERLOWER 0xa5c
1312#define RCCK0_FACOUNTERUPPER 0xa58
1313
1314#define ROFDM0_LSTF 0xc00
1315
1316#define ROFDM0_TRXPATHENABLE 0xc04
1317#define ROFDM0_TRMUXPAR 0xc08
1318#define ROFDM0_TRSWISOLATION 0xc0c
1319
1320#define ROFDM0_XARXAFE 0xc10
1321#define ROFDM0_XARXIQIMBALANCE 0xc14
1322#define ROFDM0_XBRXAFE 0xc18
1323#define ROFDM0_XBRXIQIMBALANCE 0xc1c
1324#define ROFDM0_XCRXAFE 0xc20
1325#define ROFDM0_XCRXIQIMBANLANCE 0xc24
1326#define ROFDM0_XDRXAFE 0xc28
1327#define ROFDM0_XDRXIQIMBALANCE 0xc2c
1328
1329#define ROFDM0_RXDETECTOR1 0xc30
1330#define ROFDM0_RXDETECTOR2 0xc34
1331#define ROFDM0_RXDETECTOR3 0xc38
1332#define ROFDM0_RXDETECTOR4 0xc3c
1333
1334#define ROFDM0_RXDSP 0xc40
1335#define ROFDM0_CFOANDDAGC 0xc44
1336#define ROFDM0_CCADROPTHRESHOLD 0xc48
1337#define ROFDM0_ECCATHRESHOLD 0xc4c
1338
1339#define ROFDM0_XAAGCCORE1 0xc50
1340#define ROFDM0_XAAGCCORE2 0xc54
1341#define ROFDM0_XBAGCCORE1 0xc58
1342#define ROFDM0_XBAGCCORE2 0xc5c
1343#define ROFDM0_XCAGCCORE1 0xc60
1344#define ROFDM0_XCAGCCORE2 0xc64
1345#define ROFDM0_XDAGCCORE1 0xc68
1346#define ROFDM0_XDAGCCORE2 0xc6c
1347
1348#define ROFDM0_AGCPARAMETER1 0xc70
1349#define ROFDM0_AGCPARAMETER2 0xc74
1350#define ROFDM0_AGCRSSITABLE 0xc78
1351#define ROFDM0_HTSTFAGC 0xc7c
1352
1353#define ROFDM0_XATXIQIMBALANCE 0xc80
1354#define ROFDM0_XATXAFE 0xc84
1355#define ROFDM0_XBTXIQIMBALANCE 0xc88
1356#define ROFDM0_XBTXAFE 0xc8c
1357#define ROFDM0_XCTXIQIMBALANCE 0xc90
1358#define ROFDM0_XCTXAFE 0xc94
1359#define ROFDM0_XDTXIQIMBALANCE 0xc98
1360#define ROFDM0_XDTXAFE 0xc9c
1361
1362#define ROFDM0_RXIQEXTANTA 0xca0
1363
1364#define ROFDM0_RXHPPARAMETER 0xce0
1365#define ROFDM0_TXPSEUDONOISEWGT 0xce4
1366#define ROFDM0_FRAMESYNC 0xcf0
1367#define ROFDM0_DFSREPORT 0xcf4
1368#define ROFDM0_TXCOEFF1 0xca4
1369#define ROFDM0_TXCOEFF2 0xca8
1370#define ROFDM0_TXCOEFF3 0xcac
1371#define ROFDM0_TXCOEFF4 0xcb0
1372#define ROFDM0_TXCOEFF5 0xcb4
1373#define ROFDM0_TXCOEFF6 0xcb8
1374
1375#define ROFDM1_LSTF 0xd00
1376#define ROFDM1_TRXPATHENABLE 0xd04
1377
1378#define ROFDM1_CF0 0xd08
1379#define ROFDM1_CSI1 0xd10
1380#define ROFDM1_SBD 0xd14
1381#define ROFDM1_CSI2 0xd18
1382#define ROFDM1_CFOTRACKING 0xd2c
1383#define ROFDM1_TRXMESAURE1 0xd34
1384#define ROFDM1_INTFDET 0xd3c
1385#define ROFDM1_PSEUDONOISESTATEAB 0xd50
1386#define ROFDM1_PSEUDONOISESTATECD 0xd54
1387#define ROFDM1_RXPSEUDONOISEWGT 0xd58
1388
1389#define ROFDM_PHYCOUNTER1 0xda0
1390#define ROFDM_PHYCOUNTER2 0xda4
1391#define ROFDM_PHYCOUNTER3 0xda8
1392
1393#define ROFDM_SHORTCFOAB 0xdac
1394#define ROFDM_SHORTCFOCD 0xdb0
1395#define ROFDM_LONGCFOAB 0xdb4
1396#define ROFDM_LONGCFOCD 0xdb8
1397#define ROFDM_TAILCF0AB 0xdbc
1398#define ROFDM_TAILCF0CD 0xdc0
1399#define ROFDM_PWMEASURE1 0xdc4
1400#define ROFDM_PWMEASURE2 0xdc8
1401#define ROFDM_BWREPORT 0xdcc
1402#define ROFDM_AGCREPORT 0xdd0
1403#define ROFDM_RXSNR 0xdd4
1404#define ROFDM_RXEVMCSI 0xdd8
1405#define ROFDM_SIGREPORT 0xddc
1406
1407#define RTXAGC_A_RATE18_06 0xe00
1408#define RTXAGC_A_RATE54_24 0xe04
1409#define RTXAGC_A_CCK1_MCS32 0xe08
1410#define RTXAGC_A_MCS03_MCS00 0xe10
1411#define RTXAGC_A_MCS07_MCS04 0xe14
1412#define RTXAGC_A_MCS11_MCS08 0xe18
1413#define RTXAGC_A_MCS15_MCS12 0xe1c
1414
1415#define RTXAGC_B_RATE18_06 0x830
1416#define RTXAGC_B_RATE54_24 0x834
1417#define RTXAGC_B_CCK1_55_MCS32 0x838
1418#define RTXAGC_B_MCS03_MCS00 0x83c
1419#define RTXAGC_B_MCS07_MCS04 0x848
1420#define RTXAGC_B_MCS11_MCS08 0x84c
1421#define RTXAGC_B_MCS15_MCS12 0x868
1422#define RTXAGC_B_CCK11_A_CCK2_11 0x86c
1423
1424#define RZEBRA1_HSSIENABLE 0x0
1425#define RZEBRA1_TRXENABLE1 0x1
1426#define RZEBRA1_TRXENABLE2 0x2
1427#define RZEBRA1_AGC 0x4
1428#define RZEBRA1_CHARGEPUMP 0x5
1429#define RZEBRA1_CHANNEL 0x7
1430
1431#define RZEBRA1_TXGAIN 0x8
1432#define RZEBRA1_TXLPF 0x9
1433#define RZEBRA1_RXLPF 0xb
1434#define RZEBRA1_RXHPFCORNER 0xc
1435
1436#define RGLOBALCTRL 0
1437#define RRTL8256_TXLPF 19
1438#define RRTL8256_RXLPF 11
1439#define RRTL8258_TXLPF 0x11
1440#define RRTL8258_RXLPF 0x13
1441#define RRTL8258_RSSILPF 0xa
1442
1443#define RF_AC 0x00
1444
1445#define RF_IQADJ_G1 0x01
1446#define RF_IQADJ_G2 0x02
1447#define RF_POW_TRSW 0x05
1448
1449#define RF_GAIN_RX 0x06
1450#define RF_GAIN_TX 0x07
1451
1452#define RF_TXM_IDAC 0x08
1453#define RF_BS_IQGEN 0x0F
1454
1455#define RF_MODE1 0x10
1456#define RF_MODE2 0x11
1457
1458#define RF_RX_AGC_HP 0x12
1459#define RF_TX_AGC 0x13
1460#define RF_BIAS 0x14
1461#define RF_IPA 0x15
1462#define RF_POW_ABILITY 0x17
1463#define RF_MODE_AG 0x18
1464#define RRFCHANNEL 0x18
1465#define RF_CHNLBW 0x18
1466#define RF_TOP 0x19
1467
1468#define RF_RX_G1 0x1A
1469#define RF_RX_G2 0x1B
1470
1471#define RF_RX_BB2 0x1C
1472#define RF_RX_BB1 0x1D
1473
1474#define RF_RCK1 0x1E
1475#define RF_RCK2 0x1F
1476
1477#define RF_TX_G1 0x20
1478#define RF_TX_G2 0x21
1479#define RF_TX_G3 0x22
1480
1481#define RF_TX_BB1 0x23
1482#define RF_T_METER 0x24
1483
1484#define RF_SYN_G1 0x25
1485#define RF_SYN_G2 0x26
1486#define RF_SYN_G3 0x27
1487#define RF_SYN_G4 0x28
1488#define RF_SYN_G5 0x29
1489#define RF_SYN_G6 0x2A
1490#define RF_SYN_G7 0x2B
1491#define RF_SYN_G8 0x2C
1492
1493#define RF_RCK_OS 0x30
1494#define RF_TXPA_G1 0x31
1495#define RF_TXPA_G2 0x32
1496#define RF_TXPA_G3 0x33
1497
1498#define BBBRESETB 0x100
1499#define BGLOBALRESETB 0x200
1500#define BOFDMTXSTART 0x4
1501#define BCCKTXSTART 0x8
1502#define BCRC32DEBUG 0x100
1503#define BPMACLOOPBACK 0x10
1504#define BTXLSIG 0xffffff
1505#define BOFDMTXRATE 0xf
1506#define BOFDMTXRESERVED 0x10
1507#define BOFDMTXLENGTH 0x1ffe0
1508#define BOFDMTXPARITY 0x20000
1509#define BTXHTSIG1 0xffffff
1510#define BTXHTMCSRATE 0x7f
1511#define BTXHTBW 0x80
1512#define BTXHTLENGTH 0xffff00
1513#define BTXHTSIG2 0xffffff
1514#define BTXHTSMOOTHING 0x1
1515#define BTXHTSOUNDING 0x2
1516#define BTXHTRESERVED 0x4
1517#define BTXHTAGGREATION 0x8
1518#define BTXHTSTBC 0x30
1519#define BTXHTADVANCECODING 0x40
1520#define BTXHTSHORTGI 0x80
1521#define BTXHTNUMBERHT_LTF 0x300
1522#define BTXHTCRC8 0x3fc00
1523#define BCOUNTERRESET 0x10000
1524#define BNUMOFOFDMTX 0xffff
1525#define BNUMOFCCKTX 0xffff0000
1526#define BTXIDLEINTERVAL 0xffff
1527#define BOFDMSERVICE 0xffff0000
1528#define BTXMACHEADER 0xffffffff
1529#define BTXDATAINIT 0xff
1530#define BTXHTMODE 0x100
1531#define BTXDATATYPE 0x30000
1532#define BTXRANDOMSEED 0xffffffff
1533#define BCCKTXPREAMBLE 0x1
1534#define BCCKTXSFD 0xffff0000
1535#define BCCKTXSIG 0xff
1536#define BCCKTXSERVICE 0xff00
1537#define BCCKLENGTHEXT 0x8000
1538#define BCCKTXLENGHT 0xffff0000
1539#define BCCKTXCRC16 0xffff
1540#define BCCKTXSTATUS 0x1
1541#define BOFDMTXSTATUS 0x2
1542#define IS_BB_REG_OFFSET_92S(_Offset) \
1543 ((_Offset >= 0x800) && (_Offset <= 0xfff))
1544
1545#define BRFMOD 0x1
1546#define BJAPANMODE 0x2
1547#define BCCKTXSC 0x30
1548#define BCCKEN 0x1000000
1549#define BOFDMEN 0x2000000
1550
1551#define BOFDMRXADCPHASE 0x10000
1552#define BOFDMTXDACPHASE 0x40000
1553#define BXATXAGC 0x3f
1554
1555#define BXBTXAGC 0xf00
1556#define BXCTXAGC 0xf000
1557#define BXDTXAGC 0xf0000
1558
1559#define BPASTART 0xf0000000
1560#define BTRSTART 0x00f00000
1561#define BRFSTART 0x0000f000
1562#define BBBSTART 0x000000f0
1563#define BBBCCKSTART 0x0000000f
1564#define BPAEND 0xf
1565#define BTREND 0x0f000000
1566#define BRFEND 0x000f0000
1567#define BCCAMASK 0x000000f0
1568#define BR2RCCAMASK 0x00000f00
1569#define BHSSI_R2TDELAY 0xf8000000
1570#define BHSSI_T2RDELAY 0xf80000
1571#define BCONTXHSSI 0x400
1572#define BIGFROMCCK 0x200
1573#define BAGCADDRESS 0x3f
1574#define BRXHPTX 0x7000
1575#define BRXHP2RX 0x38000
1576#define BRXHPCCKINI 0xc0000
1577#define BAGCTXCODE 0xc00000
1578#define BAGCRXCODE 0x300000
1579
1580#define B3WIREDATALENGTH 0x800
1581#define B3WIREADDREAALENGTH 0x400
1582
1583#define B3WIRERFPOWERDOWN 0x1
1584#define B5GPAPEPOLARITY 0x40000000
1585#define B2GPAPEPOLARITY 0x80000000
1586#define BRFSW_TXDEFAULTANT 0x3
1587#define BRFSW_TXOPTIONANT 0x30
1588#define BRFSW_RXDEFAULTANT 0x300
1589#define BRFSW_RXOPTIONANT 0x3000
1590#define BRFSI_3WIREDATA 0x1
1591#define BRFSI_3WIRECLOCK 0x2
1592#define BRFSI_3WIRELOAD 0x4
1593#define BRFSI_3WIRERW 0x8
1594#define BRFSI_3WIRE 0xf
1595
1596#define BRFSI_RFENV 0x10
1597
1598#define BRFSI_TRSW 0x20
1599#define BRFSI_TRSWB 0x40
1600#define BRFSI_ANTSW 0x100
1601#define BRFSI_ANTSWB 0x200
1602#define BRFSI_PAPE 0x400
1603#define BRFSI_PAPE5G 0x800
1604#define BBANDSELECT 0x1
1605#define BHTSIG2_GI 0x80
1606#define BHTSIG2_SMOOTHING 0x01
1607#define BHTSIG2_SOUNDING 0x02
1608#define BHTSIG2_AGGREATON 0x08
1609#define BHTSIG2_STBC 0x30
1610#define BHTSIG2_ADVCODING 0x40
1611#define BHTSIG2_NUMOFHTLTF 0x300
1612#define BHTSIG2_CRC8 0x3fc
1613#define BHTSIG1_MCS 0x7f
1614#define BHTSIG1_BANDWIDTH 0x80
1615#define BHTSIG1_HTLENGTH 0xffff
1616#define BLSIG_RATE 0xf
1617#define BLSIG_RESERVED 0x10
1618#define BLSIG_LENGTH 0x1fffe
1619#define BLSIG_PARITY 0x20
1620#define BCCKRXPHASE 0x4
1621
1622#define BLSSIREADADDRESS 0x7f800000
1623#define BLSSIREADEDGE 0x80000000
1624
1625#define BLSSIREADBACKDATA 0xfffff
1626
1627#define BLSSIREADOKFLAG 0x1000
1628#define BCCKSAMPLERATE 0x8
1629#define BREGULATOR0STANDBY 0x1
1630#define BREGULATORPLLSTANDBY 0x2
1631#define BREGULATOR1STANDBY 0x4
1632#define BPLLPOWERUP 0x8
1633#define BDPLLPOWERUP 0x10
1634#define BDA10POWERUP 0x20
1635#define BAD7POWERUP 0x200
1636#define BDA6POWERUP 0x2000
1637#define BXTALPOWERUP 0x4000
1638#define B40MDCLKPOWERUP 0x8000
1639#define BDA6DEBUGMODE 0x20000
1640#define BDA6SWING 0x380000
1641
1642#define BADCLKPHASE 0x4000000
1643#define B80MCLKDELAY 0x18000000
1644#define BAFEWATCHDOGENABLE 0x20000000
1645
1646#define BXTALCAP01 0xc0000000
1647#define BXTALCAP23 0x3
1648#define BXTALCAP92X 0x0f000000
1649#define BXTALCAP 0x0f000000
1650
1651#define BINTDIFCLKENABLE 0x400
1652#define BEXTSIGCLKENABLE 0x800
1653#define BBANDGAP_MBIAS_POWERUP 0x10000
1654#define BAD11SH_GAIN 0xc0000
1655#define BAD11NPUT_RANGE 0x700000
1656#define BAD110P_CURRENT 0x3800000
1657#define BLPATH_LOOPBACK 0x4000000
1658#define BQPATH_LOOPBACK 0x8000000
1659#define BAFE_LOOPBACK 0x10000000
1660#define BDA10_SWING 0x7e0
1661#define BDA10_REVERSE 0x800
1662#define BDA_CLK_SOURCE 0x1000
1663#define BDA7INPUT_RANGE 0x6000
1664#define BDA7_GAIN 0x38000
1665#define BDA7OUTPUT_CM_MODE 0x40000
1666#define BDA7INPUT_CM_MODE 0x380000
1667#define BDA7CURRENT 0xc00000
1668#define BREGULATOR_ADJUST 0x7000000
1669#define BAD11POWERUP_ATTX 0x1
1670#define BDA10PS_ATTX 0x10
1671#define BAD11POWERUP_ATRX 0x100
1672#define BDA10PS_ATRX 0x1000
1673#define BCCKRX_AGC_FORMAT 0x200
1674#define BPSDFFT_SAMPLE_POINT 0xc000
1675#define BPSD_AVERAGE_NUM 0x3000
1676#define BIQPATH_CONTROL 0xc00
1677#define BPSD_FREQ 0x3ff
1678#define BPSD_ANTENNA_PATH 0x30
1679#define BPSD_IQ_SWITCH 0x40
1680#define BPSD_RX_TRIGGER 0x400000
1681#define BPSD_TX_TRIGGER 0x80000000
1682#define BPSD_SINE_TONE_SCALE 0x7f000000
1683#define BPSD_REPORT 0xffff
1684
1685#define BOFDM_TXSC 0x30000000
1686#define BCCK_TXON 0x1
1687#define BOFDM_TXON 0x2
1688#define BDEBUG_PAGE 0xfff
1689#define BDEBUG_ITEM 0xff
1690#define BANTL 0x10
1691#define BANT_NONHT 0x100
1692#define BANT_HT1 0x1000
1693#define BANT_HT2 0x10000
1694#define BANT_HT1S1 0x100000
1695#define BANT_NONHTS1 0x1000000
1696
1697#define BCCK_BBMODE 0x3
1698#define BCCK_TXPOWERSAVING 0x80
1699#define BCCK_RXPOWERSAVING 0x40
1700
1701#define BCCK_SIDEBAND 0x10
1702
1703#define BCCK_SCRAMBLE 0x8
1704#define BCCK_ANTDIVERSITY 0x8000
1705#define BCCK_CARRIER_RECOVERY 0x4000
1706#define BCCK_TXRATE 0x3000
1707#define BCCK_DCCANCEL 0x0800
1708#define BCCK_ISICANCEL 0x0400
1709#define BCCK_MATCH_FILTER 0x0200
1710#define BCCK_EQUALIZER 0x0100
1711#define BCCK_PREAMBLE_DETECT 0x800000
1712#define BCCK_FAST_FALSECCAi 0x400000
1713#define BCCK_CH_ESTSTARTi 0x300000
1714#define BCCK_CCA_COUNTi 0x080000
1715#define BCCK_CS_LIM 0x070000
1716#define BCCK_BIST_MODEi 0x80000000
1717#define BCCK_CCAMASK 0x40000000
1718#define BCCK_TX_DAC_PHASE 0x4
1719#define BCCK_RX_ADC_PHASE 0x20000000
1720#define BCCKR_CP_MODE 0x0100
1721#define BCCK_TXDC_OFFSET 0xf0
1722#define BCCK_RXDC_OFFSET 0xf
1723#define BCCK_CCA_MODE 0xc000
1724#define BCCK_FALSECS_LIM 0x3f00
1725#define BCCK_CS_RATIO 0xc00000
1726#define BCCK_CORGBIT_SEL 0x300000
1727#define BCCK_PD_LIM 0x0f0000
1728#define BCCK_NEWCCA 0x80000000
1729#define BCCK_RXHP_OF_IG 0x8000
1730#define BCCK_RXIG 0x7f00
1731#define BCCK_LNA_POLARITY 0x800000
1732#define BCCK_RX1ST_BAIN 0x7f0000
1733#define BCCK_RF_EXTEND 0x20000000
1734#define BCCK_RXAGC_SATLEVEL 0x1f000000
1735#define BCCK_RXAGC_SATCOUNT 0xe0
1736#define bCCKRxRFSettle 0x1f
1737#define BCCK_FIXED_RXAGC 0x8000
1738#define BCCK_ANTENNA_POLARITY 0x2000
1739#define BCCK_TXFILTER_TYPE 0x0c00
1740#define BCCK_RXAGC_REPORTTYPE 0x0300
1741#define BCCK_RXDAGC_EN 0x80000000
1742#define BCCK_RXDAGC_PERIOD 0x20000000
1743#define BCCK_RXDAGC_SATLEVEL 0x1f000000
1744#define BCCK_TIMING_RECOVERY 0x800000
1745#define BCCK_TXC0 0x3f0000
1746#define BCCK_TXC1 0x3f000000
1747#define BCCK_TXC2 0x3f
1748#define BCCK_TXC3 0x3f00
1749#define BCCK_TXC4 0x3f0000
1750#define BCCK_TXC5 0x3f000000
1751#define BCCK_TXC6 0x3f
1752#define BCCK_TXC7 0x3f00
1753#define BCCK_DEBUGPORT 0xff0000
1754#define BCCK_DAC_DEBUG 0x0f000000
1755#define BCCK_FALSEALARM_ENABLE 0x8000
1756#define BCCK_FALSEALARM_READ 0x4000
1757#define BCCK_TRSSI 0x7f
1758#define BCCK_RXAGC_REPORT 0xfe
1759#define BCCK_RXREPORT_ANTSEL 0x80000000
1760#define BCCK_RXREPORT_MFOFF 0x40000000
1761#define BCCK_RXREPORT_SQLOSS 0x20000000
1762#define BCCK_RXREPORT_PKTLOSS 0x10000000
1763#define BCCK_RXREPORT_LOCKEDBIT 0x08000000
1764#define BCCK_RXREPORT_RATEERROR 0x04000000
1765#define BCCK_RXREPORT_RXRATE 0x03000000
1766#define BCCK_RXFA_COUNTER_LOWER 0xff
1767#define BCCK_RXFA_COUNTER_UPPER 0xff000000
1768#define BCCK_RXHPAGC_START 0xe000
1769#define BCCK_RXHPAGC_FINAL 0x1c00
1770#define BCCK_RXFALSEALARM_ENABLE 0x8000
1771#define BCCK_FACOUNTER_FREEZE 0x4000
1772#define BCCK_TXPATH_SEL 0x10000000
1773#define BCCK_DEFAULT_RXPATH 0xc000000
1774#define BCCK_OPTION_RXPATH 0x3000000
1775
1776#define BNUM_OFSTF 0x3
1777#define BSHIFT_L 0xc0
1778#define BGI_TH 0xc
1779#define BRXPATH_A 0x1
1780#define BRXPATH_B 0x2
1781#define BRXPATH_C 0x4
1782#define BRXPATH_D 0x8
1783#define BTXPATH_A 0x1
1784#define BTXPATH_B 0x2
1785#define BTXPATH_C 0x4
1786#define BTXPATH_D 0x8
1787#define BTRSSI_FREQ 0x200
1788#define BADC_BACKOFF 0x3000
1789#define BDFIR_BACKOFF 0xc000
1790#define BTRSSI_LATCH_PHASE 0x10000
1791#define BRX_LDC_OFFSET 0xff
1792#define BRX_QDC_OFFSET 0xff00
1793#define BRX_DFIR_MODE 0x1800000
1794#define BRX_DCNF_TYPE 0xe000000
1795#define BRXIQIMB_A 0x3ff
1796#define BRXIQIMB_B 0xfc00
1797#define BRXIQIMB_C 0x3f0000
1798#define BRXIQIMB_D 0xffc00000
1799#define BDC_DC_NOTCH 0x60000
1800#define BRXNB_NOTCH 0x1f000000
1801#define BPD_TH 0xf
1802#define BPD_TH_OPT2 0xc000
1803#define BPWED_TH 0x700
1804#define BIFMF_WIN_L 0x800
1805#define BPD_OPTION 0x1000
1806#define BMF_WIN_L 0xe000
1807#define BBW_SEARCH_L 0x30000
1808#define BWIN_ENH_L 0xc0000
1809#define BBW_TH 0x700000
1810#define BED_TH2 0x3800000
1811#define BBW_OPTION 0x4000000
1812#define BRADIO_TH 0x18000000
1813#define BWINDOW_L 0xe0000000
1814#define BSBD_OPTION 0x1
1815#define BFRAME_TH 0x1c
1816#define BFS_OPTION 0x60
1817#define BDC_SLOPE_CHECK 0x80
1818#define BFGUARD_COUNTER_DC_L 0xe00
1819#define BFRAME_WEIGHT_SHORT 0x7000
1820#define BSUB_TUNE 0xe00000
1821#define BFRAME_DC_LENGTH 0xe000000
1822#define BSBD_START_OFFSET 0x30000000
1823#define BFRAME_TH_2 0x7
1824#define BFRAME_GI2_TH 0x38
1825#define BGI2_SYNC_EN 0x40
1826#define BSARCH_SHORT_EARLY 0x300
1827#define BSARCH_SHORT_LATE 0xc00
1828#define BSARCH_GI2_LATE 0x70000
1829#define BCFOANTSUM 0x1
1830#define BCFOACC 0x2
1831#define BCFOSTARTOFFSET 0xc
1832#define BCFOLOOPBACK 0x70
1833#define BCFOSUMWEIGHT 0x80
1834#define BDAGCENABLE 0x10000
1835#define BTXIQIMB_A 0x3ff
1836#define BTXIQIMB_b 0xfc00
1837#define BTXIQIMB_C 0x3f0000
1838#define BTXIQIMB_D 0xffc00000
1839#define BTXIDCOFFSET 0xff
1840#define BTXIQDCOFFSET 0xff00
1841#define BTXDFIRMODE 0x10000
1842#define BTXPESUDO_NOISEON 0x4000000
1843#define BTXPESUDO_NOISE_A 0xff
1844#define BTXPESUDO_NOISE_B 0xff00
1845#define BTXPESUDO_NOISE_C 0xff0000
1846#define BTXPESUDO_NOISE_D 0xff000000
1847#define BCCA_DROPOPTION 0x20000
1848#define BCCA_DROPTHRES 0xfff00000
1849#define BEDCCA_H 0xf
1850#define BEDCCA_L 0xf0
1851#define BLAMBDA_ED 0x300
1852#define BRX_INITIALGAIN 0x7f
1853#define BRX_ANTDIV_EN 0x80
1854#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00
1855#define BRX_HIGHPOWER_FLOW 0x8000
1856#define BRX_AGC_FREEZE_THRES 0xc0000
1857#define BRX_FREEZESTEP_AGC1 0x300000
1858#define BRX_FREEZESTEP_AGC2 0xc00000
1859#define BRX_FREEZESTEP_AGC3 0x3000000
1860#define BRX_FREEZESTEP_AGC0 0xc000000
1861#define BRXRSSI_CMP_EN 0x10000000
1862#define BRXQUICK_AGCEN 0x20000000
1863#define BRXAGC_FREEZE_THRES_MODE 0x40000000
1864#define BRX_OVERFLOW_CHECKTYPE 0x80000000
1865#define BRX_AGCSHIFT 0x7f
1866#define BTRSW_TRI_ONLY 0x80
1867#define BPOWER_THRES 0x300
1868#define BRXAGC_EN 0x1
1869#define BRXAGC_TOGETHER_EN 0x2
1870#define BRXAGC_MIN 0x4
1871#define BRXHP_INI 0x7
1872#define BRXHP_TRLNA 0x70
1873#define BRXHP_RSSI 0x700
1874#define BRXHP_BBP1 0x7000
1875#define BRXHP_BBP2 0x70000
1876#define BRXHP_BBP3 0x700000
1877#define BRSSI_H 0x7f0000
1878#define BRSSI_GEN 0x7f000000
1879#define BRXSETTLE_TRSW 0x7
1880#define BRXSETTLE_LNA 0x38
1881#define BRXSETTLE_RSSI 0x1c0
1882#define BRXSETTLE_BBP 0xe00
1883#define BRXSETTLE_RXHP 0x7000
1884#define BRXSETTLE_ANTSW_RSSI 0x38000
1885#define BRXSETTLE_ANTSW 0xc0000
1886#define BRXPROCESS_TIME_DAGC 0x300000
1887#define BRXSETTLE_HSSI 0x400000
1888#define BRXPROCESS_TIME_BBPPW 0x800000
1889#define BRXANTENNA_POWER_SHIFT 0x3000000
1890#define BRSSI_TABLE_SELECT 0xc000000
1891#define BRXHP_FINAL 0x7000000
1892#define BRXHPSETTLE_BBP 0x7
1893#define BRXHTSETTLE_HSSI 0x8
1894#define BRXHTSETTLE_RXHP 0x70
1895#define BRXHTSETTLE_BBPPW 0x80
1896#define BRXHTSETTLE_IDLE 0x300
1897#define BRXHTSETTLE_RESERVED 0x1c00
1898#define BRXHT_RXHP_EN 0x8000
1899#define BRXAGC_FREEZE_THRES 0x30000
1900#define BRXAGC_TOGETHEREN 0x40000
1901#define BRXHTAGC_MIN 0x80000
1902#define BRXHTAGC_EN 0x100000
1903#define BRXHTDAGC_EN 0x200000
1904#define BRXHT_RXHP_BBP 0x1c00000
1905#define BRXHT_RXHP_FINAL 0xe0000000
1906#define BRXPW_RADIO_TH 0x3
1907#define BRXPW_RADIO_EN 0x4
1908#define BRXMF_HOLD 0x3800
1909#define BRXPD_DELAY_TH1 0x38
1910#define BRXPD_DELAY_TH2 0x1c0
1911#define BRXPD_DC_COUNT_MAX 0x600
1912#define BRXPD_DELAY_TH 0x8000
1913#define BRXPROCESS_DELAY 0xf0000
1914#define BRXSEARCHRANGE_GI2_EARLY 0x700000
1915#define BRXFRAME_FUARD_COUNTER_L 0x3800000
1916#define BRXSGI_GUARD_L 0xc000000
1917#define BRXSGI_SEARCH_L 0x30000000
1918#define BRXSGI_TH 0xc0000000
1919#define BDFSCNT0 0xff
1920#define BDFSCNT1 0xff00
1921#define BDFSFLAG 0xf0000
1922#define BMF_WEIGHT_SUM 0x300000
1923#define BMINIDX_TH 0x7f000000
1924#define BDAFORMAT 0x40000
1925#define BTXCH_EMU_ENABLE 0x01000000
1926#define BTRSW_ISOLATION_A 0x7f
1927#define BTRSW_ISOLATION_B 0x7f00
1928#define BTRSW_ISOLATION_C 0x7f0000
1929#define BTRSW_ISOLATION_D 0x7f000000
1930#define BEXT_LNA_GAIN 0x7c00
1931
1932#define BSTBC_EN 0x4
1933#define BANTENNA_MAPPING 0x10
1934#define BNSS 0x20
1935#define BCFO_ANTSUM_ID 0x200
1936#define BPHY_COUNTER_RESET 0x8000000
1937#define BCFO_REPORT_GET 0x4000000
1938#define BOFDM_CONTINUE_TX 0x10000000
1939#define BOFDM_SINGLE_CARRIER 0x20000000
1940#define BOFDM_SINGLE_TONE 0x40000000
1941#define BHT_DETECT 0x100
1942#define BCFOEN 0x10000
1943#define BCFOVALUE 0xfff00000
1944#define BSIGTONE_RE 0x3f
1945#define BSIGTONE_IM 0x7f00
1946#define BCOUNTER_CCA 0xffff
1947#define BCOUNTER_PARITYFAIL 0xffff0000
1948#define BCOUNTER_RATEILLEGAL 0xffff
1949#define BCOUNTER_CRC8FAIL 0xffff0000
1950#define BCOUNTER_MCSNOSUPPORT 0xffff
1951#define BCOUNTER_FASTSYNC 0xffff
1952#define BSHORTCFO 0xfff
1953#define BSHORTCFOT_LENGTH 12
1954#define BSHORTCFOF_LENGTH 11
1955#define BLONGCFO 0x7ff
1956#define BLONGCFOT_LENGTH 11
1957#define BLONGCFOF_LENGTH 11
1958#define BTAILCFO 0x1fff
1959#define BTAILCFOT_LENGTH 13
1960#define BTAILCFOF_LENGTH 12
1961#define BNOISE_EN_PWDB 0xffff
1962#define BCC_POWER_DB 0xffff0000
1963#define BMOISE_PWDB 0xffff
1964#define BPOWERMEAST_LENGTH 10
1965#define BPOWERMEASF_LENGTH 3
1966#define BRX_HT_BW 0x1
1967#define BRXSC 0x6
1968#define BRX_HT 0x8
1969#define BNB_INTF_DET_ON 0x1
1970#define BINTF_WIN_LEN_CFG 0x30
1971#define BNB_INTF_TH_CFG 0x1c0
1972#define BRFGAIN 0x3f
1973#define BTABLESEL 0x40
1974#define BTRSW 0x80
1975#define BRXSNR_A 0xff
1976#define BRXSNR_B 0xff00
1977#define BRXSNR_C 0xff0000
1978#define BRXSNR_D 0xff000000
1979#define BSNR_EVMT_LENGTH 8
1980#define BSNR_EVMF_LENGTH 1
1981#define BCSI1ST 0xff
1982#define BCSI2ND 0xff00
1983#define BRXEVM1ST 0xff0000
1984#define BRXEVM2ND 0xff000000
1985#define BSIGEVM 0xff
1986#define BPWDB 0xff00
1987#define BSGIEN 0x10000
1988
1989#define BSFACTOR_QMA1 0xf
1990#define BSFACTOR_QMA2 0xf0
1991#define BSFACTOR_QMA3 0xf00
1992#define BSFACTOR_QMA4 0xf000
1993#define BSFACTOR_QMA5 0xf0000
1994#define BSFACTOR_QMA6 0xf0000
1995#define BSFACTOR_QMA7 0xf00000
1996#define BSFACTOR_QMA8 0xf000000
1997#define BSFACTOR_QMA9 0xf0000000
1998#define BCSI_SCHEME 0x100000
1999
2000#define BNOISE_LVL_TOP_SET 0x3
2001#define BCHSMOOTH 0x4
2002#define BCHSMOOTH_CFG1 0x38
2003#define BCHSMOOTH_CFG2 0x1c0
2004#define BCHSMOOTH_CFG3 0xe00
2005#define BCHSMOOTH_CFG4 0x7000
2006#define BMRCMODE 0x800000
2007#define BTHEVMCFG 0x7000000
2008
2009#define BLOOP_FIT_TYPE 0x1
2010#define BUPD_CFO 0x40
2011#define BUPD_CFO_OFFDATA 0x80
2012#define BADV_UPD_CFO 0x100
2013#define BADV_TIME_CTRL 0x800
2014#define BUPD_CLKO 0x1000
2015#define BFC 0x6000
2016#define BTRACKING_MODE 0x8000
2017#define BPHCMP_ENABLE 0x10000
2018#define BUPD_CLKO_LTF 0x20000
2019#define BCOM_CH_CFO 0x40000
2020#define BCSI_ESTI_MODE 0x80000
2021#define BADV_UPD_EQZ 0x100000
2022#define BUCHCFG 0x7000000
2023#define BUPDEQZ 0x8000000
2024
2025#define BRX_PESUDO_NOISE_ON 0x20000000
2026#define BRX_PESUDO_NOISE_A 0xff
2027#define BRX_PESUDO_NOISE_B 0xff00
2028#define BRX_PESUDO_NOISE_C 0xff0000
2029#define BRX_PESUDO_NOISE_D 0xff000000
2030#define BRX_PESUDO_NOISESTATE_A 0xffff
2031#define BRX_PESUDO_NOISESTATE_B 0xffff0000
2032#define BRX_PESUDO_NOISESTATE_C 0xffff
2033#define BRX_PESUDO_NOISESTATE_D 0xffff0000
2034
2035#define BZEBRA1_HSSIENABLE 0x8
2036#define BZEBRA1_TRXCONTROL 0xc00
2037#define BZEBRA1_TRXGAINSETTING 0x07f
2038#define BZEBRA1_RXCOUNTER 0xc00
2039#define BZEBRA1_TXCHANGEPUMP 0x38
2040#define BZEBRA1_RXCHANGEPUMP 0x7
2041#define BZEBRA1_CHANNEL_NUM 0xf80
2042#define BZEBRA1_TXLPFBW 0x400
2043#define BZEBRA1_RXLPFBW 0x600
2044
2045#define BRTL8256REG_MODE_CTRL1 0x100
2046#define BRTL8256REG_MODE_CTRL0 0x40
2047#define BRTL8256REG_TXLPFBW 0x18
2048#define BRTL8256REG_RXLPFBW 0x600
2049
2050#define BRTL8258_TXLPFBW 0xc
2051#define BRTL8258_RXLPFBW 0xc00
2052#define BRTL8258_RSSILPFBW 0xc0
2053
2054#define BBYTE0 0x1
2055#define BBYTE1 0x2
2056#define BBYTE2 0x4
2057#define BBYTE3 0x8
2058#define BWORD0 0x3
2059#define BWORD1 0xc
2060#define BWORD 0xf
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
2079#define BDISABLE 0x0
2080
2081#define LEFT_ANTENNA 0x0
2082#define RIGHT_ANTENNA 0x1
2083
2084#define TCHECK_TXSTATUS 500
2085#define TUPDATE_RXCOUNTER 100
2086
2087/* 2 EFUSE_TEST (For RTL8723 partially) */
2088#define EFUSE_SEL(x) (((x) & 0x3) << 8)
2089#define EFUSE_SEL_MASK 0x300
2090#define EFUSE_WIFI_SEL_0 0x0
2091
2092/* Enable GPIO[9] as WiFi HW PDn source*/
2093#define WL_HWPDN_EN BIT(0)
2094/* WiFi HW PDn polarity control*/
2095#define WL_HWPDN_SL BIT(1)
2096
2097#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c
new file mode 100644
index 00000000000..50dd2fb2c93
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c
@@ -0,0 +1,505 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "reg.h"
32#include "def.h"
33#include "phy.h"
34#include "rf.h"
35#include "dm.h"
36
37void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
38{
39 struct rtl_priv *rtlpriv = rtl_priv(hw);
40 struct rtl_phy *rtlphy = &(rtlpriv->phy);
41
42 switch (bandwidth) {
43 case HT_CHANNEL_WIDTH_20:
44 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
45 0xfffff3ff) | 0x0400);
46 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
47 rtlphy->rfreg_chnlval[0]);
48 break;
49 case HT_CHANNEL_WIDTH_20_40:
50 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
51 0xfffff3ff));
52 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
53 rtlphy->rfreg_chnlval[0]);
54 break;
55 default:
56 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
57 "unknown bandwidth: %#X\n", bandwidth);
58 break;
59 }
60}
61
62void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
63 u8 *ppowerlevel)
64{
65 struct rtl_priv *rtlpriv = rtl_priv(hw);
66 struct rtl_phy *rtlphy = &(rtlpriv->phy);
67 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
68 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
69 u32 tx_agc[2] = {0, 0}, tmpval;
70 bool turbo_scanoff = false;
71 u8 idx1, idx2;
72 u8 *ptr;
73
74 if (rtlefuse->eeprom_regulatory != 0)
75 turbo_scanoff = true;
76
77 if (mac->act_scanning == true) {
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
97 if (rtlefuse->eeprom_regulatory == 0) {
98 tmpval = (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] << 24);
104 tx_agc[RF90_PATH_B] += tmpval;
105 }
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
117 tmpval = tx_agc[RF90_PATH_A] & 0xff;
118 rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
119
120 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
121 "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
122 RTXAGC_A_CCK1_MCS32);
123
124 tmpval = tx_agc[RF90_PATH_A] >> 8;
125
126 tmpval = tmpval & 0xff00ffff;
127
128 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
129
130 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
131 "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
132 RTXAGC_B_CCK11_A_CCK2_11);
133
134 tmpval = tx_agc[RF90_PATH_B] >> 24;
135 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
136
137 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
138 "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
139 RTXAGC_B_CCK11_A_CCK2_11);
140
141 tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
142 rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
143
144 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
145 "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
146 RTXAGC_B_CCK1_55_MCS32);
147}
148
149static void rtl8723ae_phy_get_power_base(struct ieee80211_hw *hw,
150 u8 *ppowerlevel, u8 channel,
151 u32 *ofdmbase, u32 *mcsbase)
152{
153 struct rtl_priv *rtlpriv = rtl_priv(hw);
154 struct rtl_phy *rtlphy = &(rtlpriv->phy);
155 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
156 u32 powerBase0, powerBase1;
157 u8 legacy_pwrdiff, ht20_pwrdiff;
158 u8 i, powerlevel[2];
159
160 for (i = 0; i < 2; i++) {
161 powerlevel[i] = ppowerlevel[i];
162 legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
163 powerBase0 = powerlevel[i] + legacy_pwrdiff;
164
165 powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
166 (powerBase0 << 8) | powerBase0;
167 *(ofdmbase + i) = powerBase0;
168 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
169 " [OFDM power base index rf(%c) = 0x%x]\n",
170 ((i == 0) ? 'A' : 'B'), *(ofdmbase + i));
171 }
172
173 for (i = 0; i < 2; i++) {
174 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
175 ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
176 powerlevel[i] += ht20_pwrdiff;
177 }
178 powerBase1 = powerlevel[i];
179 powerBase1 = (powerBase1 << 24) |
180 (powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
181
182 *(mcsbase + i) = powerBase1;
183
184 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
185 " [MCS power base index rf(%c) = 0x%x]\n",
186 ((i == 0) ? 'A' : 'B'), *(mcsbase + i));
187 }
188}
189
190static void rtl8723ae_get_txpwr_val_by_reg(struct ieee80211_hw *hw,
191 u8 channel, u8 index,
192 u32 *powerBase0,
193 u32 *powerBase1,
194 u32 *p_outwriteval)
195{
196 struct rtl_priv *rtlpriv = rtl_priv(hw);
197 struct rtl_phy *rtlphy = &(rtlpriv->phy);
198 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
199 u8 i, chnlgroup = 0, pwr_diff_limit[4];
200 u32 writeVal, customer_limit, rf;
201
202 for (rf = 0; rf < 2; rf++) {
203 switch (rtlefuse->eeprom_regulatory) {
204 case 0:
205 chnlgroup = 0;
206
207 writeVal = rtlphy->mcs_offset[chnlgroup]
208 [index + (rf ? 8 : 0)] +
209 ((index < 2) ? powerBase0[rf] :
210 powerBase1[rf]);
211
212 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
213 "RTK better performance, "
214 "writeVal(%c) = 0x%x\n",
215 ((rf == 0) ? 'A' : 'B'), writeVal);
216 break;
217 case 1:
218 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
219 writeVal = ((index < 2) ? powerBase0[rf] :
220 powerBase1[rf]);
221
222 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
223 "Realtek regulatory, 40MHz, "
224 "writeVal(%c) = 0x%x\n",
225 ((rf == 0) ? 'A' : 'B'), writeVal);
226 } else {
227 if (rtlphy->pwrgroup_cnt == 1)
228 chnlgroup = 0;
229 if (rtlphy->pwrgroup_cnt >= 3) {
230 if (channel <= 3)
231 chnlgroup = 0;
232 else if (channel >= 4 && channel <= 9)
233 chnlgroup = 1;
234 else if (channel > 9)
235 chnlgroup = 2;
236 if (rtlphy->current_chan_bw ==
237 HT_CHANNEL_WIDTH_20)
238 chnlgroup++;
239 else
240 chnlgroup += 4;
241 }
242
243 writeVal = rtlphy->mcs_offset[chnlgroup]
244 [index + (rf ? 8 : 0)] + ((index < 2) ?
245 powerBase0[rf] :
246 powerBase1[rf]);
247
248 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
249 "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n",
250 ((rf == 0) ? 'A' : 'B'), writeVal);
251 }
252 break;
253 case 2:
254 writeVal =
255 ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
256
257 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
258 "Better regulatory, writeVal(%c) = 0x%x\n",
259 ((rf == 0) ? 'A' : 'B'), writeVal);
260 break;
261 case 3:
262 chnlgroup = 0;
263
264 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
265 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
266 "customer's limit, 40MHz rf(%c) = 0x%x\n",
267 ((rf == 0) ? 'A' : 'B'),
268 rtlefuse->pwrgroup_ht40[rf][channel-1]);
269 } else {
270 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
271 "customer's limit, 20MHz rf(%c) = 0x%x\n",
272 ((rf == 0) ? 'A' : 'B'),
273 rtlefuse->pwrgroup_ht20[rf][channel-1]);
274 }
275 for (i = 0; i < 4; i++) {
276 pwr_diff_limit[i] =
277 (u8) ((rtlphy->mcs_offset
278 [chnlgroup][index + (rf ? 8 : 0)] &
279 (0x7f << (i * 8))) >> (i * 8));
280
281 if (rtlphy->current_chan_bw ==
282 HT_CHANNEL_WIDTH_20_40) {
283 if (pwr_diff_limit[i] >
284 rtlefuse->
285 pwrgroup_ht40[rf][channel - 1])
286 pwr_diff_limit[i] =
287 rtlefuse->pwrgroup_ht40[rf]
288 [channel - 1];
289 } else {
290 if (pwr_diff_limit[i] >
291 rtlefuse->
292 pwrgroup_ht20[rf][channel - 1])
293 pwr_diff_limit[i] =
294 rtlefuse->pwrgroup_ht20[rf]
295 [channel - 1];
296 }
297 }
298
299 customer_limit = (pwr_diff_limit[3] << 24) |
300 (pwr_diff_limit[2] << 16) |
301 (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
302
303 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
304 "Customer's limit rf(%c) = 0x%x\n",
305 ((rf == 0) ? 'A' : 'B'), customer_limit);
306
307 writeVal = customer_limit +
308 ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
309
310 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
311 "Customer, writeVal rf(%c)= 0x%x\n",
312 ((rf == 0) ? 'A' : 'B'), writeVal);
313 break;
314 default:
315 chnlgroup = 0;
316 writeVal = rtlphy->mcs_offset[chnlgroup][index +
317 (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] :
318 powerBase1[rf]);
319
320 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
321 "RTK better performance, writeVal rf(%c) = 0x%x\n",
322 ((rf == 0) ? 'A' : 'B'), writeVal);
323 break;
324 }
325
326 if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
327 writeVal = writeVal - 0x06060606;
328 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
329 TXHIGHPWRLEVEL_BT2)
330 writeVal = writeVal - 0x0c0c0c0c;
331 *(p_outwriteval + rf) = writeVal;
332 }
333}
334
335static void _rtl8723ae_write_ofdm_power_reg(struct ieee80211_hw *hw,
336 u8 index, u32 *pValue)
337{
338 struct rtl_priv *rtlpriv = rtl_priv(hw);
339 struct rtl_phy *rtlphy = &(rtlpriv->phy);
340
341 u16 regoffset_a[6] = {
342 RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
343 RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
344 RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
345 };
346 u16 regoffset_b[6] = {
347 RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
348 RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
349 RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
350 };
351 u8 i, rf, pwr_val[4];
352 u32 writeVal;
353 u16 regoffset;
354
355 for (rf = 0; rf < 2; rf++) {
356 writeVal = pValue[rf];
357 for (i = 0; i < 4; i++) {
358 pwr_val[i] = (u8) ((writeVal & (0x7f <<
359 (i * 8))) >> (i * 8));
360
361 if (pwr_val[i] > RF6052_MAX_TX_PWR)
362 pwr_val[i] = RF6052_MAX_TX_PWR;
363 }
364 writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
365 (pwr_val[1] << 8) | pwr_val[0];
366
367 if (rf == 0)
368 regoffset = regoffset_a[index];
369 else
370 regoffset = regoffset_b[index];
371 rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
372
373 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
374 "Set 0x%x = %08x\n", regoffset, writeVal);
375
376 if (((get_rf_type(rtlphy) == RF_2T2R) &&
377 (regoffset == RTXAGC_A_MCS15_MCS12 ||
378 regoffset == RTXAGC_B_MCS15_MCS12)) ||
379 ((get_rf_type(rtlphy) != RF_2T2R) &&
380 (regoffset == RTXAGC_A_MCS07_MCS04 ||
381 regoffset == RTXAGC_B_MCS07_MCS04))) {
382
383 writeVal = pwr_val[3];
384 if (regoffset == RTXAGC_A_MCS15_MCS12 ||
385 regoffset == RTXAGC_A_MCS07_MCS04)
386 regoffset = 0xc90;
387 if (regoffset == RTXAGC_B_MCS15_MCS12 ||
388 regoffset == RTXAGC_B_MCS07_MCS04)
389 regoffset = 0xc98;
390
391 for (i = 0; i < 3; i++) {
392 writeVal = (writeVal > 6) ? (writeVal - 6) : 0;
393 rtl_write_byte(rtlpriv, (u32) (regoffset + i),
394 (u8) writeVal);
395 }
396 }
397 }
398}
399
400void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
401 u8 *ppowerlevel, u8 channel)
402{
403 u32 writeVal[2], powerBase0[2], powerBase1[2];
404 u8 index;
405
406 rtl8723ae_phy_get_power_base(hw, ppowerlevel,
407 channel, &powerBase0[0], &powerBase1[0]);
408
409 for (index = 0; index < 6; index++) {
410 rtl8723ae_get_txpwr_val_by_reg(hw, channel, index,
411 &powerBase0[0],
412 &powerBase1[0],
413 &writeVal[0]);
414
415 _rtl8723ae_write_ofdm_power_reg(hw, index, &writeVal[0]);
416 }
417}
418
419static bool _rtl8723ae_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
420{
421 struct rtl_priv *rtlpriv = rtl_priv(hw);
422 struct rtl_phy *rtlphy = &(rtlpriv->phy);
423 u32 u4_regvalue = 0;
424 u8 rfpath;
425 bool rtstatus = true;
426 struct bb_reg_def *pphyreg;
427
428 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
429
430 pphyreg = &rtlphy->phyreg_def[rfpath];
431
432 switch (rfpath) {
433 case RF90_PATH_A:
434 case RF90_PATH_C:
435 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
436 BRFSI_RFENV);
437 break;
438 case RF90_PATH_B:
439 case RF90_PATH_D:
440 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
441 BRFSI_RFENV << 16);
442 break;
443 }
444
445 rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
446 udelay(1);
447
448 rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
449 udelay(1);
450
451 rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
452 B3WIREADDREAALENGTH, 0x0);
453 udelay(1);
454
455 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
456 udelay(1);
457
458 switch (rfpath) {
459 case RF90_PATH_A:
460 rtstatus = rtl8723ae_phy_config_rf_with_headerfile(hw,
461 (enum radio_path)rfpath);
462 break;
463 case RF90_PATH_B:
464 rtstatus = rtl8723ae_phy_config_rf_with_headerfile(hw,
465 (enum radio_path)rfpath);
466 break;
467 case RF90_PATH_C:
468 break;
469 case RF90_PATH_D:
470 break;
471 }
472 switch (rfpath) {
473 case RF90_PATH_A:
474 case RF90_PATH_C:
475 rtl_set_bbreg(hw, pphyreg->rfintfs,
476 BRFSI_RFENV, u4_regvalue);
477 break;
478 case RF90_PATH_B:
479 case RF90_PATH_D:
480 rtl_set_bbreg(hw, pphyreg->rfintfs,
481 BRFSI_RFENV << 16, u4_regvalue);
482 break;
483 }
484 if (rtstatus != true) {
485 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
486 "Radio[%d] Fail!!", rfpath);
487 return false;
488 }
489 }
490 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
491 return rtstatus;
492}
493
494bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw)
495{
496 struct rtl_priv *rtlpriv = rtl_priv(hw);
497 struct rtl_phy *rtlphy = &(rtlpriv->phy);
498
499 if (rtlphy->rf_type == RF_1T1R)
500 rtlphy->num_total_rfpath = 1;
501 else
502 rtlphy->num_total_rfpath = 2;
503
504 return _rtl8723ae_phy_rf6052_config_parafile(hw);
505}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
new file mode 100644
index 00000000000..d0f9dd79abe
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
@@ -0,0 +1,43 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL8723E_RF_H__
31#define __RTL8723E_RF_H__
32
33#define RF6052_MAX_TX_PWR 0x3F
34
35extern void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
36 u8 bandwidth);
37extern void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
38 u8 *ppowerlevel);
39extern void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
40 u8 *ppowerlevel, u8 channel);
41extern bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw);
42
43#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
new file mode 100644
index 00000000000..0afdc240f2f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
@@ -0,0 +1,387 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include <linux/vmalloc.h>
32#include <linux/module.h>
33
34#include "../core.h"
35#include "../pci.h"
36#include "reg.h"
37#include "def.h"
38#include "phy.h"
39#include "dm.h"
40#include "hw.h"
41#include "sw.h"
42#include "trx.h"
43#include "led.h"
44#include "table.h"
45#include "hal_btc.h"
46
47static void rtl8723ae_init_aspm_vars(struct ieee80211_hw *hw)
48{
49 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
50
51 /*close ASPM for AMD defaultly */
52 rtlpci->const_amdpci_aspm = 0;
53
54 /* ASPM PS mode.
55 * 0 - Disable ASPM,
56 * 1 - Enable ASPM without Clock Req,
57 * 2 - Enable ASPM with Clock Req,
58 * 3 - Alwyas Enable ASPM with Clock Req,
59 * 4 - Always Enable ASPM without Clock Req.
60 * set defult to RTL8192CE:3 RTL8192E:2
61 */
62 rtlpci->const_pci_aspm = 3;
63
64 /*Setting for PCI-E device */
65 rtlpci->const_devicepci_aspm_setting = 0x03;
66
67 /*Setting for PCI-E bridge */
68 rtlpci->const_hostpci_aspm_setting = 0x02;
69
70 /* In Hw/Sw Radio Off situation.
71 * 0 - Default,
72 * 1 - From ASPM setting without low Mac Pwr,
73 * 2 - From ASPM setting with low Mac Pwr,
74 * 3 - Bus D3
75 * set default to RTL8192CE:0 RTL8192SE:2
76 */
77 rtlpci->const_hwsw_rfoff_d3 = 0;
78
79 /* This setting works for those device with
80 * backdoor ASPM setting such as EPHY setting.
81 * 0 - Not support ASPM,
82 * 1 - Support ASPM,
83 * 2 - According to chipset.
84 */
85 rtlpci->const_support_pciaspm = 1;
86}
87
88int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw)
89{
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
92 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
93 int err;
94
95 rtl8723ae_bt_reg_init(hw);
96 rtlpriv->dm.dm_initialgain_enable = 1;
97 rtlpriv->dm.dm_flag = 0;
98 rtlpriv->dm.disable_framebursting = 0;
99 rtlpriv->dm.thermalvalue = 0;
100 rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
101
102 /* compatible 5G band 88ce just 2.4G band & smsp */
103 rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
104 rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
105 rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
106
107 rtlpci->receive_config = (RCR_APPFCS |
108 RCR_APP_MIC |
109 RCR_APP_ICV |
110 RCR_APP_PHYST_RXFF |
111 RCR_HTC_LOC_CTRL |
112 RCR_AMF |
113 RCR_ACF |
114 RCR_ADF |
115 RCR_AICV |
116 RCR_AB |
117 RCR_AM |
118 RCR_APM |
119 0);
120
121 rtlpci->irq_mask[0] =
122 (u32) (PHIMR_ROK |
123 PHIMR_RDU |
124 PHIMR_VODOK |
125 PHIMR_VIDOK |
126 PHIMR_BEDOK |
127 PHIMR_BKDOK |
128 PHIMR_MGNTDOK |
129 PHIMR_HIGHDOK |
130 PHIMR_C2HCMD |
131 PHIMR_HISRE_IND |
132 PHIMR_TSF_BIT32_TOGGLE |
133 PHIMR_TXBCNOK |
134 PHIMR_PSTIMEOUT |
135 0);
136
137 rtlpci->irq_mask[1] = (u32)(PHIMR_RXFOVW | 0);
138
139 /* for debug level */
140 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
141 /* for LPS & IPS */
142 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
143 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
144 rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
145 rtlpriv->psc.reg_fwctrl_lps = 3;
146 rtlpriv->psc.reg_max_lps_awakeintvl = 5;
147 /* for ASPM, you can close aspm through
148 * set const_support_pciaspm = 0
149 */
150 rtl8723ae_init_aspm_vars(hw);
151
152 if (rtlpriv->psc.reg_fwctrl_lps == 1)
153 rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
154 else if (rtlpriv->psc.reg_fwctrl_lps == 2)
155 rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
156 else if (rtlpriv->psc.reg_fwctrl_lps == 3)
157 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
158
159 /* for firmware buf */
160 rtlpriv->rtlhal.pfirmware = vmalloc(0x6000);
161 if (!rtlpriv->rtlhal.pfirmware) {
162 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
163 "Can't alloc buffer for fw.\n");
164 return 1;
165 }
166
167 if (IS_VENDOR_8723_A_CUT(rtlhal->version))
168 rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw.bin";
169 else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
170 rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw_B.bin";
171
172 rtlpriv->max_fw_size = 0x6000;
173 pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
174 err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
175 rtlpriv->io.dev, GFP_KERNEL, hw,
176 rtl_fw_cb);
177 if (err) {
178 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
179 "Failed to request firmware!\n");
180 return 1;
181 }
182 return 0;
183}
184
185void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw)
186{
187 struct rtl_priv *rtlpriv = rtl_priv(hw);
188
189 if (rtlpriv->rtlhal.pfirmware) {
190 vfree(rtlpriv->rtlhal.pfirmware);
191 rtlpriv->rtlhal.pfirmware = NULL;
192 }
193}
194
195static struct rtl_hal_ops rtl8723ae_hal_ops = {
196 .init_sw_vars = rtl8723ae_init_sw_vars,
197 .deinit_sw_vars = rtl8723ae_deinit_sw_vars,
198 .read_eeprom_info = rtl8723ae_read_eeprom_info,
199 .interrupt_recognized = rtl8723ae_interrupt_recognized,
200 .hw_init = rtl8723ae_hw_init,
201 .hw_disable = rtl8723ae_card_disable,
202 .hw_suspend = rtl8723ae_suspend,
203 .hw_resume = rtl8723ae_resume,
204 .enable_interrupt = rtl8723ae_enable_interrupt,
205 .disable_interrupt = rtl8723ae_disable_interrupt,
206 .set_network_type = rtl8723ae_set_network_type,
207 .set_chk_bssid = rtl8723ae_set_check_bssid,
208 .set_qos = rtl8723ae_set_qos,
209 .set_bcn_reg = rtl8723ae_set_beacon_related_registers,
210 .set_bcn_intv = rtl8723ae_set_beacon_interval,
211 .update_interrupt_mask = rtl8723ae_update_interrupt_mask,
212 .get_hw_reg = rtl8723ae_get_hw_reg,
213 .set_hw_reg = rtl8723ae_set_hw_reg,
214 .update_rate_tbl = rtl8723ae_update_hal_rate_tbl,
215 .fill_tx_desc = rtl8723ae_tx_fill_desc,
216 .fill_tx_cmddesc = rtl8723ae_tx_fill_cmddesc,
217 .query_rx_desc = rtl8723ae_rx_query_desc,
218 .set_channel_access = rtl8723ae_update_channel_access_setting,
219 .radio_onoff_checking = rtl8723ae_gpio_radio_on_off_checking,
220 .set_bw_mode = rtl8723ae_phy_set_bw_mode,
221 .switch_channel = rtl8723ae_phy_sw_chnl,
222 .dm_watchdog = rtl8723ae_dm_watchdog,
223 .scan_operation_backup = rtl8723ae_phy_scan_operation_backup,
224 .set_rf_power_state = rtl8723ae_phy_set_rf_power_state,
225 .led_control = rtl8723ae_led_control,
226 .set_desc = rtl8723ae_set_desc,
227 .get_desc = rtl8723ae_get_desc,
228 .tx_polling = rtl8723ae_tx_polling,
229 .enable_hw_sec = rtl8723ae_enable_hw_security_config,
230 .set_key = rtl8723ae_set_key,
231 .init_sw_leds = rtl8723ae_init_sw_leds,
232 .allow_all_destaddr = rtl8723ae_allow_all_destaddr,
233 .get_bbreg = rtl8723ae_phy_query_bb_reg,
234 .set_bbreg = rtl8723ae_phy_set_bb_reg,
235 .get_rfreg = rtl8723ae_phy_query_rf_reg,
236 .set_rfreg = rtl8723ae_phy_set_rf_reg,
237 .c2h_command_handle = rtl_8723e_c2h_command_handle,
238 .bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify,
239 .bt_coex_off_before_lps = rtl8723ae_bt_coex_off_before_lps,
240};
241
242static struct rtl_mod_params rtl8723ae_mod_params = {
243 .sw_crypto = false,
244 .inactiveps = true,
245 .swctrl_lps = false,
246 .fwctrl_lps = true,
247 .debug = DBG_EMERG,
248};
249
250static struct rtl_hal_cfg rtl8723ae_hal_cfg = {
251 .bar_id = 2,
252 .write_readback = true,
253 .name = "rtl8723ae_pci",
254 .fw_name = "rtlwifi/rtl8723aefw.bin",
255 .ops = &rtl8723ae_hal_ops,
256 .mod_params = &rtl8723ae_mod_params,
257 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
258 .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
259 .maps[SYS_CLK] = REG_SYS_CLKR,
260 .maps[MAC_RCR_AM] = AM,
261 .maps[MAC_RCR_AB] = AB,
262 .maps[MAC_RCR_ACRC32] = ACRC32,
263 .maps[MAC_RCR_ACF] = ACF,
264 .maps[MAC_RCR_AAP] = AAP,
265 .maps[EFUSE_TEST] = REG_EFUSE_TEST,
266 .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
267 .maps[EFUSE_CLK] = 0,
268 .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
269 .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
270 .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
271 .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
272 .maps[EFUSE_ANA8M] = ANA8M,
273 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
274 .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
275 .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
276 .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
277
278 .maps[RWCAM] = REG_CAMCMD,
279 .maps[WCAMI] = REG_CAMWRITE,
280 .maps[RCAMO] = REG_CAMREAD,
281 .maps[CAMDBG] = REG_CAMDBG,
282 .maps[SECR] = REG_SECCFG,
283 .maps[SEC_CAM_NONE] = CAM_NONE,
284 .maps[SEC_CAM_WEP40] = CAM_WEP40,
285 .maps[SEC_CAM_TKIP] = CAM_TKIP,
286 .maps[SEC_CAM_AES] = CAM_AES,
287 .maps[SEC_CAM_WEP104] = CAM_WEP104,
288
289 .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
290 .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
291 .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
292 .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
293 .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
294 .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
295 .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
296 .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
297 .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
298 .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
299 .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
300 .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
301 .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
302 .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
303 .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
304 .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
305
306 .maps[RTL_IMR_TXFOVW] = PHIMR_TXFOVW,
307 .maps[RTL_IMR_PSTIMEOUT] = PHIMR_PSTIMEOUT,
308 .maps[RTL_IMR_BcnInt] = PHIMR_BCNDMAINT0,
309 .maps[RTL_IMR_RXFOVW] = PHIMR_RXFOVW,
310 .maps[RTL_IMR_RDU] = PHIMR_RDU,
311 .maps[RTL_IMR_ATIMEND] = PHIMR_ATIMEND_E,
312 .maps[RTL_IMR_BDOK] = PHIMR_BCNDOK0,
313 .maps[RTL_IMR_MGNTDOK] = PHIMR_MGNTDOK,
314 .maps[RTL_IMR_TBDER] = PHIMR_TXBCNERR,
315 .maps[RTL_IMR_HIGHDOK] = PHIMR_HIGHDOK,
316 .maps[RTL_IMR_TBDOK] = PHIMR_TXBCNOK,
317 .maps[RTL_IMR_BKDOK] = PHIMR_BKDOK,
318 .maps[RTL_IMR_BEDOK] = PHIMR_BEDOK,
319 .maps[RTL_IMR_VIDOK] = PHIMR_VIDOK,
320 .maps[RTL_IMR_VODOK] = PHIMR_VODOK,
321 .maps[RTL_IMR_ROK] = PHIMR_ROK,
322 .maps[RTL_IBSS_INT_MASKS] = (PHIMR_BCNDMAINT0 |
323 PHIMR_TXBCNOK | PHIMR_TXBCNERR),
324 .maps[RTL_IMR_C2HCMD] = PHIMR_C2HCMD,
325
326
327 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M,
328 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M,
329 .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M,
330 .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M,
331 .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M,
332 .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M,
333 .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M,
334 .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M,
335 .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M,
336 .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M,
337 .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M,
338 .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M,
339
340 .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7,
341 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
342};
343
344static struct pci_device_id rtl8723ae_pci_ids[] __devinitdata = {
345 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8723, rtl8723ae_hal_cfg)},
346 {},
347};
348
349MODULE_DEVICE_TABLE(pci, rtl8723ae_pci_ids);
350
351MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
352MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
353MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
354MODULE_LICENSE("GPL");
355MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless");
356MODULE_FIRMWARE("rtlwifi/rtl8723aefw.bin");
357MODULE_FIRMWARE("rtlwifi/rtl8723aefw_B.bin");
358
359module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444);
360module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444);
361module_param_named(ips, rtl8723ae_mod_params.inactiveps, bool, 0444);
362module_param_named(swlps, rtl8723ae_mod_params.swctrl_lps, bool, 0444);
363module_param_named(fwlps, rtl8723ae_mod_params.fwctrl_lps, bool, 0444);
364MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
365MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
366MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
367MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
368MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
369
370static const struct dev_pm_ops rtlwifi_pm_ops = {
371 .suspend = rtl_pci_suspend,
372 .resume = rtl_pci_resume,
373 .freeze = rtl_pci_suspend,
374 .thaw = rtl_pci_resume,
375 .poweroff = rtl_pci_suspend,
376 .restore = rtl_pci_resume,
377};
378
379static struct pci_driver rtl8723ae_driver = {
380 .name = KBUILD_MODNAME,
381 .id_table = rtl8723ae_pci_ids,
382 .probe = rtl_pci_probe,
383 .remove = rtl_pci_disconnect,
384 .driver.pm = &rtlwifi_pm_ops,
385};
386
387module_pci_driver(rtl8723ae_driver);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h
new file mode 100644
index 00000000000..fc4fde5e3eb
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h
@@ -0,0 +1,37 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL8723E_SW_H__
31#define __RTL8723E_SW_H__
32
33int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw);
34void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw);
35void rtl8723ae_init_var_map(struct ieee80211_hw *hw);
36
37#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/table.c b/drivers/net/wireless/rtlwifi/rtl8723ae/table.c
new file mode 100644
index 00000000000..9b0b50cc4ad
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/table.c
@@ -0,0 +1,738 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Created on 2010/ 5/18, 1:41
27 *
28 * Larry Finger <Larry.Finger@lwfinger.net>
29 *
30 *****************************************************************************/
31
32#include "table.h"
33
34u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH] = {
35 0x800, 0x80040000,
36 0x804, 0x00000003,
37 0x808, 0x0000fc00,
38 0x80c, 0x0000000a,
39 0x810, 0x10005388,
40 0x814, 0x020c3d10,
41 0x818, 0x02200385,
42 0x81c, 0x00000000,
43 0x820, 0x01000100,
44 0x824, 0x00390004,
45 0x828, 0x00000000,
46 0x82c, 0x00000000,
47 0x830, 0x00000000,
48 0x834, 0x00000000,
49 0x838, 0x00000000,
50 0x83c, 0x00000000,
51 0x840, 0x00010000,
52 0x844, 0x00000000,
53 0x848, 0x00000000,
54 0x84c, 0x00000000,
55 0x850, 0x00000000,
56 0x854, 0x00000000,
57 0x858, 0x569a569a,
58 0x85c, 0x001b25a4,
59 0x860, 0x66f60110,
60 0x864, 0x061f0130,
61 0x868, 0x00000000,
62 0x86c, 0x32323200,
63 0x870, 0x07000760,
64 0x874, 0x22004000,
65 0x878, 0x00000808,
66 0x87c, 0x00000000,
67 0x880, 0xc0083070,
68 0x884, 0x000004d5,
69 0x888, 0x00000000,
70 0x88c, 0xccc000c0,
71 0x890, 0x00000800,
72 0x894, 0xfffffffe,
73 0x898, 0x40302010,
74 0x89c, 0x00706050,
75 0x900, 0x00000000,
76 0x904, 0x00000023,
77 0x908, 0x00000000,
78 0x90c, 0x81121111,
79 0xa00, 0x00d047c8,
80 0xa04, 0x80ff000c,
81 0xa08, 0x8c838300,
82 0xa0c, 0x2e68120f,
83 0xa10, 0x9500bb78,
84 0xa14, 0x11144028,
85 0xa18, 0x00881117,
86 0xa1c, 0x89140f00,
87 0xa20, 0x1a1b0000,
88 0xa24, 0x090e1317,
89 0xa28, 0x00000204,
90 0xa2c, 0x00d30000,
91 0xa70, 0x101fbf00,
92 0xa74, 0x00000007,
93 0xa78, 0x00000900,
94 0xc00, 0x48071d40,
95 0xc04, 0x03a05611,
96 0xc08, 0x000000e4,
97 0xc0c, 0x6c6c6c6c,
98 0xc10, 0x08800000,
99 0xc14, 0x40000100,
100 0xc18, 0x08800000,
101 0xc1c, 0x40000100,
102 0xc20, 0x00000000,
103 0xc24, 0x00000000,
104 0xc28, 0x00000000,
105 0xc2c, 0x00000000,
106 0xc30, 0x69e9ac44,
107 0xc34, 0x469652cf,
108 0xc38, 0x49795994,
109 0xc3c, 0x0a97971c,
110 0xc40, 0x1f7c403f,
111 0xc44, 0x000100b7,
112 0xc48, 0xec020107,
113 0xc4c, 0x007f037f,
114 0xc50, 0x69543420,
115 0xc54, 0x43bc0094,
116 0xc58, 0x69543420,
117 0xc5c, 0x433c0094,
118 0xc60, 0x00000000,
119 0xc64, 0x7116848b,
120 0xc68, 0x47c00bff,
121 0xc6c, 0x00000036,
122 0xc70, 0x2c7f000d,
123 0xc74, 0x018610db,
124 0xc78, 0x0000001f,
125 0xc7c, 0x00b91612,
126 0xc80, 0x40000100,
127 0xc84, 0x20f60000,
128 0xc88, 0x40000100,
129 0xc8c, 0x20200000,
130 0xc90, 0x00121820,
131 0xc94, 0x00000000,
132 0xc98, 0x00121820,
133 0xc9c, 0x00007f7f,
134 0xca0, 0x00000000,
135 0xca4, 0x00000080,
136 0xca8, 0x00000000,
137 0xcac, 0x00000000,
138 0xcb0, 0x00000000,
139 0xcb4, 0x00000000,
140 0xcb8, 0x00000000,
141 0xcbc, 0x28000000,
142 0xcc0, 0x00000000,
143 0xcc4, 0x00000000,
144 0xcc8, 0x00000000,
145 0xccc, 0x00000000,
146 0xcd0, 0x00000000,
147 0xcd4, 0x00000000,
148 0xcd8, 0x64b22427,
149 0xcdc, 0x00766932,
150 0xce0, 0x00222222,
151 0xce4, 0x00000000,
152 0xce8, 0x37644302,
153 0xcec, 0x2f97d40c,
154 0xd00, 0x00080740,
155 0xd04, 0x00020401,
156 0xd08, 0x0000907f,
157 0xd0c, 0x20010201,
158 0xd10, 0xa0633333,
159 0xd14, 0x3333bc43,
160 0xd18, 0x7a8f5b6b,
161 0xd2c, 0xcc979975,
162 0xd30, 0x00000000,
163 0xd34, 0x80608000,
164 0xd38, 0x00000000,
165 0xd3c, 0x00027293,
166 0xd40, 0x00000000,
167 0xd44, 0x00000000,
168 0xd48, 0x00000000,
169 0xd4c, 0x00000000,
170 0xd50, 0x6437140a,
171 0xd54, 0x00000000,
172 0xd58, 0x00000000,
173 0xd5c, 0x30032064,
174 0xd60, 0x4653de68,
175 0xd64, 0x04518a3c,
176 0xd68, 0x00002101,
177 0xd6c, 0x2a201c16,
178 0xd70, 0x1812362e,
179 0xd74, 0x322c2220,
180 0xd78, 0x000e3c24,
181 0xe00, 0x2a2a2a2a,
182 0xe04, 0x2a2a2a2a,
183 0xe08, 0x03902a2a,
184 0xe10, 0x2a2a2a2a,
185 0xe14, 0x2a2a2a2a,
186 0xe18, 0x2a2a2a2a,
187 0xe1c, 0x2a2a2a2a,
188 0xe28, 0x00000000,
189 0xe30, 0x1000dc1f,
190 0xe34, 0x10008c1f,
191 0xe38, 0x02140102,
192 0xe3c, 0x681604c2,
193 0xe40, 0x01007c00,
194 0xe44, 0x01004800,
195 0xe48, 0xfb000000,
196 0xe4c, 0x000028d1,
197 0xe50, 0x1000dc1f,
198 0xe54, 0x10008c1f,
199 0xe58, 0x02140102,
200 0xe5c, 0x28160d05,
201 0xe60, 0x00000008,
202 0xe68, 0x001b25a4,
203 0xe6c, 0x631b25a0,
204 0xe70, 0x631b25a0,
205 0xe74, 0x081b25a0,
206 0xe78, 0x081b25a0,
207 0xe7c, 0x081b25a0,
208 0xe80, 0x081b25a0,
209 0xe84, 0x631b25a0,
210 0xe88, 0x081b25a0,
211 0xe8c, 0x631b25a0,
212 0xed0, 0x631b25a0,
213 0xed4, 0x631b25a0,
214 0xed8, 0x631b25a0,
215 0xedc, 0x001b25a0,
216 0xee0, 0x001b25a0,
217 0xeec, 0x6b1b25a0,
218 0xf14, 0x00000003,
219 0xf4c, 0x00000000,
220 0xf00, 0x00000300,
221};
222
223u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH] = {
224 0xe00, 0xffffffff, 0x0a0c0c0c,
225 0xe04, 0xffffffff, 0x02040608,
226 0xe08, 0x0000ff00, 0x00000000,
227 0x86c, 0xffffff00, 0x00000000,
228 0xe10, 0xffffffff, 0x0a0c0d0e,
229 0xe14, 0xffffffff, 0x02040608,
230 0xe18, 0xffffffff, 0x0a0c0d0e,
231 0xe1c, 0xffffffff, 0x02040608,
232 0x830, 0xffffffff, 0x0a0c0c0c,
233 0x834, 0xffffffff, 0x02040608,
234 0x838, 0xffffff00, 0x00000000,
235 0x86c, 0x000000ff, 0x00000000,
236 0x83c, 0xffffffff, 0x0a0c0d0e,
237 0x848, 0xffffffff, 0x02040608,
238 0x84c, 0xffffffff, 0x0a0c0d0e,
239 0x868, 0xffffffff, 0x02040608,
240 0xe00, 0xffffffff, 0x00000000,
241 0xe04, 0xffffffff, 0x00000000,
242 0xe08, 0x0000ff00, 0x00000000,
243 0x86c, 0xffffff00, 0x00000000,
244 0xe10, 0xffffffff, 0x00000000,
245 0xe14, 0xffffffff, 0x00000000,
246 0xe18, 0xffffffff, 0x00000000,
247 0xe1c, 0xffffffff, 0x00000000,
248 0x830, 0xffffffff, 0x00000000,
249 0x834, 0xffffffff, 0x00000000,
250 0x838, 0xffffff00, 0x00000000,
251 0x86c, 0x000000ff, 0x00000000,
252 0x83c, 0xffffffff, 0x00000000,
253 0x848, 0xffffffff, 0x00000000,
254 0x84c, 0xffffffff, 0x00000000,
255 0x868, 0xffffffff, 0x00000000,
256 0xe00, 0xffffffff, 0x04040404,
257 0xe04, 0xffffffff, 0x00020204,
258 0xe08, 0x0000ff00, 0x00000000,
259 0x86c, 0xffffff00, 0x00000000,
260 0xe10, 0xffffffff, 0x06060606,
261 0xe14, 0xffffffff, 0x00020406,
262 0xe18, 0xffffffff, 0x00000000,
263 0xe1c, 0xffffffff, 0x00000000,
264 0x830, 0xffffffff, 0x04040404,
265 0x834, 0xffffffff, 0x00020204,
266 0x838, 0xffffff00, 0x00000000,
267 0x86c, 0x000000ff, 0x00000000,
268 0x83c, 0xffffffff, 0x06060606,
269 0x848, 0xffffffff, 0x00020406,
270 0x84c, 0xffffffff, 0x00000000,
271 0x868, 0xffffffff, 0x00000000,
272 0xe00, 0xffffffff, 0x00000000,
273 0xe04, 0xffffffff, 0x00000000,
274 0xe08, 0x0000ff00, 0x00000000,
275 0x86c, 0xffffff00, 0x00000000,
276 0xe10, 0xffffffff, 0x00000000,
277 0xe14, 0xffffffff, 0x00000000,
278 0xe18, 0xffffffff, 0x00000000,
279 0xe1c, 0xffffffff, 0x00000000,
280 0x830, 0xffffffff, 0x00000000,
281 0x834, 0xffffffff, 0x00000000,
282 0x838, 0xffffff00, 0x00000000,
283 0x86c, 0x000000ff, 0x00000000,
284 0x83c, 0xffffffff, 0x00000000,
285 0x848, 0xffffffff, 0x00000000,
286 0x84c, 0xffffffff, 0x00000000,
287 0x868, 0xffffffff, 0x00000000,
288 0xe00, 0xffffffff, 0x00000000,
289 0xe04, 0xffffffff, 0x00000000,
290 0xe08, 0x0000ff00, 0x00000000,
291 0x86c, 0xffffff00, 0x00000000,
292 0xe10, 0xffffffff, 0x00000000,
293 0xe14, 0xffffffff, 0x00000000,
294 0xe18, 0xffffffff, 0x00000000,
295 0xe1c, 0xffffffff, 0x00000000,
296 0x830, 0xffffffff, 0x00000000,
297 0x834, 0xffffffff, 0x00000000,
298 0x838, 0xffffff00, 0x00000000,
299 0x86c, 0x000000ff, 0x00000000,
300 0x83c, 0xffffffff, 0x00000000,
301 0x848, 0xffffffff, 0x00000000,
302 0x84c, 0xffffffff, 0x00000000,
303 0x868, 0xffffffff, 0x00000000,
304 0xe00, 0xffffffff, 0x04040404,
305 0xe04, 0xffffffff, 0x00020204,
306 0xe08, 0x0000ff00, 0x00000000,
307 0x86c, 0xffffff00, 0x00000000,
308 0xe10, 0xffffffff, 0x00000000,
309 0xe14, 0xffffffff, 0x00000000,
310 0xe18, 0xffffffff, 0x00000000,
311 0xe1c, 0xffffffff, 0x00000000,
312 0x830, 0xffffffff, 0x04040404,
313 0x834, 0xffffffff, 0x00020204,
314 0x838, 0xffffff00, 0x00000000,
315 0x86c, 0x000000ff, 0x00000000,
316 0x83c, 0xffffffff, 0x00000000,
317 0x848, 0xffffffff, 0x00000000,
318 0x84c, 0xffffffff, 0x00000000,
319 0x868, 0xffffffff, 0x00000000,
320 0xe00, 0xffffffff, 0x00000000,
321 0xe04, 0xffffffff, 0x00000000,
322 0xe08, 0x0000ff00, 0x00000000,
323 0x86c, 0xffffff00, 0x00000000,
324 0xe10, 0xffffffff, 0x00000000,
325 0xe14, 0xffffffff, 0x00000000,
326 0xe18, 0xffffffff, 0x00000000,
327 0xe1c, 0xffffffff, 0x00000000,
328 0x830, 0xffffffff, 0x00000000,
329 0x834, 0xffffffff, 0x00000000,
330 0x838, 0xffffff00, 0x00000000,
331 0x86c, 0x000000ff, 0x00000000,
332 0x83c, 0xffffffff, 0x00000000,
333 0x848, 0xffffffff, 0x00000000,
334 0x84c, 0xffffffff, 0x00000000,
335 0x868, 0xffffffff, 0x00000000,
336};
337
338u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH] = {
339 0x000, 0x00030159,
340 0x001, 0x00031284,
341 0x002, 0x00098000,
342 0x003, 0x00018c63,
343 0x004, 0x000210e7,
344 0x009, 0x0002044f,
345 0x00a, 0x0001a3f1,
346 0x00b, 0x00014787,
347 0x00c, 0x000896fe,
348 0x00d, 0x0000e02c,
349 0x00e, 0x00039ce7,
350 0x00f, 0x00000451,
351 0x019, 0x00000000,
352 0x01a, 0x00030355,
353 0x01b, 0x00060a00,
354 0x01c, 0x000fc378,
355 0x01d, 0x000a1250,
356 0x01e, 0x0004445f,
357 0x01f, 0x00080001,
358 0x020, 0x0000b614,
359 0x021, 0x0006c000,
360 0x022, 0x00000000,
361 0x023, 0x00001558,
362 0x024, 0x00000060,
363 0x025, 0x00000483,
364 0x026, 0x0004f000,
365 0x027, 0x000ec7d9,
366 0x028, 0x00057730,
367 0x029, 0x00004783,
368 0x02a, 0x00000001,
369 0x02b, 0x00021334,
370 0x02a, 0x00000000,
371 0x02b, 0x00000054,
372 0x02a, 0x00000001,
373 0x02b, 0x00000808,
374 0x02b, 0x00053333,
375 0x02c, 0x0000000c,
376 0x02a, 0x00000002,
377 0x02b, 0x00000808,
378 0x02b, 0x0005b333,
379 0x02c, 0x0000000d,
380 0x02a, 0x00000003,
381 0x02b, 0x00000808,
382 0x02b, 0x00063333,
383 0x02c, 0x0000000d,
384 0x02a, 0x00000004,
385 0x02b, 0x00000808,
386 0x02b, 0x0006b333,
387 0x02c, 0x0000000d,
388 0x02a, 0x00000005,
389 0x02b, 0x00000808,
390 0x02b, 0x00073333,
391 0x02c, 0x0000000d,
392 0x02a, 0x00000006,
393 0x02b, 0x00000709,
394 0x02b, 0x0005b333,
395 0x02c, 0x0000000d,
396 0x02a, 0x00000007,
397 0x02b, 0x00000709,
398 0x02b, 0x00063333,
399 0x02c, 0x0000000d,
400 0x02a, 0x00000008,
401 0x02b, 0x0000060a,
402 0x02b, 0x0004b333,
403 0x02c, 0x0000000d,
404 0x02a, 0x00000009,
405 0x02b, 0x0000060a,
406 0x02b, 0x00053333,
407 0x02c, 0x0000000d,
408 0x02a, 0x0000000a,
409 0x02b, 0x0000060a,
410 0x02b, 0x0005b333,
411 0x02c, 0x0000000d,
412 0x02a, 0x0000000b,
413 0x02b, 0x0000060a,
414 0x02b, 0x00063333,
415 0x02c, 0x0000000d,
416 0x02a, 0x0000000c,
417 0x02b, 0x0000060a,
418 0x02b, 0x0006b333,
419 0x02c, 0x0000000d,
420 0x02a, 0x0000000d,
421 0x02b, 0x0000060a,
422 0x02b, 0x00073333,
423 0x02c, 0x0000000d,
424 0x02a, 0x0000000e,
425 0x02b, 0x0000050b,
426 0x02b, 0x00066666,
427 0x02c, 0x0000001a,
428 0x02a, 0x000e0000,
429 0x010, 0x0004000f,
430 0x011, 0x000e31fc,
431 0x010, 0x0006000f,
432 0x011, 0x000ff9f8,
433 0x010, 0x0002000f,
434 0x011, 0x000203f9,
435 0x010, 0x0003000f,
436 0x011, 0x000ff500,
437 0x010, 0x00000000,
438 0x011, 0x00000000,
439 0x010, 0x0008000f,
440 0x011, 0x0003f100,
441 0x010, 0x0009000f,
442 0x011, 0x00023100,
443 0x012, 0x00032000,
444 0x012, 0x00071000,
445 0x012, 0x000b0000,
446 0x012, 0x000fc000,
447 0x013, 0x000287b3,
448 0x013, 0x000244b7,
449 0x013, 0x000204ab,
450 0x013, 0x0001c49f,
451 0x013, 0x00018493,
452 0x013, 0x0001429b,
453 0x013, 0x00010299,
454 0x013, 0x0000c29c,
455 0x013, 0x000081a0,
456 0x013, 0x000040ac,
457 0x013, 0x00000020,
458 0x014, 0x0001944c,
459 0x014, 0x00059444,
460 0x014, 0x0009944c,
461 0x014, 0x000d9444,
462 0x015, 0x0000f424,
463 0x015, 0x0004f407,
464 0x015, 0x0008f424,
465 0x015, 0x000cf424,
466 0x016, 0x00000339,
467 0x016, 0x00040339,
468 0x016, 0x00080339,
469 0x016, 0x000c0336,
470 0x000, 0x00010159,
471 0x018, 0x0000f401,
472 0x0fe, 0x00000000,
473 0x0fe, 0x00000000,
474 0x01f, 0x00080003,
475 0x0fe, 0x00000000,
476 0x0fe, 0x00000000,
477 0x01e, 0x00044457,
478 0x01f, 0x00080000,
479 0x000, 0x00030159,
480};
481
482
483u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH] = {
484 0x0,
485};
486
487
488u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH] = {
489 0x420, 0x00000080,
490 0x423, 0x00000000,
491 0x430, 0x00000000,
492 0x431, 0x00000000,
493 0x432, 0x00000000,
494 0x433, 0x00000001,
495 0x434, 0x00000004,
496 0x435, 0x00000005,
497 0x436, 0x00000006,
498 0x437, 0x00000007,
499 0x438, 0x00000000,
500 0x439, 0x00000000,
501 0x43a, 0x00000000,
502 0x43b, 0x00000001,
503 0x43c, 0x00000004,
504 0x43d, 0x00000005,
505 0x43e, 0x00000006,
506 0x43f, 0x00000007,
507 0x440, 0x0000005d,
508 0x441, 0x00000001,
509 0x442, 0x00000000,
510 0x444, 0x00000015,
511 0x445, 0x000000f0,
512 0x446, 0x0000000f,
513 0x447, 0x00000000,
514 0x458, 0x00000041,
515 0x459, 0x000000a8,
516 0x45a, 0x00000072,
517 0x45b, 0x000000b9,
518 0x460, 0x00000066,
519 0x461, 0x00000066,
520 0x462, 0x00000008,
521 0x463, 0x00000003,
522 0x4c8, 0x000000ff,
523 0x4c9, 0x00000008,
524 0x4cc, 0x000000ff,
525 0x4cd, 0x000000ff,
526 0x4ce, 0x00000001,
527 0x500, 0x00000026,
528 0x501, 0x000000a2,
529 0x502, 0x0000002f,
530 0x503, 0x00000000,
531 0x504, 0x00000028,
532 0x505, 0x000000a3,
533 0x506, 0x0000005e,
534 0x507, 0x00000000,
535 0x508, 0x0000002b,
536 0x509, 0x000000a4,
537 0x50a, 0x0000005e,
538 0x50b, 0x00000000,
539 0x50c, 0x0000004f,
540 0x50d, 0x000000a4,
541 0x50e, 0x00000000,
542 0x50f, 0x00000000,
543 0x512, 0x0000001c,
544 0x514, 0x0000000a,
545 0x515, 0x00000010,
546 0x516, 0x0000000a,
547 0x517, 0x00000010,
548 0x51a, 0x00000016,
549 0x524, 0x0000000f,
550 0x525, 0x0000004f,
551 0x546, 0x00000040,
552 0x547, 0x00000000,
553 0x550, 0x00000010,
554 0x551, 0x00000010,
555 0x559, 0x00000002,
556 0x55a, 0x00000002,
557 0x55d, 0x000000ff,
558 0x605, 0x00000030,
559 0x608, 0x0000000e,
560 0x609, 0x0000002a,
561 0x652, 0x00000020,
562 0x63c, 0x0000000a,
563 0x63d, 0x0000000e,
564 0x63e, 0x0000000a,
565 0x63f, 0x0000000e,
566 0x66e, 0x00000005,
567 0x700, 0x00000021,
568 0x701, 0x00000043,
569 0x702, 0x00000065,
570 0x703, 0x00000087,
571 0x708, 0x00000021,
572 0x709, 0x00000043,
573 0x70a, 0x00000065,
574 0x70b, 0x00000087,
575};
576
577u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH] = {
578 0xc78, 0x7b000001,
579 0xc78, 0x7b010001,
580 0xc78, 0x7b020001,
581 0xc78, 0x7b030001,
582 0xc78, 0x7b040001,
583 0xc78, 0x7b050001,
584 0xc78, 0x7a060001,
585 0xc78, 0x79070001,
586 0xc78, 0x78080001,
587 0xc78, 0x77090001,
588 0xc78, 0x760a0001,
589 0xc78, 0x750b0001,
590 0xc78, 0x740c0001,
591 0xc78, 0x730d0001,
592 0xc78, 0x720e0001,
593 0xc78, 0x710f0001,
594 0xc78, 0x70100001,
595 0xc78, 0x6f110001,
596 0xc78, 0x6e120001,
597 0xc78, 0x6d130001,
598 0xc78, 0x6c140001,
599 0xc78, 0x6b150001,
600 0xc78, 0x6a160001,
601 0xc78, 0x69170001,
602 0xc78, 0x68180001,
603 0xc78, 0x67190001,
604 0xc78, 0x661a0001,
605 0xc78, 0x651b0001,
606 0xc78, 0x641c0001,
607 0xc78, 0x631d0001,
608 0xc78, 0x621e0001,
609 0xc78, 0x611f0001,
610 0xc78, 0x60200001,
611 0xc78, 0x49210001,
612 0xc78, 0x48220001,
613 0xc78, 0x47230001,
614 0xc78, 0x46240001,
615 0xc78, 0x45250001,
616 0xc78, 0x44260001,
617 0xc78, 0x43270001,
618 0xc78, 0x42280001,
619 0xc78, 0x41290001,
620 0xc78, 0x402a0001,
621 0xc78, 0x262b0001,
622 0xc78, 0x252c0001,
623 0xc78, 0x242d0001,
624 0xc78, 0x232e0001,
625 0xc78, 0x222f0001,
626 0xc78, 0x21300001,
627 0xc78, 0x20310001,
628 0xc78, 0x06320001,
629 0xc78, 0x05330001,
630 0xc78, 0x04340001,
631 0xc78, 0x03350001,
632 0xc78, 0x02360001,
633 0xc78, 0x01370001,
634 0xc78, 0x00380001,
635 0xc78, 0x00390001,
636 0xc78, 0x003a0001,
637 0xc78, 0x003b0001,
638 0xc78, 0x003c0001,
639 0xc78, 0x003d0001,
640 0xc78, 0x003e0001,
641 0xc78, 0x003f0001,
642 0xc78, 0x7b400001,
643 0xc78, 0x7b410001,
644 0xc78, 0x7b420001,
645 0xc78, 0x7b430001,
646 0xc78, 0x7b440001,
647 0xc78, 0x7b450001,
648 0xc78, 0x7a460001,
649 0xc78, 0x79470001,
650 0xc78, 0x78480001,
651 0xc78, 0x77490001,
652 0xc78, 0x764a0001,
653 0xc78, 0x754b0001,
654 0xc78, 0x744c0001,
655 0xc78, 0x734d0001,
656 0xc78, 0x724e0001,
657 0xc78, 0x714f0001,
658 0xc78, 0x70500001,
659 0xc78, 0x6f510001,
660 0xc78, 0x6e520001,
661 0xc78, 0x6d530001,
662 0xc78, 0x6c540001,
663 0xc78, 0x6b550001,
664 0xc78, 0x6a560001,
665 0xc78, 0x69570001,
666 0xc78, 0x68580001,
667 0xc78, 0x67590001,
668 0xc78, 0x665a0001,
669 0xc78, 0x655b0001,
670 0xc78, 0x645c0001,
671 0xc78, 0x635d0001,
672 0xc78, 0x625e0001,
673 0xc78, 0x615f0001,
674 0xc78, 0x60600001,
675 0xc78, 0x49610001,
676 0xc78, 0x48620001,
677 0xc78, 0x47630001,
678 0xc78, 0x46640001,
679 0xc78, 0x45650001,
680 0xc78, 0x44660001,
681 0xc78, 0x43670001,
682 0xc78, 0x42680001,
683 0xc78, 0x41690001,
684 0xc78, 0x406a0001,
685 0xc78, 0x266b0001,
686 0xc78, 0x256c0001,
687 0xc78, 0x246d0001,
688 0xc78, 0x236e0001,
689 0xc78, 0x226f0001,
690 0xc78, 0x21700001,
691 0xc78, 0x20710001,
692 0xc78, 0x06720001,
693 0xc78, 0x05730001,
694 0xc78, 0x04740001,
695 0xc78, 0x03750001,
696 0xc78, 0x02760001,
697 0xc78, 0x01770001,
698 0xc78, 0x00780001,
699 0xc78, 0x00790001,
700 0xc78, 0x007a0001,
701 0xc78, 0x007b0001,
702 0xc78, 0x007c0001,
703 0xc78, 0x007d0001,
704 0xc78, 0x007e0001,
705 0xc78, 0x007f0001,
706 0xc78, 0x3800001e,
707 0xc78, 0x3801001e,
708 0xc78, 0x3802001e,
709 0xc78, 0x3803001e,
710 0xc78, 0x3804001e,
711 0xc78, 0x3805001e,
712 0xc78, 0x3806001e,
713 0xc78, 0x3807001e,
714 0xc78, 0x3808001e,
715 0xc78, 0x3c09001e,
716 0xc78, 0x3e0a001e,
717 0xc78, 0x400b001e,
718 0xc78, 0x440c001e,
719 0xc78, 0x480d001e,
720 0xc78, 0x4c0e001e,
721 0xc78, 0x500f001e,
722 0xc78, 0x5210001e,
723 0xc78, 0x5611001e,
724 0xc78, 0x5a12001e,
725 0xc78, 0x5e13001e,
726 0xc78, 0x6014001e,
727 0xc78, 0x6015001e,
728 0xc78, 0x6016001e,
729 0xc78, 0x6217001e,
730 0xc78, 0x6218001e,
731 0xc78, 0x6219001e,
732 0xc78, 0x621a001e,
733 0xc78, 0x621b001e,
734 0xc78, 0x621c001e,
735 0xc78, 0x621d001e,
736 0xc78, 0x621e001e,
737 0xc78, 0x621f001e,
738};
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/table.h b/drivers/net/wireless/rtlwifi/rtl8723ae/table.h
new file mode 100644
index 00000000000..f5ce71375c2
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/table.h
@@ -0,0 +1,50 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Created on 2010/ 5/18, 1:41
27 *
28 * Larry Finger <Larry.Finger@lwfinger.net>
29 *
30 *****************************************************************************/
31
32#ifndef __RTL8723E_TABLE__H_
33#define __RTL8723E_TABLE__H_
34
35#include <linux/types.h>
36
37#define RTL8723E_PHY_REG_1TARRAY_LENGTH 372
38extern u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH];
39#define RTL8723E_PHY_REG_ARRAY_PGLENGTH 336
40extern u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH];
41#define Rtl8723ERADIOA_1TARRAYLENGTH 282
42extern u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH];
43#define RTL8723E_RADIOB_1TARRAYLENGTH 1
44extern u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH];
45#define RTL8723E_MACARRAYLENGTH 172
46extern u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH];
47#define RTL8723E_AGCTAB_1TARRAYLENGTH 320
48extern u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH];
49
50#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
new file mode 100644
index 00000000000..87331d826d7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
@@ -0,0 +1,670 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../base.h"
33#include "../stats.h"
34#include "reg.h"
35#include "def.h"
36#include "phy.h"
37#include "trx.h"
38#include "led.h"
39
40static u8 _rtl8723ae_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
41{
42 __le16 fc = rtl_get_fc(skb);
43
44 if (unlikely(ieee80211_is_beacon(fc)))
45 return QSLT_BEACON;
46 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
47 return QSLT_MGNT;
48
49 return skb->priority;
50}
51
52static void _rtl8723ae_query_rxphystatus(struct ieee80211_hw *hw,
53 struct rtl_stats *pstatus, u8 *pdesc,
54 struct rx_fwinfo_8723e *p_drvinfo,
55 bool bpacket_match_bssid,
56 bool bpacket_toself, bool packet_beacon)
57{
58 struct rtl_priv *rtlpriv = rtl_priv(hw);
59 struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
60 struct phy_sts_cck_8723e_t *cck_buf;
61 s8 rx_pwr_all, rx_pwr[4];
62 u8 rf_rx_num = 0, evm, pwdb_all;
63 u8 i, max_spatial_stream;
64 u32 rssi, total_rssi = 0;
65 bool is_cck = pstatus->is_cck;
66
67 /* Record it for next packet processing */
68 pstatus->packet_matchbssid = bpacket_match_bssid;
69 pstatus->packet_toself = bpacket_toself;
70 pstatus->packet_beacon = packet_beacon;
71 pstatus->rx_mimo_sig_qual[0] = -1;
72 pstatus->rx_mimo_sig_qual[1] = -1;
73
74 if (is_cck) {
75 u8 report, cck_highpwr;
76
77 /* CCK Driver info Structure is not the same as OFDM packet. */
78 cck_buf = (struct phy_sts_cck_8723e_t *)p_drvinfo;
79
80 /* (1)Hardware does not provide RSSI for CCK
81 * (2)PWDB, Average PWDB cacluated by
82 * hardware (for rate adaptive)
83 */
84 if (ppsc->rfpwr_state == ERFON)
85 cck_highpwr = (u8) rtl_get_bbreg(hw,
86 RFPGA0_XA_HSSIPARAMETER2,
87 BIT(9));
88 else
89 cck_highpwr = false;
90
91 if (!cck_highpwr) {
92 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
93 report = cck_buf->cck_agc_rpt & 0xc0;
94 report = report >> 6;
95 switch (report) {
96 case 0x3:
97 rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
98 break;
99 case 0x2:
100 rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
101 break;
102 case 0x1:
103 rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
104 break;
105 case 0x0:
106 rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
107 break;
108 }
109 } else {
110 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
111 report = p_drvinfo->cfosho[0] & 0x60;
112 report = report >> 5;
113 switch (report) {
114 case 0x3:
115 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
116 break;
117 case 0x2:
118 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
119 break;
120 case 0x1:
121 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
122 break;
123 case 0x0:
124 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
125 break;
126 }
127 }
128
129 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
130 /* CCK gain is smaller than OFDM/MCS gain,
131 * so we add gain diff. From experience, the val is 6
132 */
133 pwdb_all += 6;
134 if (pwdb_all > 100)
135 pwdb_all = 100;
136 /* modify the offset to make the same
137 * gain index with OFDM.
138 */
139 if (pwdb_all > 34 && pwdb_all <= 42)
140 pwdb_all -= 2;
141 else if (pwdb_all > 26 && pwdb_all <= 34)
142 pwdb_all -= 6;
143 else if (pwdb_all > 14 && pwdb_all <= 26)
144 pwdb_all -= 8;
145 else if (pwdb_all > 4 && pwdb_all <= 14)
146 pwdb_all -= 4;
147
148 pstatus->rx_pwdb_all = pwdb_all;
149 pstatus->recvsignalpower = rx_pwr_all;
150
151 /* (3) Get Signal Quality (EVM) */
152 if (bpacket_match_bssid) {
153 u8 sq;
154
155 if (pstatus->rx_pwdb_all > 40) {
156 sq = 100;
157 } else {
158 sq = cck_buf->sq_rpt;
159 if (sq > 64)
160 sq = 0;
161 else if (sq < 20)
162 sq = 100;
163 else
164 sq = ((64 - sq) * 100) / 44;
165 }
166
167 pstatus->signalquality = sq;
168 pstatus->rx_mimo_sig_qual[0] = sq;
169 pstatus->rx_mimo_sig_qual[1] = -1;
170 }
171 } else {
172 rtlpriv->dm.rfpath_rxenable[0] =
173 rtlpriv->dm.rfpath_rxenable[1] = true;
174
175 /* (1)Get RSSI for HT rate */
176 for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
177
178 /* we will judge RF RX path now. */
179 if (rtlpriv->dm.rfpath_rxenable[i])
180 rf_rx_num++;
181
182 rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f)*2) - 110;
183
184 /* Translate DBM to percentage. */
185 rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
186 total_rssi += rssi;
187
188 /* Get Rx snr value in DB */
189 rtlpriv->stats.rx_snr_db[i] = (p_drvinfo->rxsnr[i] / 2);
190
191 /* Record Signal Strength for next packet */
192 if (bpacket_match_bssid)
193 pstatus->rx_mimo_signalstrength[i] = (u8) rssi;
194 }
195
196 /* (2)PWDB, Average PWDB cacluated by
197 * hardware (for rate adaptive)
198 */
199 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
200
201 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
202 pstatus->rx_pwdb_all = pwdb_all;
203 pstatus->rxpower = rx_pwr_all;
204 pstatus->recvsignalpower = rx_pwr_all;
205
206 /* (3)EVM of HT rate */
207 if (pstatus->is_ht && pstatus->rate >= DESC92_RATEMCS8 &&
208 pstatus->rate <= DESC92_RATEMCS15)
209 max_spatial_stream = 2;
210 else
211 max_spatial_stream = 1;
212
213 for (i = 0; i < max_spatial_stream; i++) {
214 evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
215
216 if (bpacket_match_bssid) {
217 /* Fill value in RFD, Get the first
218 * spatial stream only
219 */
220 if (i == 0)
221 pstatus->signalquality = (evm & 0xff);
222 pstatus->rx_mimo_sig_qual[i] = (evm & 0xff);
223 }
224 }
225 }
226
227 /* UI BSS List signal strength(in percentage),
228 * make it good looking, from 0~100.
229 */
230 if (is_cck)
231 pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
232 pwdb_all));
233 else if (rf_rx_num != 0)
234 pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
235 total_rssi /= rf_rx_num));
236}
237
238static void _rtl8723ae_translate_rx_signal_stuff(struct ieee80211_hw *hw,
239 struct sk_buff *skb, struct rtl_stats *pstatus,
240 u8 *pdesc, struct rx_fwinfo_8723e *p_drvinfo)
241{
242 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
243 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
244 struct ieee80211_hdr *hdr;
245 u8 *tmp_buf;
246 u8 *praddr;
247 u8 *psaddr;
248 __le16 fc;
249 u16 type;
250 bool packet_matchbssid, packet_toself, packet_beacon;
251
252 tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
253
254 hdr = (struct ieee80211_hdr *)tmp_buf;
255 fc = hdr->frame_control;
256 type = WLAN_FC_GET_TYPE(fc);
257 praddr = hdr->addr1;
258 psaddr = ieee80211_get_SA(hdr);
259
260 packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
261 (!compare_ether_addr(mac->bssid,
262 (le16_to_cpu(fc) & IEEE80211_FCTL_TODS) ?
263 hdr->addr1 : (le16_to_cpu(fc) &
264 IEEE80211_FCTL_FROMDS) ?
265 hdr->addr2 : hdr->addr3)) && (!pstatus->hwerror) &&
266 (!pstatus->crc) && (!pstatus->icv));
267
268 packet_toself = packet_matchbssid &&
269 (!compare_ether_addr(praddr, rtlefuse->dev_addr));
270
271 if (ieee80211_is_beacon(fc))
272 packet_beacon = true;
273
274 _rtl8723ae_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo,
275 packet_matchbssid, packet_toself,
276 packet_beacon);
277
278 rtl_process_phyinfo(hw, tmp_buf, pstatus);
279}
280
281bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,
282 struct rtl_stats *status,
283 struct ieee80211_rx_status *rx_status,
284 u8 *pdesc, struct sk_buff *skb)
285{
286 struct rx_fwinfo_8723e *p_drvinfo;
287 struct ieee80211_hdr *hdr;
288 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
289
290 status->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
291 status->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
292 RX_DRV_INFO_SIZE_UNIT;
293 status->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
294 status->icv = (u16) GET_RX_DESC_ICV(pdesc);
295 status->crc = (u16) GET_RX_DESC_CRC32(pdesc);
296 status->hwerror = (status->crc | status->icv);
297 status->decrypted = !GET_RX_DESC_SWDEC(pdesc);
298 status->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
299 status->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
300 status->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
301 status->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
302 && (GET_RX_DESC_FAGGR(pdesc) == 1));
303 status->timestamp_low = GET_RX_DESC_TSFL(pdesc);
304 status->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
305 status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
306
307 status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate);
308
309 rx_status->freq = hw->conf.channel->center_freq;
310 rx_status->band = hw->conf.channel->band;
311
312 hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size
313 + status->rx_bufshift);
314
315 if (status->crc)
316 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
317
318 if (status->rx_is40Mhzpacket)
319 rx_status->flag |= RX_FLAG_40MHZ;
320
321 if (status->is_ht)
322 rx_status->flag |= RX_FLAG_HT;
323
324 rx_status->flag |= RX_FLAG_MACTIME_START;
325
326 /* hw will set status->decrypted true, if it finds the
327 * frame is open data frame or mgmt frame.
328 * Thus hw will not decrypt a robust managment frame
329 * for IEEE80211w but still set status->decrypted
330 * true, so here we should set it back to undecrypted
331 * for IEEE80211w frame, and mac80211 sw will help
332 * to decrypt it
333 */
334 if (status->decrypted) {
335 if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
336 (ieee80211_has_protected(hdr->frame_control)))
337 rx_status->flag &= ~RX_FLAG_DECRYPTED;
338 else
339 rx_status->flag |= RX_FLAG_DECRYPTED;
340 }
341
342 /* rate_idx: index of data rate into band's
343 * supported rates or MCS index if HT rates
344 * are use (RX_FLAG_HT)
345 */
346 rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht,
347 status->rate, false);
348
349 rx_status->mactime = status->timestamp_low;
350 if (phystatus == true) {
351 p_drvinfo = (struct rx_fwinfo_8723e *)(skb->data +
352 status->rx_bufshift);
353
354 _rtl8723ae_translate_rx_signal_stuff(hw,
355 skb, status, pdesc, p_drvinfo);
356 }
357
358 /*rx_status->qual = status->signal; */
359 rx_status->signal = status->recvsignalpower + 10;
360 /*rx_status->noise = -status->noise; */
361
362 return true;
363}
364
365void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,
366 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
367 struct ieee80211_tx_info *info,
368 struct ieee80211_sta *sta,
369 struct sk_buff *skb, u8 hw_queue,
370 struct rtl_tcb_desc *ptcdesc)
371{
372 struct rtl_priv *rtlpriv = rtl_priv(hw);
373 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
374 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
375 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
376 bool defaultadapter = true;
377 u8 *pdesc = (u8 *) pdesc_tx;
378 u16 seq_number;
379 __le16 fc = hdr->frame_control;
380 u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue);
381 bool firstseg = ((hdr->seq_ctrl &
382 cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
383 bool lastseg = ((hdr->frame_control &
384 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
385 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
386 skb->data, skb->len,
387 PCI_DMA_TODEVICE);
388 u8 bw_40 = 0;
389
390 if (mac->opmode == NL80211_IFTYPE_STATION) {
391 bw_40 = mac->bw_40;
392 } else if (mac->opmode == NL80211_IFTYPE_AP ||
393 mac->opmode == NL80211_IFTYPE_ADHOC) {
394 if (sta)
395 bw_40 = sta->ht_cap.cap &
396 IEEE80211_HT_CAP_SUP_WIDTH_20_40;
397 }
398
399 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
400
401 rtl_get_tcb_desc(hw, info, sta, skb, ptcdesc);
402
403 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8723e));
404
405 if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
406 firstseg = true;
407 lastseg = true;
408 }
409
410 if (firstseg) {
411 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
412
413 SET_TX_DESC_TX_RATE(pdesc, ptcdesc->hw_rate);
414
415 if (ptcdesc->use_shortgi || ptcdesc->use_shortpreamble)
416 SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
417
418 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
419 SET_TX_DESC_AGG_BREAK(pdesc, 1);
420 SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
421 }
422 SET_TX_DESC_SEQ(pdesc, seq_number);
423
424 SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcdesc->rts_enable &&
425 !ptcdesc->
426 cts_enable) ? 1 : 0));
427 SET_TX_DESC_HW_RTS_ENABLE(pdesc,
428 ((ptcdesc->rts_enable
429 || ptcdesc->cts_enable) ? 1 : 0));
430 SET_TX_DESC_CTS2SELF(pdesc, ((ptcdesc->cts_enable) ? 1 : 0));
431 SET_TX_DESC_RTS_STBC(pdesc, ((ptcdesc->rts_stbc) ? 1 : 0));
432
433 SET_TX_DESC_RTS_RATE(pdesc, ptcdesc->rts_rate);
434 SET_TX_DESC_RTS_BW(pdesc, 0);
435 SET_TX_DESC_RTS_SC(pdesc, ptcdesc->rts_sc);
436 SET_TX_DESC_RTS_SHORT(pdesc,
437 ((ptcdesc->rts_rate <= DESC92_RATE54M) ?
438 (ptcdesc->rts_use_shortpreamble ? 1 : 0)
439 : (ptcdesc->rts_use_shortgi ? 1 : 0)));
440
441 if (bw_40) {
442 if (ptcdesc->packet_bw) {
443 SET_TX_DESC_DATA_BW(pdesc, 1);
444 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
445 } else {
446 SET_TX_DESC_DATA_BW(pdesc, 0);
447 SET_TX_DESC_TX_SUB_CARRIER(pdesc,
448 mac->cur_40_prime_sc);
449 }
450 } else {
451 SET_TX_DESC_DATA_BW(pdesc, 0);
452 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
453 }
454
455 SET_TX_DESC_LINIP(pdesc, 0);
456 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
457
458 if (sta) {
459 u8 ampdu_density = sta->ht_cap.ampdu_density;
460 SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
461 }
462
463 if (info->control.hw_key) {
464 struct ieee80211_key_conf *keyconf =
465 info->control.hw_key;
466
467 switch (keyconf->cipher) {
468 case WLAN_CIPHER_SUITE_WEP40:
469 case WLAN_CIPHER_SUITE_WEP104:
470 case WLAN_CIPHER_SUITE_TKIP:
471 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
472 break;
473 case WLAN_CIPHER_SUITE_CCMP:
474 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
475 break;
476 default:
477 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
478 break;
479 }
480 }
481
482 SET_TX_DESC_PKT_ID(pdesc, 0);
483 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
484
485 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
486 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
487 SET_TX_DESC_DISABLE_FB(pdesc, 0);
488 SET_TX_DESC_USE_RATE(pdesc, ptcdesc->use_driver_rate ? 1 : 0);
489
490 if (ieee80211_is_data_qos(fc)) {
491 if (mac->rdg_en) {
492 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
493 "Enable RDG function.\n");
494 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
495 SET_TX_DESC_HTC(pdesc, 1);
496 }
497 }
498 }
499
500 SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
501 SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
502
503 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
504
505 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
506
507 if (rtlpriv->dm.useramask) {
508 SET_TX_DESC_RATE_ID(pdesc, ptcdesc->ratr_index);
509 SET_TX_DESC_MACID(pdesc, ptcdesc->mac_id);
510 } else {
511 SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcdesc->ratr_index);
512 SET_TX_DESC_MACID(pdesc, ptcdesc->ratr_index);
513 }
514
515 if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
516 SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1);
517
518 if (!defaultadapter)
519 SET_TX_DESC_HWSEQ_SEL_8723(pdesc, 1);
520 }
521
522 SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
523
524 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
525 is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
526 SET_TX_DESC_BMC(pdesc, 1);
527 }
528
529 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
530}
531
532void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw,
533 u8 *pdesc, bool firstseg,
534 bool lastseg, struct sk_buff *skb)
535{
536 struct rtl_priv *rtlpriv = rtl_priv(hw);
537 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
538 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
539 u8 fw_queue = QSLT_BEACON;
540 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
541 skb->data, skb->len,
542 PCI_DMA_TODEVICE);
543 __le16 fc = hdr->frame_control;
544
545 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
546
547 if (firstseg)
548 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
549
550 SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
551
552 SET_TX_DESC_SEQ(pdesc, 0);
553
554 SET_TX_DESC_LINIP(pdesc, 0);
555
556 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
557
558 SET_TX_DESC_FIRST_SEG(pdesc, 1);
559 SET_TX_DESC_LAST_SEG(pdesc, 1);
560
561 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
562
563 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
564
565 SET_TX_DESC_RATE_ID(pdesc, 7);
566 SET_TX_DESC_MACID(pdesc, 0);
567
568 SET_TX_DESC_OWN(pdesc, 1);
569
570 SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
571
572 SET_TX_DESC_FIRST_SEG(pdesc, 1);
573 SET_TX_DESC_LAST_SEG(pdesc, 1);
574
575 SET_TX_DESC_OFFSET(pdesc, 0x20);
576
577 SET_TX_DESC_USE_RATE(pdesc, 1);
578
579 if (!ieee80211_is_data_qos(fc)) {
580 SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1);
581 /* SET_TX_DESC_HWSEQ_EN(pdesc, 1); */
582 /* SET_TX_DESC_PKT_ID(pdesc, 8); */
583 }
584
585 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
586 "H2C Tx Cmd Content\n",
587 pdesc, TX_DESC_SIZE);
588}
589
590void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
591{
592 if (istx == true) {
593 switch (desc_name) {
594 case HW_DESC_OWN:
595 SET_TX_DESC_OWN(pdesc, 1);
596 break;
597 case HW_DESC_TX_NEXTDESC_ADDR:
598 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
599 break;
600 default:
601 RT_ASSERT(false, "ERR txdesc :%d not process\n",
602 desc_name);
603 break;
604 }
605 } else {
606 switch (desc_name) {
607 case HW_DESC_RXOWN:
608 SET_RX_DESC_OWN(pdesc, 1);
609 break;
610 case HW_DESC_RXBUFF_ADDR:
611 SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
612 break;
613 case HW_DESC_RXPKT_LEN:
614 SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
615 break;
616 case HW_DESC_RXERO:
617 SET_RX_DESC_EOR(pdesc, 1);
618 break;
619 default:
620 RT_ASSERT(false, "ERR rxdesc :%d not process\n",
621 desc_name);
622 break;
623 }
624 }
625}
626
627u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name)
628{
629 u32 ret = 0;
630
631 if (istx == true) {
632 switch (desc_name) {
633 case HW_DESC_OWN:
634 ret = GET_TX_DESC_OWN(pdesc);
635 break;
636 case HW_DESC_TXBUFF_ADDR:
637 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc);
638 break;
639 default:
640 RT_ASSERT(false, "ERR txdesc :%d not process\n",
641 desc_name);
642 break;
643 }
644 } else {
645 switch (desc_name) {
646 case HW_DESC_OWN:
647 ret = GET_RX_DESC_OWN(pdesc);
648 break;
649 case HW_DESC_RXPKT_LEN:
650 ret = GET_RX_DESC_PKT_LEN(pdesc);
651 break;
652 default:
653 RT_ASSERT(false, "ERR rxdesc :%d not process\n",
654 desc_name);
655 break;
656 }
657 }
658 return ret;
659}
660
661void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
662{
663 struct rtl_priv *rtlpriv = rtl_priv(hw);
664 if (hw_queue == BEACON_QUEUE) {
665 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
666 } else {
667 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
668 BIT(0) << (hw_queue));
669 }
670}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h
new file mode 100644
index 00000000000..ad05b54bc0f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h
@@ -0,0 +1,725 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL8723E_TRX_H__
31#define __RTL8723E_TRX_H__
32
33#define TX_DESC_SIZE 64
34#define TX_DESC_AGGR_SUBFRAME_SIZE 32
35
36#define RX_DESC_SIZE 32
37#define RX_DRV_INFO_SIZE_UNIT 8
38
39#define TX_DESC_NEXT_DESC_OFFSET 40
40#define USB_HWDESC_HEADER_LEN 32
41#define CRCLENGTH 4
42
43#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
44 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
45#define SET_TX_DESC_OFFSET(__pdesc, __val) \
46 SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
47#define SET_TX_DESC_BMC(__pdesc, __val) \
48 SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
49#define SET_TX_DESC_HTC(__pdesc, __val) \
50 SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
51#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
52 SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
53#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
54 SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
55#define SET_TX_DESC_LINIP(__pdesc, __val) \
56 SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
57#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
58 SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
59#define SET_TX_DESC_GF(__pdesc, __val) \
60 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
61#define SET_TX_DESC_OWN(__pdesc, __val) \
62 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
63
64#define GET_TX_DESC_PKT_SIZE(__pdesc) \
65 LE_BITS_TO_4BYTE(__pdesc, 0, 16)
66#define GET_TX_DESC_OFFSET(__pdesc) \
67 LE_BITS_TO_4BYTE(__pdesc, 16, 8)
68#define GET_TX_DESC_BMC(__pdesc) \
69 LE_BITS_TO_4BYTE(__pdesc, 24, 1)
70#define GET_TX_DESC_HTC(__pdesc) \
71 LE_BITS_TO_4BYTE(__pdesc, 25, 1)
72#define GET_TX_DESC_LAST_SEG(__pdesc) \
73 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
74#define GET_TX_DESC_FIRST_SEG(__pdesc) \
75 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
76#define GET_TX_DESC_LINIP(__pdesc) \
77 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
78#define GET_TX_DESC_NO_ACM(__pdesc) \
79 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
80#define GET_TX_DESC_GF(__pdesc) \
81 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
82#define GET_TX_DESC_OWN(__pdesc) \
83 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
84
85#define SET_TX_DESC_MACID(__pdesc, __val) \
86 SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val)
87#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
88 SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val)
89#define SET_TX_DESC_BK(__pdesc, __val) \
90 SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val)
91#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
92 SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val)
93#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
94 SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
95#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
96 SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
97#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
98 SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
99#define SET_TX_DESC_PIFS(__pdesc, __val) \
100 SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
101#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
102 SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val)
103#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
104 SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val)
105#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
106 SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
107#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
108 SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
109#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
110 SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val)
111
112#define GET_TX_DESC_MACID(__pdesc) \
113 LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
114#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
115 LE_BITS_TO_4BYTE(__pdesc+4, 5, 1)
116#define GET_TX_DESC_AGG_BREAK(__pdesc) \
117 LE_BITS_TO_4BYTE(__pdesc+4, 6, 1)
118#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
119 LE_BITS_TO_4BYTE(__pdesc+4, 7, 1)
120#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
121 LE_BITS_TO_4BYTE(__pdesc+4, 8, 5)
122#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
123 LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
124#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
125 LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
126#define GET_TX_DESC_PIFS(__pdesc) \
127 LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
128#define GET_TX_DESC_RATE_ID(__pdesc) \
129 LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
130#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
131 LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
132#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
133 LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
134#define GET_TX_DESC_SEC_TYPE(__pdesc) \
135 LE_BITS_TO_4BYTE(__pdesc+4, 22, 2)
136#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
137 LE_BITS_TO_4BYTE(__pdesc+4, 24, 8)
138
139#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
140 SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val)
141#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
142 SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val)
143#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
144 SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
145#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
146 SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
147#define SET_TX_DESC_RAW(__pdesc, __val) \
148 SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
149#define SET_TX_DESC_CCX(__pdesc, __val) \
150 SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
151#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
152 SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
153#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
154 SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val)
155#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
156 SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val)
157#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
158 SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val)
159#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
160 SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val)
161#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
162 SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val)
163
164#define GET_TX_DESC_RTS_RC(__pdesc) \
165 LE_BITS_TO_4BYTE(__pdesc+8, 0, 6)
166#define GET_TX_DESC_DATA_RC(__pdesc) \
167 LE_BITS_TO_4BYTE(__pdesc+8, 6, 6)
168#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
169 LE_BITS_TO_4BYTE(__pdesc+8, 14, 2)
170#define GET_TX_DESC_MORE_FRAG(__pdesc) \
171 LE_BITS_TO_4BYTE(__pdesc+8, 17, 1)
172#define GET_TX_DESC_RAW(__pdesc) \
173 LE_BITS_TO_4BYTE(__pdesc+8, 18, 1)
174#define GET_TX_DESC_CCX(__pdesc) \
175 LE_BITS_TO_4BYTE(__pdesc+8, 19, 1)
176#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
177 LE_BITS_TO_4BYTE(__pdesc+8, 20, 3)
178#define GET_TX_DESC_ANTSEL_A(__pdesc) \
179 LE_BITS_TO_4BYTE(__pdesc+8, 24, 1)
180#define GET_TX_DESC_ANTSEL_B(__pdesc) \
181 LE_BITS_TO_4BYTE(__pdesc+8, 25, 1)
182#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
183 LE_BITS_TO_4BYTE(__pdesc+8, 26, 2)
184#define GET_TX_DESC_TX_ANTL(__pdesc) \
185 LE_BITS_TO_4BYTE(__pdesc+8, 28, 2)
186#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
187 LE_BITS_TO_4BYTE(__pdesc+8, 30, 2)
188
189#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
190 SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val)
191#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
192 SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val)
193#define SET_TX_DESC_SEQ(__pdesc, __val) \
194 SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val)
195#define SET_TX_DESC_PKT_ID(__pdesc, __val) \
196 SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val)
197
198#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
199 LE_BITS_TO_4BYTE(__pdesc+12, 0, 8)
200#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
201 LE_BITS_TO_4BYTE(__pdesc+12, 8, 8)
202#define GET_TX_DESC_SEQ(__pdesc) \
203 LE_BITS_TO_4BYTE(__pdesc+12, 16, 12)
204#define GET_TX_DESC_PKT_ID(__pdesc) \
205 LE_BITS_TO_4BYTE(__pdesc+12, 28, 4)
206
207/* For RTL8723 */
208#define SET_TX_DESC_TRIGGER_INT(__pdesc, __val) \
209 SET_BITS_TO_LE_4BYTE(__pdesc+12, 30, 1, __val)
210#define SET_TX_DESC_HWSEQ_EN_8723(__pdesc, __val) \
211 SET_BITS_TO_LE_4BYTE(__pdesc+12, 31, 1, __val)
212#define SET_TX_DESC_HWSEQ_SEL_8723(__pTxDesc, __Value) \
213 SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 6, 2, __Value)
214
215#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
216 SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val)
217#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
218 SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val)
219#define SET_TX_DESC_QOS(__pdesc, __val) \
220 SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val)
221#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
222 SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val)
223#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
224 SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val)
225#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
226 SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val)
227#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
228 SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val)
229#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
230 SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val)
231#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
232 SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val)
233#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
234 SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val)
235#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
236 SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val)
237#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
238 SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val)
239#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
240 SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val)
241#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
242 SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val)
243#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
244 SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val)
245#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
246 SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val)
247#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
248 SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val)
249#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
250 SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val)
251#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
252 SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val)
253#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
254 SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val)
255#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
256 SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val)
257
258#define GET_TX_DESC_RTS_RATE(__pdesc) \
259 LE_BITS_TO_4BYTE(__pdesc+16, 0, 5)
260#define GET_TX_DESC_AP_DCFE(__pdesc) \
261 LE_BITS_TO_4BYTE(__pdesc+16, 5, 1)
262#define GET_TX_DESC_QOS(__pdesc) \
263 LE_BITS_TO_4BYTE(__pdesc+16, 6, 1)
264#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
265 LE_BITS_TO_4BYTE(__pdesc+16, 7, 1)
266#define GET_TX_DESC_USE_RATE(__pdesc) \
267 LE_BITS_TO_4BYTE(__pdesc+16, 8, 1)
268#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
269 LE_BITS_TO_4BYTE(__pdesc+16, 9, 1)
270#define GET_TX_DESC_DISABLE_FB(__pdesc) \
271 LE_BITS_TO_4BYTE(__pdesc+16, 10, 1)
272#define GET_TX_DESC_CTS2SELF(__pdesc) \
273 LE_BITS_TO_4BYTE(__pdesc+16, 11, 1)
274#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
275 LE_BITS_TO_4BYTE(__pdesc+16, 12, 1)
276#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
277 LE_BITS_TO_4BYTE(__pdesc+16, 13, 1)
278#define GET_TX_DESC_PORT_ID(__pdesc) \
279 LE_BITS_TO_4BYTE(__pdesc+16, 14, 1)
280#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
281 LE_BITS_TO_4BYTE(__pdesc+16, 18, 1)
282#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
283 LE_BITS_TO_4BYTE(__pdesc+16, 19, 1)
284#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
285 LE_BITS_TO_4BYTE(__pdesc+16, 20, 2)
286#define GET_TX_DESC_TX_STBC(__pdesc) \
287 LE_BITS_TO_4BYTE(__pdesc+16, 22, 2)
288#define GET_TX_DESC_DATA_SHORT(__pdesc) \
289 LE_BITS_TO_4BYTE(__pdesc+16, 24, 1)
290#define GET_TX_DESC_DATA_BW(__pdesc) \
291 LE_BITS_TO_4BYTE(__pdesc+16, 25, 1)
292#define GET_TX_DESC_RTS_SHORT(__pdesc) \
293 LE_BITS_TO_4BYTE(__pdesc+16, 26, 1)
294#define GET_TX_DESC_RTS_BW(__pdesc) \
295 LE_BITS_TO_4BYTE(__pdesc+16, 27, 1)
296#define GET_TX_DESC_RTS_SC(__pdesc) \
297 LE_BITS_TO_4BYTE(__pdesc+16, 28, 2)
298#define GET_TX_DESC_RTS_STBC(__pdesc) \
299 LE_BITS_TO_4BYTE(__pdesc+16, 30, 2)
300
301#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
302 SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val)
303#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
304 SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val)
305#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
306 SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
307#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
308 SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val)
309#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
310 SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
311#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
312 SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val)
313#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
314 SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val)
315#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
316 SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val)
317
318#define GET_TX_DESC_TX_RATE(__pdesc) \
319 LE_BITS_TO_4BYTE(__pdesc+20, 0, 6)
320#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
321 LE_BITS_TO_4BYTE(__pdesc+20, 6, 1)
322#define GET_TX_DESC_CCX_TAG(__pdesc) \
323 LE_BITS_TO_4BYTE(__pdesc+20, 7, 1)
324#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
325 LE_BITS_TO_4BYTE(__pdesc+20, 8, 5)
326#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
327 LE_BITS_TO_4BYTE(__pdesc+20, 13, 4)
328#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
329 LE_BITS_TO_4BYTE(__pdesc+20, 17, 1)
330#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
331 LE_BITS_TO_4BYTE(__pdesc+20, 18, 6)
332#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
333 LE_BITS_TO_4BYTE(__pdesc+20, 24, 8)
334
335#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
336 SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val)
337#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
338 SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val)
339#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
340 SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val)
341#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
342 SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val)
343#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
344 SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val)
345#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
346 SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val)
347#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
348 SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val)
349#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val)\
350 SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val)
351
352#define GET_TX_DESC_TXAGC_A(__pdesc) \
353 LE_BITS_TO_4BYTE(__pdesc+24, 0, 5)
354#define GET_TX_DESC_TXAGC_B(__pdesc) \
355 LE_BITS_TO_4BYTE(__pdesc+24, 5, 5)
356#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
357 LE_BITS_TO_4BYTE(__pdesc+24, 10, 1)
358#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
359 LE_BITS_TO_4BYTE(__pdesc+24, 11, 5)
360#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
361 LE_BITS_TO_4BYTE(__pdesc+24, 16, 4)
362#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
363 LE_BITS_TO_4BYTE(__pdesc+24, 20, 4)
364#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
365 LE_BITS_TO_4BYTE(__pdesc+24, 24, 4)
366#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
367 LE_BITS_TO_4BYTE(__pdesc+24, 28, 4)
368
369#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
370 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
371#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \
372 SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val)
373#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \
374 SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val)
375#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \
376 SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val)
377#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \
378 SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val)
379
380#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
381 LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
382#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \
383 LE_BITS_TO_4BYTE(__pdesc+28, 16, 4)
384#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \
385 LE_BITS_TO_4BYTE(__pdesc+28, 20, 4)
386#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \
387 LE_BITS_TO_4BYTE(__pdesc+28, 24, 4)
388#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \
389 LE_BITS_TO_4BYTE(__pdesc+28, 28, 4)
390
391#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
392 SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val)
393#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
394 SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val)
395
396#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
397 LE_BITS_TO_4BYTE(__pdesc+32, 0, 32)
398#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
399 LE_BITS_TO_4BYTE(__pdesc+36, 0, 32)
400
401#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
402 SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
403#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
404 SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val)
405
406#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
407 LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
408#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
409 LE_BITS_TO_4BYTE(__pdesc+44, 0, 32)
410
411#define GET_RX_DESC_PKT_LEN(__pdesc) \
412 LE_BITS_TO_4BYTE(__pdesc, 0, 14)
413#define GET_RX_DESC_CRC32(__pdesc) \
414 LE_BITS_TO_4BYTE(__pdesc, 14, 1)
415#define GET_RX_DESC_ICV(__pdesc) \
416 LE_BITS_TO_4BYTE(__pdesc, 15, 1)
417#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
418 LE_BITS_TO_4BYTE(__pdesc, 16, 4)
419#define GET_RX_DESC_SECURITY(__pdesc) \
420 LE_BITS_TO_4BYTE(__pdesc, 20, 3)
421#define GET_RX_DESC_QOS(__pdesc) \
422 LE_BITS_TO_4BYTE(__pdesc, 23, 1)
423#define GET_RX_DESC_SHIFT(__pdesc) \
424 LE_BITS_TO_4BYTE(__pdesc, 24, 2)
425#define GET_RX_DESC_PHYST(__pdesc) \
426 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
427#define GET_RX_DESC_SWDEC(__pdesc) \
428 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
429#define GET_RX_DESC_LS(__pdesc) \
430 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
431#define GET_RX_DESC_FS(__pdesc) \
432 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
433#define GET_RX_DESC_EOR(__pdesc) \
434 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
435#define GET_RX_DESC_OWN(__pdesc) \
436 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
437
438#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
439 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
440#define SET_RX_DESC_EOR(__pdesc, __val) \
441 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
442#define SET_RX_DESC_OWN(__pdesc, __val) \
443 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
444
445#define GET_RX_DESC_MACID(__pdesc) \
446 LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
447#define GET_RX_DESC_TID(__pdesc) \
448 LE_BITS_TO_4BYTE(__pdesc+4, 5, 4)
449#define GET_RX_DESC_HWRSVD(__pdesc) \
450 LE_BITS_TO_4BYTE(__pdesc+4, 9, 5)
451#define GET_RX_DESC_PAGGR(__pdesc) \
452 LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
453#define GET_RX_DESC_FAGGR(__pdesc) \
454 LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
455#define GET_RX_DESC_A1_FIT(__pdesc) \
456 LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
457#define GET_RX_DESC_A2_FIT(__pdesc) \
458 LE_BITS_TO_4BYTE(__pdesc+4, 20, 4)
459#define GET_RX_DESC_PAM(__pdesc) \
460 LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
461#define GET_RX_DESC_PWR(__pdesc) \
462 LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
463#define GET_RX_DESC_MD(__pdesc) \
464 LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
465#define GET_RX_DESC_MF(__pdesc) \
466 LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
467#define GET_RX_DESC_TYPE(__pdesc) \
468 LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
469#define GET_RX_DESC_MC(__pdesc) \
470 LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
471#define GET_RX_DESC_BC(__pdesc) \
472 LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
473#define GET_RX_DESC_SEQ(__pdesc) \
474 LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
475#define GET_RX_DESC_FRAG(__pdesc) \
476 LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
477#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \
478 LE_BITS_TO_4BYTE(__pdesc+8, 16, 14)
479#define GET_RX_DESC_NEXT_IND(__pdesc) \
480 LE_BITS_TO_4BYTE(__pdesc+8, 30, 1)
481#define GET_RX_DESC_RSVD(__pdesc) \
482 LE_BITS_TO_4BYTE(__pdesc+8, 31, 1)
483
484#define GET_RX_DESC_RXMCS(__pdesc) \
485 LE_BITS_TO_4BYTE(__pdesc+12, 0, 6)
486#define GET_RX_DESC_RXHT(__pdesc) \
487 LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
488#define GET_RX_DESC_SPLCP(__pdesc) \
489 LE_BITS_TO_4BYTE(__pdesc+12, 8, 1)
490#define GET_RX_DESC_BW(__pdesc) \
491 LE_BITS_TO_4BYTE(__pdesc+12, 9, 1)
492#define GET_RX_DESC_HTC(__pdesc) \
493 LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
494#define GET_RX_DESC_HWPC_ERR(__pdesc) \
495 LE_BITS_TO_4BYTE(__pdesc+12, 14, 1)
496#define GET_RX_DESC_HWPC_IND(__pdesc) \
497 LE_BITS_TO_4BYTE(__pdesc+12, 15, 1)
498#define GET_RX_DESC_IV0(__pdesc) \
499 LE_BITS_TO_4BYTE(__pdesc+12, 16, 16)
500
501#define GET_RX_DESC_IV1(__pdesc) \
502 LE_BITS_TO_4BYTE(__pdesc+16, 0, 32)
503#define GET_RX_DESC_TSFL(__pdesc) \
504 LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
505
506#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
507 LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
508#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
509 LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
510
511#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
512 SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
513#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
514 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
515
516#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
517do { \
518 if (_size > TX_DESC_NEXT_DESC_OFFSET) \
519 memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
520 else \
521 memset(__pdesc, 0, _size); \
522} while (0)
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 {
531 u8 gain_trsw[4];
532 u8 pwdb_all;
533 u8 cfosho[4];
534 u8 cfotail[4];
535 char rxevm[2];
536 char rxsnr[4];
537 u8 pdsnr[2];
538 u8 csi_current[2];
539 u8 csi_target[2];
540 u8 sigevm;
541 u8 max_ex_pwr;
542 u8 ex_intf_flag:1;
543 u8 sgi_en:1;
544 u8 rxsc:2;
545 u8 reserve:4;
546} __packed;
547
548struct tx_desc_8723e {
549 u32 pktsize:16;
550 u32 offset:8;
551 u32 bmc:1;
552 u32 htc:1;
553 u32 lastseg:1;
554 u32 firstseg:1;
555 u32 linip:1;
556 u32 noacm:1;
557 u32 gf:1;
558 u32 own:1;
559
560 u32 macid:5;
561 u32 agg_en:1;
562 u32 bk:1;
563 u32 rdg_en:1;
564 u32 queuesel:5;
565 u32 rd_nav_ext:1;
566 u32 lsig_txop_en:1;
567 u32 pifs:1;
568 u32 rateid:4;
569 u32 nav_usehdr:1;
570 u32 en_descid:1;
571 u32 sectype:2;
572 u32 pktoffset:8;
573
574 u32 rts_rc:6;
575 u32 data_rc:6;
576 u32 rsvd0:2;
577 u32 bar_retryht:2;
578 u32 rsvd1:1;
579 u32 morefrag:1;
580 u32 raw:1;
581 u32 ccx:1;
582 u32 ampdudensity:3;
583 u32 rsvd2:1;
584 u32 ant_sela:1;
585 u32 ant_selb:1;
586 u32 txant_cck:2;
587 u32 txant_l:2;
588 u32 txant_ht:2;
589
590 u32 nextheadpage:8;
591 u32 tailpage:8;
592 u32 seq:12;
593 u32 pktid:4;
594
595 u32 rtsrate:5;
596 u32 apdcfe:1;
597 u32 qos:1;
598 u32 hwseq_enable:1;
599 u32 userrate:1;
600 u32 dis_rtsfb:1;
601 u32 dis_datafb:1;
602 u32 cts2self:1;
603 u32 rts_en:1;
604 u32 hwrts_en:1;
605 u32 portid:1;
606 u32 rsvd3:3;
607 u32 waitdcts:1;
608 u32 cts2ap_en:1;
609 u32 txsc:2;
610 u32 stbc:2;
611 u32 txshort:1;
612 u32 txbw:1;
613 u32 rtsshort:1;
614 u32 rtsbw:1;
615 u32 rtssc:2;
616 u32 rtsstbc:2;
617
618 u32 txrate:6;
619 u32 shortgi:1;
620 u32 ccxt:1;
621 u32 txrate_fb_lmt:5;
622 u32 rtsrate_fb_lmt:4;
623 u32 retrylmt_en:1;
624 u32 txretrylmt:6;
625 u32 usb_txaggnum:8;
626
627 u32 txagca:5;
628 u32 txagcb:5;
629 u32 usemaxlen:1;
630 u32 maxaggnum:5;
631 u32 mcsg1maxlen:4;
632 u32 mcsg2maxlen:4;
633 u32 mcsg3maxlen:4;
634 u32 mcs7sgimaxlen:4;
635
636 u32 txbuffersize:16;
637 u32 mcsg4maxlen:4;
638 u32 mcsg5maxlen:4;
639 u32 mcsg6maxlen:4;
640 u32 mcsg15sgimaxlen:4;
641
642 u32 txbuffaddr;
643 u32 txbufferaddr64;
644 u32 nextdescaddress;
645 u32 nextdescaddress64;
646
647 u32 reserve_pass_pcie_mm_limit[4];
648} __packed;
649
650struct rx_desc_8723e {
651 u32 length:14;
652 u32 crc32:1;
653 u32 icverror:1;
654 u32 drv_infosize:4;
655 u32 security:3;
656 u32 qos:1;
657 u32 shift:2;
658 u32 phystatus:1;
659 u32 swdec:1;
660 u32 lastseg:1;
661 u32 firstseg:1;
662 u32 eor:1;
663 u32 own:1;
664
665 u32 macid:5;
666 u32 tid:4;
667 u32 hwrsvd:5;
668 u32 paggr:1;
669 u32 faggr:1;
670 u32 a1_fit:4;
671 u32 a2_fit:4;
672 u32 pam:1;
673 u32 pwr:1;
674 u32 moredata:1;
675 u32 morefrag:1;
676 u32 type:2;
677 u32 mc:1;
678 u32 bc:1;
679
680 u32 seq:12;
681 u32 frag:4;
682 u32 nextpktlen:14;
683 u32 nextind:1;
684 u32 rsvd:1;
685
686 u32 rxmcs:6;
687 u32 rxht:1;
688 u32 amsdu:1;
689 u32 splcp:1;
690 u32 bandwidth:1;
691 u32 htc:1;
692 u32 tcpchk_rpt:1;
693 u32 ipcchk_rpt:1;
694 u32 tcpchk_valid:1;
695 u32 hwpcerr:1;
696 u32 hwpcind:1;
697 u32 iv0:16;
698
699 u32 iv1;
700
701 u32 tsfl;
702
703 u32 bufferaddress;
704 u32 bufferaddress64;
705
706} __packed;
707
708void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,
709 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
710 struct ieee80211_tx_info *info,
711 struct ieee80211_sta *sta,
712 struct sk_buff *skb, u8 hw_queue,
713 struct rtl_tcb_desc *ptcb_desc);
714bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,
715 struct rtl_stats *status,
716 struct ieee80211_rx_status *rx_status,
717 u8 *pdesc, struct sk_buff *skb);
718void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
719u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name);
720void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
721void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
722 bool b_firstseg, bool b_lastseg,
723 struct sk_buff *skb);
724
725#endif
diff --git a/drivers/net/wireless/rtlwifi/stats.c b/drivers/net/wireless/rtlwifi/stats.c
new file mode 100644
index 00000000000..8ed31744a05
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/stats.c
@@ -0,0 +1,268 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29#include "wifi.h"
30#include "stats.h"
31#include <linux/export.h>
32
33u8 rtl_query_rxpwrpercentage(char antpower)
34{
35 if ((antpower <= -100) || (antpower >= 20))
36 return 0;
37 else if (antpower >= 0)
38 return 100;
39 else
40 return 100 + antpower;
41}
42EXPORT_SYMBOL(rtl_query_rxpwrpercentage);
43
44u8 rtl_evm_db_to_percentage(char value)
45{
46 char ret_val;
47 ret_val = value;
48
49 if (ret_val >= 0)
50 ret_val = 0;
51 if (ret_val <= -33)
52 ret_val = -33;
53 ret_val = 0 - ret_val;
54 ret_val *= 3;
55 if (ret_val == 99)
56 ret_val = 100;
57
58 return ret_val;
59}
60EXPORT_SYMBOL(rtl_evm_db_to_percentage);
61
62static long rtl_translate_todbm(struct ieee80211_hw *hw,
63 u8 signal_strength_index)
64{
65 long signal_power;
66
67 signal_power = (long)((signal_strength_index + 1) >> 1);
68 signal_power -= 95;
69 return signal_power;
70}
71
72long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig)
73{
74 long retsig;
75
76 if (currsig >= 61 && currsig <= 100)
77 retsig = 90 + ((currsig - 60) / 4);
78 else if (currsig >= 41 && currsig <= 60)
79 retsig = 78 + ((currsig - 40) / 2);
80 else if (currsig >= 31 && currsig <= 40)
81 retsig = 66 + (currsig - 30);
82 else if (currsig >= 21 && currsig <= 30)
83 retsig = 54 + (currsig - 20);
84 else if (currsig >= 5 && currsig <= 20)
85 retsig = 42 + (((currsig - 5) * 2) / 3);
86 else if (currsig == 4)
87 retsig = 36;
88 else if (currsig == 3)
89 retsig = 27;
90 else if (currsig == 2)
91 retsig = 18;
92 else if (currsig == 1)
93 retsig = 9;
94 else
95 retsig = currsig;
96
97 return retsig;
98}
99EXPORT_SYMBOL(rtl_signal_scale_mapping);
100
101static void rtl_process_ui_rssi(struct ieee80211_hw *hw,
102 struct rtl_stats *pstatus)
103{
104 struct rtl_priv *rtlpriv = rtl_priv(hw);
105 struct rtl_phy *rtlphy = &(rtlpriv->phy);
106 u8 rfpath;
107 u32 last_rssi, tmpval;
108
109 rtlpriv->stats.rssi_calculate_cnt++;
110
111 if (rtlpriv->stats.ui_rssi.total_num++ >= PHY_RSSI_SLID_WIN_MAX) {
112 rtlpriv->stats.ui_rssi.total_num = PHY_RSSI_SLID_WIN_MAX;
113 last_rssi = rtlpriv->stats.ui_rssi.elements[
114 rtlpriv->stats.ui_rssi.index];
115 rtlpriv->stats.ui_rssi.total_val -= last_rssi;
116 }
117 rtlpriv->stats.ui_rssi.total_val += pstatus->signalstrength;
118 rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] =
119 pstatus->signalstrength;
120 if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
121 rtlpriv->stats.ui_rssi.index = 0;
122 tmpval = rtlpriv->stats.ui_rssi.total_val /
123 rtlpriv->stats.ui_rssi.total_num;
124 rtlpriv->stats.signal_strength = rtl_translate_todbm(hw,
125 (u8) tmpval);
126 pstatus->rssi = rtlpriv->stats.signal_strength;
127
128 if (pstatus->is_cck)
129 return;
130
131 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
132 rfpath++) {
133 if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
134 rtlpriv->stats.rx_rssi_percentage[rfpath] =
135 pstatus->rx_mimo_signalstrength[rfpath];
136
137 }
138 if (pstatus->rx_mimo_signalstrength[rfpath] >
139 rtlpriv->stats.rx_rssi_percentage[rfpath]) {
140 rtlpriv->stats.rx_rssi_percentage[rfpath] =
141 ((rtlpriv->stats.rx_rssi_percentage[rfpath] *
142 (RX_SMOOTH_FACTOR - 1)) +
143 (pstatus->rx_mimo_signalstrength[rfpath])) /
144 (RX_SMOOTH_FACTOR);
145 rtlpriv->stats.rx_rssi_percentage[rfpath] =
146 rtlpriv->stats.rx_rssi_percentage[rfpath] + 1;
147 } else {
148 rtlpriv->stats.rx_rssi_percentage[rfpath] =
149 ((rtlpriv->stats.rx_rssi_percentage[rfpath] *
150 (RX_SMOOTH_FACTOR - 1)) +
151 (pstatus->rx_mimo_signalstrength[rfpath])) /
152 (RX_SMOOTH_FACTOR);
153 }
154 }
155}
156
157static void rtl_update_rxsignalstatistics(struct ieee80211_hw *hw,
158 struct rtl_stats *pstatus)
159{
160 struct rtl_priv *rtlpriv = rtl_priv(hw);
161 int weighting = 0;
162
163 if (rtlpriv->stats.recv_signal_power == 0)
164 rtlpriv->stats.recv_signal_power = pstatus->recvsignalpower;
165 if (pstatus->recvsignalpower > rtlpriv->stats.recv_signal_power)
166 weighting = 5;
167 else if (pstatus->recvsignalpower < rtlpriv->stats.recv_signal_power)
168 weighting = (-5);
169 rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power *
170 5 + pstatus->recvsignalpower + weighting) / 6;
171}
172
173static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
174{
175 struct rtl_priv *rtlpriv = rtl_priv(hw);
176 struct rtl_sta_info *drv_priv = NULL;
177 struct ieee80211_sta *sta = NULL;
178 long undec_sm_pwdb;
179
180 rcu_read_lock();
181 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
182 sta = rtl_find_sta(hw, pstatus->psaddr);
183
184 /* adhoc or ap mode */
185 if (sta) {
186 drv_priv = (struct rtl_sta_info *) sta->drv_priv;
187 undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
188 } else {
189 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
190 }
191
192 if (undec_sm_pwdb < 0)
193 undec_sm_pwdb = pstatus->rx_pwdb_all;
194 if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) {
195 undec_sm_pwdb = (((undec_sm_pwdb) *
196 (RX_SMOOTH_FACTOR - 1)) +
197 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
198 undec_sm_pwdb = undec_sm_pwdb + 1;
199 } else {
200 undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) +
201 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
202 }
203
204 if (sta) {
205 drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb;
206 } else {
207 rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
208 }
209 rcu_read_unlock();
210
211 rtl_update_rxsignalstatistics(hw, pstatus);
212}
213
214static void rtl_process_ui_link_quality(struct ieee80211_hw *hw,
215 struct rtl_stats *pstatus)
216{
217 struct rtl_priv *rtlpriv = rtl_priv(hw);
218 u32 last_evm, n_stream, tmpval;
219
220 if (pstatus->signalquality == 0)
221 return;
222
223 if (rtlpriv->stats.ui_link_quality.total_num++ >=
224 PHY_LINKQUALITY_SLID_WIN_MAX) {
225 rtlpriv->stats.ui_link_quality.total_num =
226 PHY_LINKQUALITY_SLID_WIN_MAX;
227 last_evm = rtlpriv->stats.ui_link_quality.elements[
228 rtlpriv->stats.ui_link_quality.index];
229 rtlpriv->stats.ui_link_quality.total_val -= last_evm;
230 }
231 rtlpriv->stats.ui_link_quality.total_val += pstatus->signalquality;
232 rtlpriv->stats.ui_link_quality.elements[
233 rtlpriv->stats.ui_link_quality.index++] =
234 pstatus->signalquality;
235 if (rtlpriv->stats.ui_link_quality.index >=
236 PHY_LINKQUALITY_SLID_WIN_MAX)
237 rtlpriv->stats.ui_link_quality.index = 0;
238 tmpval = rtlpriv->stats.ui_link_quality.total_val /
239 rtlpriv->stats.ui_link_quality.total_num;
240 rtlpriv->stats.signal_quality = tmpval;
241 rtlpriv->stats.last_sigstrength_inpercent = tmpval;
242 for (n_stream = 0; n_stream < 2; n_stream++) {
243 if (pstatus->rx_mimo_sig_qual[n_stream] != -1) {
244 if (rtlpriv->stats.rx_evm_percentage[n_stream] == 0) {
245 rtlpriv->stats.rx_evm_percentage[n_stream] =
246 pstatus->rx_mimo_sig_qual[n_stream];
247 }
248 rtlpriv->stats.rx_evm_percentage[n_stream] =
249 ((rtlpriv->stats.rx_evm_percentage[n_stream]
250 * (RX_SMOOTH_FACTOR - 1)) +
251 (pstatus->rx_mimo_sig_qual[n_stream] * 1)) /
252 (RX_SMOOTH_FACTOR);
253 }
254 }
255}
256
257void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer,
258 struct rtl_stats *pstatus)
259{
260
261 if (!pstatus->packet_matchbssid)
262 return;
263
264 rtl_process_ui_rssi(hw, pstatus);
265 rtl_process_pwdb(hw, pstatus);
266 rtl_process_ui_link_quality(hw, pstatus);
267}
268EXPORT_SYMBOL(rtl_process_phyinfo);
diff --git a/drivers/net/wireless/rtlwifi/stats.h b/drivers/net/wireless/rtlwifi/stats.h
new file mode 100644
index 00000000000..0dbdc520383
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/stats.h
@@ -0,0 +1,46 @@
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL_STATS_H__
31#define __RTL_STATS_H__
32
33#define PHY_RSSI_SLID_WIN_MAX 100
34#define PHY_LINKQUALITY_SLID_WIN_MAX 20
35#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
36
37/* Rx smooth factor */
38#define RX_SMOOTH_FACTOR 20
39
40u8 rtl_query_rxpwrpercentage(char antpower);
41u8 rtl_evm_db_to_percentage(char value);
42long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig);
43void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer,
44 struct rtl_stats *pstatus);
45
46#endif
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 6794b688dd7..21a5f4f4a13 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -350,6 +350,11 @@ enum rt_oem_id {
350 RT_CID_819x_WNC_COREGA = 31, 350 RT_CID_819x_WNC_COREGA = 31,
351 RT_CID_819x_Foxcoon = 32, 351 RT_CID_819x_Foxcoon = 32,
352 RT_CID_819x_DELL = 33, 352 RT_CID_819x_DELL = 33,
353 RT_CID_819x_PRONETS = 34,
354 RT_CID_819x_Edimax_ASUS = 35,
355 RT_CID_NETGEAR = 36,
356 RT_CID_PLANEX = 37,
357 RT_CID_CC_C = 38,
353}; 358};
354 359
355enum hw_descs { 360enum hw_descs {
@@ -505,6 +510,7 @@ enum rtl_var_map {
505 RTL_IMR_ROK, /*Receive DMA OK Interrupt */ 510 RTL_IMR_ROK, /*Receive DMA OK Interrupt */
506 RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK | 511 RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK |
507 * RTL_IMR_TBDER) */ 512 * RTL_IMR_TBDER) */
513 RTL_IMR_C2HCMD, /*fw interrupt*/
508 514
509 /*CCK Rates, TxHT = 0 */ 515 /*CCK Rates, TxHT = 0 */
510 RTL_RC_CCK_RATE1M, 516 RTL_RC_CCK_RATE1M,
@@ -661,6 +667,11 @@ enum ba_action {
661 ACT_DELBA = 2, 667 ACT_DELBA = 2,
662}; 668};
663 669
670enum rt_polarity_ctl {
671 RT_POLARITY_LOW_ACT = 0,
672 RT_POLARITY_HIGH_ACT = 1,
673};
674
664struct octet_string { 675struct octet_string {
665 u8 *octet; 676 u8 *octet;
666 u16 length; 677 u16 length;
@@ -903,6 +914,8 @@ struct rtl_phy {
903 u8 num_total_rfpath; 914 u8 num_total_rfpath;
904 struct phy_parameters hwparam_tables[MAX_TAB]; 915 struct phy_parameters hwparam_tables[MAX_TAB];
905 u16 rf_pathmap; 916 u16 rf_pathmap;
917
918 enum rt_polarity_ctl polarity_ctl;
906}; 919};
907 920
908#define MAX_TID_COUNT 9 921#define MAX_TID_COUNT 9
@@ -1042,13 +1055,64 @@ struct rtl_mac {
1042 /*QOS & EDCA */ 1055 /*QOS & EDCA */
1043 struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE]; 1056 struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE];
1044 struct rtl_qos_parameters ac[AC_MAX]; 1057 struct rtl_qos_parameters ac[AC_MAX];
1058
1059 /* counters */
1060 u64 last_txok_cnt;
1061 u64 last_rxok_cnt;
1062 u32 last_bt_edca_ul;
1063 u32 last_bt_edca_dl;
1064};
1065
1066struct btdm_8723 {
1067 bool all_off;
1068 bool agc_table_en;
1069 bool adc_back_off_on;
1070 bool b2_ant_hid_en;
1071 bool low_penalty_rate_adaptive;
1072 bool rf_rx_lpf_shrink;
1073 bool reject_aggre_pkt;
1074 bool tra_tdma_on;
1075 u8 tra_tdma_nav;
1076 u8 tra_tdma_ant;
1077 bool tdma_on;
1078 u8 tdma_ant;
1079 u8 tdma_nav;
1080 u8 tdma_dac_swing;
1081 u8 fw_dac_swing_lvl;
1082 bool ps_tdma_on;
1083 u8 ps_tdma_byte[5];
1084 bool pta_on;
1085 u32 val_0x6c0;
1086 u32 val_0x6c8;
1087 u32 val_0x6cc;
1088 bool sw_dac_swing_on;
1089 u32 sw_dac_swing_lvl;
1090 u32 wlan_act_hi;
1091 u32 wlan_act_lo;
1092 u32 bt_retry_index;
1093 bool dec_bt_pwr;
1094 bool ignore_wlan_act;
1095};
1096
1097struct bt_coexist_8723 {
1098 u32 high_priority_tx;
1099 u32 high_priority_rx;
1100 u32 low_priority_tx;
1101 u32 low_priority_rx;
1102 u8 c2h_bt_info;
1103 bool c2h_bt_info_req_sent;
1104 bool c2h_bt_inquiry_page;
1105 u32 bt_inq_page_start_time;
1106 u8 bt_retry_cnt;
1107 u8 c2h_bt_info_original;
1108 u8 bt_inquiry_page_cnt;
1109 struct btdm_8723 btdm;
1045}; 1110};
1046 1111
1047struct rtl_hal { 1112struct rtl_hal {
1048 struct ieee80211_hw *hw; 1113 struct ieee80211_hw *hw;
1049 1114 struct bt_coexist_8723 hal_coex_8723;
1050 bool up_first_time; 1115 bool up_first_time;
1051 bool first_init;
1052 bool being_init_adapter; 1116 bool being_init_adapter;
1053 bool bbrf_ready; 1117 bool bbrf_ready;
1054 1118
@@ -1312,6 +1376,7 @@ struct rtl_ps_ctl {
1312}; 1376};
1313 1377
1314struct rtl_stats { 1378struct rtl_stats {
1379 u8 psaddr[ETH_ALEN];
1315 u32 mac_time[2]; 1380 u32 mac_time[2];
1316 s8 rssi; 1381 s8 rssi;
1317 u8 signal; 1382 u8 signal;
@@ -1503,6 +1568,7 @@ struct rtl_hal_ops {
1503 void (*phy_lc_calibrate) (struct ieee80211_hw *hw, bool is2t); 1568 void (*phy_lc_calibrate) (struct ieee80211_hw *hw, bool is2t);
1504 void (*phy_set_bw_mode_callback) (struct ieee80211_hw *hw); 1569 void (*phy_set_bw_mode_callback) (struct ieee80211_hw *hw);
1505 void (*dm_dynamic_txpower) (struct ieee80211_hw *hw); 1570 void (*dm_dynamic_txpower) (struct ieee80211_hw *hw);
1571 void (*c2h_command_handle) (struct ieee80211_hw *hw);
1506 void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, 1572 void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw,
1507 bool mstate); 1573 bool mstate);
1508 void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); 1574 void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw);
@@ -1784,9 +1850,22 @@ struct rtl_priv {
1784 struct dig_t dm_digtable; 1850 struct dig_t dm_digtable;
1785 struct ps_t dm_pstable; 1851 struct ps_t dm_pstable;
1786 1852
1787 /* data buffer pointer for USB reads */ 1853 /* section shared by individual drivers */
1788 __le32 *usb_data; 1854 union {
1789 int usb_data_index; 1855 struct { /* data buffer pointer for USB reads */
1856 __le32 *usb_data;
1857 int usb_data_index;
1858 bool initialized;
1859 };
1860 struct { /* section for 8723ae */
1861 bool reg_init; /* true if regs saved */
1862 u32 reg_874;
1863 u32 reg_c70;
1864 u32 reg_85c;
1865 u32 reg_a74;
1866 bool bt_operation_on;
1867 };
1868 };
1790 1869
1791 /*This must be the last item so 1870 /*This must be the last item so
1792 that it points to the data allocated 1871 that it points to the data allocated
@@ -1818,6 +1897,7 @@ enum bt_co_type {
1818 BT_CSR_BC4 = 3, 1897 BT_CSR_BC4 = 3,
1819 BT_CSR_BC8 = 4, 1898 BT_CSR_BC8 = 4,
1820 BT_RTL8756 = 5, 1899 BT_RTL8756 = 5,
1900 BT_RTL8723A = 6,
1821}; 1901};
1822 1902
1823enum bt_cur_state { 1903enum bt_cur_state {
@@ -1876,13 +1956,27 @@ struct bt_coexist_info {
1876 1956
1877 bool fw_coexist_all_off; 1957 bool fw_coexist_all_off;
1878 bool sw_coexist_all_off; 1958 bool sw_coexist_all_off;
1879 u32 current_state; 1959 bool hw_coexist_all_off;
1960 u32 cstate;
1880 u32 previous_state; 1961 u32 previous_state;
1962 u32 cstate_h;
1963 u32 previous_state_h;
1964
1881 u8 bt_pre_rssi_state; 1965 u8 bt_pre_rssi_state;
1966 u8 bt_pre_rssi_state1;
1882 1967
1883 u8 reg_bt_iso; 1968 u8 reg_bt_iso;
1884 u8 reg_bt_sco; 1969 u8 reg_bt_sco;
1885 1970 bool balance_on;
1971 u8 bt_active_zero_cnt;
1972 bool cur_bt_disabled;
1973 bool pre_bt_disabled;
1974
1975 u8 bt_profile_case;
1976 u8 bt_profile_action;
1977 bool bt_busy;
1978 bool hold_for_bt_operation;
1979 u8 lps_counter;
1886}; 1980};
1887 1981
1888 1982
diff --git a/drivers/net/wireless/ti/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c
index 6af35265c90..23289d49dd3 100644
--- a/drivers/net/wireless/ti/wl1251/rx.c
+++ b/drivers/net/wireless/ti/wl1251/rx.c
@@ -81,7 +81,7 @@ static void wl1251_rx_status(struct wl1251 *wl,
81 status->freq = ieee80211_channel_to_frequency(desc->channel, 81 status->freq = ieee80211_channel_to_frequency(desc->channel,
82 status->band); 82 status->band);
83 83
84 status->flag |= RX_FLAG_MACTIME_MPDU; 84 status->flag |= RX_FLAG_MACTIME_START;
85 85
86 if (desc->flags & RX_DESC_ENCRYPTION_MASK) { 86 if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
87 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; 87 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 25530c8760c..4f1a05b92d2 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -677,7 +677,7 @@ static void wl12xx_get_vif_count(struct ieee80211_hw *hw,
677 memset(data, 0, sizeof(*data)); 677 memset(data, 0, sizeof(*data));
678 data->cur_vif = cur_vif; 678 data->cur_vif = cur_vif;
679 679
680 ieee80211_iterate_active_interfaces(hw, 680 ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
681 wl12xx_vif_count_iter, data); 681 wl12xx_vif_count_iter, data);
682} 682}
683 683
@@ -3791,7 +3791,7 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
3791 3791
3792 /* Handle HT information change */ 3792 /* Handle HT information change */
3793 if ((changed & BSS_CHANGED_HT) && 3793 if ((changed & BSS_CHANGED_HT) &&
3794 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { 3794 (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
3795 ret = wl1271_acx_set_ht_information(wl, wlvif, 3795 ret = wl1271_acx_set_ht_information(wl, wlvif,
3796 bss_conf->ht_operation_mode); 3796 bss_conf->ht_operation_mode);
3797 if (ret < 0) { 3797 if (ret < 0) {
@@ -3905,7 +3905,8 @@ sta_not_found:
3905 u32 rates; 3905 u32 rates;
3906 int ieoffset; 3906 int ieoffset;
3907 wlvif->aid = bss_conf->aid; 3907 wlvif->aid = bss_conf->aid;
3908 wlvif->channel_type = bss_conf->channel_type; 3908 wlvif->channel_type =
3909 cfg80211_get_chandef_type(&bss_conf->chandef);
3909 wlvif->beacon_int = bss_conf->beacon_int; 3910 wlvif->beacon_int = bss_conf->beacon_int;
3910 do_join = true; 3911 do_join = true;
3911 set_assoc = true; 3912 set_assoc = true;
@@ -4071,7 +4072,7 @@ sta_not_found:
4071 /* Handle new association with HT. Do this after join. */ 4072 /* Handle new association with HT. Do this after join. */
4072 if (sta_exists) { 4073 if (sta_exists) {
4073 if ((changed & BSS_CHANGED_HT) && 4074 if ((changed & BSS_CHANGED_HT) &&
4074 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { 4075 (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
4075 ret = wl1271_acx_set_ht_capabilities(wl, 4076 ret = wl1271_acx_set_ht_capabilities(wl,
4076 &sta_ht_cap, 4077 &sta_ht_cap,
4077 true, 4078 true,
@@ -4098,7 +4099,7 @@ sta_not_found:
4098 4099
4099 /* Handle HT information change. Done after join. */ 4100 /* Handle HT information change. Done after join. */
4100 if ((changed & BSS_CHANGED_HT) && 4101 if ((changed & BSS_CHANGED_HT) &&
4101 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { 4102 (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
4102 ret = wl1271_acx_set_ht_information(wl, wlvif, 4103 ret = wl1271_acx_set_ht_information(wl, wlvif,
4103 bss_conf->ht_operation_mode); 4104 bss_conf->ht_operation_mode);
4104 if (ret < 0) { 4105 if (ret < 0) {
diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c
index fb430d88235..7da9071b68b 100644
--- a/drivers/nfc/pn544/i2c.c
+++ b/drivers/nfc/pn544/i2c.c
@@ -26,7 +26,7 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28 28
29#include <linux/nfc/pn544.h> 29#include <linux/platform_data/pn544.h>
30 30
31#include <net/nfc/hci.h> 31#include <net/nfc/hci.h>
32#include <net/nfc/llc.h> 32#include <net/nfc/llc.h>
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index fd15d982970..93b1e091b1e 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -157,6 +157,7 @@ struct bcma_host_ops {
157 157
158/* Chip IDs of SoCs */ 158/* Chip IDs of SoCs */
159#define BCMA_CHIP_ID_BCM4706 0x5300 159#define BCMA_CHIP_ID_BCM4706 0x5300
160#define BCMA_PKG_ID_BCM4706L 1
160#define BCMA_CHIP_ID_BCM4716 0x4716 161#define BCMA_CHIP_ID_BCM4716 0x4716
161#define BCMA_PKG_ID_BCM4716 8 162#define BCMA_PKG_ID_BCM4716 8
162#define BCMA_PKG_ID_BCM4717 9 163#define BCMA_PKG_ID_BCM4717 9
@@ -166,7 +167,11 @@ struct bcma_host_ops {
166#define BCMA_CHIP_ID_BCM4749 0x4749 167#define BCMA_CHIP_ID_BCM4749 0x4749
167#define BCMA_CHIP_ID_BCM5356 0x5356 168#define BCMA_CHIP_ID_BCM5356 0x5356
168#define BCMA_CHIP_ID_BCM5357 0x5357 169#define BCMA_CHIP_ID_BCM5357 0x5357
170#define BCMA_PKG_ID_BCM5358 9
171#define BCMA_PKG_ID_BCM47186 10
172#define BCMA_PKG_ID_BCM5357 11
169#define BCMA_CHIP_ID_BCM53572 53572 173#define BCMA_CHIP_ID_BCM53572 53572
174#define BCMA_PKG_ID_BCM47188 9
170 175
171struct bcma_device { 176struct bcma_device {
172 struct bcma_bus *bus; 177 struct bcma_bus *bus;
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 85764a90073..f9c5a787d35 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -131,6 +131,8 @@
131 131
132#define IEEE80211_MAX_MESH_ID_LEN 32 132#define IEEE80211_MAX_MESH_ID_LEN 32
133 133
134#define IEEE80211_NUM_TIDS 16
135
134#define IEEE80211_QOS_CTL_LEN 2 136#define IEEE80211_QOS_CTL_LEN 2
135/* 1d tag mask */ 137/* 1d tag mask */
136#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007 138#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007
@@ -666,6 +668,21 @@ struct ieee80211_meshconf_ie {
666} __attribute__ ((packed)); 668} __attribute__ ((packed));
667 669
668/** 670/**
671 * enum mesh_config_capab_flags - Mesh Configuration IE capability field flags
672 *
673 * @IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS: STA is willing to establish
674 * additional mesh peerings with other mesh STAs
675 * @IEEE80211_MESHCONF_CAPAB_FORWARDING: the STA forwards MSDUs
676 * @IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING: TBTT adjustment procedure
677 * is ongoing
678 */
679enum mesh_config_capab_flags {
680 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS = 0x01,
681 IEEE80211_MESHCONF_CAPAB_FORWARDING = 0x08,
682 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING = 0x20,
683};
684
685/**
669 * struct ieee80211_rann_ie 686 * struct ieee80211_rann_ie
670 * 687 *
671 * This structure refers to "Root Announcement information element" 688 * This structure refers to "Root Announcement information element"
@@ -905,6 +922,38 @@ struct ieee80211_tdls_data {
905 } u; 922 } u;
906} __packed; 923} __packed;
907 924
925/*
926 * Peer-to-Peer IE attribute related definitions.
927 */
928/**
929 * enum ieee80211_p2p_attr_id - identifies type of peer-to-peer attribute.
930 */
931enum ieee80211_p2p_attr_id {
932 IEEE80211_P2P_ATTR_STATUS = 0,
933 IEEE80211_P2P_ATTR_MINOR_REASON,
934 IEEE80211_P2P_ATTR_CAPABILITY,
935 IEEE80211_P2P_ATTR_DEVICE_ID,
936 IEEE80211_P2P_ATTR_GO_INTENT,
937 IEEE80211_P2P_ATTR_GO_CONFIG_TIMEOUT,
938 IEEE80211_P2P_ATTR_LISTEN_CHANNEL,
939 IEEE80211_P2P_ATTR_GROUP_BSSID,
940 IEEE80211_P2P_ATTR_EXT_LISTEN_TIMING,
941 IEEE80211_P2P_ATTR_INTENDED_IFACE_ADDR,
942 IEEE80211_P2P_ATTR_MANAGABILITY,
943 IEEE80211_P2P_ATTR_CHANNEL_LIST,
944 IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
945 IEEE80211_P2P_ATTR_DEVICE_INFO,
946 IEEE80211_P2P_ATTR_GROUP_INFO,
947 IEEE80211_P2P_ATTR_GROUP_ID,
948 IEEE80211_P2P_ATTR_INTERFACE,
949 IEEE80211_P2P_ATTR_OPER_CHANNEL,
950 IEEE80211_P2P_ATTR_INVITE_FLAGS,
951 /* 19 - 220: Reserved */
952 IEEE80211_P2P_ATTR_VENDOR_SPECIFIC = 221,
953
954 IEEE80211_P2P_ATTR_MAX
955};
956
908/** 957/**
909 * struct ieee80211_bar - HT Block Ack Request 958 * struct ieee80211_bar - HT Block Ack Request
910 * 959 *
@@ -1114,11 +1163,13 @@ struct ieee80211_ht_operation {
1114 * STA can receive. Rate expressed in units of 1 Mbps. 1163 * STA can receive. Rate expressed in units of 1 Mbps.
1115 * If this field is 0 this value should not be used to 1164 * If this field is 0 this value should not be used to
1116 * consider the highest RX data rate supported. 1165 * consider the highest RX data rate supported.
1166 * The top 3 bits of this field are reserved.
1117 * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams 1167 * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams
1118 * @tx_highest: Indicates highest long GI VHT PPDU data rate 1168 * @tx_highest: Indicates highest long GI VHT PPDU data rate
1119 * STA can transmit. Rate expressed in units of 1 Mbps. 1169 * STA can transmit. Rate expressed in units of 1 Mbps.
1120 * If this field is 0 this value should not be used to 1170 * If this field is 0 this value should not be used to
1121 * consider the highest TX data rate supported. 1171 * consider the highest TX data rate supported.
1172 * The top 3 bits of this field are reserved.
1122 */ 1173 */
1123struct ieee80211_vht_mcs_info { 1174struct ieee80211_vht_mcs_info {
1124 __le16 rx_mcs_map; 1175 __le16 rx_mcs_map;
@@ -1128,6 +1179,27 @@ struct ieee80211_vht_mcs_info {
1128} __packed; 1179} __packed;
1129 1180
1130/** 1181/**
1182 * enum ieee80211_vht_mcs_support - VHT MCS support definitions
1183 * @IEEE80211_VHT_MCS_SUPPORT_0_7: MCSes 0-7 are supported for the
1184 * number of streams
1185 * @IEEE80211_VHT_MCS_SUPPORT_0_8: MCSes 0-8 are supported
1186 * @IEEE80211_VHT_MCS_SUPPORT_0_9: MCSes 0-9 are supported
1187 * @IEEE80211_VHT_MCS_NOT_SUPPORTED: This number of streams isn't supported
1188 *
1189 * These definitions are used in each 2-bit subfield of the @rx_mcs_map
1190 * and @tx_mcs_map fields of &struct ieee80211_vht_mcs_info, which are
1191 * both split into 8 subfields by number of streams. These values indicate
1192 * which MCSes are supported for the number of streams the value appears
1193 * for.
1194 */
1195enum ieee80211_vht_mcs_support {
1196 IEEE80211_VHT_MCS_SUPPORT_0_7 = 0,
1197 IEEE80211_VHT_MCS_SUPPORT_0_8 = 1,
1198 IEEE80211_VHT_MCS_SUPPORT_0_9 = 2,
1199 IEEE80211_VHT_MCS_NOT_SUPPORTED = 3,
1200};
1201
1202/**
1131 * struct ieee80211_vht_cap - VHT capabilities 1203 * struct ieee80211_vht_cap - VHT capabilities
1132 * 1204 *
1133 * This structure is the "VHT capabilities element" as 1205 * This structure is the "VHT capabilities element" as
diff --git a/include/linux/nfc/pn544.h b/include/linux/nfc/pn544.h
deleted file mode 100644
index 9890bbaf432..00000000000
--- a/include/linux/nfc/pn544.h
+++ /dev/null
@@ -1,104 +0,0 @@
1/*
2 * Driver include for the PN544 NFC chip.
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Jari Vanhala <ext-jari.vanhala@nokia.com>
7 * Contact: Matti Aaltoenn <matti.j.aaltonen@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _PN544_H_
24#define _PN544_H_
25
26#include <linux/i2c.h>
27
28#define PN544_DRIVER_NAME "pn544"
29#define PN544_MAXWINDOW_SIZE 7
30#define PN544_WINDOW_SIZE 4
31#define PN544_RETRIES 10
32#define PN544_MAX_I2C_TRANSFER 0x0400
33#define PN544_MSG_MAX_SIZE 0x21 /* at normal HCI mode */
34
35/* ioctl */
36#define PN544_CHAR_BASE 'P'
37#define PN544_IOR(num, dtype) _IOR(PN544_CHAR_BASE, num, dtype)
38#define PN544_IOW(num, dtype) _IOW(PN544_CHAR_BASE, num, dtype)
39#define PN544_GET_FW_MODE PN544_IOW(1, unsigned int)
40#define PN544_SET_FW_MODE PN544_IOW(2, unsigned int)
41#define PN544_GET_DEBUG PN544_IOW(3, unsigned int)
42#define PN544_SET_DEBUG PN544_IOW(4, unsigned int)
43
44/* Timing restrictions (ms) */
45#define PN544_RESETVEN_TIME 30 /* 7 */
46#define PN544_PVDDVEN_TIME 0
47#define PN544_VBATVEN_TIME 0
48#define PN544_GPIO4VEN_TIME 0
49#define PN544_WAKEUP_ACK 5
50#define PN544_WAKEUP_GUARD (PN544_WAKEUP_ACK + 1)
51#define PN544_INACTIVITY_TIME 1000
52#define PN544_INTERFRAME_DELAY 200 /* us */
53#define PN544_BAUDRATE_CHANGE 150 /* us */
54
55/* Debug bits */
56#define PN544_DEBUG_BUF 0x01
57#define PN544_DEBUG_READ 0x02
58#define PN544_DEBUG_WRITE 0x04
59#define PN544_DEBUG_IRQ 0x08
60#define PN544_DEBUG_CALLS 0x10
61#define PN544_DEBUG_MODE 0x20
62
63/* Normal (HCI) mode */
64#define PN544_LLC_HCI_OVERHEAD 3 /* header + crc (to length) */
65#define PN544_LLC_MIN_SIZE (1 + PN544_LLC_HCI_OVERHEAD) /* length + */
66#define PN544_LLC_MAX_DATA (PN544_MSG_MAX_SIZE - 2)
67#define PN544_LLC_MAX_HCI_SIZE (PN544_LLC_MAX_DATA - 2)
68
69struct pn544_llc_packet {
70 unsigned char length; /* of rest of packet */
71 unsigned char header;
72 unsigned char data[PN544_LLC_MAX_DATA]; /* includes crc-ccitt */
73};
74
75/* Firmware upgrade mode */
76#define PN544_FW_HEADER_SIZE 3
77/* max fw transfer is 1024bytes, but I2C limits it to 0xC0 */
78#define PN544_MAX_FW_DATA (PN544_MAX_I2C_TRANSFER - PN544_FW_HEADER_SIZE)
79
80struct pn544_fw_packet {
81 unsigned char command; /* status in answer */
82 unsigned char length[2]; /* big-endian order (msf) */
83 unsigned char data[PN544_MAX_FW_DATA];
84};
85
86#ifdef __KERNEL__
87enum {
88 NFC_GPIO_ENABLE,
89 NFC_GPIO_FW_RESET,
90 NFC_GPIO_IRQ
91};
92
93/* board config */
94struct pn544_nfc_platform_data {
95 int (*request_resources) (struct i2c_client *client);
96 void (*free_resources) (void);
97 void (*enable) (int fw);
98 int (*test) (void);
99 void (*disable) (void);
100 int (*get_gpio)(int type);
101};
102#endif /* __KERNEL__ */
103
104#endif /* _PN544_H_ */
diff --git a/include/linux/platform_data/pn544.h b/include/linux/platform_data/pn544.h
new file mode 100644
index 00000000000..713bfd70334
--- /dev/null
+++ b/include/linux/platform_data/pn544.h
@@ -0,0 +1,44 @@
1/*
2 * Driver include for the PN544 NFC chip.
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Jari Vanhala <ext-jari.vanhala@nokia.com>
7 * Contact: Matti Aaltoenn <matti.j.aaltonen@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _PN544_H_
24#define _PN544_H_
25
26#include <linux/i2c.h>
27
28enum {
29 NFC_GPIO_ENABLE,
30 NFC_GPIO_FW_RESET,
31 NFC_GPIO_IRQ
32};
33
34/* board config */
35struct pn544_nfc_platform_data {
36 int (*request_resources) (struct i2c_client *client);
37 void (*free_resources) (void);
38 void (*enable) (int fw);
39 int (*test) (void);
40 void (*disable) (void);
41 int (*get_gpio)(int type);
42};
43
44#endif /* _PN544_H_ */
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index a0525019e1d..6ecfa02ddba 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -485,7 +485,7 @@
485#define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT 4 485#define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT 4
486#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL 0x0020 486#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL 0x0020
487#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT 5 487#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT 5
488#define SSB_SPROM8_TEMPDELTA 0x00BA 488#define SSB_SPROM8_TEMPDELTA 0x00BC
489#define SSB_SPROM8_TEMPDELTA_PHYCAL 0x00ff 489#define SSB_SPROM8_TEMPDELTA_PHYCAL 0x00ff
490#define SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT 0 490#define SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT 0
491#define SSB_SPROM8_TEMPDELTA_PERIOD 0x0f00 491#define SSB_SPROM8_TEMPDELTA_PERIOD 0x0f00
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index 2e7c79ea046..7ea3db77ba8 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -46,5 +46,9 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
46 struct hci_conn *hcon); 46 struct hci_conn *hcon);
47void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle); 47void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
48void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle); 48void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
49void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon);
50void amp_create_logical_link(struct l2cap_chan *chan);
51void amp_disconnect_logical_link(struct hci_chan *hchan);
52void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason);
49 53
50#endif /* __AMP_H */ 54#endif /* __AMP_H */
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 88cbbda6102..45eee08157b 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -115,6 +115,7 @@ enum {
115 HCI_SSP_ENABLED, 115 HCI_SSP_ENABLED,
116 HCI_HS_ENABLED, 116 HCI_HS_ENABLED,
117 HCI_LE_ENABLED, 117 HCI_LE_ENABLED,
118 HCI_LE_PERIPHERAL,
118 HCI_CONNECTABLE, 119 HCI_CONNECTABLE,
119 HCI_DISCOVERABLE, 120 HCI_DISCOVERABLE,
120 HCI_LINK_SECURITY, 121 HCI_LINK_SECURITY,
@@ -153,7 +154,7 @@ enum {
153#define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ 154#define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
154#define HCI_PAIRING_TIMEOUT msecs_to_jiffies(60000) /* 60 seconds */ 155#define HCI_PAIRING_TIMEOUT msecs_to_jiffies(60000) /* 60 seconds */
155#define HCI_INIT_TIMEOUT msecs_to_jiffies(10000) /* 10 seconds */ 156#define HCI_INIT_TIMEOUT msecs_to_jiffies(10000) /* 10 seconds */
156#define HCI_CMD_TIMEOUT msecs_to_jiffies(1000) /* 1 second */ 157#define HCI_CMD_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
157#define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */ 158#define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */
158#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ 159#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
159 160
@@ -318,6 +319,9 @@ enum {
318#define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00 319#define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00
319#define HCI_FLOW_CTL_MODE_BLOCK_BASED 0x01 320#define HCI_FLOW_CTL_MODE_BLOCK_BASED 0x01
320 321
322/* The core spec defines 127 as the "not available" value */
323#define HCI_TX_POWER_INVALID 127
324
321/* Extended Inquiry Response field types */ 325/* Extended Inquiry Response field types */
322#define EIR_FLAGS 0x01 /* flags */ 326#define EIR_FLAGS 0x01 /* flags */
323#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ 327#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
@@ -334,6 +338,13 @@ enum {
334#define EIR_SSP_RAND_R 0x0F /* Simple Pairing Randomizer R */ 338#define EIR_SSP_RAND_R 0x0F /* Simple Pairing Randomizer R */
335#define EIR_DEVICE_ID 0x10 /* device ID */ 339#define EIR_DEVICE_ID 0x10 /* device ID */
336 340
341/* Low Energy Advertising Flags */
342#define LE_AD_LIMITED 0x01 /* Limited Discoverable */
343#define LE_AD_GENERAL 0x02 /* General Discoverable */
344#define LE_AD_NO_BREDR 0x04 /* BR/EDR not supported */
345#define LE_AD_SIM_LE_BREDR_CTRL 0x08 /* Simultaneous LE & BR/EDR Controller */
346#define LE_AD_SIM_LE_BREDR_HOST 0x10 /* Simultaneous LE & BR/EDR Host */
347
337/* ----- HCI Commands ---- */ 348/* ----- HCI Commands ---- */
338#define HCI_OP_NOP 0x0000 349#define HCI_OP_NOP 0x0000
339 350
@@ -932,6 +943,22 @@ struct hci_rp_le_read_buffer_size {
932 __u8 le_max_pkt; 943 __u8 le_max_pkt;
933} __packed; 944} __packed;
934 945
946#define HCI_OP_LE_READ_ADV_TX_POWER 0x2007
947struct hci_rp_le_read_adv_tx_power {
948 __u8 status;
949 __s8 tx_power;
950} __packed;
951
952#define HCI_MAX_AD_LENGTH 31
953
954#define HCI_OP_LE_SET_ADV_DATA 0x2008
955struct hci_cp_le_set_adv_data {
956 __u8 length;
957 __u8 data[HCI_MAX_AD_LENGTH];
958} __packed;
959
960#define HCI_OP_LE_SET_ADV_ENABLE 0x200a
961
935#define HCI_OP_LE_SET_SCAN_PARAM 0x200b 962#define HCI_OP_LE_SET_SCAN_PARAM 0x200b
936struct hci_cp_le_set_scan_param { 963struct hci_cp_le_set_scan_param {
937 __u8 type; 964 __u8 type;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 9fe8e2dec87..ef5b85dac3f 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -278,6 +278,10 @@ struct hci_dev {
278 struct work_struct le_scan; 278 struct work_struct le_scan;
279 struct le_scan_params le_scan_params; 279 struct le_scan_params le_scan_params;
280 280
281 __s8 adv_tx_power;
282 __u8 adv_data[HCI_MAX_AD_LENGTH];
283 __u8 adv_data_len;
284
281 int (*open)(struct hci_dev *hdev); 285 int (*open)(struct hci_dev *hdev);
282 int (*close)(struct hci_dev *hdev); 286 int (*close)(struct hci_dev *hdev);
283 int (*flush)(struct hci_dev *hdev); 287 int (*flush)(struct hci_dev *hdev);
@@ -355,6 +359,7 @@ struct hci_chan {
355 struct hci_conn *conn; 359 struct hci_conn *conn;
356 struct sk_buff_head data_q; 360 struct sk_buff_head data_q;
357 unsigned int sent; 361 unsigned int sent;
362 __u8 state;
358}; 363};
359 364
360extern struct list_head hci_dev_list; 365extern struct list_head hci_dev_list;
@@ -682,7 +687,7 @@ static inline uint8_t __hci_num_ctrl(void)
682} 687}
683 688
684struct hci_dev *hci_dev_get(int index); 689struct hci_dev *hci_dev_get(int index);
685struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); 690struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src);
686 691
687struct hci_dev *hci_alloc_dev(void); 692struct hci_dev *hci_alloc_dev(void);
688void hci_free_dev(struct hci_dev *hdev); 693void hci_free_dev(struct hci_dev *hdev);
@@ -731,6 +736,8 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
731 u8 *randomizer); 736 u8 *randomizer);
732int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); 737int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
733 738
739int hci_update_ad(struct hci_dev *hdev);
740
734void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); 741void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
735 742
736int hci_recv_frame(struct sk_buff *skb); 743int hci_recv_frame(struct sk_buff *skb);
@@ -747,18 +754,29 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
747#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev)) 754#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev))
748 755
749/* ----- LMP capabilities ----- */ 756/* ----- LMP capabilities ----- */
750#define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH)
751#define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT) 757#define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT)
758#define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH)
759#define lmp_hold_capable(dev) ((dev)->features[0] & LMP_HOLD)
752#define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF) 760#define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF)
753#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) 761#define lmp_park_capable(dev) ((dev)->features[1] & LMP_PARK)
762#define lmp_inq_rssi_capable(dev) ((dev)->features[3] & LMP_RSSI_INQ)
754#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) 763#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
764#define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR))
765#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE)
766#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
767#define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC)
768#define lmp_ext_inq_capable(dev) ((dev)->features[6] & LMP_EXT_INQ)
769#define lmp_le_br_capable(dev) ((dev)->features[6] & LMP_SIMUL_LE_BR)
755#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) 770#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
756#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH) 771#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
757#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE) 772#define lmp_lsto_capable(dev) ((dev)->features[7] & LMP_LSTO)
758#define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR)) 773#define lmp_inq_tx_pwr_capable(dev) ((dev)->features[7] & LMP_INQ_TX_PWR)
774#define lmp_ext_feat_capable(dev) ((dev)->features[7] & LMP_EXTFEATURES)
759 775
760/* ----- Extended LMP capabilities ----- */ 776/* ----- Extended LMP capabilities ----- */
777#define lmp_host_ssp_capable(dev) ((dev)->host_features[0] & LMP_HOST_SSP)
761#define lmp_host_le_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE) 778#define lmp_host_le_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE)
779#define lmp_host_le_br_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE_BREDR)
762 780
763/* ----- HCI protocols ----- */ 781/* ----- HCI protocols ----- */
764static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, 782static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
@@ -877,7 +895,7 @@ struct hci_cb {
877 895
878static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) 896static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
879{ 897{
880 struct list_head *p; 898 struct hci_cb *cb;
881 __u8 encrypt; 899 __u8 encrypt;
882 900
883 hci_proto_auth_cfm(conn, status); 901 hci_proto_auth_cfm(conn, status);
@@ -888,8 +906,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
888 encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; 906 encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
889 907
890 read_lock(&hci_cb_list_lock); 908 read_lock(&hci_cb_list_lock);
891 list_for_each(p, &hci_cb_list) { 909 list_for_each_entry(cb, &hci_cb_list, list) {
892 struct hci_cb *cb = list_entry(p, struct hci_cb, list);
893 if (cb->security_cfm) 910 if (cb->security_cfm)
894 cb->security_cfm(conn, status, encrypt); 911 cb->security_cfm(conn, status, encrypt);
895 } 912 }
@@ -899,7 +916,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
899static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, 916static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
900 __u8 encrypt) 917 __u8 encrypt)
901{ 918{
902 struct list_head *p; 919 struct hci_cb *cb;
903 920
904 if (conn->sec_level == BT_SECURITY_SDP) 921 if (conn->sec_level == BT_SECURITY_SDP)
905 conn->sec_level = BT_SECURITY_LOW; 922 conn->sec_level = BT_SECURITY_LOW;
@@ -910,8 +927,7 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
910 hci_proto_encrypt_cfm(conn, status, encrypt); 927 hci_proto_encrypt_cfm(conn, status, encrypt);
911 928
912 read_lock(&hci_cb_list_lock); 929 read_lock(&hci_cb_list_lock);
913 list_for_each(p, &hci_cb_list) { 930 list_for_each_entry(cb, &hci_cb_list, list) {
914 struct hci_cb *cb = list_entry(p, struct hci_cb, list);
915 if (cb->security_cfm) 931 if (cb->security_cfm)
916 cb->security_cfm(conn, status, encrypt); 932 cb->security_cfm(conn, status, encrypt);
917 } 933 }
@@ -920,11 +936,10 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
920 936
921static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) 937static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
922{ 938{
923 struct list_head *p; 939 struct hci_cb *cb;
924 940
925 read_lock(&hci_cb_list_lock); 941 read_lock(&hci_cb_list_lock);
926 list_for_each(p, &hci_cb_list) { 942 list_for_each_entry(cb, &hci_cb_list, list) {
927 struct hci_cb *cb = list_entry(p, struct hci_cb, list);
928 if (cb->key_change_cfm) 943 if (cb->key_change_cfm)
929 cb->key_change_cfm(conn, status); 944 cb->key_change_cfm(conn, status);
930 } 945 }
@@ -934,11 +949,10 @@ static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
934static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, 949static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
935 __u8 role) 950 __u8 role)
936{ 951{
937 struct list_head *p; 952 struct hci_cb *cb;
938 953
939 read_lock(&hci_cb_list_lock); 954 read_lock(&hci_cb_list_lock);
940 list_for_each(p, &hci_cb_list) { 955 list_for_each_entry(cb, &hci_cb_list, list) {
941 struct hci_cb *cb = list_entry(p, struct hci_cb, list);
942 if (cb->role_switch_cfm) 956 if (cb->role_switch_cfm)
943 cb->role_switch_cfm(conn, status, role); 957 cb->role_switch_cfm(conn, status, role);
944 } 958 }
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6e23afdf65c..f57fab04e7c 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -52,6 +52,8 @@
52#define L2CAP_ENC_TIMEOUT msecs_to_jiffies(5000) 52#define L2CAP_ENC_TIMEOUT msecs_to_jiffies(5000)
53#define L2CAP_CONN_TIMEOUT msecs_to_jiffies(40000) 53#define L2CAP_CONN_TIMEOUT msecs_to_jiffies(40000)
54#define L2CAP_INFO_TIMEOUT msecs_to_jiffies(4000) 54#define L2CAP_INFO_TIMEOUT msecs_to_jiffies(4000)
55#define L2CAP_MOVE_TIMEOUT msecs_to_jiffies(4000)
56#define L2CAP_MOVE_ERTX_TIMEOUT msecs_to_jiffies(60000)
55 57
56#define L2CAP_A2MP_DEFAULT_MTU 670 58#define L2CAP_A2MP_DEFAULT_MTU 670
57 59
@@ -434,6 +436,8 @@ struct l2cap_chan {
434 struct sock *sk; 436 struct sock *sk;
435 437
436 struct l2cap_conn *conn; 438 struct l2cap_conn *conn;
439 struct hci_conn *hs_hcon;
440 struct hci_chan *hs_hchan;
437 struct kref kref; 441 struct kref kref;
438 442
439 __u8 state; 443 __u8 state;
@@ -477,6 +481,12 @@ struct l2cap_chan {
477 unsigned long conn_state; 481 unsigned long conn_state;
478 unsigned long flags; 482 unsigned long flags;
479 483
484 __u8 remote_amp_id;
485 __u8 local_amp_id;
486 __u8 move_id;
487 __u8 move_state;
488 __u8 move_role;
489
480 __u16 next_tx_seq; 490 __u16 next_tx_seq;
481 __u16 expected_ack_seq; 491 __u16 expected_ack_seq;
482 __u16 expected_tx_seq; 492 __u16 expected_tx_seq;
@@ -509,8 +519,6 @@ struct l2cap_chan {
509 __u32 remote_acc_lat; 519 __u32 remote_acc_lat;
510 __u32 remote_flush_to; 520 __u32 remote_flush_to;
511 521
512 __u8 ctrl_id;
513
514 struct delayed_work chan_timer; 522 struct delayed_work chan_timer;
515 struct delayed_work retrans_timer; 523 struct delayed_work retrans_timer;
516 struct delayed_work monitor_timer; 524 struct delayed_work monitor_timer;
@@ -644,6 +652,9 @@ enum {
644enum { 652enum {
645 L2CAP_RX_STATE_RECV, 653 L2CAP_RX_STATE_RECV,
646 L2CAP_RX_STATE_SREJ_SENT, 654 L2CAP_RX_STATE_SREJ_SENT,
655 L2CAP_RX_STATE_MOVE,
656 L2CAP_RX_STATE_WAIT_P,
657 L2CAP_RX_STATE_WAIT_F,
647}; 658};
648 659
649enum { 660enum {
@@ -674,6 +685,25 @@ enum {
674 L2CAP_EV_RECV_FRAME, 685 L2CAP_EV_RECV_FRAME,
675}; 686};
676 687
688enum {
689 L2CAP_MOVE_ROLE_NONE,
690 L2CAP_MOVE_ROLE_INITIATOR,
691 L2CAP_MOVE_ROLE_RESPONDER,
692};
693
694enum {
695 L2CAP_MOVE_STABLE,
696 L2CAP_MOVE_WAIT_REQ,
697 L2CAP_MOVE_WAIT_RSP,
698 L2CAP_MOVE_WAIT_RSP_SUCCESS,
699 L2CAP_MOVE_WAIT_CONFIRM,
700 L2CAP_MOVE_WAIT_CONFIRM_RSP,
701 L2CAP_MOVE_WAIT_LOGICAL_COMP,
702 L2CAP_MOVE_WAIT_LOGICAL_CFM,
703 L2CAP_MOVE_WAIT_LOCAL_BUSY,
704 L2CAP_MOVE_WAIT_PREPARE,
705};
706
677void l2cap_chan_hold(struct l2cap_chan *c); 707void l2cap_chan_hold(struct l2cap_chan *c);
678void l2cap_chan_put(struct l2cap_chan *c); 708void l2cap_chan_put(struct l2cap_chan *c);
679 709
@@ -778,5 +808,9 @@ void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
778void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); 808void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
779void l2cap_chan_del(struct l2cap_chan *chan, int err); 809void l2cap_chan_del(struct l2cap_chan *chan, int err);
780void l2cap_send_conn_req(struct l2cap_chan *chan); 810void l2cap_send_conn_req(struct l2cap_chan *chan);
811void l2cap_move_start(struct l2cap_chan *chan);
812void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
813 u8 status);
814void __l2cap_physical_cfm(struct l2cap_chan *chan, int result);
781 815
782#endif /* __L2CAP_H */ 816#endif /* __L2CAP_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index c6964572890..e78db2cf3d1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -306,6 +306,88 @@ struct key_params {
306}; 306};
307 307
308/** 308/**
309 * struct cfg80211_chan_def - channel definition
310 * @chan: the (control) channel
311 * @width: channel width
312 * @center_freq1: center frequency of first segment
313 * @center_freq2: center frequency of second segment
314 * (only with 80+80 MHz)
315 */
316struct cfg80211_chan_def {
317 struct ieee80211_channel *chan;
318 enum nl80211_chan_width width;
319 u32 center_freq1;
320 u32 center_freq2;
321};
322
323/**
324 * cfg80211_get_chandef_type - return old channel type from chandef
325 * @chandef: the channel definition
326 *
327 * Returns the old channel type (NOHT, HT20, HT40+/-) from a given
328 * chandef, which must have a bandwidth allowing this conversion.
329 */
330static inline enum nl80211_channel_type
331cfg80211_get_chandef_type(const struct cfg80211_chan_def *chandef)
332{
333 switch (chandef->width) {
334 case NL80211_CHAN_WIDTH_20_NOHT:
335 return NL80211_CHAN_NO_HT;
336 case NL80211_CHAN_WIDTH_20:
337 return NL80211_CHAN_HT20;
338 case NL80211_CHAN_WIDTH_40:
339 if (chandef->center_freq1 > chandef->chan->center_freq)
340 return NL80211_CHAN_HT40PLUS;
341 return NL80211_CHAN_HT40MINUS;
342 default:
343 WARN_ON(1);
344 return NL80211_CHAN_NO_HT;
345 }
346}
347
348/**
349 * cfg80211_chandef_create - create channel definition using channel type
350 * @chandef: the channel definition struct to fill
351 * @channel: the control channel
352 * @chantype: the channel type
353 *
354 * Given a channel type, create a channel definition.
355 */
356void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
357 struct ieee80211_channel *channel,
358 enum nl80211_channel_type chantype);
359
360/**
361 * cfg80211_chandef_identical - check if two channel definitions are identical
362 * @chandef1: first channel definition
363 * @chandef2: second channel definition
364 *
365 * Returns %true if the channels defined by the channel definitions are
366 * identical, %false otherwise.
367 */
368static inline bool
369cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1,
370 const struct cfg80211_chan_def *chandef2)
371{
372 return (chandef1->chan == chandef2->chan &&
373 chandef1->width == chandef2->width &&
374 chandef1->center_freq1 == chandef2->center_freq1 &&
375 chandef1->center_freq2 == chandef2->center_freq2);
376}
377
378/**
379 * cfg80211_chandef_compatible - check if two channel definitions are compatible
380 * @chandef1: first channel definition
381 * @chandef2: second channel definition
382 *
383 * Returns %NULL if the given channel definitions are incompatible,
384 * chandef1 or chandef2 otherwise.
385 */
386const struct cfg80211_chan_def *
387cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1,
388 const struct cfg80211_chan_def *chandef2);
389
390/**
309 * enum survey_info_flags - survey information flags 391 * enum survey_info_flags - survey information flags
310 * 392 *
311 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in 393 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
@@ -426,8 +508,7 @@ struct cfg80211_beacon_data {
426 * 508 *
427 * Used to configure an AP interface. 509 * Used to configure an AP interface.
428 * 510 *
429 * @channel: the channel to start the AP on 511 * @chandef: defines the channel to use
430 * @channel_type: the channel type to use
431 * @beacon: beacon data 512 * @beacon: beacon data
432 * @beacon_interval: beacon interval 513 * @beacon_interval: beacon interval
433 * @dtim_period: DTIM period 514 * @dtim_period: DTIM period
@@ -441,8 +522,7 @@ struct cfg80211_beacon_data {
441 * @inactivity_timeout: time in seconds to determine station's inactivity. 522 * @inactivity_timeout: time in seconds to determine station's inactivity.
442 */ 523 */
443struct cfg80211_ap_settings { 524struct cfg80211_ap_settings {
444 struct ieee80211_channel *channel; 525 struct cfg80211_chan_def chandef;
445 enum nl80211_channel_type channel_type;
446 526
447 struct cfg80211_beacon_data beacon; 527 struct cfg80211_beacon_data beacon;
448 528
@@ -582,16 +662,24 @@ enum station_info_flags {
582 * Used by the driver to indicate the specific rate transmission 662 * Used by the driver to indicate the specific rate transmission
583 * type for 802.11n transmissions. 663 * type for 802.11n transmissions.
584 * 664 *
585 * @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled 665 * @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS
586 * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission 666 * @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS
667 * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 MHz width transmission
668 * @RATE_INFO_FLAGS_80_MHZ_WIDTH: 80 MHz width transmission
669 * @RATE_INFO_FLAGS_80P80_MHZ_WIDTH: 80+80 MHz width transmission
670 * @RATE_INFO_FLAGS_160_MHZ_WIDTH: 160 MHz width transmission
587 * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval 671 * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
588 * @RATE_INFO_FLAGS_60G: 60gHz MCS 672 * @RATE_INFO_FLAGS_60G: 60GHz MCS
589 */ 673 */
590enum rate_info_flags { 674enum rate_info_flags {
591 RATE_INFO_FLAGS_MCS = 1<<0, 675 RATE_INFO_FLAGS_MCS = BIT(0),
592 RATE_INFO_FLAGS_40_MHZ_WIDTH = 1<<1, 676 RATE_INFO_FLAGS_VHT_MCS = BIT(1),
593 RATE_INFO_FLAGS_SHORT_GI = 1<<2, 677 RATE_INFO_FLAGS_40_MHZ_WIDTH = BIT(2),
594 RATE_INFO_FLAGS_60G = 1<<3, 678 RATE_INFO_FLAGS_80_MHZ_WIDTH = BIT(3),
679 RATE_INFO_FLAGS_80P80_MHZ_WIDTH = BIT(4),
680 RATE_INFO_FLAGS_160_MHZ_WIDTH = BIT(5),
681 RATE_INFO_FLAGS_SHORT_GI = BIT(6),
682 RATE_INFO_FLAGS_60G = BIT(7),
595}; 683};
596 684
597/** 685/**
@@ -602,11 +690,13 @@ enum rate_info_flags {
602 * @flags: bitflag of flags from &enum rate_info_flags 690 * @flags: bitflag of flags from &enum rate_info_flags
603 * @mcs: mcs index if struct describes a 802.11n bitrate 691 * @mcs: mcs index if struct describes a 802.11n bitrate
604 * @legacy: bitrate in 100kbit/s for 802.11abg 692 * @legacy: bitrate in 100kbit/s for 802.11abg
693 * @nss: number of streams (VHT only)
605 */ 694 */
606struct rate_info { 695struct rate_info {
607 u8 flags; 696 u8 flags;
608 u8 mcs; 697 u8 mcs;
609 u16 legacy; 698 u16 legacy;
699 u8 nss;
610}; 700};
611 701
612/** 702/**
@@ -909,8 +999,7 @@ struct mesh_config {
909 999
910/** 1000/**
911 * struct mesh_setup - 802.11s mesh setup configuration 1001 * struct mesh_setup - 802.11s mesh setup configuration
912 * @channel: the channel to start the mesh network on 1002 * @chandef: defines the channel to use
913 * @channel_type: the channel type to use
914 * @mesh_id: the mesh ID 1003 * @mesh_id: the mesh ID
915 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes 1004 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
916 * @sync_method: which synchronization method to use 1005 * @sync_method: which synchronization method to use
@@ -925,8 +1014,7 @@ struct mesh_config {
925 * These parameters are fixed when the mesh is created. 1014 * These parameters are fixed when the mesh is created.
926 */ 1015 */
927struct mesh_setup { 1016struct mesh_setup {
928 struct ieee80211_channel *channel; 1017 struct cfg80211_chan_def chandef;
929 enum nl80211_channel_type channel_type;
930 const u8 *mesh_id; 1018 const u8 *mesh_id;
931 u8 mesh_id_len; 1019 u8 mesh_id_len;
932 u8 sync_method; 1020 u8 sync_method;
@@ -1266,8 +1354,7 @@ struct cfg80211_disassoc_request {
1266 * @ssid_len: The length of the SSID, will always be non-zero. 1354 * @ssid_len: The length of the SSID, will always be non-zero.
1267 * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not 1355 * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not
1268 * search for IBSSs with a different BSSID. 1356 * search for IBSSs with a different BSSID.
1269 * @channel: The channel to use if no IBSS can be found to join. 1357 * @chandef: defines the channel to use if no other IBSS to join can be found
1270 * @channel_type: channel type (HT mode)
1271 * @channel_fixed: The channel should be fixed -- do not search for 1358 * @channel_fixed: The channel should be fixed -- do not search for
1272 * IBSSs to join on other channels. 1359 * IBSSs to join on other channels.
1273 * @ie: information element(s) to include in the beacon 1360 * @ie: information element(s) to include in the beacon
@@ -1285,8 +1372,7 @@ struct cfg80211_disassoc_request {
1285struct cfg80211_ibss_params { 1372struct cfg80211_ibss_params {
1286 u8 *ssid; 1373 u8 *ssid;
1287 u8 *bssid; 1374 u8 *bssid;
1288 struct ieee80211_channel *channel; 1375 struct cfg80211_chan_def chandef;
1289 enum nl80211_channel_type channel_type;
1290 u8 *ie; 1376 u8 *ie;
1291 u8 ssid_len, ie_len; 1377 u8 ssid_len, ie_len;
1292 u16 beacon_interval; 1378 u16 beacon_interval;
@@ -1545,13 +1631,19 @@ struct cfg80211_gtk_rekey_data {
1545 * to a merge. 1631 * to a merge.
1546 * @leave_ibss: Leave the IBSS. 1632 * @leave_ibss: Leave the IBSS.
1547 * 1633 *
1634 * @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or
1635 * MESH mode)
1636 *
1548 * @set_wiphy_params: Notify that wiphy parameters have changed; 1637 * @set_wiphy_params: Notify that wiphy parameters have changed;
1549 * @changed bitfield (see &enum wiphy_params_flags) describes which values 1638 * @changed bitfield (see &enum wiphy_params_flags) describes which values
1550 * have changed. The actual parameter values are available in 1639 * have changed. The actual parameter values are available in
1551 * struct wiphy. If returning an error, no value should be changed. 1640 * struct wiphy. If returning an error, no value should be changed.
1552 * 1641 *
1553 * @set_tx_power: set the transmit power according to the parameters, 1642 * @set_tx_power: set the transmit power according to the parameters,
1554 * the power passed is in mBm, to get dBm use MBM_TO_DBM(). 1643 * the power passed is in mBm, to get dBm use MBM_TO_DBM(). The
1644 * wdev may be %NULL if power was set for the wiphy, and will
1645 * always be %NULL unless the driver supports per-vif TX power
1646 * (as advertised by the nl80211 feature flag.)
1555 * @get_tx_power: store the current TX power into the dbm variable; 1647 * @get_tx_power: store the current TX power into the dbm variable;
1556 * return 0 if successful 1648 * return 0 if successful
1557 * 1649 *
@@ -1722,8 +1814,7 @@ struct cfg80211_ops {
1722 struct ieee80211_channel *chan); 1814 struct ieee80211_channel *chan);
1723 1815
1724 int (*set_monitor_channel)(struct wiphy *wiphy, 1816 int (*set_monitor_channel)(struct wiphy *wiphy,
1725 struct ieee80211_channel *chan, 1817 struct cfg80211_chan_def *chandef);
1726 enum nl80211_channel_type channel_type);
1727 1818
1728 int (*scan)(struct wiphy *wiphy, 1819 int (*scan)(struct wiphy *wiphy,
1729 struct cfg80211_scan_request *request); 1820 struct cfg80211_scan_request *request);
@@ -1746,11 +1837,15 @@ struct cfg80211_ops {
1746 struct cfg80211_ibss_params *params); 1837 struct cfg80211_ibss_params *params);
1747 int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); 1838 int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev);
1748 1839
1840 int (*set_mcast_rate)(struct wiphy *wiphy, struct net_device *dev,
1841 int rate[IEEE80211_NUM_BANDS]);
1842
1749 int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); 1843 int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed);
1750 1844
1751 int (*set_tx_power)(struct wiphy *wiphy, 1845 int (*set_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
1752 enum nl80211_tx_power_setting type, int mbm); 1846 enum nl80211_tx_power_setting type, int mbm);
1753 int (*get_tx_power)(struct wiphy *wiphy, int *dbm); 1847 int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
1848 int *dbm);
1754 1849
1755 int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, 1850 int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
1756 const u8 *addr); 1851 const u8 *addr);
@@ -1781,7 +1876,6 @@ struct cfg80211_ops {
1781 int (*remain_on_channel)(struct wiphy *wiphy, 1876 int (*remain_on_channel)(struct wiphy *wiphy,
1782 struct wireless_dev *wdev, 1877 struct wireless_dev *wdev,
1783 struct ieee80211_channel *chan, 1878 struct ieee80211_channel *chan,
1784 enum nl80211_channel_type channel_type,
1785 unsigned int duration, 1879 unsigned int duration,
1786 u64 *cookie); 1880 u64 *cookie);
1787 int (*cancel_remain_on_channel)(struct wiphy *wiphy, 1881 int (*cancel_remain_on_channel)(struct wiphy *wiphy,
@@ -1790,10 +1884,8 @@ struct cfg80211_ops {
1790 1884
1791 int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev, 1885 int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev,
1792 struct ieee80211_channel *chan, bool offchan, 1886 struct ieee80211_channel *chan, bool offchan,
1793 enum nl80211_channel_type channel_type, 1887 unsigned int wait, const u8 *buf, size_t len,
1794 bool channel_type_valid, unsigned int wait, 1888 bool no_cck, bool dont_wait_for_ack, u64 *cookie);
1795 const u8 *buf, size_t len, bool no_cck,
1796 bool dont_wait_for_ack, u64 *cookie);
1797 int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, 1889 int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
1798 struct wireless_dev *wdev, 1890 struct wireless_dev *wdev,
1799 u64 cookie); 1891 u64 cookie);
@@ -1848,10 +1940,9 @@ struct cfg80211_ops {
1848 void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, 1940 void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev,
1849 u32 sset, u8 *data); 1941 u32 sset, u8 *data);
1850 1942
1851 struct ieee80211_channel * 1943 int (*get_channel)(struct wiphy *wiphy,
1852 (*get_channel)(struct wiphy *wiphy,
1853 struct wireless_dev *wdev, 1944 struct wireless_dev *wdev,
1854 enum nl80211_channel_type *type); 1945 struct cfg80211_chan_def *chandef);
1855 1946
1856 int (*start_p2p_device)(struct wiphy *wiphy, 1947 int (*start_p2p_device)(struct wiphy *wiphy,
1857 struct wireless_dev *wdev); 1948 struct wireless_dev *wdev);
@@ -2459,8 +2550,7 @@ struct wireless_dev {
2459 spinlock_t event_lock; 2550 spinlock_t event_lock;
2460 2551
2461 struct cfg80211_internal_bss *current_bss; /* associated / joined */ 2552 struct cfg80211_internal_bss *current_bss; /* associated / joined */
2462 struct ieee80211_channel *preset_chan; 2553 struct cfg80211_chan_def preset_chandef;
2463 enum nl80211_channel_type preset_chantype;
2464 2554
2465 /* for AP and mesh channel tracking */ 2555 /* for AP and mesh channel tracking */
2466 struct ieee80211_channel *channel; 2556 struct ieee80211_channel *channel;
@@ -3340,14 +3430,12 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
3340 * @wdev: wireless device 3430 * @wdev: wireless device
3341 * @cookie: the request cookie 3431 * @cookie: the request cookie
3342 * @chan: The current channel (from remain_on_channel request) 3432 * @chan: The current channel (from remain_on_channel request)
3343 * @channel_type: Channel type
3344 * @duration: Duration in milliseconds that the driver intents to remain on the 3433 * @duration: Duration in milliseconds that the driver intents to remain on the
3345 * channel 3434 * channel
3346 * @gfp: allocation flags 3435 * @gfp: allocation flags
3347 */ 3436 */
3348void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, 3437void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
3349 struct ieee80211_channel *chan, 3438 struct ieee80211_channel *chan,
3350 enum nl80211_channel_type channel_type,
3351 unsigned int duration, gfp_t gfp); 3439 unsigned int duration, gfp_t gfp);
3352 3440
3353/** 3441/**
@@ -3355,12 +3443,10 @@ void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
3355 * @wdev: wireless device 3443 * @wdev: wireless device
3356 * @cookie: the request cookie 3444 * @cookie: the request cookie
3357 * @chan: The current channel (from remain_on_channel request) 3445 * @chan: The current channel (from remain_on_channel request)
3358 * @channel_type: Channel type
3359 * @gfp: allocation flags 3446 * @gfp: allocation flags
3360 */ 3447 */
3361void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, 3448void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
3362 struct ieee80211_channel *chan, 3449 struct ieee80211_channel *chan,
3363 enum nl80211_channel_type channel_type,
3364 gfp_t gfp); 3450 gfp_t gfp);
3365 3451
3366 3452
@@ -3550,7 +3636,6 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
3550 * @len: length of the frame 3636 * @len: length of the frame
3551 * @freq: frequency the frame was received on 3637 * @freq: frequency the frame was received on
3552 * @sig_dbm: signal strength in mBm, or 0 if unknown 3638 * @sig_dbm: signal strength in mBm, or 0 if unknown
3553 * @gfp: allocation flags
3554 * 3639 *
3555 * Use this function to report to userspace when a beacon was 3640 * Use this function to report to userspace when a beacon was
3556 * received. It is not useful to call this when there is no 3641 * received. It is not useful to call this when there is no
@@ -3558,31 +3643,47 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
3558 */ 3643 */
3559void cfg80211_report_obss_beacon(struct wiphy *wiphy, 3644void cfg80211_report_obss_beacon(struct wiphy *wiphy,
3560 const u8 *frame, size_t len, 3645 const u8 *frame, size_t len,
3561 int freq, int sig_dbm, gfp_t gfp); 3646 int freq, int sig_dbm);
3562 3647
3563/** 3648/**
3564 * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used 3649 * cfg80211_reg_can_beacon - check if beaconing is allowed
3565 * @wiphy: the wiphy 3650 * @wiphy: the wiphy
3566 * @chan: main channel 3651 * @chandef: the channel definition
3567 * @channel_type: HT mode
3568 * 3652 *
3569 * This function returns true if there is no secondary channel or the secondary 3653 * This function returns true if there is no secondary channel or the secondary
3570 * channel can be used for beaconing (i.e. is not a radar channel etc.) 3654 * channel(s) can be used for beaconing (i.e. is not a radar channel etc.)
3571 */ 3655 */
3572bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, 3656bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
3573 struct ieee80211_channel *chan, 3657 struct cfg80211_chan_def *chandef);
3574 enum nl80211_channel_type channel_type);
3575 3658
3576/* 3659/*
3577 * cfg80211_ch_switch_notify - update wdev channel and notify userspace 3660 * cfg80211_ch_switch_notify - update wdev channel and notify userspace
3578 * @dev: the device which switched channels 3661 * @dev: the device which switched channels
3579 * @freq: new channel frequency (in MHz) 3662 * @chandef: the new channel definition
3580 * @type: channel type
3581 * 3663 *
3582 * Acquires wdev_lock, so must only be called from sleepable driver context! 3664 * Acquires wdev_lock, so must only be called from sleepable driver context!
3583 */ 3665 */
3584void cfg80211_ch_switch_notify(struct net_device *dev, int freq, 3666void cfg80211_ch_switch_notify(struct net_device *dev,
3585 enum nl80211_channel_type type); 3667 struct cfg80211_chan_def *chandef);
3668
3669/*
3670 * cfg80211_tdls_oper_request - request userspace to perform TDLS operation
3671 * @dev: the device on which the operation is requested
3672 * @peer: the MAC address of the peer device
3673 * @oper: the requested TDLS operation (NL80211_TDLS_SETUP or
3674 * NL80211_TDLS_TEARDOWN)
3675 * @reason_code: the reason code for teardown request
3676 * @gfp: allocation flags
3677 *
3678 * This function is used to request userspace to perform TDLS operation that
3679 * requires knowledge of keys, i.e., link setup or teardown when the AP
3680 * connection uses encryption. This is optional mechanism for the driver to use
3681 * if it can automatically determine when a TDLS link could be useful (e.g.,
3682 * based on traffic and signal strength for a peer).
3683 */
3684void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
3685 enum nl80211_tdls_operation oper,
3686 u16 reason_code, gfp_t gfp);
3586 3687
3587/* 3688/*
3588 * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units) 3689 * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units)
@@ -3608,6 +3709,26 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate);
3608 */ 3709 */
3609void cfg80211_unregister_wdev(struct wireless_dev *wdev); 3710void cfg80211_unregister_wdev(struct wireless_dev *wdev);
3610 3711
3712/**
3713 * cfg80211_get_p2p_attr - find and copy a P2P attribute from IE buffer
3714 * @ies: the input IE buffer
3715 * @len: the input length
3716 * @attr: the attribute ID to find
3717 * @buf: output buffer, can be %NULL if the data isn't needed, e.g.
3718 * if the function is only called to get the needed buffer size
3719 * @bufsize: size of the output buffer
3720 *
3721 * The function finds a given P2P attribute in the (vendor) IEs and
3722 * copies its contents to the given buffer.
3723 *
3724 * The return value is a negative error code (-%EILSEQ or -%ENOENT) if
3725 * the data is malformed or the attribute can't be found (respectively),
3726 * or the length of the found attribute (which can be zero).
3727 */
3728int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
3729 enum ieee80211_p2p_attr_id attr,
3730 u8 *buf, unsigned int bufsize);
3731
3611/* Logging, debugging and troubleshooting/diagnostic helpers. */ 3732/* Logging, debugging and troubleshooting/diagnostic helpers. */
3612 3733
3613/* wiphy_printk helpers, similar to dev_printk */ 3734/* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 00b7204708b..db7680acd0d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -145,11 +145,11 @@ struct ieee80211_low_level_stats {
145 145
146/** 146/**
147 * enum ieee80211_chanctx_change - change flag for channel context 147 * enum ieee80211_chanctx_change - change flag for channel context
148 * @IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE: The channel type was changed 148 * @IEEE80211_CHANCTX_CHANGE_WIDTH: The channel width changed
149 * @IEEE80211_CHANCTX_CHANGE_RX_CHAINS: The number of RX chains changed 149 * @IEEE80211_CHANCTX_CHANGE_RX_CHAINS: The number of RX chains changed
150 */ 150 */
151enum ieee80211_chanctx_change { 151enum ieee80211_chanctx_change {
152 IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE = BIT(0), 152 IEEE80211_CHANCTX_CHANGE_WIDTH = BIT(0),
153 IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1), 153 IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1),
154}; 154};
155 155
@@ -159,8 +159,7 @@ enum ieee80211_chanctx_change {
159 * This is the driver-visible part. The ieee80211_chanctx 159 * This is the driver-visible part. The ieee80211_chanctx
160 * that contains it is visible in mac80211 only. 160 * that contains it is visible in mac80211 only.
161 * 161 *
162 * @channel: the channel to tune to 162 * @def: the channel definition
163 * @channel_type: the channel (HT) type
164 * @rx_chains_static: The number of RX chains that must always be 163 * @rx_chains_static: The number of RX chains that must always be
165 * active on the channel to receive MIMO transmissions 164 * active on the channel to receive MIMO transmissions
166 * @rx_chains_dynamic: The number of RX chains that must be enabled 165 * @rx_chains_dynamic: The number of RX chains that must be enabled
@@ -170,8 +169,7 @@ enum ieee80211_chanctx_change {
170 * sizeof(void *), size is determined in hw information. 169 * sizeof(void *), size is determined in hw information.
171 */ 170 */
172struct ieee80211_chanctx_conf { 171struct ieee80211_chanctx_conf {
173 struct ieee80211_channel *channel; 172 struct cfg80211_chan_def def;
174 enum nl80211_channel_type channel_type;
175 173
176 u8 rx_chains_static, rx_chains_dynamic; 174 u8 rx_chains_static, rx_chains_dynamic;
177 175
@@ -207,6 +205,9 @@ struct ieee80211_chanctx_conf {
207 * @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode) 205 * @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode)
208 * @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode) 206 * @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode)
209 * @BSS_CHANGED_PS: PS changed for this BSS (STA mode) 207 * @BSS_CHANGED_PS: PS changed for this BSS (STA mode)
208 * @BSS_CHANGED_TXPOWER: TX power setting changed for this interface
209 * @BSS_CHANGED_P2P_PS: P2P powersave settings (CTWindow, opportunistic PS)
210 * changed (currently only in P2P client mode, GO mode will be later)
210 */ 211 */
211enum ieee80211_bss_change { 212enum ieee80211_bss_change {
212 BSS_CHANGED_ASSOC = 1<<0, 213 BSS_CHANGED_ASSOC = 1<<0,
@@ -227,6 +228,8 @@ enum ieee80211_bss_change {
227 BSS_CHANGED_SSID = 1<<15, 228 BSS_CHANGED_SSID = 1<<15,
228 BSS_CHANGED_AP_PROBE_RESP = 1<<16, 229 BSS_CHANGED_AP_PROBE_RESP = 1<<16,
229 BSS_CHANGED_PS = 1<<17, 230 BSS_CHANGED_PS = 1<<17,
231 BSS_CHANGED_TXPOWER = 1<<18,
232 BSS_CHANGED_P2P_PS = 1<<19,
230 233
231 /* when adding here, make sure to change ieee80211_reconfig */ 234 /* when adding here, make sure to change ieee80211_reconfig */
232}; 235};
@@ -283,9 +286,8 @@ enum ieee80211_rssi_event {
283 * @mcast_rate: per-band multicast rate index + 1 (0: disabled) 286 * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
284 * @bssid: The BSSID for this BSS 287 * @bssid: The BSSID for this BSS
285 * @enable_beacon: whether beaconing should be enabled or not 288 * @enable_beacon: whether beaconing should be enabled or not
286 * @channel_type: Channel type for this BSS -- the hardware might be 289 * @chandef: Channel definition for this BSS -- the hardware might be
287 * configured for HT40+ while this BSS only uses no-HT, for 290 * configured a higher bandwidth than this BSS uses, for example.
288 * example.
289 * @ht_operation_mode: HT operation mode like in &struct ieee80211_ht_operation. 291 * @ht_operation_mode: HT operation mode like in &struct ieee80211_ht_operation.
290 * This field is only valid when the channel type is one of the HT types. 292 * This field is only valid when the channel type is one of the HT types.
291 * @cqm_rssi_thold: Connection quality monitor RSSI threshold, a zero value 293 * @cqm_rssi_thold: Connection quality monitor RSSI threshold, a zero value
@@ -309,6 +311,9 @@ enum ieee80211_rssi_event {
309 * @ssid: The SSID of the current vif. Only valid in AP-mode. 311 * @ssid: The SSID of the current vif. Only valid in AP-mode.
310 * @ssid_len: Length of SSID given in @ssid. 312 * @ssid_len: Length of SSID given in @ssid.
311 * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode. 313 * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode.
314 * @txpower: TX power in dBm
315 * @p2p_ctwindow: P2P CTWindow, only for P2P client interfaces
316 * @p2p_oppps: P2P opportunistic PS is enabled
312 */ 317 */
313struct ieee80211_bss_conf { 318struct ieee80211_bss_conf {
314 const u8 *bssid; 319 const u8 *bssid;
@@ -331,7 +336,7 @@ struct ieee80211_bss_conf {
331 u16 ht_operation_mode; 336 u16 ht_operation_mode;
332 s32 cqm_rssi_thold; 337 s32 cqm_rssi_thold;
333 u32 cqm_rssi_hyst; 338 u32 cqm_rssi_hyst;
334 enum nl80211_channel_type channel_type; 339 struct cfg80211_chan_def chandef;
335 __be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN]; 340 __be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];
336 u8 arp_addr_cnt; 341 u8 arp_addr_cnt;
337 bool arp_filter_enabled; 342 bool arp_filter_enabled;
@@ -341,6 +346,9 @@ struct ieee80211_bss_conf {
341 u8 ssid[IEEE80211_MAX_SSID_LEN]; 346 u8 ssid[IEEE80211_MAX_SSID_LEN];
342 size_t ssid_len; 347 size_t ssid_len;
343 bool hidden_ssid; 348 bool hidden_ssid;
349 int txpower;
350 u8 p2p_ctwindow;
351 bool p2p_oppps;
344}; 352};
345 353
346/** 354/**
@@ -491,9 +499,14 @@ enum mac80211_tx_control_flags {
491 * This is set if the current BSS requires ERP protection. 499 * This is set if the current BSS requires ERP protection.
492 * @IEEE80211_TX_RC_USE_SHORT_PREAMBLE: Use short preamble. 500 * @IEEE80211_TX_RC_USE_SHORT_PREAMBLE: Use short preamble.
493 * @IEEE80211_TX_RC_MCS: HT rate. 501 * @IEEE80211_TX_RC_MCS: HT rate.
502 * @IEEE80211_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is split
503 * into a higher 4 bits (Nss) and lower 4 bits (MCS number)
494 * @IEEE80211_TX_RC_GREEN_FIELD: Indicates whether this rate should be used in 504 * @IEEE80211_TX_RC_GREEN_FIELD: Indicates whether this rate should be used in
495 * Greenfield mode. 505 * Greenfield mode.
496 * @IEEE80211_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be 40 MHz. 506 * @IEEE80211_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be 40 MHz.
507 * @IEEE80211_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission
508 * @IEEE80211_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission
509 * (80+80 isn't supported yet)
497 * @IEEE80211_TX_RC_DUP_DATA: The frame should be transmitted on both of the 510 * @IEEE80211_TX_RC_DUP_DATA: The frame should be transmitted on both of the
498 * adjacent 20 MHz channels, if the current channel type is 511 * adjacent 20 MHz channels, if the current channel type is
499 * NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS. 512 * NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS.
@@ -504,12 +517,15 @@ enum mac80211_rate_control_flags {
504 IEEE80211_TX_RC_USE_CTS_PROTECT = BIT(1), 517 IEEE80211_TX_RC_USE_CTS_PROTECT = BIT(1),
505 IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(2), 518 IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(2),
506 519
507 /* rate index is an MCS rate number instead of an index */ 520 /* rate index is an HT/VHT MCS instead of an index */
508 IEEE80211_TX_RC_MCS = BIT(3), 521 IEEE80211_TX_RC_MCS = BIT(3),
509 IEEE80211_TX_RC_GREEN_FIELD = BIT(4), 522 IEEE80211_TX_RC_GREEN_FIELD = BIT(4),
510 IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(5), 523 IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(5),
511 IEEE80211_TX_RC_DUP_DATA = BIT(6), 524 IEEE80211_TX_RC_DUP_DATA = BIT(6),
512 IEEE80211_TX_RC_SHORT_GI = BIT(7), 525 IEEE80211_TX_RC_SHORT_GI = BIT(7),
526 IEEE80211_TX_RC_VHT_MCS = BIT(8),
527 IEEE80211_TX_RC_80_MHZ_WIDTH = BIT(9),
528 IEEE80211_TX_RC_160_MHZ_WIDTH = BIT(10),
513}; 529};
514 530
515 531
@@ -552,10 +568,32 @@ enum mac80211_rate_control_flags {
552 */ 568 */
553struct ieee80211_tx_rate { 569struct ieee80211_tx_rate {
554 s8 idx; 570 s8 idx;
555 u8 count; 571 u16 count:5,
556 u8 flags; 572 flags:11;
557} __packed; 573} __packed;
558 574
575#define IEEE80211_MAX_TX_RETRY 31
576
577static inline void ieee80211_rate_set_vht(struct ieee80211_tx_rate *rate,
578 u8 mcs, u8 nss)
579{
580 WARN_ON(mcs & ~0xF);
581 WARN_ON(nss & ~0x7);
582 rate->idx = (nss << 4) | mcs;
583}
584
585static inline u8
586ieee80211_rate_get_vht_mcs(const struct ieee80211_tx_rate *rate)
587{
588 return rate->idx & 0xF;
589}
590
591static inline u8
592ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate)
593{
594 return rate->idx >> 4;
595}
596
559/** 597/**
560 * struct ieee80211_tx_info - skb transmit information 598 * struct ieee80211_tx_info - skb transmit information
561 * 599 *
@@ -700,13 +738,20 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
700 * the frame. 738 * the frame.
701 * @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on 739 * @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on
702 * the frame. 740 * the frame.
703 * @RX_FLAG_MACTIME_MPDU: The timestamp passed in the RX status (@mactime 741 * @RX_FLAG_MACTIME_START: The timestamp passed in the RX status (@mactime
704 * field) is valid and contains the time the first symbol of the MPDU 742 * field) is valid and contains the time the first symbol of the MPDU
705 * was received. This is useful in monitor mode and for proper IBSS 743 * was received. This is useful in monitor mode and for proper IBSS
706 * merging. 744 * merging.
745 * @RX_FLAG_MACTIME_END: The timestamp passed in the RX status (@mactime
746 * field) is valid and contains the time the last symbol of the MPDU
747 * (including FCS) was received.
707 * @RX_FLAG_SHORTPRE: Short preamble was used for this frame 748 * @RX_FLAG_SHORTPRE: Short preamble was used for this frame
708 * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index 749 * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
750 * @RX_FLAG_VHT: VHT MCS was used and rate_index is MCS index
709 * @RX_FLAG_40MHZ: HT40 (40 MHz) was used 751 * @RX_FLAG_40MHZ: HT40 (40 MHz) was used
752 * @RX_FLAG_80MHZ: 80 MHz was used
753 * @RX_FLAG_80P80MHZ: 80+80 MHz was used
754 * @RX_FLAG_160MHZ: 160 MHz was used
710 * @RX_FLAG_SHORT_GI: Short guard interval was used 755 * @RX_FLAG_SHORT_GI: Short guard interval was used
711 * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present. 756 * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present.
712 * Valid only for data frames (mainly A-MPDU) 757 * Valid only for data frames (mainly A-MPDU)
@@ -734,7 +779,7 @@ enum mac80211_rx_flags {
734 RX_FLAG_IV_STRIPPED = BIT(4), 779 RX_FLAG_IV_STRIPPED = BIT(4),
735 RX_FLAG_FAILED_FCS_CRC = BIT(5), 780 RX_FLAG_FAILED_FCS_CRC = BIT(5),
736 RX_FLAG_FAILED_PLCP_CRC = BIT(6), 781 RX_FLAG_FAILED_PLCP_CRC = BIT(6),
737 RX_FLAG_MACTIME_MPDU = BIT(7), 782 RX_FLAG_MACTIME_START = BIT(7),
738 RX_FLAG_SHORTPRE = BIT(8), 783 RX_FLAG_SHORTPRE = BIT(8),
739 RX_FLAG_HT = BIT(9), 784 RX_FLAG_HT = BIT(9),
740 RX_FLAG_40MHZ = BIT(10), 785 RX_FLAG_40MHZ = BIT(10),
@@ -748,6 +793,11 @@ enum mac80211_rx_flags {
748 RX_FLAG_AMPDU_IS_LAST = BIT(18), 793 RX_FLAG_AMPDU_IS_LAST = BIT(18),
749 RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19), 794 RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19),
750 RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20), 795 RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20),
796 RX_FLAG_MACTIME_END = BIT(21),
797 RX_FLAG_VHT = BIT(22),
798 RX_FLAG_80MHZ = BIT(23),
799 RX_FLAG_80P80MHZ = BIT(24),
800 RX_FLAG_160MHZ = BIT(25),
751}; 801};
752 802
753/** 803/**
@@ -768,25 +818,39 @@ enum mac80211_rx_flags {
768 * @IEEE80211_HW_SIGNAL_* 818 * @IEEE80211_HW_SIGNAL_*
769 * @antenna: antenna used 819 * @antenna: antenna used
770 * @rate_idx: index of data rate into band's supported rates or MCS index if 820 * @rate_idx: index of data rate into band's supported rates or MCS index if
771 * HT rates are use (RX_FLAG_HT) 821 * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
822 * @vht_nss: number of streams (VHT only)
772 * @flag: %RX_FLAG_* 823 * @flag: %RX_FLAG_*
773 * @rx_flags: internal RX flags for mac80211 824 * @rx_flags: internal RX flags for mac80211
774 * @ampdu_reference: A-MPDU reference number, must be a different value for 825 * @ampdu_reference: A-MPDU reference number, must be a different value for
775 * each A-MPDU but the same for each subframe within one A-MPDU 826 * each A-MPDU but the same for each subframe within one A-MPDU
776 * @ampdu_delimiter_crc: A-MPDU delimiter CRC 827 * @ampdu_delimiter_crc: A-MPDU delimiter CRC
828 * @vendor_radiotap_bitmap: radiotap vendor namespace presence bitmap
829 * @vendor_radiotap_len: radiotap vendor namespace length
830 * @vendor_radiotap_align: radiotap vendor namespace alignment. Note
831 * that the actual data must be at the start of the SKB data
832 * already.
833 * @vendor_radiotap_oui: radiotap vendor namespace OUI
834 * @vendor_radiotap_subns: radiotap vendor sub namespace
777 */ 835 */
778struct ieee80211_rx_status { 836struct ieee80211_rx_status {
779 u64 mactime; 837 u64 mactime;
780 u32 device_timestamp; 838 u32 device_timestamp;
781 u32 ampdu_reference; 839 u32 ampdu_reference;
782 u32 flag; 840 u32 flag;
841 u32 vendor_radiotap_bitmap;
842 u16 vendor_radiotap_len;
783 u16 freq; 843 u16 freq;
784 u8 rate_idx; 844 u8 rate_idx;
845 u8 vht_nss;
785 u8 rx_flags; 846 u8 rx_flags;
786 u8 band; 847 u8 band;
787 u8 antenna; 848 u8 antenna;
788 s8 signal; 849 s8 signal;
789 u8 ampdu_delimiter_crc; 850 u8 ampdu_delimiter_crc;
851 u8 vendor_radiotap_align;
852 u8 vendor_radiotap_oui[3];
853 u8 vendor_radiotap_subns;
790}; 854};
791 855
792/** 856/**
@@ -884,7 +948,8 @@ enum ieee80211_smps_mode {
884 * powersave documentation below. This variable is valid only when 948 * powersave documentation below. This variable is valid only when
885 * the CONF_PS flag is set. 949 * the CONF_PS flag is set.
886 * 950 *
887 * @power_level: requested transmit power (in dBm) 951 * @power_level: requested transmit power (in dBm), backward compatibility
952 * value only that is set to the minimum of all interfaces
888 * 953 *
889 * @channel: the channel to tune to 954 * @channel: the channel to tune to
890 * @channel_type: the channel (HT) type 955 * @channel_type: the channel (HT) type
@@ -2180,6 +2245,14 @@ enum ieee80211_rate_control_changed {
2180 * @sta_remove: Notifies low level driver about removal of an associated 2245 * @sta_remove: Notifies low level driver about removal of an associated
2181 * station, AP, IBSS/WDS/mesh peer etc. This callback can sleep. 2246 * station, AP, IBSS/WDS/mesh peer etc. This callback can sleep.
2182 * 2247 *
2248 * @sta_add_debugfs: Drivers can use this callback to add debugfs files
2249 * when a station is added to mac80211's station list. This callback
2250 * and @sta_remove_debugfs should be within a CONFIG_MAC80211_DEBUGFS
2251 * conditional. This callback can sleep.
2252 *
2253 * @sta_remove_debugfs: Remove the debugfs files which were added using
2254 * @sta_add_debugfs. This callback can sleep.
2255 *
2183 * @sta_notify: Notifies low level driver about power state transition of an 2256 * @sta_notify: Notifies low level driver about power state transition of an
2184 * associated station, AP, IBSS/WDS/mesh peer etc. For a VIF operating 2257 * associated station, AP, IBSS/WDS/mesh peer etc. For a VIF operating
2185 * in AP mode, this callback will not be called when the flag 2258 * in AP mode, this callback will not be called when the flag
@@ -2381,6 +2454,17 @@ enum ieee80211_rate_control_changed {
2381 * to vif. Possible use is for hw queue remapping. 2454 * to vif. Possible use is for hw queue remapping.
2382 * @unassign_vif_chanctx: Notifies device driver about channel context being 2455 * @unassign_vif_chanctx: Notifies device driver about channel context being
2383 * unbound from vif. 2456 * unbound from vif.
2457 * @start_ap: Start operation on the AP interface, this is called after all the
2458 * information in bss_conf is set and beacon can be retrieved. A channel
2459 * context is bound before this is called. Note that if the driver uses
2460 * software scan or ROC, this (and @stop_ap) isn't called when the AP is
2461 * just "paused" for scanning/ROC, which is indicated by the beacon being
2462 * disabled/enabled via @bss_info_changed.
2463 * @stop_ap: Stop operation on the AP interface.
2464 *
2465 * @restart_complete: Called after a call to ieee80211_restart_hw(), when the
2466 * reconfiguration has completed. This can help the driver implement the
2467 * reconfiguration step. This callback may sleep.
2384 */ 2468 */
2385struct ieee80211_ops { 2469struct ieee80211_ops {
2386 void (*tx)(struct ieee80211_hw *hw, 2470 void (*tx)(struct ieee80211_hw *hw,
@@ -2406,6 +2490,9 @@ struct ieee80211_ops {
2406 struct ieee80211_bss_conf *info, 2490 struct ieee80211_bss_conf *info,
2407 u32 changed); 2491 u32 changed);
2408 2492
2493 int (*start_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
2494 void (*stop_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
2495
2409 u64 (*prepare_multicast)(struct ieee80211_hw *hw, 2496 u64 (*prepare_multicast)(struct ieee80211_hw *hw,
2410 struct netdev_hw_addr_list *mc_list); 2497 struct netdev_hw_addr_list *mc_list);
2411 void (*configure_filter)(struct ieee80211_hw *hw, 2498 void (*configure_filter)(struct ieee80211_hw *hw,
@@ -2447,6 +2534,16 @@ struct ieee80211_ops {
2447 struct ieee80211_sta *sta); 2534 struct ieee80211_sta *sta);
2448 int (*sta_remove)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2535 int (*sta_remove)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2449 struct ieee80211_sta *sta); 2536 struct ieee80211_sta *sta);
2537#ifdef CONFIG_MAC80211_DEBUGFS
2538 void (*sta_add_debugfs)(struct ieee80211_hw *hw,
2539 struct ieee80211_vif *vif,
2540 struct ieee80211_sta *sta,
2541 struct dentry *dir);
2542 void (*sta_remove_debugfs)(struct ieee80211_hw *hw,
2543 struct ieee80211_vif *vif,
2544 struct ieee80211_sta *sta,
2545 struct dentry *dir);
2546#endif
2450 void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2547 void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2451 enum sta_notify_cmd, struct ieee80211_sta *sta); 2548 enum sta_notify_cmd, struct ieee80211_sta *sta);
2452 int (*sta_state)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2549 int (*sta_state)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -2488,8 +2585,8 @@ struct ieee80211_ops {
2488 int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 2585 int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
2489 2586
2490 int (*remain_on_channel)(struct ieee80211_hw *hw, 2587 int (*remain_on_channel)(struct ieee80211_hw *hw,
2588 struct ieee80211_vif *vif,
2491 struct ieee80211_channel *chan, 2589 struct ieee80211_channel *chan,
2492 enum nl80211_channel_type channel_type,
2493 int duration); 2590 int duration);
2494 int (*cancel_remain_on_channel)(struct ieee80211_hw *hw); 2591 int (*cancel_remain_on_channel)(struct ieee80211_hw *hw);
2495 int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); 2592 int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx);
@@ -2539,6 +2636,8 @@ struct ieee80211_ops {
2539 void (*unassign_vif_chanctx)(struct ieee80211_hw *hw, 2636 void (*unassign_vif_chanctx)(struct ieee80211_hw *hw,
2540 struct ieee80211_vif *vif, 2637 struct ieee80211_vif *vif,
2541 struct ieee80211_chanctx_conf *ctx); 2638 struct ieee80211_chanctx_conf *ctx);
2639
2640 void (*restart_complete)(struct ieee80211_hw *hw);
2542}; 2641};
2543 2642
2544/** 2643/**
@@ -3385,6 +3484,21 @@ void ieee80211_sched_scan_results(struct ieee80211_hw *hw);
3385void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw); 3484void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw);
3386 3485
3387/** 3486/**
3487 * enum ieee80211_interface_iteration_flags - interface iteration flags
3488 * @IEEE80211_IFACE_ITER_NORMAL: Iterate over all interfaces that have
3489 * been added to the driver; However, note that during hardware
3490 * reconfiguration (after restart_hw) it will iterate over a new
3491 * interface and over all the existing interfaces even if they
3492 * haven't been re-added to the driver yet.
3493 * @IEEE80211_IFACE_ITER_RESUME_ALL: During resume, iterate over all
3494 * interfaces, even if they haven't been re-added to the driver yet.
3495 */
3496enum ieee80211_interface_iteration_flags {
3497 IEEE80211_IFACE_ITER_NORMAL = 0,
3498 IEEE80211_IFACE_ITER_RESUME_ALL = BIT(0),
3499};
3500
3501/**
3388 * ieee80211_iterate_active_interfaces - iterate active interfaces 3502 * ieee80211_iterate_active_interfaces - iterate active interfaces
3389 * 3503 *
3390 * This function iterates over the interfaces associated with a given 3504 * This function iterates over the interfaces associated with a given
@@ -3392,13 +3506,15 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw);
3392 * This function allows the iterator function to sleep, when the iterator 3506 * This function allows the iterator function to sleep, when the iterator
3393 * function is atomic @ieee80211_iterate_active_interfaces_atomic can 3507 * function is atomic @ieee80211_iterate_active_interfaces_atomic can
3394 * be used. 3508 * be used.
3395 * Does not iterate over a new interface during add_interface() 3509 * Does not iterate over a new interface during add_interface().
3396 * 3510 *
3397 * @hw: the hardware struct of which the interfaces should be iterated over 3511 * @hw: the hardware struct of which the interfaces should be iterated over
3512 * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags
3398 * @iterator: the iterator function to call 3513 * @iterator: the iterator function to call
3399 * @data: first argument of the iterator function 3514 * @data: first argument of the iterator function
3400 */ 3515 */
3401void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, 3516void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
3517 u32 iter_flags,
3402 void (*iterator)(void *data, u8 *mac, 3518 void (*iterator)(void *data, u8 *mac,
3403 struct ieee80211_vif *vif), 3519 struct ieee80211_vif *vif),
3404 void *data); 3520 void *data);
@@ -3410,13 +3526,15 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
3410 * hardware that are currently active and calls the callback for them. 3526 * hardware that are currently active and calls the callback for them.
3411 * This function requires the iterator callback function to be atomic, 3527 * This function requires the iterator callback function to be atomic,
3412 * if that is not desired, use @ieee80211_iterate_active_interfaces instead. 3528 * if that is not desired, use @ieee80211_iterate_active_interfaces instead.
3413 * Does not iterate over a new interface during add_interface() 3529 * Does not iterate over a new interface during add_interface().
3414 * 3530 *
3415 * @hw: the hardware struct of which the interfaces should be iterated over 3531 * @hw: the hardware struct of which the interfaces should be iterated over
3532 * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags
3416 * @iterator: the iterator function to call, cannot sleep 3533 * @iterator: the iterator function to call, cannot sleep
3417 * @data: first argument of the iterator function 3534 * @data: first argument of the iterator function
3418 */ 3535 */
3419void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw, 3536void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
3537 u32 iter_flags,
3420 void (*iterator)(void *data, 3538 void (*iterator)(void *data,
3421 u8 *mac, 3539 u8 *mac,
3422 struct ieee80211_vif *vif), 3540 struct ieee80211_vif *vif),
diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h
index 639f50af42d..671953e1157 100644
--- a/include/net/nfc/hci.h
+++ b/include/net/nfc/hci.h
@@ -149,6 +149,8 @@ void *nfc_hci_get_clientdata(struct nfc_hci_dev *hdev);
149 149
150void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err); 150void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err);
151 151
152int nfc_hci_result_to_errno(u8 result);
153
152/* Host IDs */ 154/* Host IDs */
153#define NFC_HCI_HOST_CONTROLLER_ID 0x00 155#define NFC_HCI_HOST_CONTROLLER_ID 0x00
154#define NFC_HCI_TERMINAL_HOST_ID 0x01 156#define NFC_HCI_TERMINAL_HOST_ID 0x01
@@ -235,5 +237,6 @@ int nfc_hci_send_response(struct nfc_hci_dev *hdev, u8 gate, u8 response,
235int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, 237int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event,
236 const u8 *param, size_t param_len); 238 const u8 *param, size_t param_len);
237int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate); 239int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate);
240u32 nfc_hci_sak_to_protocol(u8 sak);
238 241
239#endif /* __NET_HCI_H */ 242#endif /* __NET_HCI_H */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 617d0fbfc96..33a417481ad 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -118,8 +118,9 @@
118 * to get a list of all present wiphys. 118 * to get a list of all present wiphys.
119 * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or 119 * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
120 * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, 120 * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
121 * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, 121 * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ (and the
122 * %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT, 122 * attributes determining the channel width; this is used for setting
123 * monitor mode channel), %NL80211_ATTR_WIPHY_RETRY_SHORT,
123 * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, 124 * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
124 * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD. 125 * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
125 * However, for setting the channel, see %NL80211_CMD_SET_CHANNEL 126 * However, for setting the channel, see %NL80211_CMD_SET_CHANNEL
@@ -171,7 +172,7 @@
171 * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, 172 * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
172 * %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT. 173 * %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
173 * The channel to use can be set on the interface or be given using the 174 * The channel to use can be set on the interface or be given using the
174 * %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_WIPHY_CHANNEL_TYPE attrs. 175 * %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width.
175 * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP 176 * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
176 * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface 177 * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
177 * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP 178 * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
@@ -401,8 +402,7 @@
401 * a response while being associated to an AP on another channel. 402 * a response while being associated to an AP on another channel.
402 * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus 403 * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus
403 * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the 404 * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the
404 * frequency for the operation and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be 405 * frequency for the operation.
405 * optionally used to specify additional channel parameters.
406 * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds 406 * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds
407 * to remain on the channel. This command is also used as an event to 407 * to remain on the channel. This command is also used as an event to
408 * notify when the requested duration starts (it may take a while for the 408 * notify when the requested duration starts (it may take a while for the
@@ -440,12 +440,11 @@
440 * as an event indicating reception of a frame that was not processed in 440 * as an event indicating reception of a frame that was not processed in
441 * kernel code, but is for us (i.e., which may need to be processed in a 441 * kernel code, but is for us (i.e., which may need to be processed in a
442 * user space application). %NL80211_ATTR_FRAME is used to specify the 442 * user space application). %NL80211_ATTR_FRAME is used to specify the
443 * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and 443 * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ is used
444 * optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on 444 * to indicate on which channel the frame is to be transmitted or was
445 * which channel the frame is to be transmitted or was received. If this 445 * received. If this channel is not the current channel (remain-on-channel
446 * channel is not the current channel (remain-on-channel or the 446 * or the operational channel) the device will switch to the given channel
447 * operational channel) the device will switch to the given channel and 447 * and transmit the frame, optionally waiting for a response for the time
448 * transmit the frame, optionally waiting for a response for the time
449 * specified using %NL80211_ATTR_DURATION. When called, this operation 448 * specified using %NL80211_ATTR_DURATION. When called, this operation
450 * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the 449 * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the
451 * TX status event pertaining to the TX request. 450 * TX status event pertaining to the TX request.
@@ -473,8 +472,8 @@
473 * command is used as an event to indicate the that a trigger level was 472 * command is used as an event to indicate the that a trigger level was
474 * reached. 473 * reached.
475 * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ 474 * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
476 * and %NL80211_ATTR_WIPHY_CHANNEL_TYPE) the given interface (identifed 475 * and the attributes determining channel width) the given interface
477 * by %NL80211_ATTR_IFINDEX) shall operate on. 476 * (identifed by %NL80211_ATTR_IFINDEX) shall operate on.
478 * In case multiple channels are supported by the device, the mechanism 477 * In case multiple channels are supported by the device, the mechanism
479 * with which it switches channels is implementation-defined. 478 * with which it switches channels is implementation-defined.
480 * When a monitor interface is given, it can only switch channel while 479 * When a monitor interface is given, it can only switch channel while
@@ -526,6 +525,12 @@
526 * of PMKSA caching dandidates. 525 * of PMKSA caching dandidates.
527 * 526 *
528 * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup). 527 * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
528 * In addition, this can be used as an event to request userspace to take
529 * actions on TDLS links (set up a new link or tear down an existing one).
530 * In such events, %NL80211_ATTR_TDLS_OPERATION indicates the requested
531 * operation, %NL80211_ATTR_MAC contains the peer MAC address, and
532 * %NL80211_ATTR_REASON_CODE the reason code to be used (only with
533 * %NL80211_TDLS_TEARDOWN).
529 * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. 534 * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
530 * 535 *
531 * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP 536 * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
@@ -562,8 +567,8 @@
562 * 567 *
563 * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels 568 * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels
564 * independently of the userspace SME, send this event indicating 569 * independently of the userspace SME, send this event indicating
565 * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ with 570 * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the
566 * %NL80211_ATTR_WIPHY_CHANNEL_TYPE. 571 * attributes determining channel width.
567 * 572 *
568 * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by 573 * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by
569 * its %NL80211_ATTR_WDEV identifier. It must have been created with 574 * its %NL80211_ATTR_WDEV identifier. It must have been created with
@@ -578,6 +583,9 @@
578 * station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON 583 * station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON
579 * is used for this. 584 * is used for this.
580 * 585 *
586 * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
587 * for IBSS or MESH vif.
588 *
581 * @NL80211_CMD_MAX: highest used command number 589 * @NL80211_CMD_MAX: highest used command number
582 * @__NL80211_CMD_AFTER_LAST: internal use 590 * @__NL80211_CMD_AFTER_LAST: internal use
583 */ 591 */
@@ -726,6 +734,8 @@ enum nl80211_commands {
726 734
727 NL80211_CMD_CONN_FAILED, 735 NL80211_CMD_CONN_FAILED,
728 736
737 NL80211_CMD_SET_MCAST_RATE,
738
729 /* add new commands above here */ 739 /* add new commands above here */
730 740
731 /* used to define NL80211_CMD_MAX below */ 741 /* used to define NL80211_CMD_MAX below */
@@ -762,14 +772,26 @@ enum nl80211_commands {
762 * /sys/class/ieee80211/<phyname>/index 772 * /sys/class/ieee80211/<phyname>/index
763 * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming) 773 * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
764 * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters 774 * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters
765 * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz 775 * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz,
776 * defines the channel together with the (deprecated)
777 * %NL80211_ATTR_WIPHY_CHANNEL_TYPE attribute or the attributes
778 * %NL80211_ATTR_CHANNEL_WIDTH and if needed %NL80211_ATTR_CENTER_FREQ1
779 * and %NL80211_ATTR_CENTER_FREQ2
780 * @NL80211_ATTR_CHANNEL_WIDTH: u32 attribute containing one of the values
781 * of &enum nl80211_chan_width, describing the channel width. See the
782 * documentation of the enum for more information.
783 * @NL80211_ATTR_CENTER_FREQ1: Center frequency of the first part of the
784 * channel, used for anything but 20 MHz bandwidth
785 * @NL80211_ATTR_CENTER_FREQ2: Center frequency of the second part of the
786 * channel, used only for 80+80 MHz bandwidth
766 * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ 787 * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ
767 * if HT20 or HT40 are allowed (i.e., 802.11n disabled if not included): 788 * if HT20 or HT40 are to be used (i.e., HT disabled if not included):
768 * NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including 789 * NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including
769 * this attribute) 790 * this attribute)
770 * NL80211_CHAN_HT20 = HT20 only 791 * NL80211_CHAN_HT20 = HT20 only
771 * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel 792 * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel
772 * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel 793 * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel
794 * This attribute is now deprecated.
773 * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is 795 * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is
774 * less than or equal to the RTS threshold; allowed range: 1..255; 796 * less than or equal to the RTS threshold; allowed range: 1..255;
775 * dot11ShortRetryLimit; u8 797 * dot11ShortRetryLimit; u8
@@ -1544,6 +1566,10 @@ enum nl80211_attrs {
1544 1566
1545 NL80211_ATTR_SCAN_FLAGS, 1567 NL80211_ATTR_SCAN_FLAGS,
1546 1568
1569 NL80211_ATTR_CHANNEL_WIDTH,
1570 NL80211_ATTR_CENTER_FREQ1,
1571 NL80211_ATTR_CENTER_FREQ2,
1572
1547 /* add attributes here, update the policy in nl80211.c */ 1573 /* add attributes here, update the policy in nl80211.c */
1548 1574
1549 __NL80211_ATTR_AFTER_LAST, 1575 __NL80211_ATTR_AFTER_LAST,
@@ -1708,10 +1734,15 @@ struct nl80211_sta_flag_update {
1708 * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved 1734 * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
1709 * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) 1735 * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
1710 * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) 1736 * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
1711 * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate 1737 * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 MHz dualchannel bitrate
1712 * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval 1738 * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
1713 * @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s) 1739 * @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s)
1714 * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined 1740 * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
1741 * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8)
1742 * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8)
1743 * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate
1744 * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: 80+80 MHz VHT rate
1745 * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate
1715 * @__NL80211_RATE_INFO_AFTER_LAST: internal use 1746 * @__NL80211_RATE_INFO_AFTER_LAST: internal use
1716 */ 1747 */
1717enum nl80211_rate_info { 1748enum nl80211_rate_info {
@@ -1721,6 +1752,11 @@ enum nl80211_rate_info {
1721 NL80211_RATE_INFO_40_MHZ_WIDTH, 1752 NL80211_RATE_INFO_40_MHZ_WIDTH,
1722 NL80211_RATE_INFO_SHORT_GI, 1753 NL80211_RATE_INFO_SHORT_GI,
1723 NL80211_RATE_INFO_BITRATE32, 1754 NL80211_RATE_INFO_BITRATE32,
1755 NL80211_RATE_INFO_VHT_MCS,
1756 NL80211_RATE_INFO_VHT_NSS,
1757 NL80211_RATE_INFO_80_MHZ_WIDTH,
1758 NL80211_RATE_INFO_80P80_MHZ_WIDTH,
1759 NL80211_RATE_INFO_160_MHZ_WIDTH,
1724 1760
1725 /* keep last */ 1761 /* keep last */
1726 __NL80211_RATE_INFO_AFTER_LAST, 1762 __NL80211_RATE_INFO_AFTER_LAST,
@@ -2429,6 +2465,15 @@ enum nl80211_ac {
2429#define NL80211_TXQ_Q_BE NL80211_AC_BE 2465#define NL80211_TXQ_Q_BE NL80211_AC_BE
2430#define NL80211_TXQ_Q_BK NL80211_AC_BK 2466#define NL80211_TXQ_Q_BK NL80211_AC_BK
2431 2467
2468/**
2469 * enum nl80211_channel_type - channel type
2470 * @NL80211_CHAN_NO_HT: 20 MHz, non-HT channel
2471 * @NL80211_CHAN_HT20: 20 MHz HT channel
2472 * @NL80211_CHAN_HT40MINUS: HT40 channel, secondary channel
2473 * below the control channel
2474 * @NL80211_CHAN_HT40PLUS: HT40 channel, secondary channel
2475 * above the control channel
2476 */
2432enum nl80211_channel_type { 2477enum nl80211_channel_type {
2433 NL80211_CHAN_NO_HT, 2478 NL80211_CHAN_NO_HT,
2434 NL80211_CHAN_HT20, 2479 NL80211_CHAN_HT20,
@@ -2437,6 +2482,32 @@ enum nl80211_channel_type {
2437}; 2482};
2438 2483
2439/** 2484/**
2485 * enum nl80211_chan_width - channel width definitions
2486 *
2487 * These values are used with the %NL80211_ATTR_CHANNEL_WIDTH
2488 * attribute.
2489 *
2490 * @NL80211_CHAN_WIDTH_20_NOHT: 20 MHz, non-HT channel
2491 * @NL80211_CHAN_WIDTH_20: 20 MHz HT channel
2492 * @NL80211_CHAN_WIDTH_40: 40 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
2493 * attribute must be provided as well
2494 * @NL80211_CHAN_WIDTH_80: 80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
2495 * attribute must be provided as well
2496 * @NL80211_CHAN_WIDTH_80P80: 80+80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
2497 * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well
2498 * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
2499 * attribute must be provided as well
2500 */
2501enum nl80211_chan_width {
2502 NL80211_CHAN_WIDTH_20_NOHT,
2503 NL80211_CHAN_WIDTH_20,
2504 NL80211_CHAN_WIDTH_40,
2505 NL80211_CHAN_WIDTH_80,
2506 NL80211_CHAN_WIDTH_80P80,
2507 NL80211_CHAN_WIDTH_160,
2508};
2509
2510/**
2440 * enum nl80211_bss - netlink attributes for a BSS 2511 * enum nl80211_bss - netlink attributes for a BSS
2441 * 2512 *
2442 * @__NL80211_BSS_INVALID: invalid 2513 * @__NL80211_BSS_INVALID: invalid
@@ -3051,6 +3122,10 @@ enum nl80211_ap_sme_features {
3051 * @NL80211_FEATURE_LOW_PRIORITY_SCAN: This driver supports low priority scan 3122 * @NL80211_FEATURE_LOW_PRIORITY_SCAN: This driver supports low priority scan
3052 * @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported 3123 * @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported
3053 * @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif 3124 * @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif
3125 * @NL80211_FEATURE_VIF_TXPOWER: The driver supports per-vif TX power setting
3126 * @NL80211_FEATURE_NEED_OBSS_SCAN: The driver expects userspace to perform
3127 * OBSS scans and generate 20/40 BSS coex reports. This flag is used only
3128 * for drivers implementing the CONNECT API, for AUTH/ASSOC it is implied.
3054 */ 3129 */
3055enum nl80211_feature_flags { 3130enum nl80211_feature_flags {
3056 NL80211_FEATURE_SK_TX_STATUS = 1 << 0, 3131 NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
@@ -3062,6 +3137,8 @@ enum nl80211_feature_flags {
3062 NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, 3137 NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6,
3063 NL80211_FEATURE_SCAN_FLUSH = 1 << 7, 3138 NL80211_FEATURE_SCAN_FLUSH = 1 << 7,
3064 NL80211_FEATURE_AP_SCAN = 1 << 8, 3139 NL80211_FEATURE_AP_SCAN = 1 << 8,
3140 NL80211_FEATURE_VIF_TXPOWER = 1 << 9,
3141 NL80211_FEATURE_NEED_OBSS_SCAN = 1 << 10,
3065}; 3142};
3066 3143
3067/** 3144/**
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 1c11d0dcd86..d3f3f7b1d32 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -48,4 +48,3 @@ source "net/bluetooth/cmtp/Kconfig"
48source "net/bluetooth/hidp/Kconfig" 48source "net/bluetooth/hidp/Kconfig"
49 49
50source "drivers/bluetooth/Kconfig" 50source "drivers/bluetooth/Kconfig"
51
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index d5136cfb57e..2f67d5ecc90 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -423,7 +423,7 @@ static int a2mp_getampassoc_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
423 423
424 BT_DBG("Created hcon %p: loc:%d -> rem:%d", hcon, hdev->id, rsp->id); 424 BT_DBG("Created hcon %p: loc:%d -> rem:%d", hcon, hdev->id, rsp->id);
425 425
426 mgr->bredr_chan->ctrl_id = rsp->id; 426 mgr->bredr_chan->remote_amp_id = rsp->id;
427 427
428 amp_create_phylink(hdev, mgr, hcon); 428 amp_create_phylink(hdev, mgr, hcon);
429 429
@@ -939,7 +939,7 @@ void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status)
939 goto clean; 939 goto clean;
940 940
941 req->local_id = hdev->id; 941 req->local_id = hdev->id;
942 req->remote_id = bredr_chan->ctrl_id; 942 req->remote_id = bredr_chan->remote_amp_id;
943 memcpy(req->amp_assoc, loc_assoc->data, loc_assoc->len); 943 memcpy(req->amp_assoc, loc_assoc->data, loc_assoc->len);
944 944
945 a2mp_send(mgr, A2MP_CREATEPHYSLINK_REQ, __next_ident(mgr), len, req); 945 a2mp_send(mgr, A2MP_CREATEPHYSLINK_REQ, __next_ident(mgr), len, req);
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 231d7ef53ec..1b0d92c0643 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -372,3 +372,100 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
372 372
373 hci_send_cmd(hdev, HCI_OP_ACCEPT_PHY_LINK, sizeof(cp), &cp); 373 hci_send_cmd(hdev, HCI_OP_ACCEPT_PHY_LINK, sizeof(cp), &cp);
374} 374}
375
376void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon)
377{
378 struct hci_dev *bredr_hdev = hci_dev_hold(bredr_hcon->hdev);
379 struct amp_mgr *mgr = hs_hcon->amp_mgr;
380 struct l2cap_chan *bredr_chan;
381
382 BT_DBG("bredr_hcon %p hs_hcon %p mgr %p", bredr_hcon, hs_hcon, mgr);
383
384 if (!bredr_hdev || !mgr || !mgr->bredr_chan)
385 return;
386
387 bredr_chan = mgr->bredr_chan;
388
389 l2cap_chan_lock(bredr_chan);
390
391 set_bit(FLAG_EFS_ENABLE, &bredr_chan->flags);
392 bredr_chan->remote_amp_id = hs_hcon->remote_id;
393 bredr_chan->local_amp_id = hs_hcon->hdev->id;
394 bredr_chan->hs_hcon = hs_hcon;
395 bredr_chan->conn->mtu = hs_hcon->hdev->block_mtu;
396
397 __l2cap_physical_cfm(bredr_chan, 0);
398
399 l2cap_chan_unlock(bredr_chan);
400
401 hci_dev_put(bredr_hdev);
402}
403
404void amp_create_logical_link(struct l2cap_chan *chan)
405{
406 struct hci_cp_create_accept_logical_link cp;
407 struct hci_conn *hcon;
408 struct hci_dev *hdev;
409
410 BT_DBG("chan %p", chan);
411
412 if (!chan->hs_hcon)
413 return;
414
415 hdev = hci_dev_hold(chan->hs_hcon->hdev);
416 if (!hdev)
417 return;
418
419 BT_DBG("chan %p dst %pMR", chan, chan->conn->dst);
420
421 hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, chan->conn->dst);
422 if (!hcon)
423 goto done;
424
425 cp.phy_handle = hcon->handle;
426
427 cp.tx_flow_spec.id = chan->local_id;
428 cp.tx_flow_spec.stype = chan->local_stype;
429 cp.tx_flow_spec.msdu = cpu_to_le16(chan->local_msdu);
430 cp.tx_flow_spec.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
431 cp.tx_flow_spec.acc_lat = cpu_to_le32(chan->local_acc_lat);
432 cp.tx_flow_spec.flush_to = cpu_to_le32(chan->local_flush_to);
433
434 cp.rx_flow_spec.id = chan->remote_id;
435 cp.rx_flow_spec.stype = chan->remote_stype;
436 cp.rx_flow_spec.msdu = cpu_to_le16(chan->remote_msdu);
437 cp.rx_flow_spec.sdu_itime = cpu_to_le32(chan->remote_sdu_itime);
438 cp.rx_flow_spec.acc_lat = cpu_to_le32(chan->remote_acc_lat);
439 cp.rx_flow_spec.flush_to = cpu_to_le32(chan->remote_flush_to);
440
441 if (hcon->out)
442 hci_send_cmd(hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp),
443 &cp);
444 else
445 hci_send_cmd(hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp),
446 &cp);
447
448done:
449 hci_dev_put(hdev);
450}
451
452void amp_disconnect_logical_link(struct hci_chan *hchan)
453{
454 struct hci_conn *hcon = hchan->conn;
455 struct hci_cp_disconn_logical_link cp;
456
457 if (hcon->state != BT_CONNECTED) {
458 BT_DBG("hchan %p not connected", hchan);
459 return;
460 }
461
462 cp.log_handle = cpu_to_le16(hchan->handle);
463 hci_send_cmd(hcon->hdev, HCI_OP_DISCONN_LOGICAL_LINK, sizeof(cp), &cp);
464}
465
466void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason)
467{
468 BT_DBG("hchan %p", hchan);
469
470 hci_chan_del(hchan);
471}
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index 98f86f91d47..e58c8b32589 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -25,7 +25,6 @@
25 SOFTWARE IS DISCLAIMED. 25 SOFTWARE IS DISCLAIMED.
26*/ 26*/
27 27
28#include <linux/export.h>
29#include <linux/etherdevice.h> 28#include <linux/etherdevice.h>
30 29
31#include <net/bluetooth/bluetooth.h> 30#include <net/bluetooth/bluetooth.h>
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c
index 50f0d135eb8..a4a9d4b6816 100644
--- a/net/bluetooth/cmtp/capi.c
+++ b/net/bluetooth/cmtp/capi.c
@@ -20,7 +20,7 @@
20 SOFTWARE IS DISCLAIMED. 20 SOFTWARE IS DISCLAIMED.
21*/ 21*/
22 22
23#include <linux/module.h> 23#include <linux/export.h>
24#include <linux/proc_fs.h> 24#include <linux/proc_fs.h>
25#include <linux/seq_file.h> 25#include <linux/seq_file.h>
26#include <linux/types.h> 26#include <linux/types.h>
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index aacb802d1ee..1c57482112b 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -20,7 +20,7 @@
20 SOFTWARE IS DISCLAIMED. 20 SOFTWARE IS DISCLAIMED.
21*/ 21*/
22 22
23#include <linux/module.h> 23#include <linux/export.h>
24 24
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/capability.h> 26#include <linux/capability.h>
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index fe646211c61..25bfce0666e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -502,6 +502,9 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
502{ 502{
503 struct hci_conn *le; 503 struct hci_conn *le;
504 504
505 if (test_bit(HCI_LE_PERIPHERAL, &hdev->flags))
506 return ERR_PTR(-ENOTSUPP);
507
505 le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); 508 le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
506 if (!le) { 509 if (!le) {
507 le = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 510 le = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
@@ -959,6 +962,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn)
959 962
960 chan->conn = conn; 963 chan->conn = conn;
961 skb_queue_head_init(&chan->data_q); 964 skb_queue_head_init(&chan->data_q);
965 chan->state = BT_CONNECTED;
962 966
963 list_add_rcu(&chan->list, &conn->chan_list); 967 list_add_rcu(&chan->list, &conn->chan_list);
964 968
@@ -976,6 +980,8 @@ void hci_chan_del(struct hci_chan *chan)
976 980
977 synchronize_rcu(); 981 synchronize_rcu();
978 982
983 hci_conn_put(conn);
984
979 skb_queue_purge(&chan->data_q); 985 skb_queue_purge(&chan->data_q);
980 kfree(chan); 986 kfree(chan);
981} 987}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index f01e5e135b9..7140f83328a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -178,48 +178,13 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
178 178
179static void bredr_init(struct hci_dev *hdev) 179static void bredr_init(struct hci_dev *hdev)
180{ 180{
181 struct hci_cp_delete_stored_link_key cp;
182 __le16 param;
183 __u8 flt_type;
184
185 hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 181 hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
186 182
187 /* Mandatory initialization */
188
189 /* Read Local Supported Features */ 183 /* Read Local Supported Features */
190 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 184 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
191 185
192 /* Read Local Version */ 186 /* Read Local Version */
193 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 187 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
194
195 /* Read Buffer Size (ACL mtu, max pkt, etc.) */
196 hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
197
198 /* Read BD Address */
199 hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
200
201 /* Read Class of Device */
202 hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
203
204 /* Read Local Name */
205 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
206
207 /* Read Voice Setting */
208 hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
209
210 /* Optional initialization */
211
212 /* Clear Event Filters */
213 flt_type = HCI_FLT_CLEAR_ALL;
214 hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
215
216 /* Connection accept timeout ~20 secs */
217 param = __constant_cpu_to_le16(0x7d00);
218 hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
219
220 bacpy(&cp.bdaddr, BDADDR_ANY);
221 cp.delete_all = 1;
222 hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
223} 188}
224 189
225static void amp_init(struct hci_dev *hdev) 190static void amp_init(struct hci_dev *hdev)
@@ -273,14 +238,6 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
273 } 238 }
274} 239}
275 240
276static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
277{
278 BT_DBG("%s", hdev->name);
279
280 /* Read LE buffer size */
281 hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
282}
283
284static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) 241static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
285{ 242{
286 __u8 scan = opt; 243 __u8 scan = opt;
@@ -477,6 +434,8 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
477 434
478 BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 435 BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
479 436
437 hci_remove_remote_oob_data(hdev, &data->bdaddr);
438
480 if (ssp) 439 if (ssp)
481 *ssp = data->ssp_mode; 440 *ssp = data->ssp_mode;
482 441
@@ -637,6 +596,99 @@ done:
637 return err; 596 return err;
638} 597}
639 598
599static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
600{
601 u8 ad_len = 0, flags = 0;
602 size_t name_len;
603
604 if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
605 flags |= LE_AD_GENERAL;
606
607 if (!lmp_bredr_capable(hdev))
608 flags |= LE_AD_NO_BREDR;
609
610 if (lmp_le_br_capable(hdev))
611 flags |= LE_AD_SIM_LE_BREDR_CTRL;
612
613 if (lmp_host_le_br_capable(hdev))
614 flags |= LE_AD_SIM_LE_BREDR_HOST;
615
616 if (flags) {
617 BT_DBG("adv flags 0x%02x", flags);
618
619 ptr[0] = 2;
620 ptr[1] = EIR_FLAGS;
621 ptr[2] = flags;
622
623 ad_len += 3;
624 ptr += 3;
625 }
626
627 if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
628 ptr[0] = 2;
629 ptr[1] = EIR_TX_POWER;
630 ptr[2] = (u8) hdev->adv_tx_power;
631
632 ad_len += 3;
633 ptr += 3;
634 }
635
636 name_len = strlen(hdev->dev_name);
637 if (name_len > 0) {
638 size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
639
640 if (name_len > max_len) {
641 name_len = max_len;
642 ptr[1] = EIR_NAME_SHORT;
643 } else
644 ptr[1] = EIR_NAME_COMPLETE;
645
646 ptr[0] = name_len + 1;
647
648 memcpy(ptr + 2, hdev->dev_name, name_len);
649
650 ad_len += (name_len + 2);
651 ptr += (name_len + 2);
652 }
653
654 return ad_len;
655}
656
657int hci_update_ad(struct hci_dev *hdev)
658{
659 struct hci_cp_le_set_adv_data cp;
660 u8 len;
661 int err;
662
663 hci_dev_lock(hdev);
664
665 if (!lmp_le_capable(hdev)) {
666 err = -EINVAL;
667 goto unlock;
668 }
669
670 memset(&cp, 0, sizeof(cp));
671
672 len = create_ad(hdev, cp.data);
673
674 if (hdev->adv_data_len == len &&
675 memcmp(cp.data, hdev->adv_data, len) == 0) {
676 err = 0;
677 goto unlock;
678 }
679
680 memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
681 hdev->adv_data_len = len;
682
683 cp.length = len;
684 err = hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
685
686unlock:
687 hci_dev_unlock(hdev);
688
689 return err;
690}
691
640/* ---- HCI ioctl helpers ---- */ 692/* ---- HCI ioctl helpers ---- */
641 693
642int hci_dev_open(__u16 dev) 694int hci_dev_open(__u16 dev)
@@ -687,10 +739,6 @@ int hci_dev_open(__u16 dev)
687 739
688 ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT); 740 ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
689 741
690 if (lmp_host_le_capable(hdev))
691 ret = __hci_request(hdev, hci_le_init_req, 0,
692 HCI_INIT_TIMEOUT);
693
694 clear_bit(HCI_INIT, &hdev->flags); 742 clear_bit(HCI_INIT, &hdev->flags);
695 } 743 }
696 744
@@ -698,6 +746,7 @@ int hci_dev_open(__u16 dev)
698 hci_dev_hold(hdev); 746 hci_dev_hold(hdev);
699 set_bit(HCI_UP, &hdev->flags); 747 set_bit(HCI_UP, &hdev->flags);
700 hci_notify(hdev, HCI_DEV_UP); 748 hci_notify(hdev, HCI_DEV_UP);
749 hci_update_ad(hdev);
701 if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 750 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
702 mgmt_valid_hdev(hdev)) { 751 mgmt_valid_hdev(hdev)) {
703 hci_dev_lock(hdev); 752 hci_dev_lock(hdev);
@@ -1039,10 +1088,17 @@ int hci_get_dev_info(void __user *arg)
1039 di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); 1088 di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
1040 di.flags = hdev->flags; 1089 di.flags = hdev->flags;
1041 di.pkt_type = hdev->pkt_type; 1090 di.pkt_type = hdev->pkt_type;
1042 di.acl_mtu = hdev->acl_mtu; 1091 if (lmp_bredr_capable(hdev)) {
1043 di.acl_pkts = hdev->acl_pkts; 1092 di.acl_mtu = hdev->acl_mtu;
1044 di.sco_mtu = hdev->sco_mtu; 1093 di.acl_pkts = hdev->acl_pkts;
1045 di.sco_pkts = hdev->sco_pkts; 1094 di.sco_mtu = hdev->sco_mtu;
1095 di.sco_pkts = hdev->sco_pkts;
1096 } else {
1097 di.acl_mtu = hdev->le_mtu;
1098 di.acl_pkts = hdev->le_pkts;
1099 di.sco_mtu = 0;
1100 di.sco_pkts = 0;
1101 }
1046 di.link_policy = hdev->link_policy; 1102 di.link_policy = hdev->link_policy;
1047 di.link_mode = hdev->link_mode; 1103 di.link_mode = hdev->link_mode;
1048 1104
@@ -1617,6 +1673,9 @@ int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
1617 1673
1618 BT_DBG("%s", hdev->name); 1674 BT_DBG("%s", hdev->name);
1619 1675
1676 if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
1677 return -ENOTSUPP;
1678
1620 if (work_busy(&hdev->le_scan)) 1679 if (work_busy(&hdev->le_scan))
1621 return -EINPROGRESS; 1680 return -EINPROGRESS;
1622 1681
@@ -1643,6 +1702,8 @@ struct hci_dev *hci_alloc_dev(void)
1643 hdev->esco_type = (ESCO_HV1); 1702 hdev->esco_type = (ESCO_HV1);
1644 hdev->link_mode = (HCI_LM_ACCEPT); 1703 hdev->link_mode = (HCI_LM_ACCEPT);
1645 hdev->io_capability = 0x03; /* No Input No Output */ 1704 hdev->io_capability = 0x03; /* No Input No Output */
1705 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
1706 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
1646 1707
1647 hdev->sniff_max_interval = 800; 1708 hdev->sniff_max_interval = 800;
1648 hdev->sniff_min_interval = 80; 1709 hdev->sniff_min_interval = 80;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 0383635f91f..9f5c5f24450 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -24,7 +24,6 @@
24 24
25/* Bluetooth HCI event handling. */ 25/* Bluetooth HCI event handling. */
26 26
27#include <linux/export.h>
28#include <asm/unaligned.h> 27#include <asm/unaligned.h>
29 28
30#include <net/bluetooth/bluetooth.h> 29#include <net/bluetooth/bluetooth.h>
@@ -203,6 +202,11 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
203 BIT(HCI_PERIODIC_INQ)); 202 BIT(HCI_PERIODIC_INQ));
204 203
205 hdev->discovery.state = DISCOVERY_STOPPED; 204 hdev->discovery.state = DISCOVERY_STOPPED;
205 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
206 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
207
208 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
209 hdev->adv_data_len = 0;
206} 210}
207 211
208static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 212static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -225,6 +229,9 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
225 229
226 hci_dev_unlock(hdev); 230 hci_dev_unlock(hdev);
227 231
232 if (!status && !test_bit(HCI_INIT, &hdev->flags))
233 hci_update_ad(hdev);
234
228 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status); 235 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
229} 236}
230 237
@@ -440,7 +447,7 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
440static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 447static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
441{ 448{
442 __u8 status = *((__u8 *) skb->data); 449 __u8 status = *((__u8 *) skb->data);
443 void *sent; 450 struct hci_cp_write_ssp_mode *sent;
444 451
445 BT_DBG("%s status 0x%2.2x", hdev->name, status); 452 BT_DBG("%s status 0x%2.2x", hdev->name, status);
446 453
@@ -448,10 +455,17 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
448 if (!sent) 455 if (!sent)
449 return; 456 return;
450 457
458 if (!status) {
459 if (sent->mode)
460 hdev->host_features[0] |= LMP_HOST_SSP;
461 else
462 hdev->host_features[0] &= ~LMP_HOST_SSP;
463 }
464
451 if (test_bit(HCI_MGMT, &hdev->dev_flags)) 465 if (test_bit(HCI_MGMT, &hdev->dev_flags))
452 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status); 466 mgmt_ssp_enable_complete(hdev, sent->mode, status);
453 else if (!status) { 467 else if (!status) {
454 if (*((u8 *) sent)) 468 if (sent->mode)
455 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 469 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
456 else 470 else
457 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 471 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
@@ -460,10 +474,10 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
460 474
461static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 475static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
462{ 476{
463 if (hdev->features[6] & LMP_EXT_INQ) 477 if (lmp_ext_inq_capable(hdev))
464 return 2; 478 return 2;
465 479
466 if (hdev->features[3] & LMP_RSSI_INQ) 480 if (lmp_inq_rssi_capable(hdev))
467 return 1; 481 return 1;
468 482
469 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 483 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
@@ -507,28 +521,30 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
507 if (hdev->hci_ver < BLUETOOTH_VER_1_2) 521 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
508 return; 522 return;
509 523
510 events[4] |= 0x01; /* Flow Specification Complete */ 524 if (lmp_bredr_capable(hdev)) {
511 events[4] |= 0x02; /* Inquiry Result with RSSI */ 525 events[4] |= 0x01; /* Flow Specification Complete */
512 events[4] |= 0x04; /* Read Remote Extended Features Complete */ 526 events[4] |= 0x02; /* Inquiry Result with RSSI */
513 events[5] |= 0x08; /* Synchronous Connection Complete */ 527 events[4] |= 0x04; /* Read Remote Extended Features Complete */
514 events[5] |= 0x10; /* Synchronous Connection Changed */ 528 events[5] |= 0x08; /* Synchronous Connection Complete */
529 events[5] |= 0x10; /* Synchronous Connection Changed */
530 }
515 531
516 if (hdev->features[3] & LMP_RSSI_INQ) 532 if (lmp_inq_rssi_capable(hdev))
517 events[4] |= 0x02; /* Inquiry Result with RSSI */ 533 events[4] |= 0x02; /* Inquiry Result with RSSI */
518 534
519 if (lmp_sniffsubr_capable(hdev)) 535 if (lmp_sniffsubr_capable(hdev))
520 events[5] |= 0x20; /* Sniff Subrating */ 536 events[5] |= 0x20; /* Sniff Subrating */
521 537
522 if (hdev->features[5] & LMP_PAUSE_ENC) 538 if (lmp_pause_enc_capable(hdev))
523 events[5] |= 0x80; /* Encryption Key Refresh Complete */ 539 events[5] |= 0x80; /* Encryption Key Refresh Complete */
524 540
525 if (hdev->features[6] & LMP_EXT_INQ) 541 if (lmp_ext_inq_capable(hdev))
526 events[5] |= 0x40; /* Extended Inquiry Result */ 542 events[5] |= 0x40; /* Extended Inquiry Result */
527 543
528 if (lmp_no_flush_capable(hdev)) 544 if (lmp_no_flush_capable(hdev))
529 events[7] |= 0x01; /* Enhanced Flush Complete */ 545 events[7] |= 0x01; /* Enhanced Flush Complete */
530 546
531 if (hdev->features[7] & LMP_LSTO) 547 if (lmp_lsto_capable(hdev))
532 events[6] |= 0x80; /* Link Supervision Timeout Changed */ 548 events[6] |= 0x80; /* Link Supervision Timeout Changed */
533 549
534 if (lmp_ssp_capable(hdev)) { 550 if (lmp_ssp_capable(hdev)) {
@@ -548,6 +564,53 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
548 events[7] |= 0x20; /* LE Meta-Event */ 564 events[7] |= 0x20; /* LE Meta-Event */
549 565
550 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 566 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
567
568 if (lmp_le_capable(hdev)) {
569 memset(events, 0, sizeof(events));
570 events[0] = 0x1f;
571 hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK,
572 sizeof(events), events);
573 }
574}
575
576static void bredr_setup(struct hci_dev *hdev)
577{
578 struct hci_cp_delete_stored_link_key cp;
579 __le16 param;
580 __u8 flt_type;
581
582 /* Read Buffer Size (ACL mtu, max pkt, etc.) */
583 hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
584
585 /* Read Class of Device */
586 hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
587
588 /* Read Local Name */
589 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
590
591 /* Read Voice Setting */
592 hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
593
594 /* Clear Event Filters */
595 flt_type = HCI_FLT_CLEAR_ALL;
596 hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
597
598 /* Connection accept timeout ~20 secs */
599 param = __constant_cpu_to_le16(0x7d00);
600 hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
601
602 bacpy(&cp.bdaddr, BDADDR_ANY);
603 cp.delete_all = 1;
604 hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
605}
606
607static void le_setup(struct hci_dev *hdev)
608{
609 /* Read LE Buffer Size */
610 hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
611
612 /* Read LE Advertising Channel TX Power */
613 hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
551} 614}
552 615
553static void hci_setup(struct hci_dev *hdev) 616static void hci_setup(struct hci_dev *hdev)
@@ -555,6 +618,15 @@ static void hci_setup(struct hci_dev *hdev)
555 if (hdev->dev_type != HCI_BREDR) 618 if (hdev->dev_type != HCI_BREDR)
556 return; 619 return;
557 620
621 /* Read BD Address */
622 hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
623
624 if (lmp_bredr_capable(hdev))
625 bredr_setup(hdev);
626
627 if (lmp_le_capable(hdev))
628 le_setup(hdev);
629
558 hci_setup_event_mask(hdev); 630 hci_setup_event_mask(hdev);
559 631
560 if (hdev->hci_ver > BLUETOOTH_VER_1_1) 632 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
@@ -575,13 +647,13 @@ static void hci_setup(struct hci_dev *hdev)
575 } 647 }
576 } 648 }
577 649
578 if (hdev->features[3] & LMP_RSSI_INQ) 650 if (lmp_inq_rssi_capable(hdev))
579 hci_setup_inquiry_mode(hdev); 651 hci_setup_inquiry_mode(hdev);
580 652
581 if (hdev->features[7] & LMP_INQ_TX_PWR) 653 if (lmp_inq_tx_pwr_capable(hdev))
582 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 654 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
583 655
584 if (hdev->features[7] & LMP_EXTFEATURES) { 656 if (lmp_ext_feat_capable(hdev)) {
585 struct hci_cp_read_local_ext_features cp; 657 struct hci_cp_read_local_ext_features cp;
586 658
587 cp.page = 0x01; 659 cp.page = 0x01;
@@ -628,11 +700,11 @@ static void hci_setup_link_policy(struct hci_dev *hdev)
628 700
629 if (lmp_rswitch_capable(hdev)) 701 if (lmp_rswitch_capable(hdev))
630 link_policy |= HCI_LP_RSWITCH; 702 link_policy |= HCI_LP_RSWITCH;
631 if (hdev->features[0] & LMP_HOLD) 703 if (lmp_hold_capable(hdev))
632 link_policy |= HCI_LP_HOLD; 704 link_policy |= HCI_LP_HOLD;
633 if (lmp_sniff_capable(hdev)) 705 if (lmp_sniff_capable(hdev))
634 link_policy |= HCI_LP_SNIFF; 706 link_policy |= HCI_LP_SNIFF;
635 if (hdev->features[1] & LMP_PARK) 707 if (lmp_park_capable(hdev))
636 link_policy |= HCI_LP_PARK; 708 link_policy |= HCI_LP_PARK;
637 709
638 cp.policy = cpu_to_le16(link_policy); 710 cp.policy = cpu_to_le16(link_policy);
@@ -722,10 +794,10 @@ static void hci_set_le_support(struct hci_dev *hdev)
722 794
723 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 795 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
724 cp.le = 1; 796 cp.le = 1;
725 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); 797 cp.simul = !!lmp_le_br_capable(hdev);
726 } 798 }
727 799
728 if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE)) 800 if (cp.le != !!lmp_host_le_capable(hdev))
729 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 801 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
730 &cp); 802 &cp);
731} 803}
@@ -1018,6 +1090,31 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
1018 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); 1090 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
1019} 1091}
1020 1092
1093static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
1094 struct sk_buff *skb)
1095{
1096 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
1097
1098 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1099
1100 if (!rp->status) {
1101 hdev->adv_tx_power = rp->tx_power;
1102 if (!test_bit(HCI_INIT, &hdev->flags))
1103 hci_update_ad(hdev);
1104 }
1105
1106 hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status);
1107}
1108
1109static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
1110{
1111 __u8 status = *((__u8 *) skb->data);
1112
1113 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1114
1115 hci_req_complete(hdev, HCI_OP_LE_SET_EVENT_MASK, status);
1116}
1117
1021static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) 1118static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
1022{ 1119{
1023 struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 1120 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
@@ -1093,6 +1190,33 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1093 hci_dev_unlock(hdev); 1190 hci_dev_unlock(hdev);
1094} 1191}
1095 1192
1193static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
1194{
1195 __u8 *sent, status = *((__u8 *) skb->data);
1196
1197 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1198
1199 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
1200 if (!sent)
1201 return;
1202
1203 hci_dev_lock(hdev);
1204
1205 if (!status) {
1206 if (*sent)
1207 set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
1208 else
1209 clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
1210 }
1211
1212 hci_dev_unlock(hdev);
1213
1214 if (!test_bit(HCI_INIT, &hdev->flags))
1215 hci_update_ad(hdev);
1216
1217 hci_req_complete(hdev, HCI_OP_LE_SET_ADV_ENABLE, status);
1218}
1219
1096static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) 1220static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1097{ 1221{
1098 __u8 status = *((__u8 *) skb->data); 1222 __u8 status = *((__u8 *) skb->data);
@@ -1207,6 +1331,11 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1207 hdev->host_features[0] |= LMP_HOST_LE; 1331 hdev->host_features[0] |= LMP_HOST_LE;
1208 else 1332 else
1209 hdev->host_features[0] &= ~LMP_HOST_LE; 1333 hdev->host_features[0] &= ~LMP_HOST_LE;
1334
1335 if (sent->simul)
1336 hdev->host_features[0] |= LMP_HOST_LE_BREDR;
1337 else
1338 hdev->host_features[0] &= ~LMP_HOST_LE_BREDR;
1210 } 1339 }
1211 1340
1212 if (test_bit(HCI_MGMT, &hdev->dev_flags) && 1341 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
@@ -1718,14 +1847,23 @@ static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1718 1847
1719 BT_DBG("%s status 0x%2.2x", hdev->name, status); 1848 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1720 1849
1721 if (status)
1722 return;
1723
1724 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); 1850 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1725 if (!cp) 1851 if (!cp)
1726 return; 1852 return;
1727 1853
1728 amp_write_remote_assoc(hdev, cp->phy_handle); 1854 hci_dev_lock(hdev);
1855
1856 if (status) {
1857 struct hci_conn *hcon;
1858
1859 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1860 if (hcon)
1861 hci_conn_del(hcon);
1862 } else {
1863 amp_write_remote_assoc(hdev, cp->phy_handle);
1864 }
1865
1866 hci_dev_unlock(hdev);
1729} 1867}
1730 1868
1731static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) 1869static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
@@ -1744,6 +1882,11 @@ static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1744 amp_write_remote_assoc(hdev, cp->phy_handle); 1882 amp_write_remote_assoc(hdev, cp->phy_handle);
1745} 1883}
1746 1884
1885static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status)
1886{
1887 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1888}
1889
1747static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1890static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1748{ 1891{
1749 __u8 status = *((__u8 *) skb->data); 1892 __u8 status = *((__u8 *) skb->data);
@@ -2441,6 +2584,14 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2441 hci_cc_le_read_buffer_size(hdev, skb); 2584 hci_cc_le_read_buffer_size(hdev, skb);
2442 break; 2585 break;
2443 2586
2587 case HCI_OP_LE_READ_ADV_TX_POWER:
2588 hci_cc_le_read_adv_tx_power(hdev, skb);
2589 break;
2590
2591 case HCI_OP_LE_SET_EVENT_MASK:
2592 hci_cc_le_set_event_mask(hdev, skb);
2593 break;
2594
2444 case HCI_OP_USER_CONFIRM_REPLY: 2595 case HCI_OP_USER_CONFIRM_REPLY:
2445 hci_cc_user_confirm_reply(hdev, skb); 2596 hci_cc_user_confirm_reply(hdev, skb);
2446 break; 2597 break;
@@ -2461,6 +2612,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2461 hci_cc_le_set_scan_param(hdev, skb); 2612 hci_cc_le_set_scan_param(hdev, skb);
2462 break; 2613 break;
2463 2614
2615 case HCI_OP_LE_SET_ADV_ENABLE:
2616 hci_cc_le_set_adv_enable(hdev, skb);
2617 break;
2618
2464 case HCI_OP_LE_SET_SCAN_ENABLE: 2619 case HCI_OP_LE_SET_SCAN_ENABLE:
2465 hci_cc_le_set_scan_enable(hdev, skb); 2620 hci_cc_le_set_scan_enable(hdev, skb);
2466 break; 2621 break;
@@ -2570,6 +2725,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2570 hci_cs_accept_phylink(hdev, ev->status); 2725 hci_cs_accept_phylink(hdev, ev->status);
2571 break; 2726 break;
2572 2727
2728 case HCI_OP_CREATE_LOGICAL_LINK:
2729 hci_cs_create_logical_link(hdev, ev->status);
2730 break;
2731
2573 default: 2732 default:
2574 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 2733 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
2575 break; 2734 break;
@@ -3544,6 +3703,130 @@ unlock:
3544 hci_dev_unlock(hdev); 3703 hci_dev_unlock(hdev);
3545} 3704}
3546 3705
3706static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3707 struct sk_buff *skb)
3708{
3709 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3710 struct hci_conn *hcon, *bredr_hcon;
3711
3712 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3713 ev->status);
3714
3715 hci_dev_lock(hdev);
3716
3717 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3718 if (!hcon) {
3719 hci_dev_unlock(hdev);
3720 return;
3721 }
3722
3723 if (ev->status) {
3724 hci_conn_del(hcon);
3725 hci_dev_unlock(hdev);
3726 return;
3727 }
3728
3729 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3730
3731 hcon->state = BT_CONNECTED;
3732 bacpy(&hcon->dst, &bredr_hcon->dst);
3733
3734 hci_conn_hold(hcon);
3735 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3736 hci_conn_put(hcon);
3737
3738 hci_conn_hold_device(hcon);
3739 hci_conn_add_sysfs(hcon);
3740
3741 amp_physical_cfm(bredr_hcon, hcon);
3742
3743 hci_dev_unlock(hdev);
3744}
3745
3746static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3747{
3748 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3749 struct hci_conn *hcon;
3750 struct hci_chan *hchan;
3751 struct amp_mgr *mgr;
3752
3753 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3754 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3755 ev->status);
3756
3757 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3758 if (!hcon)
3759 return;
3760
3761 /* Create AMP hchan */
3762 hchan = hci_chan_create(hcon);
3763 if (!hchan)
3764 return;
3765
3766 hchan->handle = le16_to_cpu(ev->handle);
3767
3768 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3769
3770 mgr = hcon->amp_mgr;
3771 if (mgr && mgr->bredr_chan) {
3772 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3773
3774 l2cap_chan_lock(bredr_chan);
3775
3776 bredr_chan->conn->mtu = hdev->block_mtu;
3777 l2cap_logical_cfm(bredr_chan, hchan, 0);
3778 hci_conn_hold(hcon);
3779
3780 l2cap_chan_unlock(bredr_chan);
3781 }
3782}
3783
3784static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3785 struct sk_buff *skb)
3786{
3787 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3788 struct hci_chan *hchan;
3789
3790 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3791 le16_to_cpu(ev->handle), ev->status);
3792
3793 if (ev->status)
3794 return;
3795
3796 hci_dev_lock(hdev);
3797
3798 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3799 if (!hchan)
3800 goto unlock;
3801
3802 amp_destroy_logical_link(hchan, ev->reason);
3803
3804unlock:
3805 hci_dev_unlock(hdev);
3806}
3807
3808static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3809 struct sk_buff *skb)
3810{
3811 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3812 struct hci_conn *hcon;
3813
3814 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3815
3816 if (ev->status)
3817 return;
3818
3819 hci_dev_lock(hdev);
3820
3821 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3822 if (hcon) {
3823 hcon->state = BT_CLOSED;
3824 hci_conn_del(hcon);
3825 }
3826
3827 hci_dev_unlock(hdev);
3828}
3829
3547static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 3830static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3548{ 3831{
3549 struct hci_ev_le_conn_complete *ev = (void *) skb->data; 3832 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -3871,6 +4154,22 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3871 hci_remote_oob_data_request_evt(hdev, skb); 4154 hci_remote_oob_data_request_evt(hdev, skb);
3872 break; 4155 break;
3873 4156
4157 case HCI_EV_PHY_LINK_COMPLETE:
4158 hci_phy_link_complete_evt(hdev, skb);
4159 break;
4160
4161 case HCI_EV_LOGICAL_LINK_COMPLETE:
4162 hci_loglink_complete_evt(hdev, skb);
4163 break;
4164
4165 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4166 hci_disconn_loglink_complete_evt(hdev, skb);
4167 break;
4168
4169 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4170 hci_disconn_phylink_complete_evt(hdev, skb);
4171 break;
4172
3874 case HCI_EV_NUM_COMP_BLOCKS: 4173 case HCI_EV_NUM_COMP_BLOCKS:
3875 hci_num_comp_blocks_evt(hdev, skb); 4174 hci_num_comp_blocks_evt(hdev, skb);
3876 break; 4175 break;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 08efc256c93..b52f66d2243 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -38,6 +38,7 @@
38#include <net/bluetooth/l2cap.h> 38#include <net/bluetooth/l2cap.h>
39#include <net/bluetooth/smp.h> 39#include <net/bluetooth/smp.h>
40#include <net/bluetooth/a2mp.h> 40#include <net/bluetooth/a2mp.h>
41#include <net/bluetooth/amp.h>
41 42
42bool disable_ertm; 43bool disable_ertm;
43 44
@@ -100,6 +101,23 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
100 return c; 101 return c;
101} 102}
102 103
104/* Find channel with given DCID.
105 * Returns locked channel.
106 */
107static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
108 u16 cid)
109{
110 struct l2cap_chan *c;
111
112 mutex_lock(&conn->chan_lock);
113 c = __l2cap_get_chan_by_dcid(conn, cid);
114 if (c)
115 l2cap_chan_lock(c);
116 mutex_unlock(&conn->chan_lock);
117
118 return c;
119}
120
103static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, 121static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
104 u8 ident) 122 u8 ident)
105{ 123{
@@ -112,6 +130,20 @@ static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
112 return NULL; 130 return NULL;
113} 131}
114 132
133static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
134 u8 ident)
135{
136 struct l2cap_chan *c;
137
138 mutex_lock(&conn->chan_lock);
139 c = __l2cap_get_chan_by_ident(conn, ident);
140 if (c)
141 l2cap_chan_lock(c);
142 mutex_unlock(&conn->chan_lock);
143
144 return c;
145}
146
115static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src) 147static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
116{ 148{
117 struct l2cap_chan *c; 149 struct l2cap_chan *c;
@@ -546,6 +578,13 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
546 mgr->bredr_chan = NULL; 578 mgr->bredr_chan = NULL;
547 } 579 }
548 580
581 if (chan->hs_hchan) {
582 struct hci_chan *hs_hchan = chan->hs_hchan;
583
584 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
585 amp_disconnect_logical_link(hs_hchan);
586 }
587
549 chan->ops->teardown(chan, err); 588 chan->ops->teardown(chan, err);
550 589
551 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) 590 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
@@ -718,6 +757,12 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
718 hci_send_acl(conn->hchan, skb, flags); 757 hci_send_acl(conn->hchan, skb, flags);
719} 758}
720 759
760static bool __chan_is_moving(struct l2cap_chan *chan)
761{
762 return chan->move_state != L2CAP_MOVE_STABLE &&
763 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
764}
765
721static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) 766static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
722{ 767{
723 struct hci_conn *hcon = chan->conn->hcon; 768 struct hci_conn *hcon = chan->conn->hcon;
@@ -726,6 +771,15 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
726 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len, 771 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
727 skb->priority); 772 skb->priority);
728 773
774 if (chan->hs_hcon && !__chan_is_moving(chan)) {
775 if (chan->hs_hchan)
776 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
777 else
778 kfree_skb(skb);
779
780 return;
781 }
782
729 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) && 783 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
730 lmp_no_flush_capable(hcon->hdev)) 784 lmp_no_flush_capable(hcon->hdev))
731 flags = ACL_START_NO_FLUSH; 785 flags = ACL_START_NO_FLUSH;
@@ -901,6 +955,9 @@ static void l2cap_send_sframe(struct l2cap_chan *chan,
901 if (!control->sframe) 955 if (!control->sframe)
902 return; 956 return;
903 957
958 if (__chan_is_moving(chan))
959 return;
960
904 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) && 961 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
905 !control->poll) 962 !control->poll)
906 control->final = 1; 963 control->final = 1;
@@ -964,6 +1021,12 @@ static bool __amp_capable(struct l2cap_chan *chan)
964 return false; 1021 return false;
965} 1022}
966 1023
1024static bool l2cap_check_efs(struct l2cap_chan *chan)
1025{
1026 /* Check EFS parameters */
1027 return true;
1028}
1029
967void l2cap_send_conn_req(struct l2cap_chan *chan) 1030void l2cap_send_conn_req(struct l2cap_chan *chan)
968{ 1031{
969 struct l2cap_conn *conn = chan->conn; 1032 struct l2cap_conn *conn = chan->conn;
@@ -979,6 +1042,76 @@ void l2cap_send_conn_req(struct l2cap_chan *chan)
979 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req); 1042 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
980} 1043}
981 1044
1045static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1046{
1047 struct l2cap_create_chan_req req;
1048 req.scid = cpu_to_le16(chan->scid);
1049 req.psm = chan->psm;
1050 req.amp_id = amp_id;
1051
1052 chan->ident = l2cap_get_ident(chan->conn);
1053
1054 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1055 sizeof(req), &req);
1056}
1057
1058static void l2cap_move_setup(struct l2cap_chan *chan)
1059{
1060 struct sk_buff *skb;
1061
1062 BT_DBG("chan %p", chan);
1063
1064 if (chan->mode != L2CAP_MODE_ERTM)
1065 return;
1066
1067 __clear_retrans_timer(chan);
1068 __clear_monitor_timer(chan);
1069 __clear_ack_timer(chan);
1070
1071 chan->retry_count = 0;
1072 skb_queue_walk(&chan->tx_q, skb) {
1073 if (bt_cb(skb)->control.retries)
1074 bt_cb(skb)->control.retries = 1;
1075 else
1076 break;
1077 }
1078
1079 chan->expected_tx_seq = chan->buffer_seq;
1080
1081 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1082 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1083 l2cap_seq_list_clear(&chan->retrans_list);
1084 l2cap_seq_list_clear(&chan->srej_list);
1085 skb_queue_purge(&chan->srej_q);
1086
1087 chan->tx_state = L2CAP_TX_STATE_XMIT;
1088 chan->rx_state = L2CAP_RX_STATE_MOVE;
1089
1090 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1091}
1092
1093static void l2cap_move_done(struct l2cap_chan *chan)
1094{
1095 u8 move_role = chan->move_role;
1096 BT_DBG("chan %p", chan);
1097
1098 chan->move_state = L2CAP_MOVE_STABLE;
1099 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1100
1101 if (chan->mode != L2CAP_MODE_ERTM)
1102 return;
1103
1104 switch (move_role) {
1105 case L2CAP_MOVE_ROLE_INITIATOR:
1106 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1107 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1108 break;
1109 case L2CAP_MOVE_ROLE_RESPONDER:
1110 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1111 break;
1112 }
1113}
1114
982static void l2cap_chan_ready(struct l2cap_chan *chan) 1115static void l2cap_chan_ready(struct l2cap_chan *chan)
983{ 1116{
984 /* This clears all conf flags, including CONF_NOT_COMPLETE */ 1117 /* This clears all conf flags, including CONF_NOT_COMPLETE */
@@ -1695,6 +1828,9 @@ static void l2cap_streaming_send(struct l2cap_chan *chan,
1695 1828
1696 BT_DBG("chan %p, skbs %p", chan, skbs); 1829 BT_DBG("chan %p, skbs %p", chan, skbs);
1697 1830
1831 if (__chan_is_moving(chan))
1832 return;
1833
1698 skb_queue_splice_tail_init(skbs, &chan->tx_q); 1834 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1699 1835
1700 while (!skb_queue_empty(&chan->tx_q)) { 1836 while (!skb_queue_empty(&chan->tx_q)) {
@@ -1737,6 +1873,9 @@ static int l2cap_ertm_send(struct l2cap_chan *chan)
1737 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) 1873 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1738 return 0; 1874 return 0;
1739 1875
1876 if (__chan_is_moving(chan))
1877 return 0;
1878
1740 while (chan->tx_send_head && 1879 while (chan->tx_send_head &&
1741 chan->unacked_frames < chan->remote_tx_win && 1880 chan->unacked_frames < chan->remote_tx_win &&
1742 chan->tx_state == L2CAP_TX_STATE_XMIT) { 1881 chan->tx_state == L2CAP_TX_STATE_XMIT) {
@@ -1802,6 +1941,9 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan)
1802 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) 1941 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1803 return; 1942 return;
1804 1943
1944 if (__chan_is_moving(chan))
1945 return;
1946
1805 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) { 1947 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1806 seq = l2cap_seq_list_pop(&chan->retrans_list); 1948 seq = l2cap_seq_list_pop(&chan->retrans_list);
1807 1949
@@ -2144,7 +2286,9 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan,
2144 /* PDU size is derived from the HCI MTU */ 2286 /* PDU size is derived from the HCI MTU */
2145 pdu_len = chan->conn->mtu; 2287 pdu_len = chan->conn->mtu;
2146 2288
2147 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD); 2289 /* Constrain PDU size for BR/EDR connections */
2290 if (!chan->hs_hcon)
2291 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2148 2292
2149 /* Adjust for largest possible L2CAP overhead. */ 2293 /* Adjust for largest possible L2CAP overhead. */
2150 if (chan->fcs) 2294 if (chan->fcs)
@@ -2788,6 +2932,11 @@ int l2cap_ertm_init(struct l2cap_chan *chan)
2788 2932
2789 skb_queue_head_init(&chan->tx_q); 2933 skb_queue_head_init(&chan->tx_q);
2790 2934
2935 chan->local_amp_id = 0;
2936 chan->move_id = 0;
2937 chan->move_state = L2CAP_MOVE_STABLE;
2938 chan->move_role = L2CAP_MOVE_ROLE_NONE;
2939
2791 if (chan->mode != L2CAP_MODE_ERTM) 2940 if (chan->mode != L2CAP_MODE_ERTM)
2792 return 0; 2941 return 0;
2793 2942
@@ -2834,6 +2983,44 @@ static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2834 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW; 2983 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2835} 2984}
2836 2985
2986static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
2987 struct l2cap_conf_rfc *rfc)
2988{
2989 if (chan->local_amp_id && chan->hs_hcon) {
2990 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
2991
2992 /* Class 1 devices have must have ERTM timeouts
2993 * exceeding the Link Supervision Timeout. The
2994 * default Link Supervision Timeout for AMP
2995 * controllers is 10 seconds.
2996 *
2997 * Class 1 devices use 0xffffffff for their
2998 * best-effort flush timeout, so the clamping logic
2999 * will result in a timeout that meets the above
3000 * requirement. ERTM timeouts are 16-bit values, so
3001 * the maximum timeout is 65.535 seconds.
3002 */
3003
3004 /* Convert timeout to milliseconds and round */
3005 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3006
3007 /* This is the recommended formula for class 2 devices
3008 * that start ERTM timers when packets are sent to the
3009 * controller.
3010 */
3011 ertm_to = 3 * ertm_to + 500;
3012
3013 if (ertm_to > 0xffff)
3014 ertm_to = 0xffff;
3015
3016 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3017 rfc->monitor_timeout = rfc->retrans_timeout;
3018 } else {
3019 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3020 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3021 }
3022}
3023
2837static inline void l2cap_txwin_setup(struct l2cap_chan *chan) 3024static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2838{ 3025{
2839 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && 3026 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
@@ -2900,8 +3087,8 @@ done:
2900 case L2CAP_MODE_ERTM: 3087 case L2CAP_MODE_ERTM:
2901 rfc.mode = L2CAP_MODE_ERTM; 3088 rfc.mode = L2CAP_MODE_ERTM;
2902 rfc.max_transmit = chan->max_tx; 3089 rfc.max_transmit = chan->max_tx;
2903 rfc.retrans_timeout = 0; 3090
2904 rfc.monitor_timeout = 0; 3091 __l2cap_set_ertm_timeouts(chan, &rfc);
2905 3092
2906 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - 3093 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2907 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE - 3094 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
@@ -3129,10 +3316,7 @@ done:
3129 rfc.max_pdu_size = cpu_to_le16(size); 3316 rfc.max_pdu_size = cpu_to_le16(size);
3130 chan->remote_mps = size; 3317 chan->remote_mps = size;
3131 3318
3132 rfc.retrans_timeout = 3319 __l2cap_set_ertm_timeouts(chan, &rfc);
3133 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3134 rfc.monitor_timeout =
3135 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3136 3320
3137 set_bit(CONF_MODE_DONE, &chan->conf_state); 3321 set_bit(CONF_MODE_DONE, &chan->conf_state);
3138 3322
@@ -3308,12 +3492,21 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
3308 struct l2cap_conn_rsp rsp; 3492 struct l2cap_conn_rsp rsp;
3309 struct l2cap_conn *conn = chan->conn; 3493 struct l2cap_conn *conn = chan->conn;
3310 u8 buf[128]; 3494 u8 buf[128];
3495 u8 rsp_code;
3311 3496
3312 rsp.scid = cpu_to_le16(chan->dcid); 3497 rsp.scid = cpu_to_le16(chan->dcid);
3313 rsp.dcid = cpu_to_le16(chan->scid); 3498 rsp.dcid = cpu_to_le16(chan->scid);
3314 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); 3499 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3315 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); 3500 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
3316 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); 3501
3502 if (chan->hs_hcon)
3503 rsp_code = L2CAP_CREATE_CHAN_RSP;
3504 else
3505 rsp_code = L2CAP_CONN_RSP;
3506
3507 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3508
3509 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
3317 3510
3318 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) 3511 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
3319 return; 3512 return;
@@ -3395,8 +3588,9 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn,
3395 return 0; 3588 return 0;
3396} 3589}
3397 3590
3398static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, 3591static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3399 u8 *data, u8 rsp_code, u8 amp_id) 3592 struct l2cap_cmd_hdr *cmd,
3593 u8 *data, u8 rsp_code, u8 amp_id)
3400{ 3594{
3401 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; 3595 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3402 struct l2cap_conn_rsp rsp; 3596 struct l2cap_conn_rsp rsp;
@@ -3447,6 +3641,7 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
3447 bacpy(&bt_sk(sk)->dst, conn->dst); 3641 bacpy(&bt_sk(sk)->dst, conn->dst);
3448 chan->psm = psm; 3642 chan->psm = psm;
3449 chan->dcid = scid; 3643 chan->dcid = scid;
3644 chan->local_amp_id = amp_id;
3450 3645
3451 __l2cap_chan_add(conn, chan); 3646 __l2cap_chan_add(conn, chan);
3452 3647
@@ -3464,8 +3659,17 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
3464 status = L2CAP_CS_AUTHOR_PEND; 3659 status = L2CAP_CS_AUTHOR_PEND;
3465 chan->ops->defer(chan); 3660 chan->ops->defer(chan);
3466 } else { 3661 } else {
3467 __l2cap_state_change(chan, BT_CONFIG); 3662 /* Force pending result for AMP controllers.
3468 result = L2CAP_CR_SUCCESS; 3663 * The connection will succeed after the
3664 * physical link is up.
3665 */
3666 if (amp_id) {
3667 __l2cap_state_change(chan, BT_CONNECT2);
3668 result = L2CAP_CR_PEND;
3669 } else {
3670 __l2cap_state_change(chan, BT_CONFIG);
3671 result = L2CAP_CR_SUCCESS;
3672 }
3469 status = L2CAP_CS_NO_INFO; 3673 status = L2CAP_CS_NO_INFO;
3470 } 3674 }
3471 } else { 3675 } else {
@@ -3511,6 +3715,8 @@ sendresp:
3511 l2cap_build_conf_req(chan, buf), buf); 3715 l2cap_build_conf_req(chan, buf), buf);
3512 chan->num_conf_req++; 3716 chan->num_conf_req++;
3513 } 3717 }
3718
3719 return chan;
3514} 3720}
3515 3721
3516static int l2cap_connect_req(struct l2cap_conn *conn, 3722static int l2cap_connect_req(struct l2cap_conn *conn,
@@ -3520,7 +3726,7 @@ static int l2cap_connect_req(struct l2cap_conn *conn,
3520 return 0; 3726 return 0;
3521} 3727}
3522 3728
3523static inline int l2cap_connect_rsp(struct l2cap_conn *conn, 3729static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
3524 struct l2cap_cmd_hdr *cmd, u8 *data) 3730 struct l2cap_cmd_hdr *cmd, u8 *data)
3525{ 3731{
3526 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; 3732 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
@@ -3675,6 +3881,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
3675 goto unlock; 3881 goto unlock;
3676 } 3882 }
3677 3883
3884 chan->ident = cmd->ident;
3678 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); 3885 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
3679 chan->num_conf_rsp++; 3886 chan->num_conf_rsp++;
3680 3887
@@ -3714,7 +3921,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
3714 /* check compatibility */ 3921 /* check compatibility */
3715 3922
3716 /* Send rsp for BR/EDR channel */ 3923 /* Send rsp for BR/EDR channel */
3717 if (!chan->ctrl_id) 3924 if (!chan->hs_hcon)
3718 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags); 3925 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
3719 else 3926 else
3720 chan->ident = cmd->ident; 3927 chan->ident = cmd->ident;
@@ -3764,13 +3971,15 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3764 goto done; 3971 goto done;
3765 } 3972 }
3766 3973
3767 /* check compatibility */ 3974 if (!chan->hs_hcon) {
3768
3769 if (!chan->ctrl_id)
3770 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident, 3975 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
3771 0); 3976 0);
3772 else 3977 } else {
3773 chan->ident = cmd->ident; 3978 if (l2cap_check_efs(chan)) {
3979 amp_create_logical_link(chan);
3980 chan->ident = cmd->ident;
3981 }
3982 }
3774 } 3983 }
3775 goto done; 3984 goto done;
3776 3985
@@ -4023,12 +4232,14 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn,
4023 return 0; 4232 return 0;
4024} 4233}
4025 4234
4026static inline int l2cap_create_channel_req(struct l2cap_conn *conn, 4235static int l2cap_create_channel_req(struct l2cap_conn *conn,
4027 struct l2cap_cmd_hdr *cmd, 4236 struct l2cap_cmd_hdr *cmd,
4028 u16 cmd_len, void *data) 4237 u16 cmd_len, void *data)
4029{ 4238{
4030 struct l2cap_create_chan_req *req = data; 4239 struct l2cap_create_chan_req *req = data;
4031 struct l2cap_create_chan_rsp rsp; 4240 struct l2cap_create_chan_rsp rsp;
4241 struct l2cap_chan *chan;
4242 struct hci_dev *hdev;
4032 u16 psm, scid; 4243 u16 psm, scid;
4033 4244
4034 if (cmd_len != sizeof(*req)) 4245 if (cmd_len != sizeof(*req))
@@ -4042,57 +4253,119 @@ static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
4042 4253
4043 BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id); 4254 BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id);
4044 4255
4045 /* Placeholder: Always reject */ 4256 /* For controller id 0 make BR/EDR connection */
4257 if (req->amp_id == HCI_BREDR_ID) {
4258 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4259 req->amp_id);
4260 return 0;
4261 }
4262
4263 /* Validate AMP controller id */
4264 hdev = hci_dev_get(req->amp_id);
4265 if (!hdev)
4266 goto error;
4267
4268 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
4269 hci_dev_put(hdev);
4270 goto error;
4271 }
4272
4273 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4274 req->amp_id);
4275 if (chan) {
4276 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4277 struct hci_conn *hs_hcon;
4278
4279 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4280 if (!hs_hcon) {
4281 hci_dev_put(hdev);
4282 return -EFAULT;
4283 }
4284
4285 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4286
4287 mgr->bredr_chan = chan;
4288 chan->hs_hcon = hs_hcon;
4289 chan->fcs = L2CAP_FCS_NONE;
4290 conn->mtu = hdev->block_mtu;
4291 }
4292
4293 hci_dev_put(hdev);
4294
4295 return 0;
4296
4297error:
4046 rsp.dcid = 0; 4298 rsp.dcid = 0;
4047 rsp.scid = cpu_to_le16(scid); 4299 rsp.scid = cpu_to_le16(scid);
4048 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM); 4300 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4049 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); 4301 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4050 4302
4051 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, 4303 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4052 sizeof(rsp), &rsp); 4304 sizeof(rsp), &rsp);
4053 4305
4054 return 0; 4306 return -EFAULT;
4055} 4307}
4056 4308
4057static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn, 4309static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4058 struct l2cap_cmd_hdr *cmd,
4059 void *data)
4060{ 4310{
4061 BT_DBG("conn %p", conn); 4311 struct l2cap_move_chan_req req;
4312 u8 ident;
4313
4314 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4315
4316 ident = l2cap_get_ident(chan->conn);
4317 chan->ident = ident;
4062 4318
4063 return l2cap_connect_rsp(conn, cmd, data); 4319 req.icid = cpu_to_le16(chan->scid);
4320 req.dest_amp_id = dest_amp_id;
4321
4322 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4323 &req);
4324
4325 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4064} 4326}
4065 4327
4066static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident, 4328static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
4067 u16 icid, u16 result)
4068{ 4329{
4069 struct l2cap_move_chan_rsp rsp; 4330 struct l2cap_move_chan_rsp rsp;
4070 4331
4071 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); 4332 BT_DBG("chan %p, result 0x%4.4x", chan, result);
4072 4333
4073 rsp.icid = cpu_to_le16(icid); 4334 rsp.icid = cpu_to_le16(chan->dcid);
4074 rsp.result = cpu_to_le16(result); 4335 rsp.result = cpu_to_le16(result);
4075 4336
4076 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp); 4337 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4338 sizeof(rsp), &rsp);
4077} 4339}
4078 4340
4079static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn, 4341static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
4080 struct l2cap_chan *chan,
4081 u16 icid, u16 result)
4082{ 4342{
4083 struct l2cap_move_chan_cfm cfm; 4343 struct l2cap_move_chan_cfm cfm;
4084 u8 ident;
4085 4344
4086 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); 4345 BT_DBG("chan %p, result 0x%4.4x", chan, result);
4087 4346
4088 ident = l2cap_get_ident(conn); 4347 chan->ident = l2cap_get_ident(chan->conn);
4089 if (chan)
4090 chan->ident = ident;
4091 4348
4092 cfm.icid = cpu_to_le16(icid); 4349 cfm.icid = cpu_to_le16(chan->scid);
4093 cfm.result = cpu_to_le16(result); 4350 cfm.result = cpu_to_le16(result);
4094 4351
4095 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm); 4352 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4353 sizeof(cfm), &cfm);
4354
4355 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4356}
4357
4358static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4359{
4360 struct l2cap_move_chan_cfm cfm;
4361
4362 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4363
4364 cfm.icid = cpu_to_le16(icid);
4365 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4366
4367 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4368 sizeof(cfm), &cfm);
4096} 4369}
4097 4370
4098static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident, 4371static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
@@ -4106,11 +4379,289 @@ static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
4106 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp); 4379 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4107} 4380}
4108 4381
4382static void __release_logical_link(struct l2cap_chan *chan)
4383{
4384 chan->hs_hchan = NULL;
4385 chan->hs_hcon = NULL;
4386
4387 /* Placeholder - release the logical link */
4388}
4389
4390static void l2cap_logical_fail(struct l2cap_chan *chan)
4391{
4392 /* Logical link setup failed */
4393 if (chan->state != BT_CONNECTED) {
4394 /* Create channel failure, disconnect */
4395 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4396 return;
4397 }
4398
4399 switch (chan->move_role) {
4400 case L2CAP_MOVE_ROLE_RESPONDER:
4401 l2cap_move_done(chan);
4402 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4403 break;
4404 case L2CAP_MOVE_ROLE_INITIATOR:
4405 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4406 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4407 /* Remote has only sent pending or
4408 * success responses, clean up
4409 */
4410 l2cap_move_done(chan);
4411 }
4412
4413 /* Other amp move states imply that the move
4414 * has already aborted
4415 */
4416 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4417 break;
4418 }
4419}
4420
4421static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4422 struct hci_chan *hchan)
4423{
4424 struct l2cap_conf_rsp rsp;
4425
4426 chan->hs_hchan = hchan;
4427 chan->hs_hcon->l2cap_data = chan->conn;
4428
4429 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
4430
4431 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
4432 int err;
4433
4434 set_default_fcs(chan);
4435
4436 err = l2cap_ertm_init(chan);
4437 if (err < 0)
4438 l2cap_send_disconn_req(chan->conn, chan, -err);
4439 else
4440 l2cap_chan_ready(chan);
4441 }
4442}
4443
4444static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4445 struct hci_chan *hchan)
4446{
4447 chan->hs_hcon = hchan->conn;
4448 chan->hs_hcon->l2cap_data = chan->conn;
4449
4450 BT_DBG("move_state %d", chan->move_state);
4451
4452 switch (chan->move_state) {
4453 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4454 /* Move confirm will be sent after a success
4455 * response is received
4456 */
4457 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4458 break;
4459 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4460 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4461 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4462 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4463 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4464 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4465 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4466 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4467 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4468 }
4469 break;
4470 default:
4471 /* Move was not in expected state, free the channel */
4472 __release_logical_link(chan);
4473
4474 chan->move_state = L2CAP_MOVE_STABLE;
4475 }
4476}
4477
4478/* Call with chan locked */
4479void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4480 u8 status)
4481{
4482 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4483
4484 if (status) {
4485 l2cap_logical_fail(chan);
4486 __release_logical_link(chan);
4487 return;
4488 }
4489
4490 if (chan->state != BT_CONNECTED) {
4491 /* Ignore logical link if channel is on BR/EDR */
4492 if (chan->local_amp_id)
4493 l2cap_logical_finish_create(chan, hchan);
4494 } else {
4495 l2cap_logical_finish_move(chan, hchan);
4496 }
4497}
4498
4499void l2cap_move_start(struct l2cap_chan *chan)
4500{
4501 BT_DBG("chan %p", chan);
4502
4503 if (chan->local_amp_id == HCI_BREDR_ID) {
4504 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4505 return;
4506 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4507 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4508 /* Placeholder - start physical link setup */
4509 } else {
4510 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4511 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4512 chan->move_id = 0;
4513 l2cap_move_setup(chan);
4514 l2cap_send_move_chan_req(chan, 0);
4515 }
4516}
4517
4518static void l2cap_do_create(struct l2cap_chan *chan, int result,
4519 u8 local_amp_id, u8 remote_amp_id)
4520{
4521 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4522 local_amp_id, remote_amp_id);
4523
4524 chan->fcs = L2CAP_FCS_NONE;
4525
4526 /* Outgoing channel on AMP */
4527 if (chan->state == BT_CONNECT) {
4528 if (result == L2CAP_CR_SUCCESS) {
4529 chan->local_amp_id = local_amp_id;
4530 l2cap_send_create_chan_req(chan, remote_amp_id);
4531 } else {
4532 /* Revert to BR/EDR connect */
4533 l2cap_send_conn_req(chan);
4534 }
4535
4536 return;
4537 }
4538
4539 /* Incoming channel on AMP */
4540 if (__l2cap_no_conn_pending(chan)) {
4541 struct l2cap_conn_rsp rsp;
4542 char buf[128];
4543 rsp.scid = cpu_to_le16(chan->dcid);
4544 rsp.dcid = cpu_to_le16(chan->scid);
4545
4546 if (result == L2CAP_CR_SUCCESS) {
4547 /* Send successful response */
4548 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4549 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4550 } else {
4551 /* Send negative response */
4552 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4553 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4554 }
4555
4556 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4557 sizeof(rsp), &rsp);
4558
4559 if (result == L2CAP_CR_SUCCESS) {
4560 __l2cap_state_change(chan, BT_CONFIG);
4561 set_bit(CONF_REQ_SENT, &chan->conf_state);
4562 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4563 L2CAP_CONF_REQ,
4564 l2cap_build_conf_req(chan, buf), buf);
4565 chan->num_conf_req++;
4566 }
4567 }
4568}
4569
4570static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4571 u8 remote_amp_id)
4572{
4573 l2cap_move_setup(chan);
4574 chan->move_id = local_amp_id;
4575 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4576
4577 l2cap_send_move_chan_req(chan, remote_amp_id);
4578}
4579
4580static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4581{
4582 struct hci_chan *hchan = NULL;
4583
4584 /* Placeholder - get hci_chan for logical link */
4585
4586 if (hchan) {
4587 if (hchan->state == BT_CONNECTED) {
4588 /* Logical link is ready to go */
4589 chan->hs_hcon = hchan->conn;
4590 chan->hs_hcon->l2cap_data = chan->conn;
4591 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4592 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4593
4594 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4595 } else {
4596 /* Wait for logical link to be ready */
4597 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4598 }
4599 } else {
4600 /* Logical link not available */
4601 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4602 }
4603}
4604
4605static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4606{
4607 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4608 u8 rsp_result;
4609 if (result == -EINVAL)
4610 rsp_result = L2CAP_MR_BAD_ID;
4611 else
4612 rsp_result = L2CAP_MR_NOT_ALLOWED;
4613
4614 l2cap_send_move_chan_rsp(chan, rsp_result);
4615 }
4616
4617 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4618 chan->move_state = L2CAP_MOVE_STABLE;
4619
4620 /* Restart data transmission */
4621 l2cap_ertm_send(chan);
4622}
4623
4624/* Invoke with locked chan */
4625void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
4626{
4627 u8 local_amp_id = chan->local_amp_id;
4628 u8 remote_amp_id = chan->remote_amp_id;
4629
4630 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4631 chan, result, local_amp_id, remote_amp_id);
4632
4633 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4634 l2cap_chan_unlock(chan);
4635 return;
4636 }
4637
4638 if (chan->state != BT_CONNECTED) {
4639 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4640 } else if (result != L2CAP_MR_SUCCESS) {
4641 l2cap_do_move_cancel(chan, result);
4642 } else {
4643 switch (chan->move_role) {
4644 case L2CAP_MOVE_ROLE_INITIATOR:
4645 l2cap_do_move_initiate(chan, local_amp_id,
4646 remote_amp_id);
4647 break;
4648 case L2CAP_MOVE_ROLE_RESPONDER:
4649 l2cap_do_move_respond(chan, result);
4650 break;
4651 default:
4652 l2cap_do_move_cancel(chan, result);
4653 break;
4654 }
4655 }
4656}
4657
4109static inline int l2cap_move_channel_req(struct l2cap_conn *conn, 4658static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
4110 struct l2cap_cmd_hdr *cmd, 4659 struct l2cap_cmd_hdr *cmd,
4111 u16 cmd_len, void *data) 4660 u16 cmd_len, void *data)
4112{ 4661{
4113 struct l2cap_move_chan_req *req = data; 4662 struct l2cap_move_chan_req *req = data;
4663 struct l2cap_move_chan_rsp rsp;
4664 struct l2cap_chan *chan;
4114 u16 icid = 0; 4665 u16 icid = 0;
4115 u16 result = L2CAP_MR_NOT_ALLOWED; 4666 u16 result = L2CAP_MR_NOT_ALLOWED;
4116 4667
@@ -4124,15 +4675,206 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
4124 if (!enable_hs) 4675 if (!enable_hs)
4125 return -EINVAL; 4676 return -EINVAL;
4126 4677
4127 /* Placeholder: Always refuse */ 4678 chan = l2cap_get_chan_by_dcid(conn, icid);
4128 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result); 4679 if (!chan) {
4680 rsp.icid = cpu_to_le16(icid);
4681 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4682 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4683 sizeof(rsp), &rsp);
4684 return 0;
4685 }
4686
4687 chan->ident = cmd->ident;
4688
4689 if (chan->scid < L2CAP_CID_DYN_START ||
4690 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4691 (chan->mode != L2CAP_MODE_ERTM &&
4692 chan->mode != L2CAP_MODE_STREAMING)) {
4693 result = L2CAP_MR_NOT_ALLOWED;
4694 goto send_move_response;
4695 }
4696
4697 if (chan->local_amp_id == req->dest_amp_id) {
4698 result = L2CAP_MR_SAME_ID;
4699 goto send_move_response;
4700 }
4701
4702 if (req->dest_amp_id) {
4703 struct hci_dev *hdev;
4704 hdev = hci_dev_get(req->dest_amp_id);
4705 if (!hdev || hdev->dev_type != HCI_AMP ||
4706 !test_bit(HCI_UP, &hdev->flags)) {
4707 if (hdev)
4708 hci_dev_put(hdev);
4709
4710 result = L2CAP_MR_BAD_ID;
4711 goto send_move_response;
4712 }
4713 hci_dev_put(hdev);
4714 }
4715
4716 /* Detect a move collision. Only send a collision response
4717 * if this side has "lost", otherwise proceed with the move.
4718 * The winner has the larger bd_addr.
4719 */
4720 if ((__chan_is_moving(chan) ||
4721 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4722 bacmp(conn->src, conn->dst) > 0) {
4723 result = L2CAP_MR_COLLISION;
4724 goto send_move_response;
4725 }
4726
4727 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4728 l2cap_move_setup(chan);
4729 chan->move_id = req->dest_amp_id;
4730 icid = chan->dcid;
4731
4732 if (!req->dest_amp_id) {
4733 /* Moving to BR/EDR */
4734 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4735 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4736 result = L2CAP_MR_PEND;
4737 } else {
4738 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4739 result = L2CAP_MR_SUCCESS;
4740 }
4741 } else {
4742 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4743 /* Placeholder - uncomment when amp functions are available */
4744 /*amp_accept_physical(chan, req->dest_amp_id);*/
4745 result = L2CAP_MR_PEND;
4746 }
4747
4748send_move_response:
4749 l2cap_send_move_chan_rsp(chan, result);
4750
4751 l2cap_chan_unlock(chan);
4129 4752
4130 return 0; 4753 return 0;
4131} 4754}
4132 4755
4133static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn, 4756static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4134 struct l2cap_cmd_hdr *cmd, 4757{
4135 u16 cmd_len, void *data) 4758 struct l2cap_chan *chan;
4759 struct hci_chan *hchan = NULL;
4760
4761 chan = l2cap_get_chan_by_scid(conn, icid);
4762 if (!chan) {
4763 l2cap_send_move_chan_cfm_icid(conn, icid);
4764 return;
4765 }
4766
4767 __clear_chan_timer(chan);
4768 if (result == L2CAP_MR_PEND)
4769 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4770
4771 switch (chan->move_state) {
4772 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4773 /* Move confirm will be sent when logical link
4774 * is complete.
4775 */
4776 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4777 break;
4778 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4779 if (result == L2CAP_MR_PEND) {
4780 break;
4781 } else if (test_bit(CONN_LOCAL_BUSY,
4782 &chan->conn_state)) {
4783 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4784 } else {
4785 /* Logical link is up or moving to BR/EDR,
4786 * proceed with move
4787 */
4788 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4789 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4790 }
4791 break;
4792 case L2CAP_MOVE_WAIT_RSP:
4793 /* Moving to AMP */
4794 if (result == L2CAP_MR_SUCCESS) {
4795 /* Remote is ready, send confirm immediately
4796 * after logical link is ready
4797 */
4798 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4799 } else {
4800 /* Both logical link and move success
4801 * are required to confirm
4802 */
4803 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4804 }
4805
4806 /* Placeholder - get hci_chan for logical link */
4807 if (!hchan) {
4808 /* Logical link not available */
4809 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4810 break;
4811 }
4812
4813 /* If the logical link is not yet connected, do not
4814 * send confirmation.
4815 */
4816 if (hchan->state != BT_CONNECTED)
4817 break;
4818
4819 /* Logical link is already ready to go */
4820
4821 chan->hs_hcon = hchan->conn;
4822 chan->hs_hcon->l2cap_data = chan->conn;
4823
4824 if (result == L2CAP_MR_SUCCESS) {
4825 /* Can confirm now */
4826 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4827 } else {
4828 /* Now only need move success
4829 * to confirm
4830 */
4831 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4832 }
4833
4834 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4835 break;
4836 default:
4837 /* Any other amp move state means the move failed. */
4838 chan->move_id = chan->local_amp_id;
4839 l2cap_move_done(chan);
4840 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4841 }
4842
4843 l2cap_chan_unlock(chan);
4844}
4845
4846static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
4847 u16 result)
4848{
4849 struct l2cap_chan *chan;
4850
4851 chan = l2cap_get_chan_by_ident(conn, ident);
4852 if (!chan) {
4853 /* Could not locate channel, icid is best guess */
4854 l2cap_send_move_chan_cfm_icid(conn, icid);
4855 return;
4856 }
4857
4858 __clear_chan_timer(chan);
4859
4860 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4861 if (result == L2CAP_MR_COLLISION) {
4862 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4863 } else {
4864 /* Cleanup - cancel move */
4865 chan->move_id = chan->local_amp_id;
4866 l2cap_move_done(chan);
4867 }
4868 }
4869
4870 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4871
4872 l2cap_chan_unlock(chan);
4873}
4874
4875static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4876 struct l2cap_cmd_hdr *cmd,
4877 u16 cmd_len, void *data)
4136{ 4878{
4137 struct l2cap_move_chan_rsp *rsp = data; 4879 struct l2cap_move_chan_rsp *rsp = data;
4138 u16 icid, result; 4880 u16 icid, result;
@@ -4145,17 +4887,20 @@ static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4145 4887
4146 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); 4888 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
4147 4889
4148 /* Placeholder: Always unconfirmed */ 4890 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
4149 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED); 4891 l2cap_move_continue(conn, icid, result);
4892 else
4893 l2cap_move_fail(conn, cmd->ident, icid, result);
4150 4894
4151 return 0; 4895 return 0;
4152} 4896}
4153 4897
4154static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn, 4898static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4155 struct l2cap_cmd_hdr *cmd, 4899 struct l2cap_cmd_hdr *cmd,
4156 u16 cmd_len, void *data) 4900 u16 cmd_len, void *data)
4157{ 4901{
4158 struct l2cap_move_chan_cfm *cfm = data; 4902 struct l2cap_move_chan_cfm *cfm = data;
4903 struct l2cap_chan *chan;
4159 u16 icid, result; 4904 u16 icid, result;
4160 4905
4161 if (cmd_len != sizeof(*cfm)) 4906 if (cmd_len != sizeof(*cfm))
@@ -4166,8 +4911,29 @@ static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4166 4911
4167 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); 4912 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
4168 4913
4914 chan = l2cap_get_chan_by_dcid(conn, icid);
4915 if (!chan) {
4916 /* Spec requires a response even if the icid was not found */
4917 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4918 return 0;
4919 }
4920
4921 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
4922 if (result == L2CAP_MC_CONFIRMED) {
4923 chan->local_amp_id = chan->move_id;
4924 if (!chan->local_amp_id)
4925 __release_logical_link(chan);
4926 } else {
4927 chan->move_id = chan->local_amp_id;
4928 }
4929
4930 l2cap_move_done(chan);
4931 }
4932
4169 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); 4933 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4170 4934
4935 l2cap_chan_unlock(chan);
4936
4171 return 0; 4937 return 0;
4172} 4938}
4173 4939
@@ -4176,6 +4942,7 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
4176 u16 cmd_len, void *data) 4942 u16 cmd_len, void *data)
4177{ 4943{
4178 struct l2cap_move_chan_cfm_rsp *rsp = data; 4944 struct l2cap_move_chan_cfm_rsp *rsp = data;
4945 struct l2cap_chan *chan;
4179 u16 icid; 4946 u16 icid;
4180 4947
4181 if (cmd_len != sizeof(*rsp)) 4948 if (cmd_len != sizeof(*rsp))
@@ -4185,6 +4952,23 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
4185 4952
4186 BT_DBG("icid 0x%4.4x", icid); 4953 BT_DBG("icid 0x%4.4x", icid);
4187 4954
4955 chan = l2cap_get_chan_by_scid(conn, icid);
4956 if (!chan)
4957 return 0;
4958
4959 __clear_chan_timer(chan);
4960
4961 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
4962 chan->local_amp_id = chan->move_id;
4963
4964 if (!chan->local_amp_id && chan->hs_hchan)
4965 __release_logical_link(chan);
4966
4967 l2cap_move_done(chan);
4968 }
4969
4970 l2cap_chan_unlock(chan);
4971
4188 return 0; 4972 return 0;
4189} 4973}
4190 4974
@@ -4269,7 +5053,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4269 5053
4270 case L2CAP_CONN_RSP: 5054 case L2CAP_CONN_RSP:
4271 case L2CAP_CREATE_CHAN_RSP: 5055 case L2CAP_CREATE_CHAN_RSP:
4272 err = l2cap_connect_rsp(conn, cmd, data); 5056 err = l2cap_connect_create_rsp(conn, cmd, data);
4273 break; 5057 break;
4274 5058
4275 case L2CAP_CONF_REQ: 5059 case L2CAP_CONF_REQ:
@@ -4556,6 +5340,12 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4556 return err; 5340 return err;
4557} 5341}
4558 5342
5343static int l2cap_resegment(struct l2cap_chan *chan)
5344{
5345 /* Placeholder */
5346 return 0;
5347}
5348
4559void l2cap_chan_busy(struct l2cap_chan *chan, int busy) 5349void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
4560{ 5350{
4561 u8 event; 5351 u8 event;
@@ -4871,8 +5661,8 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4871 if (control->final) { 5661 if (control->final) {
4872 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); 5662 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4873 5663
4874 if (!test_and_clear_bit(CONN_REJ_ACT, 5664 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
4875 &chan->conn_state)) { 5665 !__chan_is_moving(chan)) {
4876 control->final = 0; 5666 control->final = 0;
4877 l2cap_retransmit_all(chan, control); 5667 l2cap_retransmit_all(chan, control);
4878 } 5668 }
@@ -5061,6 +5851,96 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5061 return err; 5851 return err;
5062} 5852}
5063 5853
5854static int l2cap_finish_move(struct l2cap_chan *chan)
5855{
5856 BT_DBG("chan %p", chan);
5857
5858 chan->rx_state = L2CAP_RX_STATE_RECV;
5859
5860 if (chan->hs_hcon)
5861 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5862 else
5863 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5864
5865 return l2cap_resegment(chan);
5866}
5867
5868static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
5869 struct l2cap_ctrl *control,
5870 struct sk_buff *skb, u8 event)
5871{
5872 int err;
5873
5874 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5875 event);
5876
5877 if (!control->poll)
5878 return -EPROTO;
5879
5880 l2cap_process_reqseq(chan, control->reqseq);
5881
5882 if (!skb_queue_empty(&chan->tx_q))
5883 chan->tx_send_head = skb_peek(&chan->tx_q);
5884 else
5885 chan->tx_send_head = NULL;
5886
5887 /* Rewind next_tx_seq to the point expected
5888 * by the receiver.
5889 */
5890 chan->next_tx_seq = control->reqseq;
5891 chan->unacked_frames = 0;
5892
5893 err = l2cap_finish_move(chan);
5894 if (err)
5895 return err;
5896
5897 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5898 l2cap_send_i_or_rr_or_rnr(chan);
5899
5900 if (event == L2CAP_EV_RECV_IFRAME)
5901 return -EPROTO;
5902
5903 return l2cap_rx_state_recv(chan, control, NULL, event);
5904}
5905
5906static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
5907 struct l2cap_ctrl *control,
5908 struct sk_buff *skb, u8 event)
5909{
5910 int err;
5911
5912 if (!control->final)
5913 return -EPROTO;
5914
5915 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5916
5917 chan->rx_state = L2CAP_RX_STATE_RECV;
5918 l2cap_process_reqseq(chan, control->reqseq);
5919
5920 if (!skb_queue_empty(&chan->tx_q))
5921 chan->tx_send_head = skb_peek(&chan->tx_q);
5922 else
5923 chan->tx_send_head = NULL;
5924
5925 /* Rewind next_tx_seq to the point expected
5926 * by the receiver.
5927 */
5928 chan->next_tx_seq = control->reqseq;
5929 chan->unacked_frames = 0;
5930
5931 if (chan->hs_hcon)
5932 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5933 else
5934 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5935
5936 err = l2cap_resegment(chan);
5937
5938 if (!err)
5939 err = l2cap_rx_state_recv(chan, control, skb, event);
5940
5941 return err;
5942}
5943
5064static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq) 5944static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5065{ 5945{
5066 /* Make sure reqseq is for a packet that has been sent but not acked */ 5946 /* Make sure reqseq is for a packet that has been sent but not acked */
@@ -5087,6 +5967,12 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5087 err = l2cap_rx_state_srej_sent(chan, control, skb, 5967 err = l2cap_rx_state_srej_sent(chan, control, skb,
5088 event); 5968 event);
5089 break; 5969 break;
5970 case L2CAP_RX_STATE_WAIT_P:
5971 err = l2cap_rx_state_wait_p(chan, control, skb, event);
5972 break;
5973 case L2CAP_RX_STATE_WAIT_F:
5974 err = l2cap_rx_state_wait_f(chan, control, skb, event);
5975 break;
5090 default: 5976 default:
5091 /* shut it down */ 5977 /* shut it down */
5092 break; 5978 break;
@@ -5206,7 +6092,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5206 control->super); 6092 control->super);
5207 6093
5208 if (len != 0) { 6094 if (len != 0) {
5209 BT_ERR("%d", len); 6095 BT_ERR("Trailing bytes: %d in sframe", len);
5210 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 6096 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5211 goto drop; 6097 goto drop;
5212 } 6098 }
@@ -5422,9 +6308,9 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
5422 conn = l2cap_conn_add(hcon, status); 6308 conn = l2cap_conn_add(hcon, status);
5423 if (conn) 6309 if (conn)
5424 l2cap_conn_ready(conn); 6310 l2cap_conn_ready(conn);
5425 } else 6311 } else {
5426 l2cap_conn_del(hcon, bt_to_errno(status)); 6312 l2cap_conn_del(hcon, bt_to_errno(status));
5427 6313 }
5428} 6314}
5429 6315
5430int l2cap_disconn_ind(struct hci_conn *hcon) 6316int l2cap_disconn_ind(struct hci_conn *hcon)
@@ -5500,7 +6386,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
5500 continue; 6386 continue;
5501 } 6387 }
5502 6388
5503 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) { 6389 if (!__l2cap_no_conn_pending(chan)) {
5504 l2cap_chan_unlock(chan); 6390 l2cap_chan_unlock(chan);
5505 continue; 6391 continue;
5506 } 6392 }
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 89f1472939e..1bcfb8422fd 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -736,6 +736,11 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
736 } 736 }
737 737
738 chan->chan_policy = (u8) opt; 738 chan->chan_policy = (u8) opt;
739
740 if (sk->sk_state == BT_CONNECTED &&
741 chan->move_role == L2CAP_MOVE_ROLE_NONE)
742 l2cap_move_start(chan);
743
739 break; 744 break;
740 745
741 default: 746 default:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 158a87bb0c0..142764aec2a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -222,7 +222,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
222 222
223 hdr = (void *) skb_put(skb, sizeof(*hdr)); 223 hdr = (void *) skb_put(skb, sizeof(*hdr));
224 224
225 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); 225 hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_STATUS);
226 hdr->index = cpu_to_le16(index); 226 hdr->index = cpu_to_le16(index);
227 hdr->len = cpu_to_le16(sizeof(*ev)); 227 hdr->len = cpu_to_le16(sizeof(*ev));
228 228
@@ -253,7 +253,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
253 253
254 hdr = (void *) skb_put(skb, sizeof(*hdr)); 254 hdr = (void *) skb_put(skb, sizeof(*hdr));
255 255
256 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); 256 hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_COMPLETE);
257 hdr->index = cpu_to_le16(index); 257 hdr->index = cpu_to_le16(index);
258 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); 258 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
259 259
@@ -377,15 +377,15 @@ static u32 get_supported_settings(struct hci_dev *hdev)
377 u32 settings = 0; 377 u32 settings = 0;
378 378
379 settings |= MGMT_SETTING_POWERED; 379 settings |= MGMT_SETTING_POWERED;
380 settings |= MGMT_SETTING_CONNECTABLE;
381 settings |= MGMT_SETTING_FAST_CONNECTABLE;
382 settings |= MGMT_SETTING_DISCOVERABLE;
383 settings |= MGMT_SETTING_PAIRABLE; 380 settings |= MGMT_SETTING_PAIRABLE;
384 381
385 if (lmp_ssp_capable(hdev)) 382 if (lmp_ssp_capable(hdev))
386 settings |= MGMT_SETTING_SSP; 383 settings |= MGMT_SETTING_SSP;
387 384
388 if (lmp_bredr_capable(hdev)) { 385 if (lmp_bredr_capable(hdev)) {
386 settings |= MGMT_SETTING_CONNECTABLE;
387 settings |= MGMT_SETTING_FAST_CONNECTABLE;
388 settings |= MGMT_SETTING_DISCOVERABLE;
389 settings |= MGMT_SETTING_BREDR; 389 settings |= MGMT_SETTING_BREDR;
390 settings |= MGMT_SETTING_LINK_SECURITY; 390 settings |= MGMT_SETTING_LINK_SECURITY;
391 } 391 }
@@ -485,7 +485,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data)
485 ptr += (name_len + 2); 485 ptr += (name_len + 2);
486 } 486 }
487 487
488 if (hdev->inq_tx_power) { 488 if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) {
489 ptr[0] = 2; 489 ptr[0] = 2;
490 ptr[1] = EIR_TX_POWER; 490 ptr[1] = EIR_TX_POWER;
491 ptr[2] = (u8) hdev->inq_tx_power; 491 ptr[2] = (u8) hdev->inq_tx_power;
@@ -566,7 +566,7 @@ static int update_eir(struct hci_dev *hdev)
566 if (!hdev_is_powered(hdev)) 566 if (!hdev_is_powered(hdev))
567 return 0; 567 return 0;
568 568
569 if (!(hdev->features[6] & LMP_EXT_INQ)) 569 if (!lmp_ext_inq_capable(hdev))
570 return 0; 570 return 0;
571 571
572 if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) 572 if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
@@ -833,7 +833,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len,
833 if (hdev) 833 if (hdev)
834 hdr->index = cpu_to_le16(hdev->id); 834 hdr->index = cpu_to_le16(hdev->id);
835 else 835 else
836 hdr->index = cpu_to_le16(MGMT_INDEX_NONE); 836 hdr->index = __constant_cpu_to_le16(MGMT_INDEX_NONE);
837 hdr->len = cpu_to_le16(data_len); 837 hdr->len = cpu_to_le16(data_len);
838 838
839 if (data) 839 if (data)
@@ -868,6 +868,10 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
868 868
869 BT_DBG("request for %s", hdev->name); 869 BT_DBG("request for %s", hdev->name);
870 870
871 if (!lmp_bredr_capable(hdev))
872 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
873 MGMT_STATUS_NOT_SUPPORTED);
874
871 timeout = __le16_to_cpu(cp->timeout); 875 timeout = __le16_to_cpu(cp->timeout);
872 if (!cp->val && timeout > 0) 876 if (!cp->val && timeout > 0)
873 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, 877 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
@@ -963,6 +967,10 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
963 967
964 BT_DBG("request for %s", hdev->name); 968 BT_DBG("request for %s", hdev->name);
965 969
970 if (!lmp_bredr_capable(hdev))
971 return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
972 MGMT_STATUS_NOT_SUPPORTED);
973
966 hci_dev_lock(hdev); 974 hci_dev_lock(hdev);
967 975
968 if (!hdev_is_powered(hdev)) { 976 if (!hdev_is_powered(hdev)) {
@@ -1061,6 +1069,10 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data,
1061 1069
1062 BT_DBG("request for %s", hdev->name); 1070 BT_DBG("request for %s", hdev->name);
1063 1071
1072 if (!lmp_bredr_capable(hdev))
1073 return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
1074 MGMT_STATUS_NOT_SUPPORTED);
1075
1064 hci_dev_lock(hdev); 1076 hci_dev_lock(hdev);
1065 1077
1066 if (!hdev_is_powered(hdev)) { 1078 if (!hdev_is_powered(hdev)) {
@@ -1214,7 +1226,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1214 } 1226 }
1215 1227
1216 val = !!cp->val; 1228 val = !!cp->val;
1217 enabled = !!(hdev->host_features[0] & LMP_HOST_LE); 1229 enabled = !!lmp_host_le_capable(hdev);
1218 1230
1219 if (!hdev_is_powered(hdev) || val == enabled) { 1231 if (!hdev_is_powered(hdev) || val == enabled) {
1220 bool changed = false; 1232 bool changed = false;
@@ -1250,7 +1262,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1250 1262
1251 if (val) { 1263 if (val) {
1252 hci_cp.le = val; 1264 hci_cp.le = val;
1253 hci_cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); 1265 hci_cp.simul = !!lmp_le_br_capable(hdev);
1254 } 1266 }
1255 1267
1256 err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp), 1268 err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp),
@@ -2596,6 +2608,10 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
2596 2608
2597 BT_DBG("%s", hdev->name); 2609 BT_DBG("%s", hdev->name);
2598 2610
2611 if (!lmp_bredr_capable(hdev))
2612 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2613 MGMT_STATUS_NOT_SUPPORTED);
2614
2599 if (!hdev_is_powered(hdev)) 2615 if (!hdev_is_powered(hdev))
2600 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, 2616 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2601 MGMT_STATUS_NOT_POWERED); 2617 MGMT_STATUS_NOT_POWERED);
@@ -2873,6 +2889,21 @@ static void settings_rsp(struct pending_cmd *cmd, void *data)
2873 mgmt_pending_free(cmd); 2889 mgmt_pending_free(cmd);
2874} 2890}
2875 2891
2892static int set_bredr_scan(struct hci_dev *hdev)
2893{
2894 u8 scan = 0;
2895
2896 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
2897 scan |= SCAN_PAGE;
2898 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
2899 scan |= SCAN_INQUIRY;
2900
2901 if (!scan)
2902 return 0;
2903
2904 return hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2905}
2906
2876int mgmt_powered(struct hci_dev *hdev, u8 powered) 2907int mgmt_powered(struct hci_dev *hdev, u8 powered)
2877{ 2908{
2878 struct cmd_lookup match = { NULL, hdev }; 2909 struct cmd_lookup match = { NULL, hdev };
@@ -2884,17 +2915,8 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
2884 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); 2915 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
2885 2916
2886 if (powered) { 2917 if (powered) {
2887 u8 scan = 0; 2918 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
2888 2919 !lmp_host_ssp_capable(hdev)) {
2889 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
2890 scan |= SCAN_PAGE;
2891 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
2892 scan |= SCAN_INQUIRY;
2893
2894 if (scan)
2895 hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2896
2897 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
2898 u8 ssp = 1; 2920 u8 ssp = 1;
2899 2921
2900 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &ssp); 2922 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &ssp);
@@ -2904,15 +2926,24 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
2904 struct hci_cp_write_le_host_supported cp; 2926 struct hci_cp_write_le_host_supported cp;
2905 2927
2906 cp.le = 1; 2928 cp.le = 1;
2907 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); 2929 cp.simul = !!lmp_le_br_capable(hdev);
2908 2930
2909 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, 2931 /* Check first if we already have the right
2910 sizeof(cp), &cp); 2932 * host state (host features set)
2933 */
2934 if (cp.le != !!lmp_host_le_capable(hdev) ||
2935 cp.simul != !!lmp_host_le_br_capable(hdev))
2936 hci_send_cmd(hdev,
2937 HCI_OP_WRITE_LE_HOST_SUPPORTED,
2938 sizeof(cp), &cp);
2911 } 2939 }
2912 2940
2913 update_class(hdev); 2941 if (lmp_bredr_capable(hdev)) {
2914 update_name(hdev, hdev->dev_name); 2942 set_bredr_scan(hdev);
2915 update_eir(hdev); 2943 update_class(hdev);
2944 update_name(hdev, hdev->dev_name);
2945 update_eir(hdev);
2946 }
2916 } else { 2947 } else {
2917 u8 status = MGMT_STATUS_NOT_POWERED; 2948 u8 status = MGMT_STATUS_NOT_POWERED;
2918 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); 2949 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
@@ -3361,7 +3392,7 @@ static int clear_eir(struct hci_dev *hdev)
3361{ 3392{
3362 struct hci_cp_write_eir cp; 3393 struct hci_cp_write_eir cp;
3363 3394
3364 if (!(hdev->features[6] & LMP_EXT_INQ)) 3395 if (!lmp_ext_inq_capable(hdev))
3365 return 0; 3396 return 0;
3366 3397
3367 memset(hdev->eir, 0, sizeof(hdev->eir)); 3398 memset(hdev->eir, 0, sizeof(hdev->eir));
@@ -3493,7 +3524,12 @@ send_event:
3493 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, 3524 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev,
3494 sizeof(ev), cmd ? cmd->sk : NULL); 3525 sizeof(ev), cmd ? cmd->sk : NULL);
3495 3526
3496 update_eir(hdev); 3527 /* EIR is taken care of separately when powering on the
3528 * adapter so only update them here if this is a name change
3529 * unrelated to power on.
3530 */
3531 if (!test_bit(HCI_INIT, &hdev->flags))
3532 update_eir(hdev);
3497 3533
3498failed: 3534failed:
3499 if (cmd) 3535 if (cmd)
@@ -3588,9 +3624,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3588 ev->addr.type = link_to_bdaddr(link_type, addr_type); 3624 ev->addr.type = link_to_bdaddr(link_type, addr_type);
3589 ev->rssi = rssi; 3625 ev->rssi = rssi;
3590 if (cfm_name) 3626 if (cfm_name)
3591 ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); 3627 ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME);
3592 if (!ssp) 3628 if (!ssp)
3593 ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); 3629 ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING);
3594 3630
3595 if (eir_len > 0) 3631 if (eir_len > 0)
3596 memcpy(ev->eir, eir, eir_len); 3632 memcpy(ev->eir, eir, eir_len);
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index 493353534a0..537488cbf94 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -10,6 +10,7 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/crypto.h> 12#include <linux/crypto.h>
13#include <linux/export.h>
13#include <linux/err.h> 14#include <linux/err.h>
14#include <crypto/aes.h> 15#include <crypto/aes.h>
15 16
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 186d9919b04..808338a1bce 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -118,7 +118,7 @@ void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
118 return; 118 return;
119 } 119 }
120 120
121 for (i = 0; i < STA_TID_NUM; i++) 121 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
122 if (ba_rx_bitmap & BIT(i)) 122 if (ba_rx_bitmap & BIT(i))
123 set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested); 123 set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested);
124 124
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 3195a6307f5..4152ed1034b 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -448,7 +448,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
448 if (WARN_ON(!local->ops->ampdu_action)) 448 if (WARN_ON(!local->ops->ampdu_action))
449 return -EINVAL; 449 return -EINVAL;
450 450
451 if ((tid >= STA_TID_NUM) || 451 if ((tid >= IEEE80211_NUM_TIDS) ||
452 !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) || 452 !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) ||
453 (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) 453 (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW))
454 return -EINVAL; 454 return -EINVAL;
@@ -605,9 +605,9 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
605 605
606 trace_api_start_tx_ba_cb(sdata, ra, tid); 606 trace_api_start_tx_ba_cb(sdata, ra, tid);
607 607
608 if (tid >= STA_TID_NUM) { 608 if (tid >= IEEE80211_NUM_TIDS) {
609 ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", 609 ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n",
610 tid, STA_TID_NUM); 610 tid, IEEE80211_NUM_TIDS);
611 return; 611 return;
612 } 612 }
613 613
@@ -687,7 +687,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
687 if (!local->ops->ampdu_action) 687 if (!local->ops->ampdu_action)
688 return -EINVAL; 688 return -EINVAL;
689 689
690 if (tid >= STA_TID_NUM) 690 if (tid >= IEEE80211_NUM_TIDS)
691 return -EINVAL; 691 return -EINVAL;
692 692
693 spin_lock_bh(&sta->lock); 693 spin_lock_bh(&sta->lock);
@@ -722,9 +722,9 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
722 722
723 trace_api_stop_tx_ba_cb(sdata, ra, tid); 723 trace_api_stop_tx_ba_cb(sdata, ra, tid);
724 724
725 if (tid >= STA_TID_NUM) { 725 if (tid >= IEEE80211_NUM_TIDS) {
726 ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", 726 ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n",
727 tid, STA_TID_NUM); 727 tid, IEEE80211_NUM_TIDS);
728 return; 728 return;
729 } 729 }
730 730
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 76690020d60..4965aa6424e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -370,30 +370,32 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
370 return 0; 370 return 0;
371} 371}
372 372
373static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx)
374{
375 enum ieee80211_band band = ieee80211_get_sdata_band(sta->sdata);
376
377 if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
378 struct ieee80211_supported_band *sband;
379 sband = sta->local->hw.wiphy->bands[band];
380 rate->legacy = sband->bitrates[idx].bitrate;
381 } else
382 rate->mcs = idx;
383}
384
385void sta_set_rate_info_tx(struct sta_info *sta, 373void sta_set_rate_info_tx(struct sta_info *sta,
386 const struct ieee80211_tx_rate *rate, 374 const struct ieee80211_tx_rate *rate,
387 struct rate_info *rinfo) 375 struct rate_info *rinfo)
388{ 376{
389 rinfo->flags = 0; 377 rinfo->flags = 0;
390 if (rate->flags & IEEE80211_TX_RC_MCS) 378 if (rate->flags & IEEE80211_TX_RC_MCS) {
391 rinfo->flags |= RATE_INFO_FLAGS_MCS; 379 rinfo->flags |= RATE_INFO_FLAGS_MCS;
380 rinfo->mcs = rate->idx;
381 } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
382 rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
383 rinfo->mcs = ieee80211_rate_get_vht_mcs(rate);
384 rinfo->nss = ieee80211_rate_get_vht_nss(rate);
385 } else {
386 struct ieee80211_supported_band *sband;
387 sband = sta->local->hw.wiphy->bands[
388 ieee80211_get_sdata_band(sta->sdata)];
389 rinfo->legacy = sband->bitrates[rate->idx].bitrate;
390 }
392 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 391 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
393 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 392 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
393 if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
394 rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
395 if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
396 rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
394 if (rate->flags & IEEE80211_TX_RC_SHORT_GI) 397 if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
395 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; 398 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
396 rate_idx_to_bitrate(rinfo, sta, rate->idx);
397} 399}
398 400
399static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 401static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
@@ -444,13 +446,32 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
444 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); 446 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
445 447
446 sinfo->rxrate.flags = 0; 448 sinfo->rxrate.flags = 0;
447 if (sta->last_rx_rate_flag & RX_FLAG_HT) 449 if (sta->last_rx_rate_flag & RX_FLAG_HT) {
448 sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS; 450 sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS;
451 sinfo->rxrate.mcs = sta->last_rx_rate_idx;
452 } else if (sta->last_rx_rate_flag & RX_FLAG_VHT) {
453 sinfo->rxrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
454 sinfo->rxrate.nss = sta->last_rx_rate_vht_nss;
455 sinfo->rxrate.mcs = sta->last_rx_rate_idx;
456 } else {
457 struct ieee80211_supported_band *sband;
458
459 sband = sta->local->hw.wiphy->bands[
460 ieee80211_get_sdata_band(sta->sdata)];
461 sinfo->rxrate.legacy =
462 sband->bitrates[sta->last_rx_rate_idx].bitrate;
463 }
464
449 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) 465 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
450 sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 466 sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
451 if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI) 467 if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
452 sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; 468 sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
453 rate_idx_to_bitrate(&sinfo->rxrate, sta, sta->last_rx_rate_idx); 469 if (sta->last_rx_rate_flag & RX_FLAG_80MHZ)
470 sinfo->rxrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
471 if (sta->last_rx_rate_flag & RX_FLAG_80P80MHZ)
472 sinfo->rxrate.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
473 if (sta->last_rx_rate_flag & RX_FLAG_160MHZ)
474 sinfo->rxrate.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
454 475
455 if (ieee80211_vif_is_mesh(&sdata->vif)) { 476 if (ieee80211_vif_is_mesh(&sdata->vif)) {
456#ifdef CONFIG_MAC80211_MESH 477#ifdef CONFIG_MAC80211_MESH
@@ -615,7 +636,7 @@ do_survey:
615 rcu_read_lock(); 636 rcu_read_lock();
616 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 637 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
617 if (chanctx_conf) 638 if (chanctx_conf)
618 channel = chanctx_conf->channel; 639 channel = chanctx_conf->def.chan;
619 else 640 else
620 channel = NULL; 641 channel = NULL;
621 rcu_read_unlock(); 642 rcu_read_unlock();
@@ -735,15 +756,13 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
735} 756}
736 757
737static int ieee80211_set_monitor_channel(struct wiphy *wiphy, 758static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
738 struct ieee80211_channel *chan, 759 struct cfg80211_chan_def *chandef)
739 enum nl80211_channel_type channel_type)
740{ 760{
741 struct ieee80211_local *local = wiphy_priv(wiphy); 761 struct ieee80211_local *local = wiphy_priv(wiphy);
742 struct ieee80211_sub_if_data *sdata; 762 struct ieee80211_sub_if_data *sdata;
743 int ret = 0; 763 int ret = 0;
744 764
745 if (local->monitor_channel == chan && 765 if (cfg80211_chandef_identical(&local->monitor_chandef, chandef))
746 local->monitor_channel_type == channel_type)
747 return 0; 766 return 0;
748 767
749 mutex_lock(&local->iflist_mtx); 768 mutex_lock(&local->iflist_mtx);
@@ -753,20 +772,17 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
753 lockdep_is_held(&local->iflist_mtx)); 772 lockdep_is_held(&local->iflist_mtx));
754 if (sdata) { 773 if (sdata) {
755 ieee80211_vif_release_channel(sdata); 774 ieee80211_vif_release_channel(sdata);
756 ret = ieee80211_vif_use_channel( 775 ret = ieee80211_vif_use_channel(sdata, chandef,
757 sdata, chan, channel_type,
758 IEEE80211_CHANCTX_EXCLUSIVE); 776 IEEE80211_CHANCTX_EXCLUSIVE);
759 } 777 }
760 } else if (local->open_count == local->monitors) { 778 } else if (local->open_count == local->monitors) {
761 local->_oper_channel = chan; 779 local->_oper_channel = chandef->chan;
762 local->_oper_channel_type = channel_type; 780 local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
763 ieee80211_hw_config(local, 0); 781 ieee80211_hw_config(local, 0);
764 } 782 }
765 783
766 if (ret == 0) { 784 if (ret == 0)
767 local->monitor_channel = chan; 785 local->monitor_chandef = *chandef;
768 local->monitor_channel_type = channel_type;
769 }
770 mutex_unlock(&local->iflist_mtx); 786 mutex_unlock(&local->iflist_mtx);
771 787
772 return ret; 788 return ret;
@@ -888,8 +904,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
888 sdata->smps_mode = IEEE80211_SMPS_OFF; 904 sdata->smps_mode = IEEE80211_SMPS_OFF;
889 sdata->needed_rx_chains = sdata->local->rx_chains; 905 sdata->needed_rx_chains = sdata->local->rx_chains;
890 906
891 err = ieee80211_vif_use_channel(sdata, params->channel, 907 err = ieee80211_vif_use_channel(sdata, &params->chandef,
892 params->channel_type,
893 IEEE80211_CHANCTX_SHARED); 908 IEEE80211_CHANCTX_SHARED);
894 if (err) 909 if (err)
895 return err; 910 return err;
@@ -922,6 +937,15 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
922 return err; 937 return err;
923 changed |= err; 938 changed |= err;
924 939
940 err = drv_start_ap(sdata->local, sdata);
941 if (err) {
942 old = rtnl_dereference(sdata->u.ap.beacon);
943 if (old)
944 kfree_rcu(old, rcu_head);
945 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
946 return err;
947 }
948
925 ieee80211_bss_info_change_notify(sdata, changed); 949 ieee80211_bss_info_change_notify(sdata, changed);
926 950
927 netif_carrier_on(dev); 951 netif_carrier_on(dev);
@@ -953,26 +977,38 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
953 977
954static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) 978static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
955{ 979{
956 struct ieee80211_sub_if_data *sdata, *vlan; 980 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
957 struct beacon_data *old; 981 struct ieee80211_sub_if_data *vlan;
958 982 struct ieee80211_local *local = sdata->local;
959 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 983 struct beacon_data *old_beacon;
984 struct probe_resp *old_probe_resp;
960 985
961 old = rtnl_dereference(sdata->u.ap.beacon); 986 old_beacon = rtnl_dereference(sdata->u.ap.beacon);
962 if (!old) 987 if (!old_beacon)
963 return -ENOENT; 988 return -ENOENT;
989 old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp);
964 990
991 /* turn off carrier for this interface and dependent VLANs */
965 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 992 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
966 netif_carrier_off(vlan->dev); 993 netif_carrier_off(vlan->dev);
967 netif_carrier_off(dev); 994 netif_carrier_off(dev);
968 995
996 /* remove beacon and probe response */
969 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); 997 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
998 RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
999 kfree_rcu(old_beacon, rcu_head);
1000 if (old_probe_resp)
1001 kfree_rcu(old_probe_resp, rcu_head);
970 1002
971 kfree_rcu(old, rcu_head); 1003 sta_info_flush(local, sdata);
972
973 sta_info_flush(sdata->local, sdata);
974 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 1004 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
975 1005
1006 drv_stop_ap(sdata->local, sdata);
1007
1008 /* free all potentially still buffered bcast frames */
1009 local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
1010 skb_queue_purge(&sdata->u.ap.ps.bc_buf);
1011
976 ieee80211_vif_release_channel(sdata); 1012 ieee80211_vif_release_channel(sdata);
977 1013
978 return 0; 1014 return 0;
@@ -1686,8 +1722,7 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
1686 sdata->smps_mode = IEEE80211_SMPS_OFF; 1722 sdata->smps_mode = IEEE80211_SMPS_OFF;
1687 sdata->needed_rx_chains = sdata->local->rx_chains; 1723 sdata->needed_rx_chains = sdata->local->rx_chains;
1688 1724
1689 err = ieee80211_vif_use_channel(sdata, setup->channel, 1725 err = ieee80211_vif_use_channel(sdata, &setup->chandef,
1690 setup->channel_type,
1691 IEEE80211_CHANCTX_SHARED); 1726 IEEE80211_CHANCTX_SHARED);
1692 if (err) 1727 if (err)
1693 return err; 1728 return err;
@@ -1933,6 +1968,16 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1933 return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev)); 1968 return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev));
1934} 1969}
1935 1970
1971static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev,
1972 int rate[IEEE80211_NUM_BANDS])
1973{
1974 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1975
1976 memcpy(sdata->vif.bss_conf.mcast_rate, rate, sizeof(rate));
1977
1978 return 0;
1979}
1980
1936static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1981static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1937{ 1982{
1938 struct ieee80211_local *local = wiphy_priv(wiphy); 1983 struct ieee80211_local *local = wiphy_priv(wiphy);
@@ -1959,10 +2004,16 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1959 return err; 2004 return err;
1960 } 2005 }
1961 2006
1962 if (changed & WIPHY_PARAM_RETRY_SHORT) 2007 if (changed & WIPHY_PARAM_RETRY_SHORT) {
2008 if (wiphy->retry_short > IEEE80211_MAX_TX_RETRY)
2009 return -EINVAL;
1963 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 2010 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
1964 if (changed & WIPHY_PARAM_RETRY_LONG) 2011 }
2012 if (changed & WIPHY_PARAM_RETRY_LONG) {
2013 if (wiphy->retry_long > IEEE80211_MAX_TX_RETRY)
2014 return -EINVAL;
1965 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 2015 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
2016 }
1966 if (changed & 2017 if (changed &
1967 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG)) 2018 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
1968 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); 2019 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
@@ -1971,45 +2022,65 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1971} 2022}
1972 2023
1973static int ieee80211_set_tx_power(struct wiphy *wiphy, 2024static int ieee80211_set_tx_power(struct wiphy *wiphy,
2025 struct wireless_dev *wdev,
1974 enum nl80211_tx_power_setting type, int mbm) 2026 enum nl80211_tx_power_setting type, int mbm)
1975{ 2027{
1976 struct ieee80211_local *local = wiphy_priv(wiphy); 2028 struct ieee80211_local *local = wiphy_priv(wiphy);
1977 struct ieee80211_channel *chan = local->_oper_channel; 2029 struct ieee80211_sub_if_data *sdata;
1978 u32 changes = 0;
1979 2030
1980 /* FIXME */ 2031 if (wdev) {
1981 if (local->use_chanctx) 2032 sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
1982 return -EOPNOTSUPP; 2033
2034 switch (type) {
2035 case NL80211_TX_POWER_AUTOMATIC:
2036 sdata->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
2037 break;
2038 case NL80211_TX_POWER_LIMITED:
2039 case NL80211_TX_POWER_FIXED:
2040 if (mbm < 0 || (mbm % 100))
2041 return -EOPNOTSUPP;
2042 sdata->user_power_level = MBM_TO_DBM(mbm);
2043 break;
2044 }
2045
2046 ieee80211_recalc_txpower(sdata);
2047
2048 return 0;
2049 }
1983 2050
1984 switch (type) { 2051 switch (type) {
1985 case NL80211_TX_POWER_AUTOMATIC: 2052 case NL80211_TX_POWER_AUTOMATIC:
1986 local->user_power_level = -1; 2053 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
1987 break; 2054 break;
1988 case NL80211_TX_POWER_LIMITED: 2055 case NL80211_TX_POWER_LIMITED:
1989 if (mbm < 0 || (mbm % 100))
1990 return -EOPNOTSUPP;
1991 local->user_power_level = MBM_TO_DBM(mbm);
1992 break;
1993 case NL80211_TX_POWER_FIXED: 2056 case NL80211_TX_POWER_FIXED:
1994 if (mbm < 0 || (mbm % 100)) 2057 if (mbm < 0 || (mbm % 100))
1995 return -EOPNOTSUPP; 2058 return -EOPNOTSUPP;
1996 /* TODO: move to cfg80211 when it knows the channel */
1997 if (MBM_TO_DBM(mbm) > chan->max_power)
1998 return -EINVAL;
1999 local->user_power_level = MBM_TO_DBM(mbm); 2059 local->user_power_level = MBM_TO_DBM(mbm);
2000 break; 2060 break;
2001 } 2061 }
2002 2062
2003 ieee80211_hw_config(local, changes); 2063 mutex_lock(&local->iflist_mtx);
2064 list_for_each_entry(sdata, &local->interfaces, list)
2065 sdata->user_power_level = local->user_power_level;
2066 list_for_each_entry(sdata, &local->interfaces, list)
2067 ieee80211_recalc_txpower(sdata);
2068 mutex_unlock(&local->iflist_mtx);
2004 2069
2005 return 0; 2070 return 0;
2006} 2071}
2007 2072
2008static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm) 2073static int ieee80211_get_tx_power(struct wiphy *wiphy,
2074 struct wireless_dev *wdev,
2075 int *dbm)
2009{ 2076{
2010 struct ieee80211_local *local = wiphy_priv(wiphy); 2077 struct ieee80211_local *local = wiphy_priv(wiphy);
2078 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2011 2079
2012 *dbm = local->hw.conf.power_level; 2080 if (!local->use_chanctx)
2081 *dbm = local->hw.conf.power_level;
2082 else
2083 *dbm = sdata->vif.bss_conf.txpower;
2013 2084
2014 return 0; 2085 return 0;
2015} 2086}
@@ -2078,7 +2149,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
2078 * the new value until we associate. 2149 * the new value until we associate.
2079 */ 2150 */
2080 if (!sdata->u.mgd.associated || 2151 if (!sdata->u.mgd.associated ||
2081 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) 2152 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
2082 return 0; 2153 return 0;
2083 2154
2084 ap = sdata->u.mgd.associated->bssid; 2155 ap = sdata->u.mgd.associated->bssid;
@@ -2185,7 +2256,6 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
2185static int ieee80211_start_roc_work(struct ieee80211_local *local, 2256static int ieee80211_start_roc_work(struct ieee80211_local *local,
2186 struct ieee80211_sub_if_data *sdata, 2257 struct ieee80211_sub_if_data *sdata,
2187 struct ieee80211_channel *channel, 2258 struct ieee80211_channel *channel,
2188 enum nl80211_channel_type channel_type,
2189 unsigned int duration, u64 *cookie, 2259 unsigned int duration, u64 *cookie,
2190 struct sk_buff *txskb) 2260 struct sk_buff *txskb)
2191{ 2261{
@@ -2203,7 +2273,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2203 return -ENOMEM; 2273 return -ENOMEM;
2204 2274
2205 roc->chan = channel; 2275 roc->chan = channel;
2206 roc->chan_type = channel_type;
2207 roc->duration = duration; 2276 roc->duration = duration;
2208 roc->req_duration = duration; 2277 roc->req_duration = duration;
2209 roc->frame = txskb; 2278 roc->frame = txskb;
@@ -2236,7 +2305,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2236 if (!duration) 2305 if (!duration)
2237 duration = 10; 2306 duration = 10;
2238 2307
2239 ret = drv_remain_on_channel(local, channel, channel_type, duration); 2308 ret = drv_remain_on_channel(local, sdata, channel, duration);
2240 if (ret) { 2309 if (ret) {
2241 kfree(roc); 2310 kfree(roc);
2242 return ret; 2311 return ret;
@@ -2247,7 +2316,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2247 2316
2248 out_check_combine: 2317 out_check_combine:
2249 list_for_each_entry(tmp, &local->roc_list, list) { 2318 list_for_each_entry(tmp, &local->roc_list, list) {
2250 if (tmp->chan != channel || tmp->chan_type != channel_type) 2319 if (tmp->chan != channel || tmp->sdata != sdata)
2251 continue; 2320 continue;
2252 2321
2253 /* 2322 /*
@@ -2341,13 +2410,22 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2341 list_add_tail(&roc->list, &local->roc_list); 2410 list_add_tail(&roc->list, &local->roc_list);
2342 2411
2343 /* 2412 /*
2344 * cookie is either the roc (for normal roc) 2413 * cookie is either the roc cookie (for normal roc)
2345 * or the SKB (for mgmt TX) 2414 * or the SKB (for mgmt TX)
2346 */ 2415 */
2347 if (txskb) 2416 if (!txskb) {
2417 /* local->mtx protects this */
2418 local->roc_cookie_counter++;
2419 roc->cookie = local->roc_cookie_counter;
2420 /* wow, you wrapped 64 bits ... more likely a bug */
2421 if (WARN_ON(roc->cookie == 0)) {
2422 roc->cookie = 1;
2423 local->roc_cookie_counter++;
2424 }
2425 *cookie = roc->cookie;
2426 } else {
2348 *cookie = (unsigned long)txskb; 2427 *cookie = (unsigned long)txskb;
2349 else 2428 }
2350 *cookie = (unsigned long)roc;
2351 2429
2352 return 0; 2430 return 0;
2353} 2431}
@@ -2355,7 +2433,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2355static int ieee80211_remain_on_channel(struct wiphy *wiphy, 2433static int ieee80211_remain_on_channel(struct wiphy *wiphy,
2356 struct wireless_dev *wdev, 2434 struct wireless_dev *wdev,
2357 struct ieee80211_channel *chan, 2435 struct ieee80211_channel *chan,
2358 enum nl80211_channel_type channel_type,
2359 unsigned int duration, 2436 unsigned int duration,
2360 u64 *cookie) 2437 u64 *cookie)
2361{ 2438{
@@ -2364,7 +2441,7 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy,
2364 int ret; 2441 int ret;
2365 2442
2366 mutex_lock(&local->mtx); 2443 mutex_lock(&local->mtx);
2367 ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, 2444 ret = ieee80211_start_roc_work(local, sdata, chan,
2368 duration, cookie, NULL); 2445 duration, cookie, NULL);
2369 mutex_unlock(&local->mtx); 2446 mutex_unlock(&local->mtx);
2370 2447
@@ -2382,7 +2459,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2382 struct ieee80211_roc_work *dep, *tmp2; 2459 struct ieee80211_roc_work *dep, *tmp2;
2383 2460
2384 list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) { 2461 list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) {
2385 if (!mgmt_tx && (unsigned long)dep != cookie) 2462 if (!mgmt_tx && dep->cookie != cookie)
2386 continue; 2463 continue;
2387 else if (mgmt_tx && dep->mgmt_tx_cookie != cookie) 2464 else if (mgmt_tx && dep->mgmt_tx_cookie != cookie)
2388 continue; 2465 continue;
@@ -2394,7 +2471,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2394 return 0; 2471 return 0;
2395 } 2472 }
2396 2473
2397 if (!mgmt_tx && (unsigned long)roc != cookie) 2474 if (!mgmt_tx && roc->cookie != cookie)
2398 continue; 2475 continue;
2399 else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) 2476 else if (mgmt_tx && roc->mgmt_tx_cookie != cookie)
2400 continue; 2477 continue;
@@ -2457,10 +2534,8 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
2457 2534
2458static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 2535static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2459 struct ieee80211_channel *chan, bool offchan, 2536 struct ieee80211_channel *chan, bool offchan,
2460 enum nl80211_channel_type channel_type, 2537 unsigned int wait, const u8 *buf, size_t len,
2461 bool channel_type_valid, unsigned int wait, 2538 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
2462 const u8 *buf, size_t len, bool no_cck,
2463 bool dont_wait_for_ack, u64 *cookie)
2464{ 2539{
2465 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 2540 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2466 struct ieee80211_local *local = sdata->local; 2541 struct ieee80211_local *local = sdata->local;
@@ -2529,14 +2604,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2529 rcu_read_lock(); 2604 rcu_read_lock();
2530 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2605 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2531 2606
2532 if (chanctx_conf) { 2607 if (chanctx_conf)
2533 need_offchan = chan != chanctx_conf->channel; 2608 need_offchan = chan != chanctx_conf->def.chan;
2534 if (channel_type_valid && 2609 else
2535 channel_type != chanctx_conf->channel_type)
2536 need_offchan = true;
2537 } else {
2538 need_offchan = true; 2610 need_offchan = true;
2539 }
2540 rcu_read_unlock(); 2611 rcu_read_unlock();
2541 } 2612 }
2542 2613
@@ -2571,7 +2642,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2571 local->hw.offchannel_tx_hw_queue; 2642 local->hw.offchannel_tx_hw_queue;
2572 2643
2573 /* This will handle all kinds of coalescing and immediate TX */ 2644 /* This will handle all kinds of coalescing and immediate TX */
2574 ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, 2645 ret = ieee80211_start_roc_work(local, sdata, chan,
2575 wait, cookie, skb); 2646 wait, cookie, skb);
2576 if (ret) 2647 if (ret)
2577 kfree_skb(skb); 2648 kfree_skb(skb);
@@ -3005,7 +3076,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
3005 rcu_read_unlock(); 3076 rcu_read_unlock();
3006 return -EINVAL; 3077 return -EINVAL;
3007 } 3078 }
3008 band = chanctx_conf->channel->band; 3079 band = chanctx_conf->def.chan->band;
3009 sta = sta_info_get(sdata, peer); 3080 sta = sta_info_get(sdata, peer);
3010 if (sta) { 3081 if (sta) {
3011 qos = test_sta_flag(sta, WLAN_STA_WME); 3082 qos = test_sta_flag(sta, WLAN_STA_WME);
@@ -3062,23 +3133,23 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
3062 return 0; 3133 return 0;
3063} 3134}
3064 3135
3065static struct ieee80211_channel * 3136static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
3066ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, 3137 struct wireless_dev *wdev,
3067 enum nl80211_channel_type *type) 3138 struct cfg80211_chan_def *chandef)
3068{ 3139{
3069 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 3140 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
3070 struct ieee80211_chanctx_conf *chanctx_conf; 3141 struct ieee80211_chanctx_conf *chanctx_conf;
3071 struct ieee80211_channel *chan = NULL; 3142 int ret = -ENODATA;
3072 3143
3073 rcu_read_lock(); 3144 rcu_read_lock();
3074 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 3145 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3075 if (chanctx_conf) { 3146 if (chanctx_conf) {
3076 *type = chanctx_conf->channel_type; 3147 *chandef = chanctx_conf->def;
3077 chan = chanctx_conf->channel; 3148 ret = 0;
3078 } 3149 }
3079 rcu_read_unlock(); 3150 rcu_read_unlock();
3080 3151
3081 return chan; 3152 return ret;
3082} 3153}
3083 3154
3084#ifdef CONFIG_PM 3155#ifdef CONFIG_PM
@@ -3133,6 +3204,7 @@ struct cfg80211_ops mac80211_config_ops = {
3133 .disassoc = ieee80211_disassoc, 3204 .disassoc = ieee80211_disassoc,
3134 .join_ibss = ieee80211_join_ibss, 3205 .join_ibss = ieee80211_join_ibss,
3135 .leave_ibss = ieee80211_leave_ibss, 3206 .leave_ibss = ieee80211_leave_ibss,
3207 .set_mcast_rate = ieee80211_set_mcast_rate,
3136 .set_wiphy_params = ieee80211_set_wiphy_params, 3208 .set_wiphy_params = ieee80211_set_wiphy_params,
3137 .set_tx_power = ieee80211_set_tx_power, 3209 .set_tx_power = ieee80211_set_tx_power,
3138 .get_tx_power = ieee80211_get_tx_power, 3210 .get_tx_power = ieee80211_get_tx_power,
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index f84b86028a9..53f03120db5 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -8,93 +8,47 @@
8#include "ieee80211_i.h" 8#include "ieee80211_i.h"
9#include "driver-ops.h" 9#include "driver-ops.h"
10 10
11static bool 11static void ieee80211_change_chandef(struct ieee80211_local *local,
12ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1, 12 struct ieee80211_chanctx *ctx,
13 enum nl80211_channel_type chantype2, 13 const struct cfg80211_chan_def *chandef)
14 enum nl80211_channel_type *compat)
15{ 14{
16 /* 15 if (cfg80211_chandef_identical(&ctx->conf.def, chandef))
17 * start out with chantype1 being the result,
18 * overwriting later if needed
19 */
20 if (compat)
21 *compat = chantype1;
22
23 switch (chantype1) {
24 case NL80211_CHAN_NO_HT:
25 if (compat)
26 *compat = chantype2;
27 break;
28 case NL80211_CHAN_HT20:
29 /*
30 * allow any change that doesn't go to no-HT
31 * (if it already is no-HT no change is needed)
32 */
33 if (chantype2 == NL80211_CHAN_NO_HT)
34 break;
35 if (compat)
36 *compat = chantype2;
37 break;
38 case NL80211_CHAN_HT40PLUS:
39 case NL80211_CHAN_HT40MINUS:
40 /* allow smaller bandwidth and same */
41 if (chantype2 == NL80211_CHAN_NO_HT)
42 break;
43 if (chantype2 == NL80211_CHAN_HT20)
44 break;
45 if (chantype2 == chantype1)
46 break;
47 return false;
48 }
49
50 return true;
51}
52
53static void ieee80211_change_chantype(struct ieee80211_local *local,
54 struct ieee80211_chanctx *ctx,
55 enum nl80211_channel_type chantype)
56{
57 if (chantype == ctx->conf.channel_type)
58 return; 16 return;
59 17
60 ctx->conf.channel_type = chantype; 18 WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
61 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE); 19
20 ctx->conf.def = *chandef;
21 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
62 22
63 if (!local->use_chanctx) { 23 if (!local->use_chanctx) {
64 local->_oper_channel_type = chantype; 24 local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
65 ieee80211_hw_config(local, 0); 25 ieee80211_hw_config(local, 0);
66 } 26 }
67} 27}
68 28
69static struct ieee80211_chanctx * 29static struct ieee80211_chanctx *
70ieee80211_find_chanctx(struct ieee80211_local *local, 30ieee80211_find_chanctx(struct ieee80211_local *local,
71 struct ieee80211_channel *channel, 31 const struct cfg80211_chan_def *chandef,
72 enum nl80211_channel_type channel_type,
73 enum ieee80211_chanctx_mode mode) 32 enum ieee80211_chanctx_mode mode)
74{ 33{
75 struct ieee80211_chanctx *ctx; 34 struct ieee80211_chanctx *ctx;
76 enum nl80211_channel_type compat_type;
77 35
78 lockdep_assert_held(&local->chanctx_mtx); 36 lockdep_assert_held(&local->chanctx_mtx);
79 37
80 if (mode == IEEE80211_CHANCTX_EXCLUSIVE) 38 if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
81 return NULL; 39 return NULL;
82 if (WARN_ON(!channel))
83 return NULL;
84 40
85 list_for_each_entry(ctx, &local->chanctx_list, list) { 41 list_for_each_entry(ctx, &local->chanctx_list, list) {
86 compat_type = ctx->conf.channel_type; 42 const struct cfg80211_chan_def *compat;
87 43
88 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 44 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
89 continue; 45 continue;
90 if (ctx->conf.channel != channel) 46
91 continue; 47 compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef);
92 if (!ieee80211_channel_types_are_compatible(ctx->conf.channel_type, 48 if (!compat)
93 channel_type,
94 &compat_type))
95 continue; 49 continue;
96 50
97 ieee80211_change_chantype(local, ctx, compat_type); 51 ieee80211_change_chandef(local, ctx, compat);
98 52
99 return ctx; 53 return ctx;
100 } 54 }
@@ -104,8 +58,7 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
104 58
105static struct ieee80211_chanctx * 59static struct ieee80211_chanctx *
106ieee80211_new_chanctx(struct ieee80211_local *local, 60ieee80211_new_chanctx(struct ieee80211_local *local,
107 struct ieee80211_channel *channel, 61 const struct cfg80211_chan_def *chandef,
108 enum nl80211_channel_type channel_type,
109 enum ieee80211_chanctx_mode mode) 62 enum ieee80211_chanctx_mode mode)
110{ 63{
111 struct ieee80211_chanctx *ctx; 64 struct ieee80211_chanctx *ctx;
@@ -117,15 +70,15 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
117 if (!ctx) 70 if (!ctx)
118 return ERR_PTR(-ENOMEM); 71 return ERR_PTR(-ENOMEM);
119 72
120 ctx->conf.channel = channel; 73 ctx->conf.def = *chandef;
121 ctx->conf.channel_type = channel_type;
122 ctx->conf.rx_chains_static = 1; 74 ctx->conf.rx_chains_static = 1;
123 ctx->conf.rx_chains_dynamic = 1; 75 ctx->conf.rx_chains_dynamic = 1;
124 ctx->mode = mode; 76 ctx->mode = mode;
125 77
126 if (!local->use_chanctx) { 78 if (!local->use_chanctx) {
127 local->_oper_channel_type = channel_type; 79 local->_oper_channel_type =
128 local->_oper_channel = channel; 80 cfg80211_get_chandef_type(chandef);
81 local->_oper_channel = chandef->chan;
129 ieee80211_hw_config(local, 0); 82 ieee80211_hw_config(local, 0);
130 } else { 83 } else {
131 err = drv_add_chanctx(local, ctx); 84 err = drv_add_chanctx(local, ctx);
@@ -173,44 +126,42 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
173 rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf); 126 rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf);
174 ctx->refcount++; 127 ctx->refcount++;
175 128
129 ieee80211_recalc_txpower(sdata);
130
176 return 0; 131 return 0;
177} 132}
178 133
179static enum nl80211_channel_type 134static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
180ieee80211_calc_chantype(struct ieee80211_local *local, 135 struct ieee80211_chanctx *ctx)
181 struct ieee80211_chanctx *ctx)
182{ 136{
183 struct ieee80211_chanctx_conf *conf = &ctx->conf; 137 struct ieee80211_chanctx_conf *conf = &ctx->conf;
184 struct ieee80211_sub_if_data *sdata; 138 struct ieee80211_sub_if_data *sdata;
185 enum nl80211_channel_type result = NL80211_CHAN_NO_HT; 139 const struct cfg80211_chan_def *compat = NULL;
186 140
187 lockdep_assert_held(&local->chanctx_mtx); 141 lockdep_assert_held(&local->chanctx_mtx);
188 142
189 rcu_read_lock(); 143 rcu_read_lock();
190 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 144 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
145
191 if (!ieee80211_sdata_running(sdata)) 146 if (!ieee80211_sdata_running(sdata))
192 continue; 147 continue;
193 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) 148 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
194 continue; 149 continue;
195 150
196 WARN_ON_ONCE(!ieee80211_channel_types_are_compatible( 151 if (!compat)
197 sdata->vif.bss_conf.channel_type, 152 compat = &sdata->vif.bss_conf.chandef;
198 result, &result)); 153
154 compat = cfg80211_chandef_compatible(
155 &sdata->vif.bss_conf.chandef, compat);
156 if (!compat)
157 break;
199 } 158 }
200 rcu_read_unlock(); 159 rcu_read_unlock();
201 160
202 return result; 161 if (WARN_ON_ONCE(!compat))
203} 162 return;
204
205static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
206 struct ieee80211_chanctx *ctx)
207{
208 enum nl80211_channel_type chantype;
209
210 lockdep_assert_held(&local->chanctx_mtx);
211 163
212 chantype = ieee80211_calc_chantype(local, ctx); 164 ieee80211_change_chandef(local, ctx, compat);
213 ieee80211_change_chantype(local, ctx, chantype);
214} 165}
215 166
216static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, 167static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
@@ -335,8 +286,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
335} 286}
336 287
337int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 288int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
338 struct ieee80211_channel *channel, 289 const struct cfg80211_chan_def *chandef,
339 enum nl80211_channel_type channel_type,
340 enum ieee80211_chanctx_mode mode) 290 enum ieee80211_chanctx_mode mode)
341{ 291{
342 struct ieee80211_local *local = sdata->local; 292 struct ieee80211_local *local = sdata->local;
@@ -348,15 +298,15 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
348 mutex_lock(&local->chanctx_mtx); 298 mutex_lock(&local->chanctx_mtx);
349 __ieee80211_vif_release_channel(sdata); 299 __ieee80211_vif_release_channel(sdata);
350 300
351 ctx = ieee80211_find_chanctx(local, channel, channel_type, mode); 301 ctx = ieee80211_find_chanctx(local, chandef, mode);
352 if (!ctx) 302 if (!ctx)
353 ctx = ieee80211_new_chanctx(local, channel, channel_type, mode); 303 ctx = ieee80211_new_chanctx(local, chandef, mode);
354 if (IS_ERR(ctx)) { 304 if (IS_ERR(ctx)) {
355 ret = PTR_ERR(ctx); 305 ret = PTR_ERR(ctx);
356 goto out; 306 goto out;
357 } 307 }
358 308
359 sdata->vif.bss_conf.channel_type = channel_type; 309 sdata->vif.bss_conf.chandef = *chandef;
360 310
361 ret = ieee80211_assign_vif_chanctx(sdata, ctx); 311 ret = ieee80211_assign_vif_chanctx(sdata, ctx);
362 if (ret) { 312 if (ret) {
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 090d08ff22c..2d4235497f1 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -116,7 +116,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
116 size_t count, loff_t *ppos) 116 size_t count, loff_t *ppos)
117{ 117{
118 struct ieee80211_key *key = file->private_data; 118 struct ieee80211_key *key = file->private_data;
119 char buf[14*NUM_RX_DATA_QUEUES+1], *p = buf; 119 char buf[14*IEEE80211_NUM_TIDS+1], *p = buf;
120 int i, len; 120 int i, len;
121 const u8 *rpn; 121 const u8 *rpn;
122 122
@@ -126,7 +126,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
126 len = scnprintf(buf, sizeof(buf), "\n"); 126 len = scnprintf(buf, sizeof(buf), "\n");
127 break; 127 break;
128 case WLAN_CIPHER_SUITE_TKIP: 128 case WLAN_CIPHER_SUITE_TKIP:
129 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) 129 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
130 p += scnprintf(p, sizeof(buf)+buf-p, 130 p += scnprintf(p, sizeof(buf)+buf-p,
131 "%08x %04x\n", 131 "%08x %04x\n",
132 key->u.tkip.rx[i].iv32, 132 key->u.tkip.rx[i].iv32,
@@ -134,7 +134,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
134 len = p - buf; 134 len = p - buf;
135 break; 135 break;
136 case WLAN_CIPHER_SUITE_CCMP: 136 case WLAN_CIPHER_SUITE_CCMP:
137 for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) { 137 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
138 rpn = key->u.ccmp.rx_pn[i]; 138 rpn = key->u.ccmp.rx_pn[i];
139 p += scnprintf(p, sizeof(buf)+buf-p, 139 p += scnprintf(p, sizeof(buf)+buf-p,
140 "%02x%02x%02x%02x%02x%02x\n", 140 "%02x%02x%02x%02x%02x%02x\n",
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 3393ad5b8ab..cbde5cc49a4 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -10,6 +10,7 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/if.h> 12#include <linux/if.h>
13#include <linux/if_ether.h>
13#include <linux/interrupt.h> 14#include <linux/interrupt.h>
14#include <linux/netdevice.h> 15#include <linux/netdevice.h>
15#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
@@ -167,7 +168,29 @@ IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
167 168
168IEEE80211_IF_FILE(flags, flags, HEX); 169IEEE80211_IF_FILE(flags, flags, HEX);
169IEEE80211_IF_FILE(state, state, LHEX); 170IEEE80211_IF_FILE(state, state, LHEX);
170IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC); 171IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC);
172IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC);
173IEEE80211_IF_FILE(user_power_level, user_power_level, DEC);
174
175static ssize_t
176ieee80211_if_fmt_hw_queues(const struct ieee80211_sub_if_data *sdata,
177 char *buf, int buflen)
178{
179 int len;
180
181 len = scnprintf(buf, buflen, "AC queues: VO:%d VI:%d BE:%d BK:%d\n",
182 sdata->vif.hw_queue[IEEE80211_AC_VO],
183 sdata->vif.hw_queue[IEEE80211_AC_VI],
184 sdata->vif.hw_queue[IEEE80211_AC_BE],
185 sdata->vif.hw_queue[IEEE80211_AC_BK]);
186
187 if (sdata->vif.type == NL80211_IFTYPE_AP)
188 len += scnprintf(buf + len, buflen - len, "cab queue: %d\n",
189 sdata->vif.cab_queue);
190
191 return len;
192}
193__IEEE80211_IF_FILE(hw_queues, NULL);
171 194
172/* STA attributes */ 195/* STA attributes */
173IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 196IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
@@ -245,27 +268,6 @@ static ssize_t ieee80211_if_fmt_tkip_mic_test(
245 return -EOPNOTSUPP; 268 return -EOPNOTSUPP;
246} 269}
247 270
248static int hwaddr_aton(const char *txt, u8 *addr)
249{
250 int i;
251
252 for (i = 0; i < ETH_ALEN; i++) {
253 int a, b;
254
255 a = hex_to_bin(*txt++);
256 if (a < 0)
257 return -1;
258 b = hex_to_bin(*txt++);
259 if (b < 0)
260 return -1;
261 *addr++ = (a << 4) | b;
262 if (i < 5 && *txt++ != ':')
263 return -1;
264 }
265
266 return 0;
267}
268
269static ssize_t ieee80211_if_parse_tkip_mic_test( 271static ssize_t ieee80211_if_parse_tkip_mic_test(
270 struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) 272 struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
271{ 273{
@@ -275,13 +277,7 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
275 struct ieee80211_hdr *hdr; 277 struct ieee80211_hdr *hdr;
276 __le16 fc; 278 __le16 fc;
277 279
278 /* 280 if (!mac_pton(buf, addr))
279 * Assume colon-delimited MAC address with possible white space
280 * following.
281 */
282 if (buflen < 3 * ETH_ALEN - 1)
283 return -EINVAL;
284 if (hwaddr_aton(buf, addr) < 0)
285 return -EINVAL; 281 return -EINVAL;
286 282
287 if (!ieee80211_sdata_running(sdata)) 283 if (!ieee80211_sdata_running(sdata))
@@ -307,13 +303,16 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
307 case NL80211_IFTYPE_STATION: 303 case NL80211_IFTYPE_STATION:
308 fc |= cpu_to_le16(IEEE80211_FCTL_TODS); 304 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
309 /* BSSID SA DA */ 305 /* BSSID SA DA */
310 if (sdata->vif.bss_conf.bssid == NULL) { 306 mutex_lock(&sdata->u.mgd.mtx);
307 if (!sdata->u.mgd.associated) {
308 mutex_unlock(&sdata->u.mgd.mtx);
311 dev_kfree_skb(skb); 309 dev_kfree_skb(skb);
312 return -ENOTCONN; 310 return -ENOTCONN;
313 } 311 }
314 memcpy(hdr->addr1, sdata->vif.bss_conf.bssid, ETH_ALEN); 312 memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN);
315 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); 313 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
316 memcpy(hdr->addr3, addr, ETH_ALEN); 314 memcpy(hdr->addr3, addr, ETH_ALEN);
315 mutex_unlock(&sdata->u.mgd.mtx);
317 break; 316 break;
318 default: 317 default:
319 dev_kfree_skb(skb); 318 dev_kfree_skb(skb);
@@ -443,7 +442,7 @@ static ssize_t ieee80211_if_parse_tsf(
443 } 442 }
444 ret = kstrtoull(buf, 10, &tsf); 443 ret = kstrtoull(buf, 10, &tsf);
445 if (ret < 0) 444 if (ret < 0)
446 return -EINVAL; 445 return ret;
447 if (tsf_is_delta) 446 if (tsf_is_delta)
448 tsf = drv_get_tsf(local, sdata) + tsf_is_delta * tsf; 447 tsf = drv_get_tsf(local, sdata) + tsf_is_delta * tsf;
449 if (local->ops->set_tsf) { 448 if (local->ops->set_tsf) {
@@ -531,6 +530,7 @@ static void add_common_files(struct ieee80211_sub_if_data *sdata)
531 DEBUGFS_ADD(rc_rateidx_mask_5ghz); 530 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
532 DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz); 531 DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
533 DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz); 532 DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
533 DEBUGFS_ADD(hw_queues);
534} 534}
535 535
536static void add_sta_files(struct ieee80211_sub_if_data *sdata) 536static void add_sta_files(struct ieee80211_sub_if_data *sdata)
@@ -631,7 +631,9 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
631 631
632 DEBUGFS_ADD(flags); 632 DEBUGFS_ADD(flags);
633 DEBUGFS_ADD(state); 633 DEBUGFS_ADD(state);
634 DEBUGFS_ADD(channel_type); 634 DEBUGFS_ADD(txpower);
635 DEBUGFS_ADD(user_power_level);
636 DEBUGFS_ADD(ap_power_level);
635 637
636 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) 638 if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
637 add_common_files(sdata); 639 add_common_files(sdata);
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 5ccec2c1e9f..89281d24b09 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -14,6 +14,7 @@
14#include "debugfs.h" 14#include "debugfs.h"
15#include "debugfs_sta.h" 15#include "debugfs_sta.h"
16#include "sta_info.h" 16#include "sta_info.h"
17#include "driver-ops.h"
17 18
18/* sta attributtes */ 19/* sta attributtes */
19 20
@@ -131,10 +132,10 @@ STA_OPS(connected_time);
131static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, 132static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
132 size_t count, loff_t *ppos) 133 size_t count, loff_t *ppos)
133{ 134{
134 char buf[15*NUM_RX_DATA_QUEUES], *p = buf; 135 char buf[15*IEEE80211_NUM_TIDS], *p = buf;
135 int i; 136 int i;
136 struct sta_info *sta = file->private_data; 137 struct sta_info *sta = file->private_data;
137 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) 138 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
138 p += scnprintf(p, sizeof(buf)+buf-p, "%x ", 139 p += scnprintf(p, sizeof(buf)+buf-p, "%x ",
139 le16_to_cpu(sta->last_seq_ctrl[i])); 140 le16_to_cpu(sta->last_seq_ctrl[i]));
140 p += scnprintf(p, sizeof(buf)+buf-p, "\n"); 141 p += scnprintf(p, sizeof(buf)+buf-p, "\n");
@@ -145,7 +146,7 @@ STA_OPS(last_seq_ctrl);
145static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, 146static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
146 size_t count, loff_t *ppos) 147 size_t count, loff_t *ppos)
147{ 148{
148 char buf[71 + STA_TID_NUM * 40], *p = buf; 149 char buf[71 + IEEE80211_NUM_TIDS * 40], *p = buf;
149 int i; 150 int i;
150 struct sta_info *sta = file->private_data; 151 struct sta_info *sta = file->private_data;
151 struct tid_ampdu_rx *tid_rx; 152 struct tid_ampdu_rx *tid_rx;
@@ -158,7 +159,7 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
158 p += scnprintf(p, sizeof(buf) + buf - p, 159 p += scnprintf(p, sizeof(buf) + buf - p,
159 "TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tpending\n"); 160 "TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tpending\n");
160 161
161 for (i = 0; i < STA_TID_NUM; i++) { 162 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
162 tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]); 163 tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]);
163 tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[i]); 164 tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[i]);
164 165
@@ -220,7 +221,7 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu
220 221
221 tid = simple_strtoul(buf, NULL, 0); 222 tid = simple_strtoul(buf, NULL, 0);
222 223
223 if (tid >= STA_TID_NUM) 224 if (tid >= IEEE80211_NUM_TIDS)
224 return -EINVAL; 225 return -EINVAL;
225 226
226 if (tx) { 227 if (tx) {
@@ -334,6 +335,8 @@ STA_OPS(ht_capa);
334 335
335void ieee80211_sta_debugfs_add(struct sta_info *sta) 336void ieee80211_sta_debugfs_add(struct sta_info *sta)
336{ 337{
338 struct ieee80211_local *local = sta->local;
339 struct ieee80211_sub_if_data *sdata = sta->sdata;
337 struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations; 340 struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations;
338 u8 mac[3*ETH_ALEN]; 341 u8 mac[3*ETH_ALEN];
339 342
@@ -379,10 +382,16 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
379 DEBUGFS_ADD_COUNTER(tx_retry_failed, tx_retry_failed); 382 DEBUGFS_ADD_COUNTER(tx_retry_failed, tx_retry_failed);
380 DEBUGFS_ADD_COUNTER(tx_retry_count, tx_retry_count); 383 DEBUGFS_ADD_COUNTER(tx_retry_count, tx_retry_count);
381 DEBUGFS_ADD_COUNTER(wep_weak_iv_count, wep_weak_iv_count); 384 DEBUGFS_ADD_COUNTER(wep_weak_iv_count, wep_weak_iv_count);
385
386 drv_sta_add_debugfs(local, sdata, &sta->sta, sta->debugfs.dir);
382} 387}
383 388
384void ieee80211_sta_debugfs_remove(struct sta_info *sta) 389void ieee80211_sta_debugfs_remove(struct sta_info *sta)
385{ 390{
391 struct ieee80211_local *local = sta->local;
392 struct ieee80211_sub_if_data *sdata = sta->sdata;
393
394 drv_sta_remove_debugfs(local, sdata, &sta->sta, sta->debugfs.dir);
386 debugfs_remove_recursive(sta->debugfs.dir); 395 debugfs_remove_recursive(sta->debugfs.dir);
387 sta->debugfs.dir = NULL; 396 sta->debugfs.dir = NULL;
388} 397}
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 77407b31e1f..c6560cc7a9d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -490,6 +490,38 @@ static inline void drv_sta_remove(struct ieee80211_local *local,
490 trace_drv_return_void(local); 490 trace_drv_return_void(local);
491} 491}
492 492
493#ifdef CONFIG_MAC80211_DEBUGFS
494static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
495 struct ieee80211_sub_if_data *sdata,
496 struct ieee80211_sta *sta,
497 struct dentry *dir)
498{
499 might_sleep();
500
501 sdata = get_bss_sdata(sdata);
502 check_sdata_in_driver(sdata);
503
504 if (local->ops->sta_add_debugfs)
505 local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
506 sta, dir);
507}
508
509static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
510 struct ieee80211_sub_if_data *sdata,
511 struct ieee80211_sta *sta,
512 struct dentry *dir)
513{
514 might_sleep();
515
516 sdata = get_bss_sdata(sdata);
517 check_sdata_in_driver(sdata);
518
519 if (local->ops->sta_remove_debugfs)
520 local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
521 sta, dir);
522}
523#endif
524
493static inline __must_check 525static inline __must_check
494int drv_sta_state(struct ieee80211_local *local, 526int drv_sta_state(struct ieee80211_local *local,
495 struct ieee80211_sub_if_data *sdata, 527 struct ieee80211_sub_if_data *sdata,
@@ -704,17 +736,17 @@ static inline int drv_get_antenna(struct ieee80211_local *local,
704} 736}
705 737
706static inline int drv_remain_on_channel(struct ieee80211_local *local, 738static inline int drv_remain_on_channel(struct ieee80211_local *local,
739 struct ieee80211_sub_if_data *sdata,
707 struct ieee80211_channel *chan, 740 struct ieee80211_channel *chan,
708 enum nl80211_channel_type chantype,
709 unsigned int duration) 741 unsigned int duration)
710{ 742{
711 int ret; 743 int ret;
712 744
713 might_sleep(); 745 might_sleep();
714 746
715 trace_drv_remain_on_channel(local, chan, chantype, duration); 747 trace_drv_remain_on_channel(local, sdata, chan, duration);
716 ret = local->ops->remain_on_channel(&local->hw, chan, chantype, 748 ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
717 duration); 749 chan, duration);
718 trace_drv_return_int(local, ret); 750 trace_drv_return_int(local, ret);
719 751
720 return ret; 752 return ret;
@@ -936,4 +968,39 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
936 trace_drv_return_void(local); 968 trace_drv_return_void(local);
937} 969}
938 970
971static inline int drv_start_ap(struct ieee80211_local *local,
972 struct ieee80211_sub_if_data *sdata)
973{
974 int ret = 0;
975
976 check_sdata_in_driver(sdata);
977
978 trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf);
979 if (local->ops->start_ap)
980 ret = local->ops->start_ap(&local->hw, &sdata->vif);
981 trace_drv_return_int(local, ret);
982 return ret;
983}
984
985static inline void drv_stop_ap(struct ieee80211_local *local,
986 struct ieee80211_sub_if_data *sdata)
987{
988 check_sdata_in_driver(sdata);
989
990 trace_drv_stop_ap(local, sdata);
991 if (local->ops->stop_ap)
992 local->ops->stop_ap(&local->hw, &sdata->vif);
993 trace_drv_return_void(local);
994}
995
996static inline void drv_restart_complete(struct ieee80211_local *local)
997{
998 might_sleep();
999
1000 trace_drv_restart_complete(local);
1001 if (local->ops->restart_complete)
1002 local->ops->restart_complete(&local->hw);
1003 trace_drv_return_void(local);
1004}
1005
939#endif /* __MAC80211_DRIVER_OPS */ 1006#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 4b4538d6392..a71d891794a 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -185,7 +185,7 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx)
185 185
186 cancel_work_sync(&sta->ampdu_mlme.work); 186 cancel_work_sync(&sta->ampdu_mlme.work);
187 187
188 for (i = 0; i < STA_TID_NUM; i++) { 188 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
189 __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx); 189 __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx);
190 __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, 190 __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
191 WLAN_REASON_QSTA_LEAVE_QBSS, tx); 191 WLAN_REASON_QSTA_LEAVE_QBSS, tx);
@@ -209,7 +209,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
209 return; 209 return;
210 210
211 mutex_lock(&sta->ampdu_mlme.mtx); 211 mutex_lock(&sta->ampdu_mlme.mtx);
212 for (tid = 0; tid < STA_TID_NUM; tid++) { 212 for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) {
213 if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired)) 213 if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired))
214 ___ieee80211_stop_rx_ba_session( 214 ___ieee80211_stop_rx_ba_session(
215 sta, tid, WLAN_BACK_RECIPIENT, 215 sta, tid, WLAN_BACK_RECIPIENT,
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 67774b05353..fa862b24a7e 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -51,7 +51,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
51 struct cfg80211_bss *bss; 51 struct cfg80211_bss *bss;
52 u32 bss_change; 52 u32 bss_change;
53 u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; 53 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
54 enum nl80211_channel_type channel_type; 54 struct cfg80211_chan_def chandef;
55 55
56 lockdep_assert_held(&ifibss->mtx); 56 lockdep_assert_held(&ifibss->mtx);
57 57
@@ -79,12 +79,14 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
79 79
80 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; 80 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
81 81
82 channel_type = ifibss->channel_type; 82 cfg80211_chandef_create(&chandef, chan, ifibss->channel_type);
83 if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) 83 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
84 channel_type = NL80211_CHAN_HT20; 84 chandef.width = NL80211_CHAN_WIDTH_20;
85 chandef.center_freq1 = chan->center_freq;
86 }
85 87
86 ieee80211_vif_release_channel(sdata); 88 ieee80211_vif_release_channel(sdata);
87 if (ieee80211_vif_use_channel(sdata, chan, channel_type, 89 if (ieee80211_vif_use_channel(sdata, &chandef,
88 ifibss->fixed_channel ? 90 ifibss->fixed_channel ?
89 IEEE80211_CHANCTX_SHARED : 91 IEEE80211_CHANCTX_SHARED :
90 IEEE80211_CHANCTX_EXCLUSIVE)) { 92 IEEE80211_CHANCTX_EXCLUSIVE)) {
@@ -158,7 +160,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
158 ifibss->ie, ifibss->ie_len); 160 ifibss->ie, ifibss->ie_len);
159 161
160 /* add HT capability and information IEs */ 162 /* add HT capability and information IEs */
161 if (channel_type && sband->ht_cap.ht_supported) { 163 if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
164 sband->ht_cap.ht_supported) {
162 pos = skb_put(skb, 4 + 165 pos = skb_put(skb, 4 +
163 sizeof(struct ieee80211_ht_cap) + 166 sizeof(struct ieee80211_ht_cap) +
164 sizeof(struct ieee80211_ht_operation)); 167 sizeof(struct ieee80211_ht_operation));
@@ -170,7 +173,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
170 * keep them at 0 173 * keep them at 0
171 */ 174 */
172 pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, 175 pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap,
173 chan, channel_type, 0); 176 &chandef, 0);
174 } 177 }
175 178
176 if (local->hw.queues >= IEEE80211_NUM_ACS) { 179 if (local->hw.queues >= IEEE80211_NUM_ACS) {
@@ -326,7 +329,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
326 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 329 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
327 if (WARN_ON_ONCE(!chanctx_conf)) 330 if (WARN_ON_ONCE(!chanctx_conf))
328 return NULL; 331 return NULL;
329 band = chanctx_conf->channel->band; 332 band = chanctx_conf->def.chan->band;
330 rcu_read_unlock(); 333 rcu_read_unlock();
331 334
332 sta = sta_info_alloc(sdata, addr, GFP_KERNEL); 335 sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
@@ -374,11 +377,13 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
374 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); 377 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
375 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); 378 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
376 379
377 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
378 return;
379 ibss_dbg(sdata, 380 ibss_dbg(sdata,
380 "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", 381 "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n",
381 mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); 382 mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction);
383
384 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
385 return;
386
382 sta_info_destroy_addr(sdata, mgmt->sa); 387 sta_info_destroy_addr(sdata, mgmt->sa);
383 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); 388 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
384 rcu_read_unlock(); 389 rcu_read_unlock();
@@ -473,9 +478,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
473 sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) { 478 sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) {
474 /* we both use HT */ 479 /* we both use HT */
475 struct ieee80211_sta_ht_cap sta_ht_cap_new; 480 struct ieee80211_sta_ht_cap sta_ht_cap_new;
476 enum nl80211_channel_type channel_type = 481 struct cfg80211_chan_def chandef;
477 ieee80211_ht_oper_to_channel_type( 482
478 elems->ht_operation); 483 ieee80211_ht_oper_to_chandef(channel,
484 elems->ht_operation,
485 &chandef);
479 486
480 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 487 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
481 elems->ht_cap_elem, 488 elems->ht_cap_elem,
@@ -485,9 +492,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
485 * fall back to HT20 if we don't use or use 492 * fall back to HT20 if we don't use or use
486 * the other extension channel 493 * the other extension channel
487 */ 494 */
488 if (!(channel_type == NL80211_CHAN_HT40MINUS || 495 if (chandef.width != NL80211_CHAN_WIDTH_40 ||
489 channel_type == NL80211_CHAN_HT40PLUS) || 496 cfg80211_get_chandef_type(&chandef) !=
490 channel_type != sdata->u.ibss.channel_type) 497 sdata->u.ibss.channel_type)
491 sta_ht_cap_new.cap &= 498 sta_ht_cap_new.cap &=
492 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 499 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
493 500
@@ -543,30 +550,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
543 if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid)) 550 if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid))
544 goto put_bss; 551 goto put_bss;
545 552
546 if (rx_status->flag & RX_FLAG_MACTIME_MPDU) { 553 if (ieee80211_have_rx_timestamp(rx_status)) {
547 /* 554 /* time when timestamp field was received */
548 * For correct IBSS merging we need mactime; since mactime is 555 rx_timestamp =
549 * defined as the time the first data symbol of the frame hits 556 ieee80211_calculate_rx_timestamp(local, rx_status,
550 * the PHY, and the timestamp of the beacon is defined as "the 557 len + FCS_LEN, 24);
551 * time that the data symbol containing the first bit of the
552 * timestamp is transmitted to the PHY plus the transmitting
553 * STA's delays through its local PHY from the MAC-PHY
554 * interface to its interface with the WM" (802.11 11.1.2)
555 * - equals the time this bit arrives at the receiver - we have
556 * to take into account the offset between the two.
557 *
558 * E.g. at 1 MBit that means mactime is 192 usec earlier
559 * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
560 */
561 int rate;
562
563 if (rx_status->flag & RX_FLAG_HT)
564 rate = 65; /* TODO: HT rates */
565 else
566 rate = local->hw.wiphy->bands[band]->
567 bitrates[rx_status->rate_idx].bitrate;
568
569 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
570 } else { 558 } else {
571 /* 559 /*
572 * second best option: get current TSF 560 * second best option: get current TSF
@@ -630,7 +618,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
630 rcu_read_unlock(); 618 rcu_read_unlock();
631 return; 619 return;
632 } 620 }
633 band = chanctx_conf->channel->band; 621 band = chanctx_conf->def.chan->band;
634 rcu_read_unlock(); 622 rcu_read_unlock();
635 623
636 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); 624 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
@@ -1095,8 +1083,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1095 1083
1096 sdata->vif.bss_conf.beacon_int = params->beacon_interval; 1084 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
1097 1085
1098 sdata->u.ibss.channel = params->channel; 1086 sdata->u.ibss.channel = params->chandef.chan;
1099 sdata->u.ibss.channel_type = params->channel_type; 1087 sdata->u.ibss.channel_type =
1088 cfg80211_get_chandef_type(&params->chandef);
1100 sdata->u.ibss.fixed_channel = params->channel_fixed; 1089 sdata->u.ibss.fixed_channel = params->channel_fixed;
1101 1090
1102 if (params->ie) { 1091 if (params->ie) {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 32e47853f32..5c0d5a6946c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -56,6 +56,9 @@ struct ieee80211_local;
56#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) 56#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024))
57#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) 57#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x))
58 58
59/* power level hasn't been configured (or set to automatic) */
60#define IEEE80211_UNSET_POWER_LEVEL INT_MIN
61
59/* 62/*
60 * Some APs experience problems when working with U-APSD. Decrease the 63 * Some APs experience problems when working with U-APSD. Decrease the
61 * probability of that happening by using legacy mode for all ACs but VO. 64 * probability of that happening by using legacy mode for all ACs but VO.
@@ -345,7 +348,6 @@ struct ieee80211_roc_work {
345 struct ieee80211_sub_if_data *sdata; 348 struct ieee80211_sub_if_data *sdata;
346 349
347 struct ieee80211_channel *chan; 350 struct ieee80211_channel *chan;
348 enum nl80211_channel_type chan_type;
349 351
350 bool started, abort, hw_begun, notified; 352 bool started, abort, hw_begun, notified;
351 353
@@ -353,7 +355,7 @@ struct ieee80211_roc_work {
353 355
354 u32 duration, req_duration; 356 u32 duration, req_duration;
355 struct sk_buff *frame; 357 struct sk_buff *frame;
356 u64 mgmt_tx_cookie; 358 u64 cookie, mgmt_tx_cookie;
357}; 359};
358 360
359/* flags used in struct ieee80211_if_managed.flags */ 361/* flags used in struct ieee80211_if_managed.flags */
@@ -361,7 +363,7 @@ enum ieee80211_sta_flags {
361 IEEE80211_STA_BEACON_POLL = BIT(0), 363 IEEE80211_STA_BEACON_POLL = BIT(0),
362 IEEE80211_STA_CONNECTION_POLL = BIT(1), 364 IEEE80211_STA_CONNECTION_POLL = BIT(1),
363 IEEE80211_STA_CONTROL_PORT = BIT(2), 365 IEEE80211_STA_CONTROL_PORT = BIT(2),
364 IEEE80211_STA_DISABLE_11N = BIT(4), 366 IEEE80211_STA_DISABLE_HT = BIT(4),
365 IEEE80211_STA_CSA_RECEIVED = BIT(5), 367 IEEE80211_STA_CSA_RECEIVED = BIT(5),
366 IEEE80211_STA_MFP_ENABLED = BIT(6), 368 IEEE80211_STA_MFP_ENABLED = BIT(6),
367 IEEE80211_STA_UAPSD_ENABLED = BIT(7), 369 IEEE80211_STA_UAPSD_ENABLED = BIT(7),
@@ -470,6 +472,8 @@ struct ieee80211_if_managed {
470 472
471 u8 use_4addr; 473 u8 use_4addr;
472 474
475 u8 p2p_noa_index;
476
473 /* Signal strength from the last Beacon frame in the current BSS. */ 477 /* Signal strength from the last Beacon frame in the current BSS. */
474 int last_beacon_signal; 478 int last_beacon_signal;
475 479
@@ -743,6 +747,9 @@ struct ieee80211_sub_if_data {
743 u8 needed_rx_chains; 747 u8 needed_rx_chains;
744 enum ieee80211_smps_mode smps_mode; 748 enum ieee80211_smps_mode smps_mode;
745 749
750 int user_power_level; /* in dBm */
751 int ap_power_level; /* in dBm */
752
746 /* 753 /*
747 * AP this belongs to: self in AP mode and 754 * AP this belongs to: self in AP mode and
748 * corresponding AP in VLAN mode, NULL for 755 * corresponding AP in VLAN mode, NULL for
@@ -792,7 +799,7 @@ ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
792 rcu_read_lock(); 799 rcu_read_lock();
793 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 800 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
794 if (!WARN_ON(!chanctx_conf)) 801 if (!WARN_ON(!chanctx_conf))
795 band = chanctx_conf->channel->band; 802 band = chanctx_conf->def.chan->band;
796 rcu_read_unlock(); 803 rcu_read_unlock();
797 804
798 return band; 805 return band;
@@ -1040,7 +1047,6 @@ struct ieee80211_local {
1040 1047
1041 /* Temporary remain-on-channel for off-channel operations */ 1048 /* Temporary remain-on-channel for off-channel operations */
1042 struct ieee80211_channel *tmp_channel; 1049 struct ieee80211_channel *tmp_channel;
1043 enum nl80211_channel_type tmp_channel_type;
1044 1050
1045 /* channel contexts */ 1051 /* channel contexts */
1046 struct list_head chanctx_list; 1052 struct list_head chanctx_list;
@@ -1117,8 +1123,7 @@ struct ieee80211_local {
1117 int dynamic_ps_user_timeout; 1123 int dynamic_ps_user_timeout;
1118 bool disable_dynamic_ps; 1124 bool disable_dynamic_ps;
1119 1125
1120 int user_power_level; /* in dBm */ 1126 int user_power_level; /* in dBm, for all interfaces */
1121 int ap_power_level; /* in dBm */
1122 1127
1123 enum ieee80211_smps_mode smps_mode; 1128 enum ieee80211_smps_mode smps_mode;
1124 1129
@@ -1137,6 +1142,7 @@ struct ieee80211_local {
1137 struct list_head roc_list; 1142 struct list_head roc_list;
1138 struct work_struct hw_roc_start, hw_roc_done; 1143 struct work_struct hw_roc_start, hw_roc_done;
1139 unsigned long hw_roc_start_time; 1144 unsigned long hw_roc_start_time;
1145 u64 roc_cookie_counter;
1140 1146
1141 struct idr ack_status_frames; 1147 struct idr ack_status_frames;
1142 spinlock_t ack_status_lock; 1148 spinlock_t ack_status_lock;
@@ -1150,8 +1156,7 @@ struct ieee80211_local {
1150 1156
1151 /* virtual monitor interface */ 1157 /* virtual monitor interface */
1152 struct ieee80211_sub_if_data __rcu *monitor_sdata; 1158 struct ieee80211_sub_if_data __rcu *monitor_sdata;
1153 struct ieee80211_channel *monitor_channel; 1159 struct cfg80211_chan_def monitor_chandef;
1154 enum nl80211_channel_type monitor_channel_type;
1155}; 1160};
1156 1161
1157static inline struct ieee80211_sub_if_data * 1162static inline struct ieee80211_sub_if_data *
@@ -1251,7 +1256,18 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
1251 is_broadcast_ether_addr(raddr); 1256 is_broadcast_ether_addr(raddr);
1252} 1257}
1253 1258
1259static inline bool
1260ieee80211_have_rx_timestamp(struct ieee80211_rx_status *status)
1261{
1262 WARN_ON_ONCE(status->flag & RX_FLAG_MACTIME_START &&
1263 status->flag & RX_FLAG_MACTIME_END);
1264 return status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END);
1265}
1254 1266
1267u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
1268 struct ieee80211_rx_status *status,
1269 unsigned int mpdu_len,
1270 unsigned int mpdu_offset);
1255int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); 1271int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
1256void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); 1272void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
1257void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, 1273void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
@@ -1365,6 +1381,9 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
1365int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up); 1381int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up);
1366void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata); 1382void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata);
1367 1383
1384bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
1385void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
1386
1368static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) 1387static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
1369{ 1388{
1370 return test_bit(SDATA_STATE_RUNNING, &sdata->state); 1389 return test_bit(SDATA_STATE_RUNNING, &sdata->state);
@@ -1496,7 +1515,7 @@ static inline void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
1496 } 1515 }
1497 1516
1498 __ieee80211_tx_skb_tid_band(sdata, skb, tid, 1517 __ieee80211_tx_skb_tid_band(sdata, skb, tid,
1499 chanctx_conf->channel->band); 1518 chanctx_conf->def.chan->band);
1500 rcu_read_unlock(); 1519 rcu_read_unlock();
1501} 1520}
1502 1521
@@ -1585,8 +1604,7 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
1585u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1604u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1586 u16 cap); 1605 u16 cap);
1587u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1606u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1588 struct ieee80211_channel *channel, 1607 const struct cfg80211_chan_def *chandef,
1589 enum nl80211_channel_type channel_type,
1590 u16 prot_mode); 1608 u16 prot_mode);
1591u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, 1609u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1592 u32 cap); 1610 u32 cap);
@@ -1598,13 +1616,13 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1598 enum ieee80211_band band); 1616 enum ieee80211_band band);
1599 1617
1600/* channel management */ 1618/* channel management */
1601enum nl80211_channel_type 1619void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
1602ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper); 1620 struct ieee80211_ht_operation *ht_oper,
1621 struct cfg80211_chan_def *chandef);
1603 1622
1604int __must_check 1623int __must_check
1605ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 1624ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
1606 struct ieee80211_channel *channel, 1625 const struct cfg80211_chan_def *chandef,
1607 enum nl80211_channel_type channel_type,
1608 enum ieee80211_chanctx_mode mode); 1626 enum ieee80211_chanctx_mode mode);
1609void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); 1627void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
1610 1628
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index bc3e3e1db09..5331662489f 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -42,6 +42,41 @@
42 * by either the RTNL, the iflist_mtx or RCU. 42 * by either the RTNL, the iflist_mtx or RCU.
43 */ 43 */
44 44
45bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
46{
47 struct ieee80211_chanctx_conf *chanctx_conf;
48 int power;
49
50 rcu_read_lock();
51 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
52 if (!chanctx_conf) {
53 rcu_read_unlock();
54 return false;
55 }
56
57 power = chanctx_conf->def.chan->max_power;
58 rcu_read_unlock();
59
60 if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
61 power = min(power, sdata->user_power_level);
62
63 if (sdata->ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
64 power = min(power, sdata->ap_power_level);
65
66 if (power != sdata->vif.bss_conf.txpower) {
67 sdata->vif.bss_conf.txpower = power;
68 ieee80211_hw_config(sdata->local, 0);
69 return true;
70 }
71
72 return false;
73}
74
75void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
76{
77 if (__ieee80211_recalc_txpower(sdata))
78 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
79}
45 80
46static u32 ieee80211_idle_off(struct ieee80211_local *local, 81static u32 ieee80211_idle_off(struct ieee80211_local *local,
47 const char *reason) 82 const char *reason)
@@ -380,8 +415,7 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
380 goto out_unlock; 415 goto out_unlock;
381 } 416 }
382 417
383 ret = ieee80211_vif_use_channel(sdata, local->monitor_channel, 418 ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
384 local->monitor_channel_type,
385 IEEE80211_CHANCTX_EXCLUSIVE); 419 IEEE80211_CHANCTX_EXCLUSIVE);
386 if (ret) { 420 if (ret) {
387 drv_remove_interface(local, sdata); 421 drv_remove_interface(local, sdata);
@@ -744,31 +778,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
744 /* APs need special treatment */ 778 /* APs need special treatment */
745 if (sdata->vif.type == NL80211_IFTYPE_AP) { 779 if (sdata->vif.type == NL80211_IFTYPE_AP) {
746 struct ieee80211_sub_if_data *vlan, *tmpsdata; 780 struct ieee80211_sub_if_data *vlan, *tmpsdata;
747 struct beacon_data *old_beacon =
748 rtnl_dereference(sdata->u.ap.beacon);
749 struct probe_resp *old_probe_resp =
750 rtnl_dereference(sdata->u.ap.probe_resp);
751
752 /* sdata_running will return false, so this will disable */
753 ieee80211_bss_info_change_notify(sdata,
754 BSS_CHANGED_BEACON_ENABLED);
755
756 /* remove beacon and probe response */
757 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
758 RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
759 synchronize_rcu();
760 kfree(old_beacon);
761 kfree(old_probe_resp);
762 781
763 /* down all dependent devices, that is VLANs */ 782 /* down all dependent devices, that is VLANs */
764 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, 783 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
765 u.vlan.list) 784 u.vlan.list)
766 dev_close(vlan->dev); 785 dev_close(vlan->dev);
767 WARN_ON(!list_empty(&sdata->u.ap.vlans)); 786 WARN_ON(!list_empty(&sdata->u.ap.vlans));
768
769 /* free all potentially still buffered bcast frames */
770 local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
771 skb_queue_purge(&sdata->u.ap.ps.bc_buf);
772 } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { 787 } else if (sdata->vif.type == NL80211_IFTYPE_STATION) {
773 ieee80211_mgd_stop(sdata); 788 ieee80211_mgd_stop(sdata);
774 } 789 }
@@ -1529,6 +1544,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1529 1544
1530 ieee80211_set_default_queues(sdata); 1545 ieee80211_set_default_queues(sdata);
1531 1546
1547 sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
1548 sdata->user_power_level = local->user_power_level;
1549
1532 /* setup type-dependent data */ 1550 /* setup type-dependent data */
1533 ieee80211_setup_sdata(sdata, type); 1551 ieee80211_setup_sdata(sdata, type);
1534 1552
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index d27e61aaa71..619c5d69799 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -339,7 +339,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
339 key->conf.iv_len = TKIP_IV_LEN; 339 key->conf.iv_len = TKIP_IV_LEN;
340 key->conf.icv_len = TKIP_ICV_LEN; 340 key->conf.icv_len = TKIP_ICV_LEN;
341 if (seq) { 341 if (seq) {
342 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) { 342 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
343 key->u.tkip.rx[i].iv32 = 343 key->u.tkip.rx[i].iv32 =
344 get_unaligned_le32(&seq[2]); 344 get_unaligned_le32(&seq[2]);
345 key->u.tkip.rx[i].iv16 = 345 key->u.tkip.rx[i].iv16 =
@@ -352,7 +352,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
352 key->conf.iv_len = CCMP_HDR_LEN; 352 key->conf.iv_len = CCMP_HDR_LEN;
353 key->conf.icv_len = CCMP_MIC_LEN; 353 key->conf.icv_len = CCMP_MIC_LEN;
354 if (seq) { 354 if (seq) {
355 for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) 355 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++)
356 for (j = 0; j < CCMP_PN_LEN; j++) 356 for (j = 0; j < CCMP_PN_LEN; j++)
357 key->u.ccmp.rx_pn[i][j] = 357 key->u.ccmp.rx_pn[i][j] =
358 seq[CCMP_PN_LEN - j - 1]; 358 seq[CCMP_PN_LEN - j - 1];
@@ -372,8 +372,9 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
372 key->conf.iv_len = 0; 372 key->conf.iv_len = 0;
373 key->conf.icv_len = sizeof(struct ieee80211_mmie); 373 key->conf.icv_len = sizeof(struct ieee80211_mmie);
374 if (seq) 374 if (seq)
375 for (j = 0; j < 6; j++) 375 for (j = 0; j < CMAC_PN_LEN; j++)
376 key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1]; 376 key->u.aes_cmac.rx_pn[j] =
377 seq[CMAC_PN_LEN - j - 1];
377 /* 378 /*
378 * Initialize AES key state here as an optimization so that 379 * Initialize AES key state here as an optimization so that
379 * it does not need to be initialized for every packet. 380 * it does not need to be initialized for every packet.
@@ -654,16 +655,16 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
654 655
655 switch (key->conf.cipher) { 656 switch (key->conf.cipher) {
656 case WLAN_CIPHER_SUITE_TKIP: 657 case WLAN_CIPHER_SUITE_TKIP:
657 if (WARN_ON(tid < 0 || tid >= NUM_RX_DATA_QUEUES)) 658 if (WARN_ON(tid < 0 || tid >= IEEE80211_NUM_TIDS))
658 return; 659 return;
659 seq->tkip.iv32 = key->u.tkip.rx[tid].iv32; 660 seq->tkip.iv32 = key->u.tkip.rx[tid].iv32;
660 seq->tkip.iv16 = key->u.tkip.rx[tid].iv16; 661 seq->tkip.iv16 = key->u.tkip.rx[tid].iv16;
661 break; 662 break;
662 case WLAN_CIPHER_SUITE_CCMP: 663 case WLAN_CIPHER_SUITE_CCMP:
663 if (WARN_ON(tid < -1 || tid >= NUM_RX_DATA_QUEUES)) 664 if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
664 return; 665 return;
665 if (tid < 0) 666 if (tid < 0)
666 pn = key->u.ccmp.rx_pn[NUM_RX_DATA_QUEUES]; 667 pn = key->u.ccmp.rx_pn[IEEE80211_NUM_TIDS];
667 else 668 else
668 pn = key->u.ccmp.rx_pn[tid]; 669 pn = key->u.ccmp.rx_pn[tid];
669 memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN); 670 memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN);
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 7d4e31f037d..7cff0d3a519 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -30,8 +30,6 @@
30#define TKIP_ICV_LEN 4 30#define TKIP_ICV_LEN 4
31#define CMAC_PN_LEN 6 31#define CMAC_PN_LEN 6
32 32
33#define NUM_RX_DATA_QUEUES 16
34
35struct ieee80211_local; 33struct ieee80211_local;
36struct ieee80211_sub_if_data; 34struct ieee80211_sub_if_data;
37struct sta_info; 35struct sta_info;
@@ -82,17 +80,17 @@ struct ieee80211_key {
82 struct tkip_ctx tx; 80 struct tkip_ctx tx;
83 81
84 /* last received RSC */ 82 /* last received RSC */
85 struct tkip_ctx rx[NUM_RX_DATA_QUEUES]; 83 struct tkip_ctx rx[IEEE80211_NUM_TIDS];
86 } tkip; 84 } tkip;
87 struct { 85 struct {
88 atomic64_t tx_pn; 86 atomic64_t tx_pn;
89 /* 87 /*
90 * Last received packet number. The first 88 * Last received packet number. The first
91 * NUM_RX_DATA_QUEUES counters are used with Data 89 * IEEE80211_NUM_TIDS counters are used with Data
92 * frames and the last counter is used with Robust 90 * frames and the last counter is used with Robust
93 * Management frames. 91 * Management frames.
94 */ 92 */
95 u8 rx_pn[NUM_RX_DATA_QUEUES + 1][CCMP_PN_LEN]; 93 u8 rx_pn[IEEE80211_NUM_TIDS + 1][CCMP_PN_LEN];
96 struct crypto_cipher *tfm; 94 struct crypto_cipher *tfm;
97 u32 replays; /* dot11RSNAStatsCCMPReplays */ 95 u32 replays; /* dot11RSNAStatsCCMPReplays */
98 } ccmp; 96 } ccmp;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d6e43b08d62..f5e4c1f24bf 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -95,11 +95,13 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
95 95
96static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) 96static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
97{ 97{
98 struct ieee80211_sub_if_data *sdata;
98 struct ieee80211_channel *chan; 99 struct ieee80211_channel *chan;
99 u32 changed = 0; 100 u32 changed = 0;
100 int power; 101 int power;
101 enum nl80211_channel_type channel_type; 102 enum nl80211_channel_type channel_type;
102 u32 offchannel_flag; 103 u32 offchannel_flag;
104 bool scanning = false;
103 105
104 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 106 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
105 if (local->scan_channel) { 107 if (local->scan_channel) {
@@ -113,7 +115,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
113 channel_type = NL80211_CHAN_NO_HT; 115 channel_type = NL80211_CHAN_NO_HT;
114 } else if (local->tmp_channel) { 116 } else if (local->tmp_channel) {
115 chan = local->tmp_channel; 117 chan = local->tmp_channel;
116 channel_type = local->tmp_channel_type; 118 channel_type = NL80211_CHAN_NO_HT;
117 } else { 119 } else {
118 chan = local->_oper_channel; 120 chan = local->_oper_channel;
119 channel_type = local->_oper_channel_type; 121 channel_type = local->_oper_channel_type;
@@ -146,16 +148,18 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
146 changed |= IEEE80211_CONF_CHANGE_SMPS; 148 changed |= IEEE80211_CONF_CHANGE_SMPS;
147 } 149 }
148 150
149 if (test_bit(SCAN_SW_SCANNING, &local->scanning) || 151 scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
150 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || 152 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
151 test_bit(SCAN_HW_SCANNING, &local->scanning) || 153 test_bit(SCAN_HW_SCANNING, &local->scanning);
152 !local->ap_power_level) 154 power = chan->max_power;
153 power = chan->max_power;
154 else
155 power = min(chan->max_power, local->ap_power_level);
156 155
157 if (local->user_power_level >= 0) 156 rcu_read_lock();
158 power = min(power, local->user_power_level); 157 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
158 if (!rcu_access_pointer(sdata->vif.chanctx_conf))
159 continue;
160 power = min(power, sdata->vif.bss_conf.txpower);
161 }
162 rcu_read_unlock();
159 163
160 if (local->hw.conf.power_level != power) { 164 if (local->hw.conf.power_level != power) {
161 changed |= IEEE80211_CONF_CHANGE_POWER; 165 changed |= IEEE80211_CONF_CHANGE_POWER;
@@ -600,7 +604,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
600 604
601 wiphy->features |= NL80211_FEATURE_SK_TX_STATUS | 605 wiphy->features |= NL80211_FEATURE_SK_TX_STATUS |
602 NL80211_FEATURE_SAE | 606 NL80211_FEATURE_SAE |
603 NL80211_FEATURE_HT_IBSS; 607 NL80211_FEATURE_HT_IBSS |
608 NL80211_FEATURE_VIF_TXPOWER;
604 609
605 if (!ops->hw_scan) 610 if (!ops->hw_scan)
606 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | 611 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
@@ -633,7 +638,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
633 local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS | 638 local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
634 IEEE80211_RADIOTAP_MCS_HAVE_GI | 639 IEEE80211_RADIOTAP_MCS_HAVE_GI |
635 IEEE80211_RADIOTAP_MCS_HAVE_BW; 640 IEEE80211_RADIOTAP_MCS_HAVE_BW;
636 local->user_power_level = -1; 641 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
637 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; 642 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
638 643
639 INIT_LIST_HEAD(&local->interfaces); 644 INIT_LIST_HEAD(&local->interfaces);
@@ -793,10 +798,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
793 local->_oper_channel = &sband->channels[0]; 798 local->_oper_channel = &sband->channels[0];
794 local->hw.conf.channel_type = NL80211_CHAN_NO_HT; 799 local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
795 } 800 }
796 if (!local->monitor_channel) { 801 cfg80211_chandef_create(&local->monitor_chandef,
797 local->monitor_channel = &sband->channels[0]; 802 &sband->channels[0],
798 local->monitor_channel_type = NL80211_CHAN_NO_HT; 803 NL80211_CHAN_NO_HT);
799 }
800 channels += sband->n_channels; 804 channels += sband->n_channels;
801 805
802 if (max_bitrates < sband->n_bitrates) 806 if (max_bitrates < sband->n_bitrates)
@@ -879,10 +883,22 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
879 if (supp_ht) 883 if (supp_ht)
880 local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); 884 local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
881 885
882 if (supp_vht) 886 if (supp_vht) {
883 local->scan_ies_len += 887 local->scan_ies_len +=
884 2 + sizeof(struct ieee80211_vht_cap); 888 2 + sizeof(struct ieee80211_vht_cap);
885 889
890 /*
891 * (for now at least), drivers wanting to use VHT must
892 * support channel contexts, as they contain all the
893 * necessary VHT information and the global hw config
894 * doesn't (yet)
895 */
896 if (WARN_ON(!local->use_chanctx)) {
897 result = -EINVAL;
898 goto fail_wiphy_register;
899 }
900 }
901
886 if (!local->ops->hw_scan) { 902 if (!local->ops->hw_scan) {
887 /* For hw_scan, driver needs to set these up. */ 903 /* For hw_scan, driver needs to set these up. */
888 local->hw.wiphy->max_scan_ssids = 4; 904 local->hw.wiphy->max_scan_ssids = 4;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index a350cab4b33..1bf03f9ff3b 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -76,7 +76,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
76 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 76 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
77 struct ieee80211_local *local = sdata->local; 77 struct ieee80211_local *local = sdata->local;
78 u32 basic_rates = 0; 78 u32 basic_rates = 0;
79 enum nl80211_channel_type sta_channel_type = NL80211_CHAN_NO_HT; 79 struct cfg80211_chan_def sta_chan_def;
80 80
81 /* 81 /*
82 * As support for each feature is added, check for matching 82 * As support for each feature is added, check for matching
@@ -103,17 +103,11 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
103 if (sdata->vif.bss_conf.basic_rates != basic_rates) 103 if (sdata->vif.bss_conf.basic_rates != basic_rates)
104 goto mismatch; 104 goto mismatch;
105 105
106 if (ie->ht_operation) 106 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
107 sta_channel_type = 107 ie->ht_operation, &sta_chan_def);
108 ieee80211_ht_oper_to_channel_type(ie->ht_operation); 108
109 109 if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef,
110 /* Disallow HT40+/- mismatch */ 110 &sta_chan_def))
111 if (ie->ht_operation &&
112 (sdata->vif.bss_conf.channel_type == NL80211_CHAN_HT40MINUS ||
113 sdata->vif.bss_conf.channel_type == NL80211_CHAN_HT40PLUS) &&
114 (sta_channel_type == NL80211_CHAN_HT40MINUS ||
115 sta_channel_type == NL80211_CHAN_HT40PLUS) &&
116 sdata->vif.bss_conf.channel_type != sta_channel_type)
117 goto mismatch; 111 goto mismatch;
118 112
119 return true; 113 return true;
@@ -129,7 +123,7 @@ mismatch:
129bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) 123bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
130{ 124{
131 return (ie->mesh_config->meshconf_cap & 125 return (ie->mesh_config->meshconf_cap &
132 MESHCONF_CAPAB_ACCEPT_PLINKS) != 0; 126 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS) != 0;
133} 127}
134 128
135/** 129/**
@@ -269,11 +263,11 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
269 neighbors = (neighbors > 15) ? 15 : neighbors; 263 neighbors = (neighbors > 15) ? 15 : neighbors;
270 *pos++ = neighbors << 1; 264 *pos++ = neighbors << 1;
271 /* Mesh capability */ 265 /* Mesh capability */
272 *pos = MESHCONF_CAPAB_FORWARDING; 266 *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING;
273 *pos |= ifmsh->accepting_plinks ? 267 *pos |= ifmsh->accepting_plinks ?
274 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 268 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
275 *pos++ |= ifmsh->adjusting_tbtt ? 269 *pos++ |= ifmsh->adjusting_tbtt ?
276 MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00; 270 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00;
277 *pos++ = 0x00; 271 *pos++ = 0x00;
278 272
279 return 0; 273 return 0;
@@ -368,7 +362,7 @@ int mesh_add_ds_params_ie(struct sk_buff *skb,
368 rcu_read_unlock(); 362 rcu_read_unlock();
369 return -EINVAL; 363 return -EINVAL;
370 } 364 }
371 chan = chanctx_conf->channel; 365 chan = chanctx_conf->def.chan;
372 rcu_read_unlock(); 366 rcu_read_unlock();
373 367
374 sband = local->hw.wiphy->bands[chan->band]; 368 sband = local->hw.wiphy->bands[chan->band];
@@ -392,7 +386,7 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb,
392 386
393 sband = local->hw.wiphy->bands[band]; 387 sband = local->hw.wiphy->bands[band];
394 if (!sband->ht_cap.ht_supported || 388 if (!sband->ht_cap.ht_supported ||
395 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) 389 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
396 return 0; 390 return 0;
397 391
398 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) 392 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
@@ -411,7 +405,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
411 struct ieee80211_chanctx_conf *chanctx_conf; 405 struct ieee80211_chanctx_conf *chanctx_conf;
412 struct ieee80211_channel *channel; 406 struct ieee80211_channel *channel;
413 enum nl80211_channel_type channel_type = 407 enum nl80211_channel_type channel_type =
414 sdata->vif.bss_conf.channel_type; 408 cfg80211_get_chandef_type(&sdata->vif.bss_conf.chandef);
415 struct ieee80211_supported_band *sband; 409 struct ieee80211_supported_band *sband;
416 struct ieee80211_sta_ht_cap *ht_cap; 410 struct ieee80211_sta_ht_cap *ht_cap;
417 u8 *pos; 411 u8 *pos;
@@ -422,7 +416,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
422 rcu_read_unlock(); 416 rcu_read_unlock();
423 return -EINVAL; 417 return -EINVAL;
424 } 418 }
425 channel = chanctx_conf->channel; 419 channel = chanctx_conf->def.chan;
426 rcu_read_unlock(); 420 rcu_read_unlock();
427 421
428 sband = local->hw.wiphy->bands[channel->band]; 422 sband = local->hw.wiphy->bands[channel->band];
@@ -435,7 +429,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
435 return -ENOMEM; 429 return -ENOMEM;
436 430
437 pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation)); 431 pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation));
438 ieee80211_ie_build_ht_oper(pos, ht_cap, channel, channel_type, 432 ieee80211_ie_build_ht_oper(pos, ht_cap, &sdata->vif.bss_conf.chandef,
439 sdata->vif.bss_conf.ht_operation_mode); 433 sdata->vif.bss_conf.ht_operation_mode);
440 434
441 return 0; 435 return 0;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 9285f3f67e6..7c9215fb2ac 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -19,20 +19,6 @@
19/* Data structures */ 19/* Data structures */
20 20
21/** 21/**
22 * enum mesh_config_capab_flags - mesh config IE capability flags
23 *
24 * @MESHCONF_CAPAB_ACCEPT_PLINKS: STA is willing to establish
25 * additional mesh peerings with other mesh STAs
26 * @MESHCONF_CAPAB_FORWARDING: the STA forwards MSDUs
27 * @MESHCONF_CAPAB_TBTT_ADJUSTING: TBTT adjustment procedure is ongoing
28 */
29enum mesh_config_capab_flags {
30 MESHCONF_CAPAB_ACCEPT_PLINKS = BIT(0),
31 MESHCONF_CAPAB_FORWARDING = BIT(3),
32 MESHCONF_CAPAB_TBTT_ADJUSTING = BIT(5),
33};
34
35/**
36 * enum mesh_path_flags - mac80211 mesh path flags 22 * enum mesh_path_flags - mac80211 mesh path flags
37 * 23 *
38 * 24 *
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 234fe755968..ca52dfdd537 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -19,12 +19,6 @@
19#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ 19#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
20 jiffies + HZ * t / 1000)) 20 jiffies + HZ * t / 1000))
21 21
22#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries)
23#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout)
24#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout)
25#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
26#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
27
28/* We only need a valid sta if user configured a minimum rssi_threshold. */ 22/* We only need a valid sta if user configured a minimum rssi_threshold. */
29#define rssi_threshold_check(sta, sdata) \ 23#define rssi_threshold_check(sta, sdata) \
30 (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\ 24 (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
@@ -117,7 +111,7 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
117 u16 ht_opmode; 111 u16 ht_opmode;
118 bool non_ht_sta = false, ht20_sta = false; 112 bool non_ht_sta = false, ht20_sta = false;
119 113
120 if (sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) 114 if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
121 return 0; 115 return 0;
122 116
123 rcu_read_lock(); 117 rcu_read_lock();
@@ -126,14 +120,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
126 sta->plink_state != NL80211_PLINK_ESTAB) 120 sta->plink_state != NL80211_PLINK_ESTAB)
127 continue; 121 continue;
128 122
129 switch (sta->ch_type) { 123 switch (sta->ch_width) {
130 case NL80211_CHAN_NO_HT: 124 case NL80211_CHAN_WIDTH_20_NOHT:
131 mpl_dbg(sdata, 125 mpl_dbg(sdata,
132 "mesh_plink %pM: nonHT sta (%pM) is present\n", 126 "mesh_plink %pM: nonHT sta (%pM) is present\n",
133 sdata->vif.addr, sta->sta.addr); 127 sdata->vif.addr, sta->sta.addr);
134 non_ht_sta = true; 128 non_ht_sta = true;
135 goto out; 129 goto out;
136 case NL80211_CHAN_HT20: 130 case NL80211_CHAN_WIDTH_20:
137 mpl_dbg(sdata, 131 mpl_dbg(sdata,
138 "mesh_plink %pM: HT20 sta (%pM) is present\n", 132 "mesh_plink %pM: HT20 sta (%pM) is present\n",
139 sdata->vif.addr, sta->sta.addr); 133 sdata->vif.addr, sta->sta.addr);
@@ -148,7 +142,7 @@ out:
148 if (non_ht_sta) 142 if (non_ht_sta)
149 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED; 143 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
150 else if (ht20_sta && 144 else if (ht20_sta &&
151 sdata->vif.bss_conf.channel_type > NL80211_CHAN_HT20) 145 sdata->vif.bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
152 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ; 146 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
153 else 147 else
154 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE; 148 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
@@ -378,7 +372,7 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
378 372
379 sta->sta.supp_rates[band] = rates; 373 sta->sta.supp_rates[band] = rates;
380 if (elems->ht_cap_elem && 374 if (elems->ht_cap_elem &&
381 sdata->vif.bss_conf.channel_type != NL80211_CHAN_NO_HT) 375 sdata->vif.bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
382 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 376 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
383 elems->ht_cap_elem, 377 elems->ht_cap_elem,
384 &sta->sta.ht_cap); 378 &sta->sta.ht_cap);
@@ -386,12 +380,15 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
386 memset(&sta->sta.ht_cap, 0, sizeof(sta->sta.ht_cap)); 380 memset(&sta->sta.ht_cap, 0, sizeof(sta->sta.ht_cap));
387 381
388 if (elems->ht_operation) { 382 if (elems->ht_operation) {
383 struct cfg80211_chan_def chandef;
384
389 if (!(elems->ht_operation->ht_param & 385 if (!(elems->ht_operation->ht_param &
390 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) 386 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
391 sta->sta.ht_cap.cap &= 387 sta->sta.ht_cap.cap &=
392 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 388 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
393 sta->ch_type = 389 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
394 ieee80211_ht_oper_to_channel_type(elems->ht_operation); 390 elems->ht_operation, &chandef);
391 sta->ch_width = chandef.width;
395 } 392 }
396 393
397 rate_control_rate_init(sta); 394 rate_control_rate_init(sta);
@@ -430,6 +427,7 @@ static void mesh_plink_timer(unsigned long data)
430 struct sta_info *sta; 427 struct sta_info *sta;
431 __le16 llid, plid, reason; 428 __le16 llid, plid, reason;
432 struct ieee80211_sub_if_data *sdata; 429 struct ieee80211_sub_if_data *sdata;
430 struct mesh_config *mshcfg;
433 431
434 /* 432 /*
435 * This STA is valid because sta_info_destroy() will 433 * This STA is valid because sta_info_destroy() will
@@ -456,12 +454,13 @@ static void mesh_plink_timer(unsigned long data)
456 llid = sta->llid; 454 llid = sta->llid;
457 plid = sta->plid; 455 plid = sta->plid;
458 sdata = sta->sdata; 456 sdata = sta->sdata;
457 mshcfg = &sdata->u.mesh.mshcfg;
459 458
460 switch (sta->plink_state) { 459 switch (sta->plink_state) {
461 case NL80211_PLINK_OPN_RCVD: 460 case NL80211_PLINK_OPN_RCVD:
462 case NL80211_PLINK_OPN_SNT: 461 case NL80211_PLINK_OPN_SNT:
463 /* retry timer */ 462 /* retry timer */
464 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { 463 if (sta->plink_retries < mshcfg->dot11MeshMaxRetries) {
465 u32 rand; 464 u32 rand;
466 mpl_dbg(sta->sdata, 465 mpl_dbg(sta->sdata,
467 "Mesh plink for %pM (retry, timeout): %d %d\n", 466 "Mesh plink for %pM (retry, timeout): %d %d\n",
@@ -484,7 +483,7 @@ static void mesh_plink_timer(unsigned long data)
484 if (!reason) 483 if (!reason)
485 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT); 484 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
486 sta->plink_state = NL80211_PLINK_HOLDING; 485 sta->plink_state = NL80211_PLINK_HOLDING;
487 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 486 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
488 spin_unlock_bh(&sta->lock); 487 spin_unlock_bh(&sta->lock);
489 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 488 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
490 sta->sta.addr, llid, plid, reason); 489 sta->sta.addr, llid, plid, reason);
@@ -543,7 +542,7 @@ int mesh_plink_open(struct sta_info *sta)
543 return -EBUSY; 542 return -EBUSY;
544 } 543 }
545 sta->plink_state = NL80211_PLINK_OPN_SNT; 544 sta->plink_state = NL80211_PLINK_OPN_SNT;
546 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 545 mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
547 spin_unlock_bh(&sta->lock); 546 spin_unlock_bh(&sta->lock);
548 mpl_dbg(sdata, 547 mpl_dbg(sdata,
549 "Mesh plink: starting establishment with %pM\n", 548 "Mesh plink: starting establishment with %pM\n",
@@ -570,6 +569,7 @@ void mesh_plink_block(struct sta_info *sta)
570void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, 569void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt,
571 size_t len, struct ieee80211_rx_status *rx_status) 570 size_t len, struct ieee80211_rx_status *rx_status)
572{ 571{
572 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
573 struct ieee802_11_elems elems; 573 struct ieee802_11_elems elems;
574 struct sta_info *sta; 574 struct sta_info *sta;
575 enum plink_event event; 575 enum plink_event event;
@@ -777,7 +777,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
777 sta->plid = plid; 777 sta->plid = plid;
778 get_random_bytes(&llid, 2); 778 get_random_bytes(&llid, 2);
779 sta->llid = llid; 779 sta->llid = llid;
780 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 780 mesh_plink_timer_set(sta,
781 mshcfg->dot11MeshRetryTimeout);
781 spin_unlock_bh(&sta->lock); 782 spin_unlock_bh(&sta->lock);
782 mesh_plink_frame_tx(sdata, 783 mesh_plink_frame_tx(sdata,
783 WLAN_SP_MESH_PEERING_OPEN, 784 WLAN_SP_MESH_PEERING_OPEN,
@@ -803,7 +804,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
803 sta->reason = reason; 804 sta->reason = reason;
804 sta->plink_state = NL80211_PLINK_HOLDING; 805 sta->plink_state = NL80211_PLINK_HOLDING;
805 if (!mod_plink_timer(sta, 806 if (!mod_plink_timer(sta,
806 dot11MeshHoldingTimeout(sdata))) 807 mshcfg->dot11MeshHoldingTimeout))
807 sta->ignore_plink_timer = true; 808 sta->ignore_plink_timer = true;
808 809
809 llid = sta->llid; 810 llid = sta->llid;
@@ -825,7 +826,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
825 case CNF_ACPT: 826 case CNF_ACPT:
826 sta->plink_state = NL80211_PLINK_CNF_RCVD; 827 sta->plink_state = NL80211_PLINK_CNF_RCVD;
827 if (!mod_plink_timer(sta, 828 if (!mod_plink_timer(sta,
828 dot11MeshConfirmTimeout(sdata))) 829 mshcfg->dot11MeshConfirmTimeout))
829 sta->ignore_plink_timer = true; 830 sta->ignore_plink_timer = true;
830 831
831 spin_unlock_bh(&sta->lock); 832 spin_unlock_bh(&sta->lock);
@@ -847,7 +848,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
847 sta->reason = reason; 848 sta->reason = reason;
848 sta->plink_state = NL80211_PLINK_HOLDING; 849 sta->plink_state = NL80211_PLINK_HOLDING;
849 if (!mod_plink_timer(sta, 850 if (!mod_plink_timer(sta,
850 dot11MeshHoldingTimeout(sdata))) 851 mshcfg->dot11MeshHoldingTimeout))
851 sta->ignore_plink_timer = true; 852 sta->ignore_plink_timer = true;
852 853
853 llid = sta->llid; 854 llid = sta->llid;
@@ -888,7 +889,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
888 sta->reason = reason; 889 sta->reason = reason;
889 sta->plink_state = NL80211_PLINK_HOLDING; 890 sta->plink_state = NL80211_PLINK_HOLDING;
890 if (!mod_plink_timer(sta, 891 if (!mod_plink_timer(sta,
891 dot11MeshHoldingTimeout(sdata))) 892 mshcfg->dot11MeshHoldingTimeout))
892 sta->ignore_plink_timer = true; 893 sta->ignore_plink_timer = true;
893 894
894 llid = sta->llid; 895 llid = sta->llid;
@@ -923,7 +924,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
923 changed |= __mesh_plink_deactivate(sta); 924 changed |= __mesh_plink_deactivate(sta);
924 sta->plink_state = NL80211_PLINK_HOLDING; 925 sta->plink_state = NL80211_PLINK_HOLDING;
925 llid = sta->llid; 926 llid = sta->llid;
926 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 927 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
927 spin_unlock_bh(&sta->lock); 928 spin_unlock_bh(&sta->lock);
928 changed |= mesh_set_ht_prot_mode(sdata); 929 changed |= mesh_set_ht_prot_mode(sdata);
929 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 930 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index 407c8705e10..0f40086cce1 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -43,7 +43,7 @@ struct sync_method {
43static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie) 43static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie)
44{ 44{
45 return (ie->mesh_config->meshconf_cap & 45 return (ie->mesh_config->meshconf_cap &
46 MESHCONF_CAPAB_TBTT_ADJUSTING) != 0; 46 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0;
47} 47}
48 48
49void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) 49void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
@@ -116,43 +116,13 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
116 goto no_sync; 116 goto no_sync;
117 } 117 }
118 118
119 if (rx_status->flag & RX_FLAG_MACTIME_MPDU && rx_status->mactime) { 119 if (ieee80211_have_rx_timestamp(rx_status))
120 /* 120 /* time when timestamp field was received */
121 * The mactime is defined as the time the first data symbol 121 t_r = ieee80211_calculate_rx_timestamp(local, rx_status,
122 * of the frame hits the PHY, and the timestamp of the beacon 122 24 + 12 +
123 * is defined as "the time that the data symbol containing the 123 elems->total_len +
124 * first bit of the timestamp is transmitted to the PHY plus 124 FCS_LEN,
125 * the transmitting STA's delays through its local PHY from the 125 24);
126 * MAC-PHY interface to its interface with the WM" (802.11
127 * 11.1.2)
128 *
129 * T_r, in 13.13.2.2.2, is just defined as "the frame reception
130 * time" but we unless we interpret that time to be the same
131 * time of the beacon timestamp, the offset calculation will be
132 * off. Below we adjust t_r to be "the time at which the first
133 * symbol of the timestamp element in the beacon is received".
134 * This correction depends on the rate.
135 *
136 * Based on similar code in ibss.c
137 */
138 int rate;
139
140 if (rx_status->flag & RX_FLAG_HT) {
141 /* TODO:
142 * In principle there could be HT-beacons (Dual Beacon
143 * HT Operation options), but for now ignore them and
144 * just use the primary (i.e. non-HT) beacons for
145 * synchronization.
146 * */
147 goto no_sync;
148 } else
149 rate = local->hw.wiphy->bands[rx_status->band]->
150 bitrates[rx_status->rate_idx].bitrate;
151
152 /* 24 bytes of header * 8 bits/byte *
153 * 10*(100 Kbps)/Mbps / rate (100 Kbps)*/
154 t_r = rx_status->mactime + (24 * 8 * 10 / rate);
155 }
156 126
157 /* Timing offset calculation (see 13.13.2.2.2) */ 127 /* Timing offset calculation (see 13.13.2.2.2) */
158 t_t = le64_to_cpu(mgmt->u.beacon.timestamp); 128 t_t = le64_to_cpu(mgmt->u.beacon.timestamp);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1d1fdf0791f..d2a4f78b4b0 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -191,17 +191,19 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
191 rcu_read_unlock(); 191 rcu_read_unlock();
192 return 0; 192 return 0;
193 } 193 }
194 chan = chanctx_conf->channel; 194 chan = chanctx_conf->def.chan;
195 rcu_read_unlock(); 195 rcu_read_unlock();
196 sband = local->hw.wiphy->bands[chan->band]; 196 sband = local->hw.wiphy->bands[chan->band];
197 197
198 switch (sdata->vif.bss_conf.channel_type) { 198 switch (sdata->vif.bss_conf.chandef.width) {
199 case NL80211_CHAN_HT40PLUS: 199 case NL80211_CHAN_WIDTH_40:
200 if (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) 200 if (sdata->vif.bss_conf.chandef.chan->center_freq >
201 sdata->vif.bss_conf.chandef.center_freq1 &&
202 chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
201 disable_40 = true; 203 disable_40 = true;
202 break; 204 if (sdata->vif.bss_conf.chandef.chan->center_freq <
203 case NL80211_CHAN_HT40MINUS: 205 sdata->vif.bss_conf.chandef.center_freq1 &&
204 if (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) 206 chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
205 disable_40 = true; 207 disable_40 = true;
206 break; 208 break;
207 default: 209 default:
@@ -381,7 +383,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
381 rcu_read_unlock(); 383 rcu_read_unlock();
382 return; 384 return;
383 } 385 }
384 chan = chanctx_conf->channel; 386 chan = chanctx_conf->def.chan;
385 rcu_read_unlock(); 387 rcu_read_unlock();
386 sband = local->hw.wiphy->bands[chan->band]; 388 sband = local->hw.wiphy->bands[chan->band];
387 389
@@ -541,7 +543,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
541 offset = noffset; 543 offset = noffset;
542 } 544 }
543 545
544 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 546 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
545 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, 547 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
546 sband, chan, sdata->smps_mode); 548 sband, chan, sdata->smps_mode);
547 549
@@ -820,10 +822,10 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
820 cbss->beacon_interval)); 822 cbss->beacon_interval));
821} 823}
822 824
823static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, 825static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
824 struct ieee80211_channel *channel, 826 struct ieee80211_channel *channel,
825 const u8 *country_ie, u8 country_ie_len, 827 const u8 *country_ie, u8 country_ie_len,
826 const u8 *pwr_constr_elem) 828 const u8 *pwr_constr_elem)
827{ 829{
828 struct ieee80211_country_ie_triplet *triplet; 830 struct ieee80211_country_ie_triplet *triplet;
829 int chan = ieee80211_frequency_to_channel(channel->center_freq); 831 int chan = ieee80211_frequency_to_channel(channel->center_freq);
@@ -832,7 +834,7 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
832 834
833 /* Invalid IE */ 835 /* Invalid IE */
834 if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) 836 if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
835 return; 837 return 0;
836 838
837 triplet = (void *)(country_ie + 3); 839 triplet = (void *)(country_ie + 3);
838 country_ie_len -= 3; 840 country_ie_len -= 3;
@@ -873,19 +875,21 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
873 } 875 }
874 876
875 if (!have_chan_pwr) 877 if (!have_chan_pwr)
876 return; 878 return 0;
877 879
878 new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem); 880 new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem);
879 881
880 if (sdata->local->ap_power_level == new_ap_level) 882 if (sdata->ap_power_level == new_ap_level)
881 return; 883 return 0;
882 884
883 sdata_info(sdata, 885 sdata_info(sdata,
884 "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n", 886 "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
885 new_ap_level, chan_pwr, *pwr_constr_elem, 887 new_ap_level, chan_pwr, *pwr_constr_elem,
886 sdata->u.mgd.bssid); 888 sdata->u.mgd.bssid);
887 sdata->local->ap_power_level = new_ap_level; 889 sdata->ap_power_level = new_ap_level;
888 ieee80211_hw_config(sdata->local, 0); 890 if (__ieee80211_recalc_txpower(sdata))
891 return BSS_CHANGED_TXPOWER;
892 return 0;
889} 893}
890 894
891void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif) 895void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
@@ -1363,6 +1367,22 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1363 1367
1364 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; 1368 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
1365 1369
1370 if (sdata->vif.p2p) {
1371 u8 noa[2];
1372 int ret;
1373
1374 ret = cfg80211_get_p2p_attr(cbss->information_elements,
1375 cbss->len_information_elements,
1376 IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
1377 noa, sizeof(noa));
1378 if (ret >= 2) {
1379 bss_conf->p2p_oppps = noa[1] & 0x80;
1380 bss_conf->p2p_ctwindow = noa[1] & 0x7f;
1381 bss_info_changed |= BSS_CHANGED_P2P_PS;
1382 sdata->u.mgd.p2p_noa_index = noa[0];
1383 }
1384 }
1385
1366 /* just to be sure */ 1386 /* just to be sure */
1367 ieee80211_stop_poll(sdata); 1387 ieee80211_stop_poll(sdata);
1368 1388
@@ -1485,11 +1505,14 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1485 changed |= BSS_CHANGED_ASSOC; 1505 changed |= BSS_CHANGED_ASSOC;
1486 sdata->vif.bss_conf.assoc = false; 1506 sdata->vif.bss_conf.assoc = false;
1487 1507
1508 sdata->vif.bss_conf.p2p_ctwindow = 0;
1509 sdata->vif.bss_conf.p2p_oppps = false;
1510
1488 /* on the next assoc, re-program HT parameters */ 1511 /* on the next assoc, re-program HT parameters */
1489 memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); 1512 memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
1490 memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask)); 1513 memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));
1491 1514
1492 local->ap_power_level = 0; 1515 sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
1493 1516
1494 del_timer_sync(&local->dynamic_ps_timer); 1517 del_timer_sync(&local->dynamic_ps_timer);
1495 cancel_work_sync(&local->dynamic_ps_enable_work); 1518 cancel_work_sync(&local->dynamic_ps_enable_work);
@@ -1507,8 +1530,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1507 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; 1530 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
1508 ieee80211_bss_info_change_notify(sdata, changed); 1531 ieee80211_bss_info_change_notify(sdata, changed);
1509 1532
1510 ieee80211_vif_release_channel(sdata);
1511
1512 /* disassociated - set to defaults now */ 1533 /* disassociated - set to defaults now */
1513 ieee80211_set_wmm_default(sdata, false); 1534 ieee80211_set_wmm_default(sdata, false);
1514 1535
@@ -1518,6 +1539,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1518 del_timer_sync(&sdata->u.mgd.chswitch_timer); 1539 del_timer_sync(&sdata->u.mgd.chswitch_timer);
1519 1540
1520 sdata->u.mgd.timers_running = 0; 1541 sdata->u.mgd.timers_running = 0;
1542
1543 ifmgd->flags = 0;
1544 ieee80211_vif_release_channel(sdata);
1521} 1545}
1522 1546
1523void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1547void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -1843,6 +1867,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
1843 1867
1844 memset(sdata->u.mgd.bssid, 0, ETH_ALEN); 1868 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
1845 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); 1869 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
1870 sdata->u.mgd.flags = 0;
1846 ieee80211_vif_release_channel(sdata); 1871 ieee80211_vif_release_channel(sdata);
1847 } 1872 }
1848 1873
@@ -2085,6 +2110,7 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
2085 2110
2086 memset(sdata->u.mgd.bssid, 0, ETH_ALEN); 2111 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
2087 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); 2112 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
2113 sdata->u.mgd.flags = 0;
2088 ieee80211_vif_release_channel(sdata); 2114 ieee80211_vif_release_channel(sdata);
2089 } 2115 }
2090 2116
@@ -2149,7 +2175,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2149 2175
2150 sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; 2176 sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
2151 2177
2152 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2178 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2153 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 2179 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
2154 elems.ht_cap_elem, &sta->sta.ht_cap); 2180 elems.ht_cap_elem, &sta->sta.ht_cap);
2155 2181
@@ -2201,7 +2227,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2201 changed |= BSS_CHANGED_QOS; 2227 changed |= BSS_CHANGED_QOS;
2202 2228
2203 if (elems.ht_operation && elems.wmm_param && 2229 if (elems.ht_operation && elems.wmm_param &&
2204 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2230 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2205 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, 2231 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
2206 cbss->bssid, false); 2232 cbss->bssid, false);
2207 2233
@@ -2452,11 +2478,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2452 return; 2478 return;
2453 } 2479 }
2454 2480
2455 if (rx_status->freq != chanctx_conf->channel->center_freq) { 2481 if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
2456 rcu_read_unlock(); 2482 rcu_read_unlock();
2457 return; 2483 return;
2458 } 2484 }
2459 chan = chanctx_conf->channel; 2485 chan = chanctx_conf->def.chan;
2460 rcu_read_unlock(); 2486 rcu_read_unlock();
2461 2487
2462 if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && 2488 if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
@@ -2592,6 +2618,27 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2592 } 2618 }
2593 } 2619 }
2594 2620
2621 if (sdata->vif.p2p) {
2622 u8 noa[2];
2623 int ret;
2624
2625 ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable,
2626 len - baselen,
2627 IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
2628 noa, sizeof(noa));
2629 if (ret >= 2 && sdata->u.mgd.p2p_noa_index != noa[0]) {
2630 bss_conf->p2p_oppps = noa[1] & 0x80;
2631 bss_conf->p2p_ctwindow = noa[1] & 0x7f;
2632 changed |= BSS_CHANGED_P2P_PS;
2633 sdata->u.mgd.p2p_noa_index = noa[0];
2634 /*
2635 * make sure we update all information, the CRC
2636 * mechanism doesn't look at P2P attributes.
2637 */
2638 ifmgd->beacon_crc_valid = false;
2639 }
2640 }
2641
2595 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) 2642 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
2596 return; 2643 return;
2597 ifmgd->beacon_crc = ncrc; 2644 ifmgd->beacon_crc = ncrc;
@@ -2616,17 +2663,17 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2616 2663
2617 2664
2618 if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param && 2665 if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param &&
2619 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2666 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2620 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, 2667 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
2621 bssid, true); 2668 bssid, true);
2622 2669
2623 if (elems.country_elem && elems.pwr_constr_elem && 2670 if (elems.country_elem && elems.pwr_constr_elem &&
2624 mgmt->u.probe_resp.capab_info & 2671 mgmt->u.probe_resp.capab_info &
2625 cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT)) 2672 cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT))
2626 ieee80211_handle_pwr_constr(sdata, chan, 2673 changed |= ieee80211_handle_pwr_constr(sdata, chan,
2627 elems.country_elem, 2674 elems.country_elem,
2628 elems.country_elem_len, 2675 elems.country_elem_len,
2629 elems.pwr_constr_elem); 2676 elems.pwr_constr_elem);
2630 2677
2631 ieee80211_bss_info_change_notify(sdata, changed); 2678 ieee80211_bss_info_change_notify(sdata, changed);
2632} 2679}
@@ -3146,6 +3193,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3146 const u8 *ht_oper_ie; 3193 const u8 *ht_oper_ie;
3147 const struct ieee80211_ht_operation *ht_oper = NULL; 3194 const struct ieee80211_ht_operation *ht_oper = NULL;
3148 struct ieee80211_supported_band *sband; 3195 struct ieee80211_supported_band *sband;
3196 struct cfg80211_chan_def chandef;
3149 3197
3150 sband = local->hw.wiphy->bands[cbss->channel->band]; 3198 sband = local->hw.wiphy->bands[cbss->channel->band];
3151 3199
@@ -3177,12 +3225,10 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3177 ht_cfreq, ht_oper->primary_chan, 3225 ht_cfreq, ht_oper->primary_chan,
3178 cbss->channel->band); 3226 cbss->channel->band);
3179 ht_oper = NULL; 3227 ht_oper = NULL;
3180 } else {
3181 channel_type = NL80211_CHAN_HT20;
3182 } 3228 }
3183 } 3229 }
3184 3230
3185 if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { 3231 if (ht_oper) {
3186 /* 3232 /*
3187 * cfg80211 already verified that the channel itself can 3233 * cfg80211 already verified that the channel itself can
3188 * be used, but it didn't check that we can do the right 3234 * be used, but it didn't check that we can do the right
@@ -3195,19 +3241,26 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3195 3241
3196 channel_type = NL80211_CHAN_HT20; 3242 channel_type = NL80211_CHAN_HT20;
3197 3243
3198 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { 3244 if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
3199 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 3245 switch (ht_oper->ht_param &
3200 if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS) 3246 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
3201 ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; 3247 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
3202 else 3248 if (cbss->channel->flags &
3203 channel_type = NL80211_CHAN_HT40PLUS; 3249 IEEE80211_CHAN_NO_HT40PLUS)
3204 break; 3250 ifmgd->flags |=
3205 case IEEE80211_HT_PARAM_CHA_SEC_BELOW: 3251 IEEE80211_STA_DISABLE_40MHZ;
3206 if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS) 3252 else
3207 ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; 3253 channel_type = NL80211_CHAN_HT40PLUS;
3208 else 3254 break;
3209 channel_type = NL80211_CHAN_HT40MINUS; 3255 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
3210 break; 3256 if (cbss->channel->flags &
3257 IEEE80211_CHAN_NO_HT40MINUS)
3258 ifmgd->flags |=
3259 IEEE80211_STA_DISABLE_40MHZ;
3260 else
3261 channel_type = NL80211_CHAN_HT40MINUS;
3262 break;
3263 }
3211 } 3264 }
3212 3265
3213 ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, 3266 ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
@@ -3220,13 +3273,15 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3220 sdata->needed_rx_chains = min(chains, local->rx_chains); 3273 sdata->needed_rx_chains = min(chains, local->rx_chains);
3221 } else { 3274 } else {
3222 sdata->needed_rx_chains = 1; 3275 sdata->needed_rx_chains = 1;
3276 sdata->u.mgd.flags |= IEEE80211_STA_DISABLE_HT;
3223 } 3277 }
3224 3278
3225 /* will change later if needed */ 3279 /* will change later if needed */
3226 sdata->smps_mode = IEEE80211_SMPS_OFF; 3280 sdata->smps_mode = IEEE80211_SMPS_OFF;
3227 3281
3228 ieee80211_vif_release_channel(sdata); 3282 ieee80211_vif_release_channel(sdata);
3229 return ieee80211_vif_use_channel(sdata, cbss->channel, channel_type, 3283 cfg80211_chandef_create(&chandef, cbss->channel, channel_type);
3284 return ieee80211_vif_use_channel(sdata, &chandef,
3230 IEEE80211_CHANCTX_SHARED); 3285 IEEE80211_CHANCTX_SHARED);
3231} 3286}
3232 3287
@@ -3488,13 +3543,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3488 3543
3489 /* prepare assoc data */ 3544 /* prepare assoc data */
3490 3545
3491 /*
3492 * keep only the 40 MHz disable bit set as it might have
3493 * been set during authentication already, all other bits
3494 * should be reset for a new connection
3495 */
3496 ifmgd->flags &= IEEE80211_STA_DISABLE_40MHZ;
3497
3498 ifmgd->beacon_crc_valid = false; 3546 ifmgd->beacon_crc_valid = false;
3499 3547
3500 /* 3548 /*
@@ -3508,7 +3556,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3508 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || 3556 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
3509 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || 3557 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
3510 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) { 3558 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) {
3511 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3559 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3512 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 3560 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
3513 netdev_info(sdata->dev, 3561 netdev_info(sdata->dev,
3514 "disabling HT/VHT due to WEP/TKIP use\n"); 3562 "disabling HT/VHT due to WEP/TKIP use\n");
@@ -3516,7 +3564,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3516 } 3564 }
3517 3565
3518 if (req->flags & ASSOC_REQ_DISABLE_HT) { 3566 if (req->flags & ASSOC_REQ_DISABLE_HT) {
3519 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3567 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3520 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 3568 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
3521 } 3569 }
3522 3570
@@ -3524,7 +3572,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3524 sband = local->hw.wiphy->bands[req->bss->channel->band]; 3572 sband = local->hw.wiphy->bands[req->bss->channel->band];
3525 if (!sband->ht_cap.ht_supported || 3573 if (!sband->ht_cap.ht_supported ||
3526 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { 3574 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) {
3527 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3575 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3528 if (!bss->wmm_used) 3576 if (!bss->wmm_used)
3529 netdev_info(sdata->dev, 3577 netdev_info(sdata->dev,
3530 "disabling HT as WMM/QoS is not supported by the AP\n"); 3578 "disabling HT as WMM/QoS is not supported by the AP\n");
@@ -3569,7 +3617,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3569 assoc_data->ap_ht_param = 3617 assoc_data->ap_ht_param =
3570 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param; 3618 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param;
3571 else 3619 else
3572 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3620 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3573 3621
3574 if (bss->wmm_used && bss->uapsd_supported && 3622 if (bss->wmm_used && bss->uapsd_supported &&
3575 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { 3623 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
@@ -3660,40 +3708,44 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
3660 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3708 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3661 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 3709 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
3662 bool tx = !req->local_state_change; 3710 bool tx = !req->local_state_change;
3711 bool sent_frame = false;
3663 3712
3664 mutex_lock(&ifmgd->mtx); 3713 mutex_lock(&ifmgd->mtx);
3665 3714
3666 if (ifmgd->auth_data) {
3667 ieee80211_destroy_auth_data(sdata, false);
3668 mutex_unlock(&ifmgd->mtx);
3669 return 0;
3670 }
3671
3672 sdata_info(sdata, 3715 sdata_info(sdata,
3673 "deauthenticating from %pM by local choice (reason=%d)\n", 3716 "deauthenticating from %pM by local choice (reason=%d)\n",
3674 req->bssid, req->reason_code); 3717 req->bssid, req->reason_code);
3675 3718
3676 if (ifmgd->associated && 3719 if (ifmgd->auth_data) {
3677 ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
3678 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
3679 req->reason_code, tx, frame_buf);
3680 } else {
3681 drv_mgd_prepare_tx(sdata->local, sdata); 3720 drv_mgd_prepare_tx(sdata->local, sdata);
3682 ieee80211_send_deauth_disassoc(sdata, req->bssid, 3721 ieee80211_send_deauth_disassoc(sdata, req->bssid,
3683 IEEE80211_STYPE_DEAUTH, 3722 IEEE80211_STYPE_DEAUTH,
3684 req->reason_code, tx, 3723 req->reason_code, tx,
3685 frame_buf); 3724 frame_buf);
3725 ieee80211_destroy_auth_data(sdata, false);
3726 mutex_unlock(&ifmgd->mtx);
3727
3728 sent_frame = tx;
3729 goto out;
3686 } 3730 }
3687 3731
3732 if (ifmgd->associated &&
3733 ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
3734 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
3735 req->reason_code, tx, frame_buf);
3736 sent_frame = tx;
3737 }
3688 mutex_unlock(&ifmgd->mtx); 3738 mutex_unlock(&ifmgd->mtx);
3689 3739
3690 __cfg80211_send_deauth(sdata->dev, frame_buf, 3740 out:
3691 IEEE80211_DEAUTH_FRAME_LEN);
3692
3693 mutex_lock(&sdata->local->mtx); 3741 mutex_lock(&sdata->local->mtx);
3694 ieee80211_recalc_idle(sdata->local); 3742 ieee80211_recalc_idle(sdata->local);
3695 mutex_unlock(&sdata->local->mtx); 3743 mutex_unlock(&sdata->local->mtx);
3696 3744
3745 if (sent_frame)
3746 __cfg80211_send_deauth(sdata->dev, frame_buf,
3747 IEEE80211_DEAUTH_FRAME_LEN);
3748
3697 return 0; 3749 return 0;
3698} 3750}
3699 3751
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index c349f3aaf59..5abddfe3e10 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -204,9 +204,9 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
204 roc->frame = NULL; 204 roc->frame = NULL;
205 } 205 }
206 } else { 206 } else {
207 cfg80211_ready_on_channel(&roc->sdata->wdev, (unsigned long)roc, 207 cfg80211_ready_on_channel(&roc->sdata->wdev, roc->cookie,
208 roc->chan, roc->chan_type, 208 roc->chan, roc->req_duration,
209 roc->req_duration, GFP_KERNEL); 209 GFP_KERNEL);
210 } 210 }
211 211
212 roc->notified = true; 212 roc->notified = true;
@@ -283,8 +283,7 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
283 if (!duration) 283 if (!duration)
284 duration = 10; 284 duration = 10;
285 285
286 ret = drv_remain_on_channel(local, roc->chan, 286 ret = drv_remain_on_channel(local, roc->sdata, roc->chan,
287 roc->chan_type,
288 duration); 287 duration);
289 288
290 roc->started = true; 289 roc->started = true;
@@ -320,8 +319,7 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
320 319
321 if (!roc->mgmt_tx_cookie) 320 if (!roc->mgmt_tx_cookie)
322 cfg80211_remain_on_channel_expired(&roc->sdata->wdev, 321 cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
323 (unsigned long)roc, 322 roc->cookie, roc->chan,
324 roc->chan, roc->chan_type,
325 GFP_KERNEL); 323 GFP_KERNEL);
326 324
327 list_for_each_entry_safe(dep, tmp, &roc->dependents, list) 325 list_for_each_entry_safe(dep, tmp, &roc->dependents, list)
@@ -360,7 +358,6 @@ void ieee80211_sw_roc_work(struct work_struct *work)
360 ieee80211_recalc_idle(local); 358 ieee80211_recalc_idle(local);
361 359
362 local->tmp_channel = roc->chan; 360 local->tmp_channel = roc->chan;
363 local->tmp_channel_type = roc->chan_type;
364 ieee80211_hw_config(local, 0); 361 ieee80211_hw_config(local, 0);
365 362
366 /* tell userspace or send frame */ 363 /* tell userspace or send frame */
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 9f404ac901a..79a48f37d40 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -33,6 +33,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
33 struct ieee80211_local *local = hw_to_local(hw); 33 struct ieee80211_local *local = hw_to_local(hw);
34 struct ieee80211_sub_if_data *sdata; 34 struct ieee80211_sub_if_data *sdata;
35 struct sta_info *sta; 35 struct sta_info *sta;
36 struct ieee80211_chanctx *ctx;
36 37
37 if (!local->open_count) 38 if (!local->open_count)
38 goto suspend; 39 goto suspend;
@@ -135,14 +136,55 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
135 ieee80211_bss_info_change_notify(sdata, 136 ieee80211_bss_info_change_notify(sdata,
136 BSS_CHANGED_BEACON_ENABLED); 137 BSS_CHANGED_BEACON_ENABLED);
137 138
138 /* the interface is leaving the channel and is removed */ 139 if (sdata->vif.type == NL80211_IFTYPE_AP &&
139 ieee80211_vif_release_channel(sdata); 140 rcu_access_pointer(sdata->u.ap.beacon))
141 drv_stop_ap(local, sdata);
142
143 if (local->use_chanctx) {
144 struct ieee80211_chanctx_conf *conf;
145
146 mutex_lock(&local->chanctx_mtx);
147 conf = rcu_dereference_protected(
148 sdata->vif.chanctx_conf,
149 lockdep_is_held(&local->chanctx_mtx));
150 if (conf) {
151 ctx = container_of(conf,
152 struct ieee80211_chanctx,
153 conf);
154 drv_unassign_vif_chanctx(local, sdata, ctx);
155 }
156
157 mutex_unlock(&local->chanctx_mtx);
158 }
140 drv_remove_interface(local, sdata); 159 drv_remove_interface(local, sdata);
141 } 160 }
142 161
143 sdata = rtnl_dereference(local->monitor_sdata); 162 sdata = rtnl_dereference(local->monitor_sdata);
144 if (sdata) 163 if (sdata) {
164 if (local->use_chanctx) {
165 struct ieee80211_chanctx_conf *conf;
166
167 mutex_lock(&local->chanctx_mtx);
168 conf = rcu_dereference_protected(
169 sdata->vif.chanctx_conf,
170 lockdep_is_held(&local->chanctx_mtx));
171 if (conf) {
172 ctx = container_of(conf,
173 struct ieee80211_chanctx,
174 conf);
175 drv_unassign_vif_chanctx(local, sdata, ctx);
176 }
177
178 mutex_unlock(&local->chanctx_mtx);
179 }
180
145 drv_remove_interface(local, sdata); 181 drv_remove_interface(local, sdata);
182 }
183
184 mutex_lock(&local->chanctx_mtx);
185 list_for_each_entry(ctx, &local->chanctx_list, list)
186 drv_remove_chanctx(local, ctx);
187 mutex_unlock(&local->chanctx_mtx);
146 188
147 /* stop hardware - this must stop RX */ 189 /* stop hardware - this must stop RX */
148 if (local->open_count) 190 if (local->open_count)
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 3313c117b32..dd88381c53b 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -391,7 +391,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
391 return; 391 return;
392 392
393 /* if HT BSS, and we handle a data frame, also try HT rates */ 393 /* if HT BSS, and we handle a data frame, also try HT rates */
394 if (txrc->bss_conf->channel_type == NL80211_CHAN_NO_HT) 394 if (txrc->bss_conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
395 return; 395 return;
396 396
397 fc = hdr->frame_control; 397 fc = hdr->frame_control;
@@ -408,8 +408,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
408 408
409 alt_rate.flags |= IEEE80211_TX_RC_MCS; 409 alt_rate.flags |= IEEE80211_TX_RC_MCS;
410 410
411 if ((txrc->bss_conf->channel_type == NL80211_CHAN_HT40MINUS) || 411 if (txrc->bss_conf->chandef.width == NL80211_CHAN_WIDTH_40)
412 (txrc->bss_conf->channel_type == NL80211_CHAN_HT40PLUS))
413 alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; 412 alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
414 413
415 if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) { 414 if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) {
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index ec198ef6aa8..301386dabf8 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -65,7 +65,7 @@ static inline void rate_control_rate_init(struct sta_info *sta)
65 return; 65 return;
66 } 66 }
67 67
68 sband = local->hw.wiphy->bands[chanctx_conf->channel->band]; 68 sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
69 rcu_read_unlock(); 69 rcu_read_unlock();
70 70
71 ref->ops->rate_init(ref->priv, sband, ista, priv_sta); 71 ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8c1f1527d67..825f33cf7bb 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -40,6 +40,8 @@
40static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, 40static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
41 struct sk_buff *skb) 41 struct sk_buff *skb)
42{ 42{
43 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
44
43 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { 45 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
44 if (likely(skb->len > FCS_LEN)) 46 if (likely(skb->len > FCS_LEN))
45 __pskb_trim(skb, skb->len - FCS_LEN); 47 __pskb_trim(skb, skb->len - FCS_LEN);
@@ -51,20 +53,25 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
51 } 53 }
52 } 54 }
53 55
56 if (status->vendor_radiotap_len)
57 __pskb_pull(skb, status->vendor_radiotap_len);
58
54 return skb; 59 return skb;
55} 60}
56 61
57static inline int should_drop_frame(struct sk_buff *skb, 62static inline int should_drop_frame(struct sk_buff *skb, int present_fcs_len)
58 int present_fcs_len)
59{ 63{
60 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 64 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
61 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 65 struct ieee80211_hdr *hdr;
66
67 hdr = (void *)(skb->data + status->vendor_radiotap_len);
62 68
63 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | 69 if (status->flag & (RX_FLAG_FAILED_FCS_CRC |
64 RX_FLAG_FAILED_PLCP_CRC | 70 RX_FLAG_FAILED_PLCP_CRC |
65 RX_FLAG_AMPDU_IS_ZEROLEN)) 71 RX_FLAG_AMPDU_IS_ZEROLEN))
66 return 1; 72 return 1;
67 if (unlikely(skb->len < 16 + present_fcs_len)) 73 if (unlikely(skb->len < 16 + present_fcs_len +
74 status->vendor_radiotap_len))
68 return 1; 75 return 1;
69 if (ieee80211_is_ctl(hdr->frame_control) && 76 if (ieee80211_is_ctl(hdr->frame_control) &&
70 !ieee80211_is_pspoll(hdr->frame_control) && 77 !ieee80211_is_pspoll(hdr->frame_control) &&
@@ -74,32 +81,48 @@ static inline int should_drop_frame(struct sk_buff *skb,
74} 81}
75 82
76static int 83static int
77ieee80211_rx_radiotap_len(struct ieee80211_local *local, 84ieee80211_rx_radiotap_space(struct ieee80211_local *local,
78 struct ieee80211_rx_status *status) 85 struct ieee80211_rx_status *status)
79{ 86{
80 int len; 87 int len;
81 88
82 /* always present fields */ 89 /* always present fields */
83 len = sizeof(struct ieee80211_radiotap_header) + 9; 90 len = sizeof(struct ieee80211_radiotap_header) + 9;
84 91
85 if (status->flag & RX_FLAG_MACTIME_MPDU) 92 /* allocate extra bitmap */
93 if (status->vendor_radiotap_len)
94 len += 4;
95
96 if (ieee80211_have_rx_timestamp(status)) {
97 len = ALIGN(len, 8);
86 len += 8; 98 len += 8;
99 }
87 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 100 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
88 len += 1; 101 len += 1;
89 102
90 if (len & 1) /* padding for RX_FLAGS if necessary */ 103 /* padding for RX_FLAGS if necessary */
91 len++; 104 len = ALIGN(len, 2);
92 105
93 if (status->flag & RX_FLAG_HT) /* HT info */ 106 if (status->flag & RX_FLAG_HT) /* HT info */
94 len += 3; 107 len += 3;
95 108
96 if (status->flag & RX_FLAG_AMPDU_DETAILS) { 109 if (status->flag & RX_FLAG_AMPDU_DETAILS) {
97 /* padding */ 110 len = ALIGN(len, 4);
98 while (len & 3)
99 len++;
100 len += 8; 111 len += 8;
101 } 112 }
102 113
114 if (status->vendor_radiotap_len) {
115 if (WARN_ON_ONCE(status->vendor_radiotap_align == 0))
116 status->vendor_radiotap_align = 1;
117 /* align standard part of vendor namespace */
118 len = ALIGN(len, 2);
119 /* allocate standard part of vendor namespace */
120 len += 6;
121 /* align vendor-defined part */
122 len = ALIGN(len, status->vendor_radiotap_align);
123 /* vendor-defined part is already in skb */
124 }
125
103 return len; 126 return len;
104} 127}
105 128
@@ -118,6 +141,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
118 struct ieee80211_radiotap_header *rthdr; 141 struct ieee80211_radiotap_header *rthdr;
119 unsigned char *pos; 142 unsigned char *pos;
120 u16 rx_flags = 0; 143 u16 rx_flags = 0;
144 int mpdulen;
145
146 mpdulen = skb->len;
147 if (!(has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)))
148 mpdulen += FCS_LEN;
121 149
122 rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); 150 rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len);
123 memset(rthdr, 0, rtap_len); 151 memset(rthdr, 0, rtap_len);
@@ -128,17 +156,30 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
128 (1 << IEEE80211_RADIOTAP_CHANNEL) | 156 (1 << IEEE80211_RADIOTAP_CHANNEL) |
129 (1 << IEEE80211_RADIOTAP_ANTENNA) | 157 (1 << IEEE80211_RADIOTAP_ANTENNA) |
130 (1 << IEEE80211_RADIOTAP_RX_FLAGS)); 158 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
131 rthdr->it_len = cpu_to_le16(rtap_len); 159 rthdr->it_len = cpu_to_le16(rtap_len + status->vendor_radiotap_len);
132 160
133 pos = (unsigned char *)(rthdr+1); 161 pos = (unsigned char *)(rthdr + 1);
162
163 if (status->vendor_radiotap_len) {
164 rthdr->it_present |=
165 cpu_to_le32(BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE)) |
166 cpu_to_le32(BIT(IEEE80211_RADIOTAP_EXT));
167 put_unaligned_le32(status->vendor_radiotap_bitmap, pos);
168 pos += 4;
169 }
134 170
135 /* the order of the following fields is important */ 171 /* the order of the following fields is important */
136 172
137 /* IEEE80211_RADIOTAP_TSFT */ 173 /* IEEE80211_RADIOTAP_TSFT */
138 if (status->flag & RX_FLAG_MACTIME_MPDU) { 174 if (ieee80211_have_rx_timestamp(status)) {
139 put_unaligned_le64(status->mactime, pos); 175 /* padding */
140 rthdr->it_present |= 176 while ((pos - (u8 *)rthdr) & 7)
141 cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); 177 *pos++ = 0;
178 put_unaligned_le64(
179 ieee80211_calculate_rx_timestamp(local, status,
180 mpdulen, 0),
181 pos);
182 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT);
142 pos += 8; 183 pos += 8;
143 } 184 }
144 185
@@ -152,7 +193,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
152 pos++; 193 pos++;
153 194
154 /* IEEE80211_RADIOTAP_RATE */ 195 /* IEEE80211_RADIOTAP_RATE */
155 if (!rate || status->flag & RX_FLAG_HT) { 196 if (!rate || status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) {
156 /* 197 /*
157 * Without rate information don't add it. If we have, 198 * Without rate information don't add it. If we have,
158 * MCS information is a separate field in radiotap, 199 * MCS information is a separate field in radiotap,
@@ -172,7 +213,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
172 if (status->band == IEEE80211_BAND_5GHZ) 213 if (status->band == IEEE80211_BAND_5GHZ)
173 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, 214 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
174 pos); 215 pos);
175 else if (status->flag & RX_FLAG_HT) 216 else if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
176 put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, 217 put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
177 pos); 218 pos);
178 else if (rate && rate->flags & IEEE80211_RATE_ERP_G) 219 else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
@@ -205,7 +246,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
205 /* IEEE80211_RADIOTAP_RX_FLAGS */ 246 /* IEEE80211_RADIOTAP_RX_FLAGS */
206 /* ensure 2 byte alignment for the 2 byte field as required */ 247 /* ensure 2 byte alignment for the 2 byte field as required */
207 if ((pos - (u8 *)rthdr) & 1) 248 if ((pos - (u8 *)rthdr) & 1)
208 pos++; 249 *pos++ = 0;
209 if (status->flag & RX_FLAG_FAILED_PLCP_CRC) 250 if (status->flag & RX_FLAG_FAILED_PLCP_CRC)
210 rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP; 251 rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP;
211 put_unaligned_le16(rx_flags, pos); 252 put_unaligned_le16(rx_flags, pos);
@@ -255,6 +296,21 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
255 *pos++ = 0; 296 *pos++ = 0;
256 *pos++ = 0; 297 *pos++ = 0;
257 } 298 }
299
300 if (status->vendor_radiotap_len) {
301 /* ensure 2 byte alignment for the vendor field as required */
302 if ((pos - (u8 *)rthdr) & 1)
303 *pos++ = 0;
304 *pos++ = status->vendor_radiotap_oui[0];
305 *pos++ = status->vendor_radiotap_oui[1];
306 *pos++ = status->vendor_radiotap_oui[2];
307 *pos++ = status->vendor_radiotap_subns;
308 put_unaligned_le16(status->vendor_radiotap_len, pos);
309 pos += 2;
310 /* align the actual payload as requested */
311 while ((pos - (u8 *)rthdr) & (status->vendor_radiotap_align - 1))
312 *pos++ = 0;
313 }
258} 314}
259 315
260/* 316/*
@@ -283,13 +339,13 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
283 */ 339 */
284 340
285 /* room for the radiotap header based on driver features */ 341 /* room for the radiotap header based on driver features */
286 needed_headroom = ieee80211_rx_radiotap_len(local, status); 342 needed_headroom = ieee80211_rx_radiotap_space(local, status);
287 343
288 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 344 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
289 present_fcs_len = FCS_LEN; 345 present_fcs_len = FCS_LEN;
290 346
291 /* make sure hdr->frame_control is on the linear part */ 347 /* ensure hdr->frame_control and vendor radiotap data are in skb head */
292 if (!pskb_may_pull(origskb, 2)) { 348 if (!pskb_may_pull(origskb, 2 + status->vendor_radiotap_len)) {
293 dev_kfree_skb(origskb); 349 dev_kfree_skb(origskb);
294 return NULL; 350 return NULL;
295 } 351 }
@@ -374,7 +430,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
374 return origskb; 430 return origskb;
375} 431}
376 432
377
378static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) 433static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
379{ 434{
380 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 435 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
@@ -403,10 +458,10 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
403 * 458 *
404 * We also use that counter for non-QoS STAs. 459 * We also use that counter for non-QoS STAs.
405 */ 460 */
406 seqno_idx = NUM_RX_DATA_QUEUES; 461 seqno_idx = IEEE80211_NUM_TIDS;
407 security_idx = 0; 462 security_idx = 0;
408 if (ieee80211_is_mgmt(hdr->frame_control)) 463 if (ieee80211_is_mgmt(hdr->frame_control))
409 security_idx = NUM_RX_DATA_QUEUES; 464 security_idx = IEEE80211_NUM_TIDS;
410 tid = 0; 465 tid = 0;
411 } 466 }
412 467
@@ -481,8 +536,7 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
481 struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data; 536 struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data;
482 struct ieee80211_mmie *mmie; 537 struct ieee80211_mmie *mmie;
483 538
484 if (skb->len < 24 + sizeof(*mmie) || 539 if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da))
485 !is_multicast_ether_addr(hdr->da))
486 return -1; 540 return -1;
487 541
488 if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr)) 542 if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr))
@@ -497,9 +551,7 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
497 return le16_to_cpu(mmie->key_id); 551 return le16_to_cpu(mmie->key_id);
498} 552}
499 553
500 554static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
501static ieee80211_rx_result
502ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
503{ 555{
504 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 556 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
505 char *dev_addr = rx->sdata->vif.addr; 557 char *dev_addr = rx->sdata->vif.addr;
@@ -507,7 +559,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
507 if (ieee80211_is_data(hdr->frame_control)) { 559 if (ieee80211_is_data(hdr->frame_control)) {
508 if (is_multicast_ether_addr(hdr->addr1)) { 560 if (is_multicast_ether_addr(hdr->addr1)) {
509 if (ieee80211_has_tods(hdr->frame_control) || 561 if (ieee80211_has_tods(hdr->frame_control) ||
510 !ieee80211_has_fromds(hdr->frame_control)) 562 !ieee80211_has_fromds(hdr->frame_control))
511 return RX_DROP_MONITOR; 563 return RX_DROP_MONITOR;
512 if (ether_addr_equal(hdr->addr3, dev_addr)) 564 if (ether_addr_equal(hdr->addr3, dev_addr))
513 return RX_DROP_MONITOR; 565 return RX_DROP_MONITOR;
@@ -539,7 +591,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
539 mgmt = (struct ieee80211_mgmt *)hdr; 591 mgmt = (struct ieee80211_mgmt *)hdr;
540 category = mgmt->u.action.category; 592 category = mgmt->u.action.category;
541 if (category != WLAN_CATEGORY_MESH_ACTION && 593 if (category != WLAN_CATEGORY_MESH_ACTION &&
542 category != WLAN_CATEGORY_SELF_PROTECTED) 594 category != WLAN_CATEGORY_SELF_PROTECTED)
543 return RX_DROP_MONITOR; 595 return RX_DROP_MONITOR;
544 return RX_CONTINUE; 596 return RX_CONTINUE;
545 } 597 }
@@ -551,7 +603,6 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
551 return RX_CONTINUE; 603 return RX_CONTINUE;
552 604
553 return RX_DROP_MONITOR; 605 return RX_DROP_MONITOR;
554
555 } 606 }
556 607
557 return RX_CONTINUE; 608 return RX_CONTINUE;
@@ -575,7 +626,6 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
575 return (sq1 - sq2) & SEQ_MASK; 626 return (sq1 - sq2) & SEQ_MASK;
576} 627}
577 628
578
579static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, 629static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
580 struct tid_ampdu_rx *tid_agg_rx, 630 struct tid_ampdu_rx *tid_agg_rx,
581 int index) 631 int index)
@@ -1291,17 +1341,22 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1291 1341
1292 /* 1342 /*
1293 * Update last_rx only for IBSS packets which are for the current 1343 * Update last_rx only for IBSS packets which are for the current
1294 * BSSID to avoid keeping the current IBSS network alive in cases 1344 * BSSID and for station already AUTHORIZED to avoid keeping the
1295 * where other STAs start using different BSSID. 1345 * current IBSS network alive in cases where other STAs start
1346 * using different BSSID. This will also give the station another
1347 * chance to restart the authentication/authorization in case
1348 * something went wrong the first time.
1296 */ 1349 */
1297 if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) { 1350 if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) {
1298 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, 1351 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
1299 NL80211_IFTYPE_ADHOC); 1352 NL80211_IFTYPE_ADHOC);
1300 if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid)) { 1353 if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid) &&
1354 test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
1301 sta->last_rx = jiffies; 1355 sta->last_rx = jiffies;
1302 if (ieee80211_is_data(hdr->frame_control)) { 1356 if (ieee80211_is_data(hdr->frame_control)) {
1303 sta->last_rx_rate_idx = status->rate_idx; 1357 sta->last_rx_rate_idx = status->rate_idx;
1304 sta->last_rx_rate_flag = status->flag; 1358 sta->last_rx_rate_flag = status->flag;
1359 sta->last_rx_rate_vht_nss = status->vht_nss;
1305 } 1360 }
1306 } 1361 }
1307 } else if (!is_multicast_ether_addr(hdr->addr1)) { 1362 } else if (!is_multicast_ether_addr(hdr->addr1)) {
@@ -1313,6 +1368,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1313 if (ieee80211_is_data(hdr->frame_control)) { 1368 if (ieee80211_is_data(hdr->frame_control)) {
1314 sta->last_rx_rate_idx = status->rate_idx; 1369 sta->last_rx_rate_idx = status->rate_idx;
1315 sta->last_rx_rate_flag = status->flag; 1370 sta->last_rx_rate_flag = status->flag;
1371 sta->last_rx_rate_vht_nss = status->vht_nss;
1316 } 1372 }
1317 } 1373 }
1318 1374
@@ -1585,18 +1641,15 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1585 return RX_CONTINUE; 1641 return RX_CONTINUE;
1586} 1642}
1587 1643
1588static int 1644static int ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)
1589ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)
1590{ 1645{
1591 if (unlikely(!rx->sta || 1646 if (unlikely(!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_AUTHORIZED)))
1592 !test_sta_flag(rx->sta, WLAN_STA_AUTHORIZED)))
1593 return -EACCES; 1647 return -EACCES;
1594 1648
1595 return 0; 1649 return 0;
1596} 1650}
1597 1651
1598static int 1652static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
1599ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
1600{ 1653{
1601 struct sk_buff *skb = rx->skb; 1654 struct sk_buff *skb = rx->skb;
1602 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 1655 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
@@ -1618,8 +1671,7 @@ ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
1618 return 0; 1671 return 0;
1619} 1672}
1620 1673
1621static int 1674static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1622ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1623{ 1675{
1624 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1676 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1625 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); 1677 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
@@ -2003,7 +2055,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2003 } else { 2055 } else {
2004 /* unable to resolve next hop */ 2056 /* unable to resolve next hop */
2005 mesh_path_error_tx(ifmsh->mshcfg.element_ttl, fwd_hdr->addr3, 2057 mesh_path_error_tx(ifmsh->mshcfg.element_ttl, fwd_hdr->addr3,
2006 0, reason, fwd_hdr->addr2, sdata); 2058 0, reason, fwd_hdr->addr2, sdata);
2007 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); 2059 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
2008 kfree_skb(fwd_skb); 2060 kfree_skb(fwd_skb);
2009 return RX_DROP_MONITOR; 2061 return RX_DROP_MONITOR;
@@ -2212,7 +2264,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
2212 2264
2213 cfg80211_report_obss_beacon(rx->local->hw.wiphy, 2265 cfg80211_report_obss_beacon(rx->local->hw.wiphy,
2214 rx->skb->data, rx->skb->len, 2266 rx->skb->data, rx->skb->len,
2215 status->freq, sig, GFP_ATOMIC); 2267 status->freq, sig);
2216 rx->flags |= IEEE80211_RX_BEACON_REPORTED; 2268 rx->flags |= IEEE80211_RX_BEACON_REPORTED;
2217 } 2269 }
2218 2270
@@ -2412,7 +2464,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2412 if (!ieee80211_vif_is_mesh(&sdata->vif)) 2464 if (!ieee80211_vif_is_mesh(&sdata->vif))
2413 break; 2465 break;
2414 if (mesh_action_is_path_sel(mgmt) && 2466 if (mesh_action_is_path_sel(mgmt) &&
2415 (!mesh_path_sel_is_hwmp(sdata))) 2467 !mesh_path_sel_is_hwmp(sdata))
2416 break; 2468 break;
2417 goto queue; 2469 goto queue;
2418 } 2470 }
@@ -2468,7 +2520,6 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
2468 return RX_QUEUED; 2520 return RX_QUEUED;
2469 } 2521 }
2470 2522
2471
2472 return RX_CONTINUE; 2523 return RX_CONTINUE;
2473} 2524}
2474 2525
@@ -2598,7 +2649,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
2598 goto out_free_skb; 2649 goto out_free_skb;
2599 2650
2600 /* room for the radiotap header based on driver features */ 2651 /* room for the radiotap header based on driver features */
2601 needed_headroom = ieee80211_rx_radiotap_len(local, status); 2652 needed_headroom = ieee80211_rx_radiotap_space(local, status);
2602 2653
2603 if (skb_headroom(skb) < needed_headroom && 2654 if (skb_headroom(skb) < needed_headroom &&
2604 pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) 2655 pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC))
@@ -2661,7 +2712,8 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
2661 status = IEEE80211_SKB_RXCB((rx->skb)); 2712 status = IEEE80211_SKB_RXCB((rx->skb));
2662 2713
2663 sband = rx->local->hw.wiphy->bands[status->band]; 2714 sband = rx->local->hw.wiphy->bands[status->band];
2664 if (!(status->flag & RX_FLAG_HT)) 2715 if (!(status->flag & RX_FLAG_HT) &&
2716 !(status->flag & RX_FLAG_VHT))
2665 rate = &sband->bitrates[status->rate_idx]; 2717 rate = &sband->bitrates[status->rate_idx];
2666 2718
2667 ieee80211_rx_cooked_monitor(rx, rate); 2719 ieee80211_rx_cooked_monitor(rx, rate);
@@ -2828,8 +2880,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2828 status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 2880 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2829 } else if (!rx->sta) { 2881 } else if (!rx->sta) {
2830 int rate_idx; 2882 int rate_idx;
2831 if (status->flag & RX_FLAG_HT) 2883 if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
2832 rate_idx = 0; /* TODO: HT rates */ 2884 rate_idx = 0; /* TODO: HT/VHT rates */
2833 else 2885 else
2834 rate_idx = status->rate_idx; 2886 rate_idx = status->rate_idx;
2835 ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2, 2887 ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2,
@@ -3105,6 +3157,13 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
3105 status->rate_idx, 3157 status->rate_idx,
3106 status->rate_idx)) 3158 status->rate_idx))
3107 goto drop; 3159 goto drop;
3160 } else if (status->flag & RX_FLAG_VHT) {
3161 if (WARN_ONCE(status->rate_idx > 9 ||
3162 !status->vht_nss ||
3163 status->vht_nss > 8,
3164 "Rate marked as a VHT rate but data is invalid: MCS: %d, NSS: %d\n",
3165 status->rate_idx, status->vht_nss))
3166 goto drop;
3108 } else { 3167 } else {
3109 if (WARN_ON(status->rate_idx >= sband->n_bitrates)) 3168 if (WARN_ON(status->rate_idx >= sband->n_bitrates))
3110 goto drop; 3169 goto drop;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 8e9bb168b73..f3340279aba 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -174,7 +174,6 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
174 u8 *elements; 174 u8 *elements;
175 struct ieee80211_channel *channel; 175 struct ieee80211_channel *channel;
176 size_t baselen; 176 size_t baselen;
177 int freq;
178 bool beacon; 177 bool beacon;
179 struct ieee802_11_elems elems; 178 struct ieee802_11_elems elems;
180 179
@@ -209,13 +208,7 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
209 208
210 ieee802_11_parse_elems(elements, skb->len - baselen, &elems); 209 ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
211 210
212 if (elems.ds_params && elems.ds_params_len == 1) 211 channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
213 freq = ieee80211_channel_to_frequency(elems.ds_params[0],
214 rx_status->band);
215 else
216 freq = rx_status->freq;
217
218 channel = ieee80211_get_channel(local->hw.wiphy, freq);
219 212
220 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) 213 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
221 return; 214 return;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index e9d57689c05..f3e502502fe 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -142,7 +142,7 @@ static void free_sta_work(struct work_struct *wk)
142 * drivers have to handle aggregation stop being requested, followed 142 * drivers have to handle aggregation stop being requested, followed
143 * directly by station destruction. 143 * directly by station destruction.
144 */ 144 */
145 for (i = 0; i < STA_TID_NUM; i++) { 145 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
146 tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); 146 tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
147 if (!tid_tx) 147 if (!tid_tx)
148 continue; 148 continue;
@@ -330,7 +330,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
330 return NULL; 330 return NULL;
331 } 331 }
332 332
333 for (i = 0; i < STA_TID_NUM; i++) { 333 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
334 /* 334 /*
335 * timer_to_tid must be initialized with identity mapping 335 * timer_to_tid must be initialized with identity mapping
336 * to enable session_timer's data differentiation. See 336 * to enable session_timer's data differentiation. See
@@ -343,7 +343,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
343 skb_queue_head_init(&sta->tx_filtered[i]); 343 skb_queue_head_init(&sta->tx_filtered[i]);
344 } 344 }
345 345
346 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) 346 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
347 sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); 347 sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX);
348 348
349 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); 349 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
@@ -986,7 +986,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
986 986
987 clear_sta_flag(sta, WLAN_STA_SP); 987 clear_sta_flag(sta, WLAN_STA_SP);
988 988
989 BUILD_BUG_ON(BITS_TO_LONGS(STA_TID_NUM) > 1); 989 BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1);
990 sta->driver_buffered_tids = 0; 990 sta->driver_buffered_tids = 0;
991 991
992 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) 992 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
@@ -1092,7 +1092,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
1092 return; 1092 return;
1093 } 1093 }
1094 1094
1095 ieee80211_xmit(sdata, skb, chanctx_conf->channel->band); 1095 ieee80211_xmit(sdata, skb, chanctx_conf->def.chan->band);
1096 rcu_read_unlock(); 1096 rcu_read_unlock();
1097} 1097}
1098 1098
@@ -1374,7 +1374,7 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
1374{ 1374{
1375 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 1375 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
1376 1376
1377 if (WARN_ON(tid >= STA_TID_NUM)) 1377 if (WARN_ON(tid >= IEEE80211_NUM_TIDS))
1378 return; 1378 return;
1379 1379
1380 if (buffered) 1380 if (buffered)
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index c88f161f811..6835cea4e40 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -80,7 +80,6 @@ enum ieee80211_sta_info_flags {
80 WLAN_STA_TOFFSET_KNOWN, 80 WLAN_STA_TOFFSET_KNOWN,
81}; 81};
82 82
83#define STA_TID_NUM 16
84#define ADDBA_RESP_INTERVAL HZ 83#define ADDBA_RESP_INTERVAL HZ
85#define HT_AGG_MAX_RETRIES 15 84#define HT_AGG_MAX_RETRIES 15
86#define HT_AGG_BURST_RETRIES 3 85#define HT_AGG_BURST_RETRIES 3
@@ -197,15 +196,15 @@ struct tid_ampdu_rx {
197struct sta_ampdu_mlme { 196struct sta_ampdu_mlme {
198 struct mutex mtx; 197 struct mutex mtx;
199 /* rx */ 198 /* rx */
200 struct tid_ampdu_rx __rcu *tid_rx[STA_TID_NUM]; 199 struct tid_ampdu_rx __rcu *tid_rx[IEEE80211_NUM_TIDS];
201 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)]; 200 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
202 unsigned long tid_rx_stop_requested[BITS_TO_LONGS(STA_TID_NUM)]; 201 unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
203 /* tx */ 202 /* tx */
204 struct work_struct work; 203 struct work_struct work;
205 struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM]; 204 struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS];
206 struct tid_ampdu_tx *tid_start_tx[STA_TID_NUM]; 205 struct tid_ampdu_tx *tid_start_tx[IEEE80211_NUM_TIDS];
207 unsigned long last_addba_req_time[STA_TID_NUM]; 206 unsigned long last_addba_req_time[IEEE80211_NUM_TIDS];
208 u8 addba_req_num[STA_TID_NUM]; 207 u8 addba_req_num[IEEE80211_NUM_TIDS];
209 u8 dialog_token_allocator; 208 u8 dialog_token_allocator;
210}; 209};
211 210
@@ -228,6 +227,7 @@ struct sta_ampdu_mlme {
228 * "the" transmit rate 227 * "the" transmit rate
229 * @last_rx_rate_idx: rx status rate index of the last data packet 228 * @last_rx_rate_idx: rx status rate index of the last data packet
230 * @last_rx_rate_flag: rx status flag of the last data packet 229 * @last_rx_rate_flag: rx status flag of the last data packet
230 * @last_rx_rate_vht_nss: rx status nss of last data packet
231 * @lock: used for locking all fields that require locking, see comments 231 * @lock: used for locking all fields that require locking, see comments
232 * in the header file. 232 * in the header file.
233 * @drv_unblock_wk: used for driver PS unblocking 233 * @drv_unblock_wk: used for driver PS unblocking
@@ -273,7 +273,7 @@ struct sta_ampdu_mlme {
273 * @t_offset: timing offset relative to this host 273 * @t_offset: timing offset relative to this host
274 * @t_offset_setpoint: reference timing offset of this sta to be used when 274 * @t_offset_setpoint: reference timing offset of this sta to be used when
275 * calculating clockdrift 275 * calculating clockdrift
276 * @ch_type: peer's channel type 276 * @ch_width: peer's channel width
277 * @debugfs: debug filesystem info 277 * @debugfs: debug filesystem info
278 * @dead: set to true when sta is unlinked 278 * @dead: set to true when sta is unlinked
279 * @uploaded: set to true when sta is uploaded to the driver 279 * @uploaded: set to true when sta is uploaded to the driver
@@ -330,7 +330,7 @@ struct sta_info {
330 int last_signal; 330 int last_signal;
331 struct ewma avg_signal; 331 struct ewma avg_signal;
332 /* Plus 1 for non-QoS frames */ 332 /* Plus 1 for non-QoS frames */
333 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES + 1]; 333 __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
334 334
335 /* Updated from TX status path only, no locking requirements */ 335 /* Updated from TX status path only, no locking requirements */
336 unsigned long tx_filtered_count; 336 unsigned long tx_filtered_count;
@@ -344,14 +344,15 @@ struct sta_info {
344 unsigned long tx_fragments; 344 unsigned long tx_fragments;
345 struct ieee80211_tx_rate last_tx_rate; 345 struct ieee80211_tx_rate last_tx_rate;
346 int last_rx_rate_idx; 346 int last_rx_rate_idx;
347 int last_rx_rate_flag; 347 u32 last_rx_rate_flag;
348 u8 last_rx_rate_vht_nss;
348 u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; 349 u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
349 350
350 /* 351 /*
351 * Aggregation information, locked with lock. 352 * Aggregation information, locked with lock.
352 */ 353 */
353 struct sta_ampdu_mlme ampdu_mlme; 354 struct sta_ampdu_mlme ampdu_mlme;
354 u8 timer_to_tid[STA_TID_NUM]; 355 u8 timer_to_tid[IEEE80211_NUM_TIDS];
355 356
356#ifdef CONFIG_MAC80211_MESH 357#ifdef CONFIG_MAC80211_MESH
357 /* 358 /*
@@ -369,7 +370,7 @@ struct sta_info {
369 struct timer_list plink_timer; 370 struct timer_list plink_timer;
370 s64 t_offset; 371 s64 t_offset;
371 s64 t_offset_setpoint; 372 s64 t_offset_setpoint;
372 enum nl80211_channel_type ch_type; 373 enum nl80211_chan_width ch_width;
373#endif 374#endif
374 375
375#ifdef CONFIG_MAC80211_DEBUGFS 376#ifdef CONFIG_MAC80211_DEBUGFS
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 248247877eb..ab63237107c 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -325,6 +325,75 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
325 325
326} 326}
327 327
328static void ieee80211_report_used_skb(struct ieee80211_local *local,
329 struct sk_buff *skb, bool dropped)
330{
331 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
332 struct ieee80211_hdr *hdr = (void *)skb->data;
333 bool acked = info->flags & IEEE80211_TX_STAT_ACK;
334
335 if (dropped)
336 acked = false;
337
338 if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) {
339 struct ieee80211_sub_if_data *sdata = NULL;
340 struct ieee80211_sub_if_data *iter_sdata;
341 u64 cookie = (unsigned long)skb;
342
343 rcu_read_lock();
344
345 if (skb->dev) {
346 list_for_each_entry_rcu(iter_sdata, &local->interfaces,
347 list) {
348 if (!iter_sdata->dev)
349 continue;
350
351 if (skb->dev == iter_sdata->dev) {
352 sdata = iter_sdata;
353 break;
354 }
355 }
356 } else {
357 sdata = rcu_dereference(local->p2p_sdata);
358 }
359
360 if (!sdata)
361 skb->dev = NULL;
362 else if (ieee80211_is_nullfunc(hdr->frame_control) ||
363 ieee80211_is_qos_nullfunc(hdr->frame_control)) {
364 cfg80211_probe_status(sdata->dev, hdr->addr1,
365 cookie, acked, GFP_ATOMIC);
366 } else {
367 cfg80211_mgmt_tx_status(&sdata->wdev, cookie, skb->data,
368 skb->len, acked, GFP_ATOMIC);
369 }
370
371 rcu_read_unlock();
372 }
373
374 if (unlikely(info->ack_frame_id)) {
375 struct sk_buff *ack_skb;
376 unsigned long flags;
377
378 spin_lock_irqsave(&local->ack_status_lock, flags);
379 ack_skb = idr_find(&local->ack_status_frames,
380 info->ack_frame_id);
381 if (ack_skb)
382 idr_remove(&local->ack_status_frames,
383 info->ack_frame_id);
384 spin_unlock_irqrestore(&local->ack_status_lock, flags);
385
386 if (ack_skb) {
387 if (!dropped) {
388 /* consumes ack_skb */
389 skb_complete_wifi_ack(ack_skb, acked);
390 } else {
391 dev_kfree_skb_any(ack_skb);
392 }
393 }
394 }
395}
396
328/* 397/*
329 * Use a static threshold for now, best value to be determined 398 * Use a static threshold for now, best value to be determined
330 * by testing ... 399 * by testing ...
@@ -516,62 +585,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
516 msecs_to_jiffies(10)); 585 msecs_to_jiffies(10));
517 } 586 }
518 587
519 if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { 588 ieee80211_report_used_skb(local, skb, false);
520 u64 cookie = (unsigned long)skb;
521 bool found = false;
522
523 acked = info->flags & IEEE80211_TX_STAT_ACK;
524
525 rcu_read_lock();
526
527 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
528 if (!sdata->dev)
529 continue;
530
531 if (skb->dev != sdata->dev)
532 continue;
533
534 found = true;
535 break;
536 }
537
538 if (!skb->dev) {
539 sdata = rcu_dereference(local->p2p_sdata);
540 if (sdata)
541 found = true;
542 }
543
544 if (!found)
545 skb->dev = NULL;
546 else if (ieee80211_is_nullfunc(hdr->frame_control) ||
547 ieee80211_is_qos_nullfunc(hdr->frame_control)) {
548 cfg80211_probe_status(sdata->dev, hdr->addr1,
549 cookie, acked, GFP_ATOMIC);
550 } else {
551 cfg80211_mgmt_tx_status(&sdata->wdev, cookie, skb->data,
552 skb->len, acked, GFP_ATOMIC);
553 }
554
555 rcu_read_unlock();
556 }
557
558 if (unlikely(info->ack_frame_id)) {
559 struct sk_buff *ack_skb;
560 unsigned long flags;
561
562 spin_lock_irqsave(&local->ack_status_lock, flags);
563 ack_skb = idr_find(&local->ack_status_frames,
564 info->ack_frame_id);
565 if (ack_skb)
566 idr_remove(&local->ack_status_frames,
567 info->ack_frame_id);
568 spin_unlock_irqrestore(&local->ack_status_lock, flags);
569
570 /* consumes ack_skb */
571 if (ack_skb)
572 skb_complete_wifi_ack(ack_skb,
573 info->flags & IEEE80211_TX_STAT_ACK);
574 }
575 589
576 /* this was a transmitted frame, but now we want to reuse it */ 590 /* this was a transmitted frame, but now we want to reuse it */
577 skb_orphan(skb); 591 skb_orphan(skb);
@@ -647,25 +661,8 @@ EXPORT_SYMBOL(ieee80211_report_low_ack);
647void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) 661void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb)
648{ 662{
649 struct ieee80211_local *local = hw_to_local(hw); 663 struct ieee80211_local *local = hw_to_local(hw);
650 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
651
652 if (unlikely(info->ack_frame_id)) {
653 struct sk_buff *ack_skb;
654 unsigned long flags;
655
656 spin_lock_irqsave(&local->ack_status_lock, flags);
657 ack_skb = idr_find(&local->ack_status_frames,
658 info->ack_frame_id);
659 if (ack_skb)
660 idr_remove(&local->ack_status_frames,
661 info->ack_frame_id);
662 spin_unlock_irqrestore(&local->ack_status_lock, flags);
663
664 /* consumes ack_skb */
665 if (ack_skb)
666 dev_kfree_skb_any(ack_skb);
667 }
668 664
665 ieee80211_report_used_skb(local, skb, true);
669 dev_kfree_skb_any(skb); 666 dev_kfree_skb_any(skb);
670} 667}
671EXPORT_SYMBOL(ieee80211_free_txskb); 668EXPORT_SYMBOL(ieee80211_free_txskb);
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 0638541b625..a8270b441a6 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -28,16 +28,21 @@
28#define VIF_PR_FMT " vif:%s(%d%s)" 28#define VIF_PR_FMT " vif:%s(%d%s)"
29#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" 29#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
30 30
31#define CHANCTX_ENTRY __field(int, freq) \ 31#define CHANCTX_ENTRY __field(u32, control_freq) \
32 __field(int, chantype) \ 32 __field(u32, chan_width) \
33 __field(u32, center_freq1) \
34 __field(u32, center_freq2) \
33 __field(u8, rx_chains_static) \ 35 __field(u8, rx_chains_static) \
34 __field(u8, rx_chains_dynamic) 36 __field(u8, rx_chains_dynamic)
35#define CHANCTX_ASSIGN __entry->freq = ctx->conf.channel->center_freq; \ 37#define CHANCTX_ASSIGN __entry->control_freq = ctx->conf.def.chan->center_freq;\
36 __entry->chantype = ctx->conf.channel_type; \ 38 __entry->chan_width = ctx->conf.def.width; \
39 __entry->center_freq1 = ctx->conf.def.center_freq1; \
40 __entry->center_freq2 = ctx->conf.def.center_freq2; \
37 __entry->rx_chains_static = ctx->conf.rx_chains_static; \ 41 __entry->rx_chains_static = ctx->conf.rx_chains_static; \
38 __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic 42 __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic
39#define CHANCTX_PR_FMT " freq:%d MHz chantype:%d chains:%d/%d" 43#define CHANCTX_PR_FMT " control:%d MHz width:%d center: %d/%d MHz chains:%d/%d"
40#define CHANCTX_PR_ARG __entry->freq, __entry->chantype, \ 44#define CHANCTX_PR_ARG __entry->control_freq, __entry->chan_width, \
45 __entry->center_freq1, __entry->center_freq2, \
41 __entry->rx_chains_static, __entry->rx_chains_dynamic 46 __entry->rx_chains_static, __entry->rx_chains_dynamic
42 47
43 48
@@ -334,7 +339,8 @@ TRACE_EVENT(drv_bss_info_changed,
334 __field(u16, ht_operation_mode) 339 __field(u16, ht_operation_mode)
335 __field(s32, cqm_rssi_thold); 340 __field(s32, cqm_rssi_thold);
336 __field(s32, cqm_rssi_hyst); 341 __field(s32, cqm_rssi_hyst);
337 __field(u32, channel_type); 342 __field(u32, channel_width);
343 __field(u32, channel_cfreq1);
338 __dynamic_array(u32, arp_addr_list, info->arp_addr_cnt); 344 __dynamic_array(u32, arp_addr_list, info->arp_addr_cnt);
339 __field(bool, arp_filter_enabled); 345 __field(bool, arp_filter_enabled);
340 __field(bool, qos); 346 __field(bool, qos);
@@ -342,6 +348,9 @@ TRACE_EVENT(drv_bss_info_changed,
342 __field(bool, ps); 348 __field(bool, ps);
343 __dynamic_array(u8, ssid, info->ssid_len); 349 __dynamic_array(u8, ssid, info->ssid_len);
344 __field(bool, hidden_ssid); 350 __field(bool, hidden_ssid);
351 __field(int, txpower)
352 __field(u8, p2p_ctwindow)
353 __field(bool, p2p_oppps)
345 ), 354 ),
346 355
347 TP_fast_assign( 356 TP_fast_assign(
@@ -367,7 +376,8 @@ TRACE_EVENT(drv_bss_info_changed,
367 __entry->ht_operation_mode = info->ht_operation_mode; 376 __entry->ht_operation_mode = info->ht_operation_mode;
368 __entry->cqm_rssi_thold = info->cqm_rssi_thold; 377 __entry->cqm_rssi_thold = info->cqm_rssi_thold;
369 __entry->cqm_rssi_hyst = info->cqm_rssi_hyst; 378 __entry->cqm_rssi_hyst = info->cqm_rssi_hyst;
370 __entry->channel_type = info->channel_type; 379 __entry->channel_width = info->chandef.width;
380 __entry->channel_cfreq1 = info->chandef.center_freq1;
371 memcpy(__get_dynamic_array(arp_addr_list), info->arp_addr_list, 381 memcpy(__get_dynamic_array(arp_addr_list), info->arp_addr_list,
372 sizeof(u32) * info->arp_addr_cnt); 382 sizeof(u32) * info->arp_addr_cnt);
373 __entry->arp_filter_enabled = info->arp_filter_enabled; 383 __entry->arp_filter_enabled = info->arp_filter_enabled;
@@ -376,6 +386,9 @@ TRACE_EVENT(drv_bss_info_changed,
376 __entry->ps = info->ps; 386 __entry->ps = info->ps;
377 memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len); 387 memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len);
378 __entry->hidden_ssid = info->hidden_ssid; 388 __entry->hidden_ssid = info->hidden_ssid;
389 __entry->txpower = info->txpower;
390 __entry->p2p_ctwindow = info->p2p_ctwindow;
391 __entry->p2p_oppps = info->p2p_oppps;
379 ), 392 ),
380 393
381 TP_printk( 394 TP_printk(
@@ -1013,28 +1026,31 @@ TRACE_EVENT(drv_get_antenna,
1013); 1026);
1014 1027
1015TRACE_EVENT(drv_remain_on_channel, 1028TRACE_EVENT(drv_remain_on_channel,
1016 TP_PROTO(struct ieee80211_local *local, struct ieee80211_channel *chan, 1029 TP_PROTO(struct ieee80211_local *local,
1017 enum nl80211_channel_type chantype, unsigned int duration), 1030 struct ieee80211_sub_if_data *sdata,
1031 struct ieee80211_channel *chan,
1032 unsigned int duration),
1018 1033
1019 TP_ARGS(local, chan, chantype, duration), 1034 TP_ARGS(local, sdata, chan, duration),
1020 1035
1021 TP_STRUCT__entry( 1036 TP_STRUCT__entry(
1022 LOCAL_ENTRY 1037 LOCAL_ENTRY
1038 VIF_ENTRY
1023 __field(int, center_freq) 1039 __field(int, center_freq)
1024 __field(int, channel_type)
1025 __field(unsigned int, duration) 1040 __field(unsigned int, duration)
1026 ), 1041 ),
1027 1042
1028 TP_fast_assign( 1043 TP_fast_assign(
1029 LOCAL_ASSIGN; 1044 LOCAL_ASSIGN;
1045 VIF_ASSIGN;
1030 __entry->center_freq = chan->center_freq; 1046 __entry->center_freq = chan->center_freq;
1031 __entry->channel_type = chantype;
1032 __entry->duration = duration; 1047 __entry->duration = duration;
1033 ), 1048 ),
1034 1049
1035 TP_printk( 1050 TP_printk(
1036 LOCAL_PR_FMT " freq:%dMHz duration:%dms", 1051 LOCAL_PR_FMT VIF_PR_FMT " freq:%dMHz duration:%dms",
1037 LOCAL_PR_ARG, __entry->center_freq, __entry->duration 1052 LOCAL_PR_ARG, VIF_PR_ARG,
1053 __entry->center_freq, __entry->duration
1038 ) 1054 )
1039); 1055);
1040 1056
@@ -1043,34 +1059,6 @@ DEFINE_EVENT(local_only_evt, drv_cancel_remain_on_channel,
1043 TP_ARGS(local) 1059 TP_ARGS(local)
1044); 1060);
1045 1061
1046TRACE_EVENT(drv_offchannel_tx,
1047 TP_PROTO(struct ieee80211_local *local, struct sk_buff *skb,
1048 struct ieee80211_channel *chan,
1049 enum nl80211_channel_type channel_type,
1050 unsigned int wait),
1051
1052 TP_ARGS(local, skb, chan, channel_type, wait),
1053
1054 TP_STRUCT__entry(
1055 LOCAL_ENTRY
1056 __field(int, center_freq)
1057 __field(int, channel_type)
1058 __field(unsigned int, wait)
1059 ),
1060
1061 TP_fast_assign(
1062 LOCAL_ASSIGN;
1063 __entry->center_freq = chan->center_freq;
1064 __entry->channel_type = channel_type;
1065 __entry->wait = wait;
1066 ),
1067
1068 TP_printk(
1069 LOCAL_PR_FMT " freq:%dMHz, wait:%dms",
1070 LOCAL_PR_ARG, __entry->center_freq, __entry->wait
1071 )
1072);
1073
1074TRACE_EVENT(drv_set_ringparam, 1062TRACE_EVENT(drv_set_ringparam,
1075 TP_PROTO(struct ieee80211_local *local, u32 tx, u32 rx), 1063 TP_PROTO(struct ieee80211_local *local, u32 tx, u32 rx),
1076 1064
@@ -1396,6 +1384,48 @@ DEFINE_EVENT(local_sdata_chanctx, drv_unassign_vif_chanctx,
1396 TP_ARGS(local, sdata, ctx) 1384 TP_ARGS(local, sdata, ctx)
1397); 1385);
1398 1386
1387TRACE_EVENT(drv_start_ap,
1388 TP_PROTO(struct ieee80211_local *local,
1389 struct ieee80211_sub_if_data *sdata,
1390 struct ieee80211_bss_conf *info),
1391
1392 TP_ARGS(local, sdata, info),
1393
1394 TP_STRUCT__entry(
1395 LOCAL_ENTRY
1396 VIF_ENTRY
1397 __field(u8, dtimper)
1398 __field(u16, bcnint)
1399 __dynamic_array(u8, ssid, info->ssid_len);
1400 __field(bool, hidden_ssid);
1401 ),
1402
1403 TP_fast_assign(
1404 LOCAL_ASSIGN;
1405 VIF_ASSIGN;
1406 __entry->dtimper = info->dtim_period;
1407 __entry->bcnint = info->beacon_int;
1408 memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len);
1409 __entry->hidden_ssid = info->hidden_ssid;
1410 ),
1411
1412 TP_printk(
1413 LOCAL_PR_FMT VIF_PR_FMT,
1414 LOCAL_PR_ARG, VIF_PR_ARG
1415 )
1416);
1417
1418DEFINE_EVENT(local_sdata_evt, drv_stop_ap,
1419 TP_PROTO(struct ieee80211_local *local,
1420 struct ieee80211_sub_if_data *sdata),
1421 TP_ARGS(local, sdata)
1422);
1423
1424DEFINE_EVENT(local_only_evt, drv_restart_complete,
1425 TP_PROTO(struct ieee80211_local *local),
1426 TP_ARGS(local)
1427);
1428
1399/* 1429/*
1400 * Tracing for API calls that drivers call. 1430 * Tracing for API calls that drivers call.
1401 */ 1431 */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 6f1981816dc..d287a4f2c01 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1676,7 +1676,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1676 if (!chanctx_conf) 1676 if (!chanctx_conf)
1677 goto fail_rcu; 1677 goto fail_rcu;
1678 1678
1679 chan = chanctx_conf->channel; 1679 chan = chanctx_conf->def.chan;
1680 1680
1681 /* 1681 /*
1682 * Frame injection is not allowed if beaconing is not allowed 1682 * Frame injection is not allowed if beaconing is not allowed
@@ -1779,7 +1779,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1779 chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf); 1779 chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf);
1780 if (!chanctx_conf) 1780 if (!chanctx_conf)
1781 goto fail_rcu; 1781 goto fail_rcu;
1782 band = chanctx_conf->channel->band; 1782 band = chanctx_conf->def.chan->band;
1783 if (sta) 1783 if (sta)
1784 break; 1784 break;
1785 /* fall through */ 1785 /* fall through */
@@ -1794,7 +1794,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1794 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1794 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1795 if (!chanctx_conf) 1795 if (!chanctx_conf)
1796 goto fail_rcu; 1796 goto fail_rcu;
1797 band = chanctx_conf->channel->band; 1797 band = chanctx_conf->def.chan->band;
1798 break; 1798 break;
1799 case NL80211_IFTYPE_WDS: 1799 case NL80211_IFTYPE_WDS:
1800 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1800 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
@@ -1871,7 +1871,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1871 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1871 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1872 if (!chanctx_conf) 1872 if (!chanctx_conf)
1873 goto fail_rcu; 1873 goto fail_rcu;
1874 band = chanctx_conf->channel->band; 1874 band = chanctx_conf->def.chan->band;
1875 break; 1875 break;
1876#endif 1876#endif
1877 case NL80211_IFTYPE_STATION: 1877 case NL80211_IFTYPE_STATION:
@@ -1930,7 +1930,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1930 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1930 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1931 if (!chanctx_conf) 1931 if (!chanctx_conf)
1932 goto fail_rcu; 1932 goto fail_rcu;
1933 band = chanctx_conf->channel->band; 1933 band = chanctx_conf->def.chan->band;
1934 break; 1934 break;
1935 case NL80211_IFTYPE_ADHOC: 1935 case NL80211_IFTYPE_ADHOC:
1936 /* DA SA BSSID */ 1936 /* DA SA BSSID */
@@ -1941,7 +1941,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1941 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1941 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1942 if (!chanctx_conf) 1942 if (!chanctx_conf)
1943 goto fail_rcu; 1943 goto fail_rcu;
1944 band = chanctx_conf->channel->band; 1944 band = chanctx_conf->def.chan->band;
1945 break; 1945 break;
1946 default: 1946 default:
1947 goto fail_rcu; 1947 goto fail_rcu;
@@ -2089,6 +2089,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
2089 head_need = max_t(int, 0, head_need); 2089 head_need = max_t(int, 0, head_need);
2090 if (ieee80211_skb_resize(sdata, skb, head_need, true)) { 2090 if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
2091 ieee80211_free_txskb(&local->hw, skb); 2091 ieee80211_free_txskb(&local->hw, skb);
2092 skb = NULL;
2092 goto fail_rcu; 2093 goto fail_rcu;
2093 } 2094 }
2094 } 2095 }
@@ -2193,7 +2194,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
2193 return true; 2194 return true;
2194 } 2195 }
2195 result = ieee80211_tx(sdata, skb, true, 2196 result = ieee80211_tx(sdata, skb, true,
2196 chanctx_conf->channel->band); 2197 chanctx_conf->def.chan->band);
2197 } else { 2198 } else {
2198 struct sk_buff_head skbs; 2199 struct sk_buff_head skbs;
2199 2200
@@ -2457,7 +2458,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2457 *pos++ = WLAN_EID_SSID; 2458 *pos++ = WLAN_EID_SSID;
2458 *pos++ = 0x0; 2459 *pos++ = 0x0;
2459 2460
2460 band = chanctx_conf->channel->band; 2461 band = chanctx_conf->def.chan->band;
2461 2462
2462 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 2463 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
2463 mesh_add_ds_params_ie(skb, sdata) || 2464 mesh_add_ds_params_ie(skb, sdata) ||
@@ -2476,7 +2477,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2476 goto out; 2477 goto out;
2477 } 2478 }
2478 2479
2479 band = chanctx_conf->channel->band; 2480 band = chanctx_conf->def.chan->band;
2480 2481
2481 info = IEEE80211_SKB_CB(skb); 2482 info = IEEE80211_SKB_CB(skb);
2482 2483
@@ -2756,7 +2757,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2756 info = IEEE80211_SKB_CB(skb); 2757 info = IEEE80211_SKB_CB(skb);
2757 2758
2758 tx.flags |= IEEE80211_TX_PS_BUFFERED; 2759 tx.flags |= IEEE80211_TX_PS_BUFFERED;
2759 info->band = chanctx_conf->channel->band; 2760 info->band = chanctx_conf->def.chan->band;
2760 2761
2761 if (invoke_tx_handlers(&tx)) 2762 if (invoke_tx_handlers(&tx))
2762 skb = NULL; 2763 skb = NULL;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index acbb8c9bae2..08132ff9815 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -512,7 +512,7 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw)
512EXPORT_SYMBOL(ieee80211_wake_queues); 512EXPORT_SYMBOL(ieee80211_wake_queues);
513 513
514void ieee80211_iterate_active_interfaces( 514void ieee80211_iterate_active_interfaces(
515 struct ieee80211_hw *hw, 515 struct ieee80211_hw *hw, u32 iter_flags,
516 void (*iterator)(void *data, u8 *mac, 516 void (*iterator)(void *data, u8 *mac,
517 struct ieee80211_vif *vif), 517 struct ieee80211_vif *vif),
518 void *data) 518 void *data)
@@ -530,6 +530,9 @@ void ieee80211_iterate_active_interfaces(
530 default: 530 default:
531 break; 531 break;
532 } 532 }
533 if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) &&
534 !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
535 continue;
533 if (ieee80211_sdata_running(sdata)) 536 if (ieee80211_sdata_running(sdata))
534 iterator(data, sdata->vif.addr, 537 iterator(data, sdata->vif.addr,
535 &sdata->vif); 538 &sdata->vif);
@@ -537,7 +540,9 @@ void ieee80211_iterate_active_interfaces(
537 540
538 sdata = rcu_dereference_protected(local->monitor_sdata, 541 sdata = rcu_dereference_protected(local->monitor_sdata,
539 lockdep_is_held(&local->iflist_mtx)); 542 lockdep_is_held(&local->iflist_mtx));
540 if (sdata) 543 if (sdata &&
544 (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL ||
545 sdata->flags & IEEE80211_SDATA_IN_DRIVER))
541 iterator(data, sdata->vif.addr, &sdata->vif); 546 iterator(data, sdata->vif.addr, &sdata->vif);
542 547
543 mutex_unlock(&local->iflist_mtx); 548 mutex_unlock(&local->iflist_mtx);
@@ -545,7 +550,7 @@ void ieee80211_iterate_active_interfaces(
545EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); 550EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);
546 551
547void ieee80211_iterate_active_interfaces_atomic( 552void ieee80211_iterate_active_interfaces_atomic(
548 struct ieee80211_hw *hw, 553 struct ieee80211_hw *hw, u32 iter_flags,
549 void (*iterator)(void *data, u8 *mac, 554 void (*iterator)(void *data, u8 *mac,
550 struct ieee80211_vif *vif), 555 struct ieee80211_vif *vif),
551 void *data) 556 void *data)
@@ -563,13 +568,18 @@ void ieee80211_iterate_active_interfaces_atomic(
563 default: 568 default:
564 break; 569 break;
565 } 570 }
571 if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) &&
572 !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
573 continue;
566 if (ieee80211_sdata_running(sdata)) 574 if (ieee80211_sdata_running(sdata))
567 iterator(data, sdata->vif.addr, 575 iterator(data, sdata->vif.addr,
568 &sdata->vif); 576 &sdata->vif);
569 } 577 }
570 578
571 sdata = rcu_dereference(local->monitor_sdata); 579 sdata = rcu_dereference(local->monitor_sdata);
572 if (sdata) 580 if (sdata &&
581 (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL ||
582 sdata->flags & IEEE80211_SDATA_IN_DRIVER))
573 iterator(data, sdata->vif.addr, &sdata->vif); 583 iterator(data, sdata->vif.addr, &sdata->vif);
574 584
575 rcu_read_unlock(); 585 rcu_read_unlock();
@@ -888,7 +898,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
888 rcu_read_lock(); 898 rcu_read_lock();
889 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 899 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
890 use_11b = (chanctx_conf && 900 use_11b = (chanctx_conf &&
891 chanctx_conf->channel->band == IEEE80211_BAND_2GHZ) && 901 chanctx_conf->def.chan->band == IEEE80211_BAND_2GHZ) &&
892 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); 902 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
893 rcu_read_unlock(); 903 rcu_read_unlock();
894 904
@@ -981,7 +991,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
981 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 991 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
982 992
983 if (chanctx_conf && 993 if (chanctx_conf &&
984 chanctx_conf->channel->band == IEEE80211_BAND_2GHZ && 994 chanctx_conf->def.chan->band == IEEE80211_BAND_2GHZ &&
985 have_higher_than_11mbit) 995 have_higher_than_11mbit)
986 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 996 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
987 else 997 else
@@ -1407,10 +1417,44 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1407 } 1417 }
1408 1418
1409 /* add channel contexts */ 1419 /* add channel contexts */
1410 mutex_lock(&local->chanctx_mtx); 1420 if (local->use_chanctx) {
1411 list_for_each_entry(ctx, &local->chanctx_list, list) 1421 mutex_lock(&local->chanctx_mtx);
1412 WARN_ON(drv_add_chanctx(local, ctx)); 1422 list_for_each_entry(ctx, &local->chanctx_list, list)
1413 mutex_unlock(&local->chanctx_mtx); 1423 WARN_ON(drv_add_chanctx(local, ctx));
1424 mutex_unlock(&local->chanctx_mtx);
1425 }
1426
1427 list_for_each_entry(sdata, &local->interfaces, list) {
1428 struct ieee80211_chanctx_conf *ctx_conf;
1429
1430 if (!ieee80211_sdata_running(sdata))
1431 continue;
1432
1433 mutex_lock(&local->chanctx_mtx);
1434 ctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1435 lockdep_is_held(&local->chanctx_mtx));
1436 if (ctx_conf) {
1437 ctx = container_of(ctx_conf, struct ieee80211_chanctx,
1438 conf);
1439 drv_assign_vif_chanctx(local, sdata, ctx);
1440 }
1441 mutex_unlock(&local->chanctx_mtx);
1442 }
1443
1444 sdata = rtnl_dereference(local->monitor_sdata);
1445 if (sdata && local->use_chanctx && ieee80211_sdata_running(sdata)) {
1446 struct ieee80211_chanctx_conf *ctx_conf;
1447
1448 mutex_lock(&local->chanctx_mtx);
1449 ctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1450 lockdep_is_held(&local->chanctx_mtx));
1451 if (ctx_conf) {
1452 ctx = container_of(ctx_conf, struct ieee80211_chanctx,
1453 conf);
1454 drv_assign_vif_chanctx(local, sdata, ctx);
1455 }
1456 mutex_unlock(&local->chanctx_mtx);
1457 }
1414 1458
1415 /* add STAs back */ 1459 /* add STAs back */
1416 mutex_lock(&local->sta_mtx); 1460 mutex_lock(&local->sta_mtx);
@@ -1452,22 +1496,11 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1452 1496
1453 /* Finally also reconfigure all the BSS information */ 1497 /* Finally also reconfigure all the BSS information */
1454 list_for_each_entry(sdata, &local->interfaces, list) { 1498 list_for_each_entry(sdata, &local->interfaces, list) {
1455 struct ieee80211_chanctx_conf *ctx_conf;
1456 u32 changed; 1499 u32 changed;
1457 1500
1458 if (!ieee80211_sdata_running(sdata)) 1501 if (!ieee80211_sdata_running(sdata))
1459 continue; 1502 continue;
1460 1503
1461 mutex_lock(&local->chanctx_mtx);
1462 ctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1463 lockdep_is_held(&local->chanctx_mtx));
1464 if (ctx_conf) {
1465 ctx = container_of(ctx_conf, struct ieee80211_chanctx,
1466 conf);
1467 drv_assign_vif_chanctx(local, sdata, ctx);
1468 }
1469 mutex_unlock(&local->chanctx_mtx);
1470
1471 /* common change flags for all interface types */ 1504 /* common change flags for all interface types */
1472 changed = BSS_CHANGED_ERP_CTS_PROT | 1505 changed = BSS_CHANGED_ERP_CTS_PROT |
1473 BSS_CHANGED_ERP_PREAMBLE | 1506 BSS_CHANGED_ERP_PREAMBLE |
@@ -1478,7 +1511,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1478 BSS_CHANGED_BSSID | 1511 BSS_CHANGED_BSSID |
1479 BSS_CHANGED_CQM | 1512 BSS_CHANGED_CQM |
1480 BSS_CHANGED_QOS | 1513 BSS_CHANGED_QOS |
1481 BSS_CHANGED_IDLE; 1514 BSS_CHANGED_IDLE |
1515 BSS_CHANGED_TXPOWER;
1482 1516
1483 switch (sdata->vif.type) { 1517 switch (sdata->vif.type) {
1484 case NL80211_IFTYPE_STATION: 1518 case NL80211_IFTYPE_STATION:
@@ -1495,9 +1529,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1495 case NL80211_IFTYPE_AP: 1529 case NL80211_IFTYPE_AP:
1496 changed |= BSS_CHANGED_SSID; 1530 changed |= BSS_CHANGED_SSID;
1497 1531
1498 if (sdata->vif.type == NL80211_IFTYPE_AP) 1532 if (sdata->vif.type == NL80211_IFTYPE_AP) {
1499 changed |= BSS_CHANGED_AP_PROBE_RESP; 1533 changed |= BSS_CHANGED_AP_PROBE_RESP;
1500 1534
1535 if (rcu_access_pointer(sdata->u.ap.beacon))
1536 drv_start_ap(local, sdata);
1537 }
1538
1501 /* fall through */ 1539 /* fall through */
1502 case NL80211_IFTYPE_MESH_POINT: 1540 case NL80211_IFTYPE_MESH_POINT:
1503 changed |= BSS_CHANGED_BEACON | 1541 changed |= BSS_CHANGED_BEACON |
@@ -1596,8 +1634,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1596 * If this is for hw restart things are still running. 1634 * If this is for hw restart things are still running.
1597 * We may want to change that later, however. 1635 * We may want to change that later, however.
1598 */ 1636 */
1599 if (!local->suspended) 1637 if (!local->suspended) {
1638 drv_restart_complete(local);
1600 return 0; 1639 return 0;
1640 }
1601 1641
1602#ifdef CONFIG_PM 1642#ifdef CONFIG_PM
1603 /* first set suspended false, then resuming */ 1643 /* first set suspended false, then resuming */
@@ -1833,8 +1873,7 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1833} 1873}
1834 1874
1835u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1875u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1836 struct ieee80211_channel *channel, 1876 const struct cfg80211_chan_def *chandef,
1837 enum nl80211_channel_type channel_type,
1838 u16 prot_mode) 1877 u16 prot_mode)
1839{ 1878{
1840 struct ieee80211_ht_operation *ht_oper; 1879 struct ieee80211_ht_operation *ht_oper;
@@ -1842,23 +1881,25 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1842 *pos++ = WLAN_EID_HT_OPERATION; 1881 *pos++ = WLAN_EID_HT_OPERATION;
1843 *pos++ = sizeof(struct ieee80211_ht_operation); 1882 *pos++ = sizeof(struct ieee80211_ht_operation);
1844 ht_oper = (struct ieee80211_ht_operation *)pos; 1883 ht_oper = (struct ieee80211_ht_operation *)pos;
1845 ht_oper->primary_chan = 1884 ht_oper->primary_chan = ieee80211_frequency_to_channel(
1846 ieee80211_frequency_to_channel(channel->center_freq); 1885 chandef->chan->center_freq);
1847 switch (channel_type) { 1886 switch (chandef->width) {
1848 case NL80211_CHAN_HT40MINUS: 1887 case NL80211_CHAN_WIDTH_160:
1849 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW; 1888 case NL80211_CHAN_WIDTH_80P80:
1850 break; 1889 case NL80211_CHAN_WIDTH_80:
1851 case NL80211_CHAN_HT40PLUS: 1890 case NL80211_CHAN_WIDTH_40:
1852 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; 1891 if (chandef->center_freq1 > chandef->chan->center_freq)
1892 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
1893 else
1894 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
1853 break; 1895 break;
1854 case NL80211_CHAN_HT20:
1855 default: 1896 default:
1856 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; 1897 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
1857 break; 1898 break;
1858 } 1899 }
1859 if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && 1900 if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
1860 channel_type != NL80211_CHAN_NO_HT && 1901 chandef->width != NL80211_CHAN_WIDTH_20_NOHT &&
1861 channel_type != NL80211_CHAN_HT20) 1902 chandef->width != NL80211_CHAN_WIDTH_20)
1862 ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; 1903 ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
1863 1904
1864 ht_oper->operation_mode = cpu_to_le16(prot_mode); 1905 ht_oper->operation_mode = cpu_to_le16(prot_mode);
@@ -1872,13 +1913,17 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1872 return pos + sizeof(struct ieee80211_ht_operation); 1913 return pos + sizeof(struct ieee80211_ht_operation);
1873} 1914}
1874 1915
1875enum nl80211_channel_type 1916void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
1876ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper) 1917 struct ieee80211_ht_operation *ht_oper,
1918 struct cfg80211_chan_def *chandef)
1877{ 1919{
1878 enum nl80211_channel_type channel_type; 1920 enum nl80211_channel_type channel_type;
1879 1921
1880 if (!ht_oper) 1922 if (!ht_oper) {
1881 return NL80211_CHAN_NO_HT; 1923 cfg80211_chandef_create(chandef, control_chan,
1924 NL80211_CHAN_NO_HT);
1925 return;
1926 }
1882 1927
1883 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { 1928 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
1884 case IEEE80211_HT_PARAM_CHA_SEC_NONE: 1929 case IEEE80211_HT_PARAM_CHA_SEC_NONE:
@@ -1894,7 +1939,7 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper)
1894 channel_type = NL80211_CHAN_NO_HT; 1939 channel_type = NL80211_CHAN_NO_HT;
1895 } 1940 }
1896 1941
1897 return channel_type; 1942 cfg80211_chandef_create(chandef, control_chan, channel_type);
1898} 1943}
1899 1944
1900int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, 1945int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
@@ -1992,3 +2037,68 @@ u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs)
1992 return 2; 2037 return 2;
1993 return 1; 2038 return 1;
1994} 2039}
2040
2041/**
2042 * ieee80211_calculate_rx_timestamp - calculate timestamp in frame
2043 * @local: mac80211 hw info struct
2044 * @status: RX status
2045 * @mpdu_len: total MPDU length (including FCS)
2046 * @mpdu_offset: offset into MPDU to calculate timestamp at
2047 *
2048 * This function calculates the RX timestamp at the given MPDU offset, taking
2049 * into account what the RX timestamp was. An offset of 0 will just normalize
2050 * the timestamp to TSF at beginning of MPDU reception.
2051 */
2052u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2053 struct ieee80211_rx_status *status,
2054 unsigned int mpdu_len,
2055 unsigned int mpdu_offset)
2056{
2057 u64 ts = status->mactime;
2058 struct rate_info ri;
2059 u16 rate;
2060
2061 if (WARN_ON(!ieee80211_have_rx_timestamp(status)))
2062 return 0;
2063
2064 memset(&ri, 0, sizeof(ri));
2065
2066 /* Fill cfg80211 rate info */
2067 if (status->flag & RX_FLAG_HT) {
2068 ri.mcs = status->rate_idx;
2069 ri.flags |= RATE_INFO_FLAGS_MCS;
2070 if (status->flag & RX_FLAG_40MHZ)
2071 ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
2072 if (status->flag & RX_FLAG_SHORT_GI)
2073 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
2074 } else if (status->flag & RX_FLAG_VHT) {
2075 ri.flags |= RATE_INFO_FLAGS_VHT_MCS;
2076 ri.mcs = status->rate_idx;
2077 ri.nss = status->vht_nss;
2078 if (status->flag & RX_FLAG_40MHZ)
2079 ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
2080 if (status->flag & RX_FLAG_80MHZ)
2081 ri.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
2082 if (status->flag & RX_FLAG_80P80MHZ)
2083 ri.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
2084 if (status->flag & RX_FLAG_160MHZ)
2085 ri.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
2086 if (status->flag & RX_FLAG_SHORT_GI)
2087 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
2088 } else {
2089 struct ieee80211_supported_band *sband;
2090
2091 sband = local->hw.wiphy->bands[status->band];
2092 ri.legacy = sband->bitrates[status->rate_idx].bitrate;
2093 }
2094
2095 rate = cfg80211_calculate_bitrate(&ri);
2096
2097 /* rewind from end of MPDU */
2098 if (status->flag & RX_FLAG_MACTIME_END)
2099 ts -= mpdu_len * 8 * 10 / rate;
2100
2101 ts += mpdu_offset * 8 * 10 / rate;
2102
2103 return ts;
2104}
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index cea06e9f26f..906f00cd6d2 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -160,31 +160,37 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
160 return ieee80211_downgrade_queue(sdata, skb); 160 return ieee80211_downgrade_queue(sdata, skb);
161} 161}
162 162
163/**
164 * ieee80211_set_qos_hdr - Fill in the QoS header if there is one.
165 *
166 * @sdata: local subif
167 * @skb: packet to be updated
168 */
163void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, 169void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
164 struct sk_buff *skb) 170 struct sk_buff *skb)
165{ 171{
166 struct ieee80211_hdr *hdr = (void *)skb->data; 172 struct ieee80211_hdr *hdr = (void *)skb->data;
167 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 173 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
174 u8 *p;
175 u8 ack_policy, tid;
168 176
169 /* Fill in the QoS header if there is one. */ 177 if (!ieee80211_is_data_qos(hdr->frame_control))
170 if (ieee80211_is_data_qos(hdr->frame_control)) { 178 return;
171 u8 *p = ieee80211_get_qos_ctl(hdr);
172 u8 ack_policy, tid;
173
174 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
175 179
176 /* preserve EOSP bit */ 180 p = ieee80211_get_qos_ctl(hdr);
177 ack_policy = *p & IEEE80211_QOS_CTL_EOSP; 181 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
178 182
179 if (is_multicast_ether_addr(hdr->addr1) || 183 /* preserve EOSP bit */
180 sdata->noack_map & BIT(tid)) { 184 ack_policy = *p & IEEE80211_QOS_CTL_EOSP;
181 ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
182 info->flags |= IEEE80211_TX_CTL_NO_ACK;
183 }
184 185
185 /* qos header is 2 bytes */ 186 if (is_multicast_ether_addr(hdr->addr1) ||
186 *p++ = ack_policy | tid; 187 sdata->noack_map & BIT(tid)) {
187 *p = ieee80211_vif_is_mesh(&sdata->vif) ? 188 ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
188 (IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8) : 0; 189 info->flags |= IEEE80211_TX_CTL_NO_ACK;
189 } 190 }
191
192 /* qos header is 2 bytes */
193 *p++ = ack_policy | tid;
194 *p = ieee80211_vif_is_mesh(&sdata->vif) ?
195 (IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8) : 0;
190} 196}
diff --git a/net/nfc/hci/command.c b/net/nfc/hci/command.c
index 07659cfd6d7..7d99410e6c1 100644
--- a/net/nfc/hci/command.c
+++ b/net/nfc/hci/command.c
@@ -344,7 +344,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
344 return -EADDRINUSE; 344 return -EADDRINUSE;
345 345
346 if (pipe != NFC_HCI_INVALID_PIPE) 346 if (pipe != NFC_HCI_INVALID_PIPE)
347 goto pipe_is_open; 347 goto open_pipe;
348 348
349 switch (dest_gate) { 349 switch (dest_gate) {
350 case NFC_HCI_LINK_MGMT_GATE: 350 case NFC_HCI_LINK_MGMT_GATE:
@@ -361,6 +361,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
361 break; 361 break;
362 } 362 }
363 363
364open_pipe:
364 r = nfc_hci_open_pipe(hdev, pipe); 365 r = nfc_hci_open_pipe(hdev, pipe);
365 if (r < 0) { 366 if (r < 0) {
366 if (pipe_created) 367 if (pipe_created)
@@ -371,7 +372,6 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
371 return r; 372 return r;
372 } 373 }
373 374
374pipe_is_open:
375 hdev->gate2pipe[dest_gate] = pipe; 375 hdev->gate2pipe[dest_gate] = pipe;
376 376
377 return 0; 377 return 0;
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c
index bc571b0efb9..7bea574d593 100644
--- a/net/nfc/hci/core.c
+++ b/net/nfc/hci/core.c
@@ -33,17 +33,20 @@
33/* Largest headroom needed for outgoing HCI commands */ 33/* Largest headroom needed for outgoing HCI commands */
34#define HCI_CMDS_HEADROOM 1 34#define HCI_CMDS_HEADROOM 1
35 35
36static int nfc_hci_result_to_errno(u8 result) 36int nfc_hci_result_to_errno(u8 result)
37{ 37{
38 switch (result) { 38 switch (result) {
39 case NFC_HCI_ANY_OK: 39 case NFC_HCI_ANY_OK:
40 return 0; 40 return 0;
41 case NFC_HCI_ANY_E_REG_PAR_UNKNOWN:
42 return -EOPNOTSUPP;
41 case NFC_HCI_ANY_E_TIMEOUT: 43 case NFC_HCI_ANY_E_TIMEOUT:
42 return -ETIME; 44 return -ETIME;
43 default: 45 default:
44 return -1; 46 return -1;
45 } 47 }
46} 48}
49EXPORT_SYMBOL(nfc_hci_result_to_errno);
47 50
48static void nfc_hci_msg_tx_work(struct work_struct *work) 51static void nfc_hci_msg_tx_work(struct work_struct *work)
49{ 52{
@@ -167,7 +170,7 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
167 kfree_skb(skb); 170 kfree_skb(skb);
168} 171}
169 172
170static u32 nfc_hci_sak_to_protocol(u8 sak) 173u32 nfc_hci_sak_to_protocol(u8 sak)
171{ 174{
172 switch (NFC_HCI_TYPE_A_SEL_PROT(sak)) { 175 switch (NFC_HCI_TYPE_A_SEL_PROT(sak)) {
173 case NFC_HCI_TYPE_A_SEL_PROT_MIFARE: 176 case NFC_HCI_TYPE_A_SEL_PROT_MIFARE:
@@ -182,6 +185,7 @@ static u32 nfc_hci_sak_to_protocol(u8 sak)
182 return 0xffffffff; 185 return 0xffffffff;
183 } 186 }
184} 187}
188EXPORT_SYMBOL(nfc_hci_sak_to_protocol);
185 189
186int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) 190int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate)
187{ 191{
@@ -284,6 +288,12 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,
284 struct sk_buff *skb) 288 struct sk_buff *skb)
285{ 289{
286 int r = 0; 290 int r = 0;
291 u8 gate = nfc_hci_pipe2gate(hdev, pipe);
292
293 if (gate == 0xff) {
294 pr_err("Discarded event %x to unopened pipe %x\n", event, pipe);
295 goto exit;
296 }
287 297
288 switch (event) { 298 switch (event) {
289 case NFC_HCI_EVT_TARGET_DISCOVERED: 299 case NFC_HCI_EVT_TARGET_DISCOVERED:
@@ -307,14 +317,11 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,
307 goto exit; 317 goto exit;
308 } 318 }
309 319
310 r = nfc_hci_target_discovered(hdev, 320 r = nfc_hci_target_discovered(hdev, gate);
311 nfc_hci_pipe2gate(hdev, pipe));
312 break; 321 break;
313 default: 322 default:
314 if (hdev->ops->event_received) { 323 if (hdev->ops->event_received) {
315 hdev->ops->event_received(hdev, 324 hdev->ops->event_received(hdev, gate, event, skb);
316 nfc_hci_pipe2gate(hdev, pipe),
317 event, skb);
318 return; 325 return;
319 } 326 }
320 327
@@ -419,6 +426,10 @@ static int hci_dev_version(struct nfc_hci_dev *hdev)
419 426
420 r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE, 427 r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE,
421 NFC_HCI_ID_MGMT_VERSION_SW, &skb); 428 NFC_HCI_ID_MGMT_VERSION_SW, &skb);
429 if (r == -EOPNOTSUPP) {
430 pr_info("Software/Hardware info not available\n");
431 return 0;
432 }
422 if (r < 0) 433 if (r < 0)
423 return r; 434 return r;
424 435
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c
index ed2d17312d6..df24be48d4d 100644
--- a/net/nfc/llcp/commands.c
+++ b/net/nfc/llcp/commands.c
@@ -528,6 +528,23 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
528 if (local == NULL) 528 if (local == NULL)
529 return -ENODEV; 529 return -ENODEV;
530 530
531 /* Remote is ready but has not acknowledged our frames */
532 if((sock->remote_ready &&
533 skb_queue_len(&sock->tx_pending_queue) >= sock->rw &&
534 skb_queue_len(&sock->tx_queue) >= 2 * sock->rw)) {
535 pr_err("Pending queue is full %d frames\n",
536 skb_queue_len(&sock->tx_pending_queue));
537 return -ENOBUFS;
538 }
539
540 /* Remote is not ready and we've been queueing enough frames */
541 if ((!sock->remote_ready &&
542 skb_queue_len(&sock->tx_queue) >= 2 * sock->rw)) {
543 pr_err("Tx queue is full %d frames\n",
544 skb_queue_len(&sock->tx_queue));
545 return -ENOBUFS;
546 }
547
531 msg_data = kzalloc(len, GFP_KERNEL); 548 msg_data = kzalloc(len, GFP_KERNEL);
532 if (msg_data == NULL) 549 if (msg_data == NULL)
533 return -ENOMEM; 550 return -ENOMEM;
@@ -579,7 +596,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
579 struct sk_buff *pdu; 596 struct sk_buff *pdu;
580 struct nfc_llcp_local *local; 597 struct nfc_llcp_local *local;
581 size_t frag_len = 0, remaining_len; 598 size_t frag_len = 0, remaining_len;
582 u8 *msg_ptr; 599 u8 *msg_ptr, *msg_data;
583 int err; 600 int err;
584 601
585 pr_debug("Send UI frame len %zd\n", len); 602 pr_debug("Send UI frame len %zd\n", len);
@@ -588,8 +605,17 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
588 if (local == NULL) 605 if (local == NULL)
589 return -ENODEV; 606 return -ENODEV;
590 607
608 msg_data = kzalloc(len, GFP_KERNEL);
609 if (msg_data == NULL)
610 return -ENOMEM;
611
612 if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) {
613 kfree(msg_data);
614 return -EFAULT;
615 }
616
591 remaining_len = len; 617 remaining_len = len;
592 msg_ptr = (u8 *) msg->msg_iov; 618 msg_ptr = msg_data;
593 619
594 while (remaining_len > 0) { 620 while (remaining_len > 0) {
595 621
@@ -616,6 +642,8 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
616 msg_ptr += frag_len; 642 msg_ptr += frag_len;
617 } 643 }
618 644
645 kfree(msg_data);
646
619 return len; 647 return len;
620} 648}
621 649
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 2e9ddf34c09..2df87056c6d 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -656,6 +656,8 @@ static void nfc_llcp_tx_work(struct work_struct *work)
656 if (llcp_sock == NULL && nfc_llcp_ptype(skb) == LLCP_PDU_I) { 656 if (llcp_sock == NULL && nfc_llcp_ptype(skb) == LLCP_PDU_I) {
657 nfc_llcp_send_symm(local->dev); 657 nfc_llcp_send_symm(local->dev);
658 } else { 658 } else {
659 struct sk_buff *copy_skb = NULL;
660 u8 ptype = nfc_llcp_ptype(skb);
659 int ret; 661 int ret;
660 662
661 pr_debug("Sending pending skb\n"); 663 pr_debug("Sending pending skb\n");
@@ -663,22 +665,29 @@ static void nfc_llcp_tx_work(struct work_struct *work)
663 DUMP_PREFIX_OFFSET, 16, 1, 665 DUMP_PREFIX_OFFSET, 16, 1,
664 skb->data, skb->len, true); 666 skb->data, skb->len, true);
665 667
668 if (ptype == LLCP_PDU_I)
669 copy_skb = skb_copy(skb, GFP_ATOMIC);
670
666 nfc_llcp_send_to_raw_sock(local, skb, 671 nfc_llcp_send_to_raw_sock(local, skb,
667 NFC_LLCP_DIRECTION_TX); 672 NFC_LLCP_DIRECTION_TX);
668 673
669 ret = nfc_data_exchange(local->dev, local->target_idx, 674 ret = nfc_data_exchange(local->dev, local->target_idx,
670 skb, nfc_llcp_recv, local); 675 skb, nfc_llcp_recv, local);
671 676
672 if (!ret && nfc_llcp_ptype(skb) == LLCP_PDU_I) { 677 if (ret) {
673 skb = skb_get(skb); 678 kfree_skb(copy_skb);
674 skb_queue_tail(&llcp_sock->tx_pending_queue, 679 goto out;
675 skb);
676 } 680 }
681
682 if (ptype == LLCP_PDU_I && copy_skb)
683 skb_queue_tail(&llcp_sock->tx_pending_queue,
684 copy_skb);
677 } 685 }
678 } else { 686 } else {
679 nfc_llcp_send_symm(local->dev); 687 nfc_llcp_send_symm(local->dev);
680 } 688 }
681 689
690out:
682 mod_timer(&local->link_timer, 691 mod_timer(&local->link_timer,
683 jiffies + msecs_to_jiffies(2 * local->remote_lto)); 692 jiffies + msecs_to_jiffies(2 * local->remote_lto));
684} 693}
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index fe4adb12b3e..16d08b39921 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -140,14 +140,13 @@ config CFG80211_WEXT
140 extensions with cfg80211-based drivers. 140 extensions with cfg80211-based drivers.
141 141
142config LIB80211 142config LIB80211
143 tristate "Common routines for IEEE802.11 drivers" 143 tristate
144 default n 144 default n
145 help 145 help
146 This options enables a library of common routines used 146 This options enables a library of common routines used
147 by IEEE802.11 wireless LAN drivers. 147 by IEEE802.11 wireless LAN drivers.
148 148
149 Drivers should select this themselves if needed. Say Y if 149 Drivers should select this themselves if needed.
150 you want this built into your kernel.
151 150
152config LIB80211_CRYPT_WEP 151config LIB80211_CRYPT_WEP
153 tristate 152 tristate
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index e143505f05b..324e8d851dc 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -28,6 +28,7 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
28 if (!err) { 28 if (!err) {
29 wdev->beacon_interval = 0; 29 wdev->beacon_interval = 0;
30 wdev->channel = NULL; 30 wdev->channel = NULL;
31 wdev->ssid_len = 0;
31 } 32 }
32 33
33 return err; 34 return err;
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 48febd2160b..bf2dfd54ff3 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -11,96 +11,264 @@
11#include "core.h" 11#include "core.h"
12#include "rdev-ops.h" 12#include "rdev-ops.h"
13 13
14struct ieee80211_channel * 14void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
15rdev_freq_to_chan(struct cfg80211_registered_device *rdev, 15 struct ieee80211_channel *chan,
16 int freq, enum nl80211_channel_type channel_type) 16 enum nl80211_channel_type chan_type)
17{ 17{
18 struct ieee80211_channel *chan; 18 if (WARN_ON(!chan))
19 struct ieee80211_sta_ht_cap *ht_cap; 19 return;
20 20
21 chan = ieee80211_get_channel(&rdev->wiphy, freq); 21 chandef->chan = chan;
22 chandef->center_freq2 = 0;
22 23
23 /* Primary channel not allowed */ 24 switch (chan_type) {
24 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) 25 case NL80211_CHAN_NO_HT:
25 return NULL; 26 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
27 chandef->center_freq1 = chan->center_freq;
28 break;
29 case NL80211_CHAN_HT20:
30 chandef->width = NL80211_CHAN_WIDTH_20;
31 chandef->center_freq1 = chan->center_freq;
32 break;
33 case NL80211_CHAN_HT40PLUS:
34 chandef->width = NL80211_CHAN_WIDTH_40;
35 chandef->center_freq1 = chan->center_freq + 10;
36 break;
37 case NL80211_CHAN_HT40MINUS:
38 chandef->width = NL80211_CHAN_WIDTH_40;
39 chandef->center_freq1 = chan->center_freq - 10;
40 break;
41 default:
42 WARN_ON(1);
43 }
44}
45EXPORT_SYMBOL(cfg80211_chandef_create);
26 46
27 if (channel_type == NL80211_CHAN_HT40MINUS && 47bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef)
28 chan->flags & IEEE80211_CHAN_NO_HT40MINUS) 48{
29 return NULL; 49 u32 control_freq;
30 else if (channel_type == NL80211_CHAN_HT40PLUS &&
31 chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
32 return NULL;
33 50
34 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap; 51 if (!chandef->chan)
52 return false;
35 53
36 if (channel_type != NL80211_CHAN_NO_HT) { 54 control_freq = chandef->chan->center_freq;
37 if (!ht_cap->ht_supported)
38 return NULL;
39 55
40 if (channel_type != NL80211_CHAN_HT20 && 56 switch (chandef->width) {
41 (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || 57 case NL80211_CHAN_WIDTH_20:
42 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)) 58 case NL80211_CHAN_WIDTH_20_NOHT:
43 return NULL; 59 if (chandef->center_freq1 != control_freq)
60 return false;
61 if (chandef->center_freq2)
62 return false;
63 break;
64 case NL80211_CHAN_WIDTH_40:
65 if (chandef->center_freq1 != control_freq + 10 &&
66 chandef->center_freq1 != control_freq - 10)
67 return false;
68 if (chandef->center_freq2)
69 return false;
70 break;
71 case NL80211_CHAN_WIDTH_80P80:
72 if (chandef->center_freq1 != control_freq + 30 &&
73 chandef->center_freq1 != control_freq + 10 &&
74 chandef->center_freq1 != control_freq - 10 &&
75 chandef->center_freq1 != control_freq - 30)
76 return false;
77 if (!chandef->center_freq2)
78 return false;
79 break;
80 case NL80211_CHAN_WIDTH_80:
81 if (chandef->center_freq1 != control_freq + 30 &&
82 chandef->center_freq1 != control_freq + 10 &&
83 chandef->center_freq1 != control_freq - 10 &&
84 chandef->center_freq1 != control_freq - 30)
85 return false;
86 if (chandef->center_freq2)
87 return false;
88 break;
89 case NL80211_CHAN_WIDTH_160:
90 if (chandef->center_freq1 != control_freq + 70 &&
91 chandef->center_freq1 != control_freq + 50 &&
92 chandef->center_freq1 != control_freq + 30 &&
93 chandef->center_freq1 != control_freq + 10 &&
94 chandef->center_freq1 != control_freq - 10 &&
95 chandef->center_freq1 != control_freq - 30 &&
96 chandef->center_freq1 != control_freq - 50 &&
97 chandef->center_freq1 != control_freq - 70)
98 return false;
99 if (chandef->center_freq2)
100 return false;
101 break;
102 default:
103 return false;
44 } 104 }
45 105
46 return chan; 106 return true;
47} 107}
48 108
49bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, 109static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
50 struct ieee80211_channel *chan, 110 int *pri40, int *pri80)
51 enum nl80211_channel_type channel_type)
52{ 111{
53 struct ieee80211_channel *sec_chan; 112 int tmp;
54 int diff;
55
56 trace_cfg80211_can_beacon_sec_chan(wiphy, chan, channel_type);
57 113
58 switch (channel_type) { 114 switch (c->width) {
59 case NL80211_CHAN_HT40PLUS: 115 case NL80211_CHAN_WIDTH_40:
60 diff = 20; 116 *pri40 = c->center_freq1;
117 *pri80 = 0;
61 break; 118 break;
62 case NL80211_CHAN_HT40MINUS: 119 case NL80211_CHAN_WIDTH_80:
63 diff = -20; 120 case NL80211_CHAN_WIDTH_80P80:
121 *pri80 = c->center_freq1;
122 /* n_P20 */
123 tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
124 /* n_P40 */
125 tmp /= 2;
126 /* freq_P40 */
127 *pri40 = c->center_freq1 - 20 + 40 * tmp;
128 break;
129 case NL80211_CHAN_WIDTH_160:
130 /* n_P20 */
131 tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
132 /* n_P40 */
133 tmp /= 2;
134 /* freq_P40 */
135 *pri40 = c->center_freq1 - 60 + 40 * tmp;
136 /* n_P80 */
137 tmp /= 2;
138 *pri80 = c->center_freq1 - 40 + 80 * tmp;
64 break; 139 break;
65 default: 140 default:
66 trace_cfg80211_return_bool(true); 141 WARN_ON_ONCE(1);
67 return true;
68 } 142 }
143}
144
145const struct cfg80211_chan_def *
146cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
147 const struct cfg80211_chan_def *c2)
148{
149 u32 c1_pri40, c1_pri80, c2_pri40, c2_pri80;
69 150
70 sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff); 151 /* If they are identical, return */
71 if (!sec_chan) { 152 if (cfg80211_chandef_identical(c1, c2))
153 return c1;
154
155 /* otherwise, must have same control channel */
156 if (c1->chan != c2->chan)
157 return NULL;
158
159 /*
160 * If they have the same width, but aren't identical,
161 * then they can't be compatible.
162 */
163 if (c1->width == c2->width)
164 return NULL;
165
166 if (c1->width == NL80211_CHAN_WIDTH_20_NOHT ||
167 c1->width == NL80211_CHAN_WIDTH_20)
168 return c2;
169
170 if (c2->width == NL80211_CHAN_WIDTH_20_NOHT ||
171 c2->width == NL80211_CHAN_WIDTH_20)
172 return c1;
173
174 chandef_primary_freqs(c1, &c1_pri40, &c1_pri80);
175 chandef_primary_freqs(c2, &c2_pri40, &c2_pri80);
176
177 if (c1_pri40 != c2_pri40)
178 return NULL;
179
180 WARN_ON(!c1_pri80 && !c2_pri80);
181 if (c1_pri80 && c2_pri80 && c1_pri80 != c2_pri80)
182 return NULL;
183
184 if (c1->width > c2->width)
185 return c1;
186 return c2;
187}
188EXPORT_SYMBOL(cfg80211_chandef_compatible);
189
190bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
191 u32 center_freq, u32 bandwidth,
192 u32 prohibited_flags)
193{
194 struct ieee80211_channel *c;
195 u32 freq;
196
197 for (freq = center_freq - bandwidth/2 + 10;
198 freq <= center_freq + bandwidth/2 - 10;
199 freq += 20) {
200 c = ieee80211_get_channel(wiphy, freq);
201 if (!c || c->flags & prohibited_flags)
202 return false;
203 }
204
205 return true;
206}
207
208static bool cfg80211_check_beacon_chans(struct wiphy *wiphy,
209 u32 center_freq, u32 bw)
210{
211 return cfg80211_secondary_chans_ok(wiphy, center_freq, bw,
212 IEEE80211_CHAN_DISABLED |
213 IEEE80211_CHAN_PASSIVE_SCAN |
214 IEEE80211_CHAN_NO_IBSS |
215 IEEE80211_CHAN_RADAR);
216}
217
218bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
219 struct cfg80211_chan_def *chandef)
220{
221 u32 width;
222 bool res;
223
224 trace_cfg80211_reg_can_beacon(wiphy, chandef);
225
226 if (WARN_ON(!cfg80211_chan_def_valid(chandef))) {
72 trace_cfg80211_return_bool(false); 227 trace_cfg80211_return_bool(false);
73 return false; 228 return false;
74 } 229 }
75 230
76 /* we'll need a DFS capability later */ 231 switch (chandef->width) {
77 if (sec_chan->flags & (IEEE80211_CHAN_DISABLED | 232 case NL80211_CHAN_WIDTH_20_NOHT:
78 IEEE80211_CHAN_PASSIVE_SCAN | 233 case NL80211_CHAN_WIDTH_20:
79 IEEE80211_CHAN_NO_IBSS | 234 width = 20;
80 IEEE80211_CHAN_RADAR)) { 235 break;
236 case NL80211_CHAN_WIDTH_40:
237 width = 40;
238 break;
239 case NL80211_CHAN_WIDTH_80:
240 case NL80211_CHAN_WIDTH_80P80:
241 width = 80;
242 break;
243 case NL80211_CHAN_WIDTH_160:
244 width = 160;
245 break;
246 default:
247 WARN_ON_ONCE(1);
81 trace_cfg80211_return_bool(false); 248 trace_cfg80211_return_bool(false);
82 return false; 249 return false;
83 } 250 }
84 trace_cfg80211_return_bool(true); 251
85 return true; 252 res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq1, width);
253
254 if (res && chandef->center_freq2)
255 res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq2,
256 width);
257
258 trace_cfg80211_return_bool(res);
259 return res;
86} 260}
87EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); 261EXPORT_SYMBOL(cfg80211_reg_can_beacon);
88 262
89int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, 263int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
90 int freq, enum nl80211_channel_type chantype) 264 struct cfg80211_chan_def *chandef)
91{ 265{
92 struct ieee80211_channel *chan;
93
94 if (!rdev->ops->set_monitor_channel) 266 if (!rdev->ops->set_monitor_channel)
95 return -EOPNOTSUPP; 267 return -EOPNOTSUPP;
96 if (!cfg80211_has_monitors_only(rdev)) 268 if (!cfg80211_has_monitors_only(rdev))
97 return -EBUSY; 269 return -EBUSY;
98 270
99 chan = rdev_freq_to_chan(rdev, freq, chantype); 271 return rdev_set_monitor_channel(rdev, chandef);
100 if (!chan)
101 return -EINVAL;
102
103 return rdev_set_monitor_channel(rdev, chan, chantype);
104} 272}
105 273
106void 274void
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 26711f46a3b..14d99040035 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -326,6 +326,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
326 mutex_init(&rdev->devlist_mtx); 326 mutex_init(&rdev->devlist_mtx);
327 mutex_init(&rdev->sched_scan_mtx); 327 mutex_init(&rdev->sched_scan_mtx);
328 INIT_LIST_HEAD(&rdev->wdev_list); 328 INIT_LIST_HEAD(&rdev->wdev_list);
329 INIT_LIST_HEAD(&rdev->beacon_registrations);
330 spin_lock_init(&rdev->beacon_registrations_lock);
329 spin_lock_init(&rdev->bss_lock); 331 spin_lock_init(&rdev->bss_lock);
330 INIT_LIST_HEAD(&rdev->bss_list); 332 INIT_LIST_HEAD(&rdev->bss_list);
331 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 333 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
@@ -698,10 +700,15 @@ EXPORT_SYMBOL(wiphy_unregister);
698void cfg80211_dev_free(struct cfg80211_registered_device *rdev) 700void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
699{ 701{
700 struct cfg80211_internal_bss *scan, *tmp; 702 struct cfg80211_internal_bss *scan, *tmp;
703 struct cfg80211_beacon_registration *reg, *treg;
701 rfkill_destroy(rdev->rfkill); 704 rfkill_destroy(rdev->rfkill);
702 mutex_destroy(&rdev->mtx); 705 mutex_destroy(&rdev->mtx);
703 mutex_destroy(&rdev->devlist_mtx); 706 mutex_destroy(&rdev->devlist_mtx);
704 mutex_destroy(&rdev->sched_scan_mtx); 707 mutex_destroy(&rdev->sched_scan_mtx);
708 list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) {
709 list_del(&reg->list);
710 kfree(reg);
711 }
705 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) 712 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
706 cfg80211_put_bss(&scan->pub); 713 cfg80211_put_bss(&scan->pub);
707 kfree(rdev); 714 kfree(rdev);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index b8eb743fe7d..a0c8decf6a4 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -55,7 +55,8 @@ struct cfg80211_registered_device {
55 int opencount; /* also protected by devlist_mtx */ 55 int opencount; /* also protected by devlist_mtx */
56 wait_queue_head_t dev_wait; 56 wait_queue_head_t dev_wait;
57 57
58 u32 ap_beacons_nlportid; 58 struct list_head beacon_registrations;
59 spinlock_t beacon_registrations_lock;
59 60
60 /* protected by RTNL only */ 61 /* protected by RTNL only */
61 int num_running_ifaces; 62 int num_running_ifaces;
@@ -260,6 +261,10 @@ enum cfg80211_chan_mode {
260 CHAN_MODE_EXCLUSIVE, 261 CHAN_MODE_EXCLUSIVE,
261}; 262};
262 263
264struct cfg80211_beacon_registration {
265 struct list_head list;
266 u32 nlportid;
267};
263 268
264/* free object */ 269/* free object */
265extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev); 270extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
@@ -304,9 +309,9 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
304 const struct mesh_config *conf); 309 const struct mesh_config *conf);
305int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 310int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
306 struct net_device *dev); 311 struct net_device *dev);
307int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, 312int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
308 struct wireless_dev *wdev, int freq, 313 struct wireless_dev *wdev,
309 enum nl80211_channel_type channel_type); 314 struct cfg80211_chan_def *chandef);
310 315
311/* AP */ 316/* AP */
312int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 317int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
@@ -373,10 +378,8 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
373int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 378int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
374 struct wireless_dev *wdev, 379 struct wireless_dev *wdev,
375 struct ieee80211_channel *chan, bool offchan, 380 struct ieee80211_channel *chan, bool offchan,
376 enum nl80211_channel_type channel_type, 381 unsigned int wait, const u8 *buf, size_t len,
377 bool channel_type_valid, unsigned int wait, 382 bool no_cck, bool dont_wait_for_ack, u64 *cookie);
378 const u8 *buf, size_t len, bool no_cck,
379 bool dont_wait_for_ack, u64 *cookie);
380void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, 383void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
381 const struct ieee80211_ht_cap *ht_capa_mask); 384 const struct ieee80211_ht_cap *ht_capa_mask);
382 385
@@ -467,11 +470,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
467 struct ieee80211_channel **chan, 470 struct ieee80211_channel **chan,
468 enum cfg80211_chan_mode *chanmode); 471 enum cfg80211_chan_mode *chanmode);
469 472
470struct ieee80211_channel *
471rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
472 int freq, enum nl80211_channel_type channel_type);
473int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, 473int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
474 int freq, enum nl80211_channel_type chantype); 474 struct cfg80211_chan_def *chandef);
475 475
476int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, 476int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
477 const u8 *rates, unsigned int n_rates, 477 const u8 *rates, unsigned int n_rates,
@@ -483,6 +483,12 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
483void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, 483void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
484 enum nl80211_iftype iftype, int num); 484 enum nl80211_iftype iftype, int num);
485 485
486bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef);
487
488bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
489 u32 center_freq, u32 bandwidth,
490 u32 prohibited_flags);
491
486#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 492#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
487 493
488#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 494#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 27941d5db72..9b9551e4a6f 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -100,9 +100,9 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
100 * 11a for maximum compatibility. 100 * 11a for maximum compatibility.
101 */ 101 */
102 struct ieee80211_supported_band *sband = 102 struct ieee80211_supported_band *sband =
103 rdev->wiphy.bands[params->channel->band]; 103 rdev->wiphy.bands[params->chandef.chan->band];
104 int j; 104 int j;
105 u32 flag = params->channel->band == IEEE80211_BAND_5GHZ ? 105 u32 flag = params->chandef.chan->band == IEEE80211_BAND_5GHZ ?
106 IEEE80211_RATE_MANDATORY_A : 106 IEEE80211_RATE_MANDATORY_A :
107 IEEE80211_RATE_MANDATORY_B; 107 IEEE80211_RATE_MANDATORY_B;
108 108
@@ -118,11 +118,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
118 118
119 wdev->ibss_fixed = params->channel_fixed; 119 wdev->ibss_fixed = params->channel_fixed;
120#ifdef CONFIG_CFG80211_WEXT 120#ifdef CONFIG_CFG80211_WEXT
121 wdev->wext.ibss.channel = params->channel; 121 wdev->wext.ibss.chandef = params->chandef;
122#endif 122#endif
123 wdev->sme_state = CFG80211_SME_CONNECTING; 123 wdev->sme_state = CFG80211_SME_CONNECTING;
124 124
125 err = cfg80211_can_use_chan(rdev, wdev, params->channel, 125 err = cfg80211_can_use_chan(rdev, wdev, params->chandef.chan,
126 params->channel_fixed 126 params->channel_fixed
127 ? CHAN_MODE_SHARED 127 ? CHAN_MODE_SHARED
128 : CHAN_MODE_EXCLUSIVE); 128 : CHAN_MODE_EXCLUSIVE);
@@ -251,7 +251,9 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
251 wdev->wext.ibss.beacon_interval = 100; 251 wdev->wext.ibss.beacon_interval = 100;
252 252
253 /* try to find an IBSS channel if none requested ... */ 253 /* try to find an IBSS channel if none requested ... */
254 if (!wdev->wext.ibss.channel) { 254 if (!wdev->wext.ibss.chandef.chan) {
255 wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
256
255 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 257 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
256 struct ieee80211_supported_band *sband; 258 struct ieee80211_supported_band *sband;
257 struct ieee80211_channel *chan; 259 struct ieee80211_channel *chan;
@@ -266,15 +268,15 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
266 continue; 268 continue;
267 if (chan->flags & IEEE80211_CHAN_DISABLED) 269 if (chan->flags & IEEE80211_CHAN_DISABLED)
268 continue; 270 continue;
269 wdev->wext.ibss.channel = chan; 271 wdev->wext.ibss.chandef.chan = chan;
270 break; 272 break;
271 } 273 }
272 274
273 if (wdev->wext.ibss.channel) 275 if (wdev->wext.ibss.chandef.chan)
274 break; 276 break;
275 } 277 }
276 278
277 if (!wdev->wext.ibss.channel) 279 if (!wdev->wext.ibss.chandef.chan)
278 return -EINVAL; 280 return -EINVAL;
279 } 281 }
280 282
@@ -336,7 +338,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
336 return -EINVAL; 338 return -EINVAL;
337 } 339 }
338 340
339 if (wdev->wext.ibss.channel == chan) 341 if (wdev->wext.ibss.chandef.chan == chan)
340 return 0; 342 return 0;
341 343
342 wdev_lock(wdev); 344 wdev_lock(wdev);
@@ -349,7 +351,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
349 return err; 351 return err;
350 352
351 if (chan) { 353 if (chan) {
352 wdev->wext.ibss.channel = chan; 354 wdev->wext.ibss.chandef.chan = chan;
355 wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
353 wdev->wext.ibss.channel_fixed = true; 356 wdev->wext.ibss.channel_fixed = true;
354 } else { 357 } else {
355 /* cfg80211_ibss_wext_join will pick one if needed */ 358 /* cfg80211_ibss_wext_join will pick one if needed */
@@ -379,8 +382,8 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
379 wdev_lock(wdev); 382 wdev_lock(wdev);
380 if (wdev->current_bss) 383 if (wdev->current_bss)
381 chan = wdev->current_bss->pub.channel; 384 chan = wdev->current_bss->pub.channel;
382 else if (wdev->wext.ibss.channel) 385 else if (wdev->wext.ibss.chandef.chan)
383 chan = wdev->wext.ibss.channel; 386 chan = wdev->wext.ibss.chandef.chan;
384 wdev_unlock(wdev); 387 wdev_unlock(wdev);
385 388
386 if (chan) { 389 if (chan) {
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 966cfc4cd79..3ee5a728228 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -73,8 +73,6 @@ const struct mesh_config default_mesh_config = {
73 73
74const struct mesh_setup default_mesh_setup = { 74const struct mesh_setup default_mesh_setup = {
75 /* cfg80211_join_mesh() will pick a channel if needed */ 75 /* cfg80211_join_mesh() will pick a channel if needed */
76 .channel = NULL,
77 .channel_type = NL80211_CHAN_NO_HT,
78 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, 76 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET,
79 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, 77 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
80 .path_metric = IEEE80211_PATH_METRIC_AIRTIME, 78 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
@@ -111,13 +109,12 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
111 if (!rdev->ops->join_mesh) 109 if (!rdev->ops->join_mesh)
112 return -EOPNOTSUPP; 110 return -EOPNOTSUPP;
113 111
114 if (!setup->channel) { 112 if (!setup->chandef.chan) {
115 /* if no channel explicitly given, use preset channel */ 113 /* if no channel explicitly given, use preset channel */
116 setup->channel = wdev->preset_chan; 114 setup->chandef = wdev->preset_chandef;
117 setup->channel_type = wdev->preset_chantype;
118 } 115 }
119 116
120 if (!setup->channel) { 117 if (!setup->chandef.chan) {
121 /* if we don't have that either, use the first usable channel */ 118 /* if we don't have that either, use the first usable channel */
122 enum ieee80211_band band; 119 enum ieee80211_band band;
123 120
@@ -137,26 +134,25 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
137 IEEE80211_CHAN_DISABLED | 134 IEEE80211_CHAN_DISABLED |
138 IEEE80211_CHAN_RADAR)) 135 IEEE80211_CHAN_RADAR))
139 continue; 136 continue;
140 setup->channel = chan; 137 setup->chandef.chan = chan;
141 break; 138 break;
142 } 139 }
143 140
144 if (setup->channel) 141 if (setup->chandef.chan)
145 break; 142 break;
146 } 143 }
147 144
148 /* no usable channel ... */ 145 /* no usable channel ... */
149 if (!setup->channel) 146 if (!setup->chandef.chan)
150 return -EINVAL; 147 return -EINVAL;
151 148
152 setup->channel_type = NL80211_CHAN_NO_HT; 149 setup->chandef.width = NL80211_CHAN_WIDTH_20_NOHT;;
153 } 150 }
154 151
155 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, setup->channel, 152 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
156 setup->channel_type))
157 return -EINVAL; 153 return -EINVAL;
158 154
159 err = cfg80211_can_use_chan(rdev, wdev, setup->channel, 155 err = cfg80211_can_use_chan(rdev, wdev, setup->chandef.chan,
160 CHAN_MODE_SHARED); 156 CHAN_MODE_SHARED);
161 if (err) 157 if (err)
162 return err; 158 return err;
@@ -165,7 +161,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
165 if (!err) { 161 if (!err) {
166 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); 162 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
167 wdev->mesh_id_len = setup->mesh_id_len; 163 wdev->mesh_id_len = setup->mesh_id_len;
168 wdev->channel = setup->channel; 164 wdev->channel = setup->chandef.chan;
169 } 165 }
170 166
171 return err; 167 return err;
@@ -188,20 +184,12 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
188 return err; 184 return err;
189} 185}
190 186
191int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, 187int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
192 struct wireless_dev *wdev, int freq, 188 struct wireless_dev *wdev,
193 enum nl80211_channel_type channel_type) 189 struct cfg80211_chan_def *chandef)
194{ 190{
195 struct ieee80211_channel *channel;
196 int err; 191 int err;
197 192
198 channel = rdev_freq_to_chan(rdev, freq, channel_type);
199 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
200 channel,
201 channel_type)) {
202 return -EINVAL;
203 }
204
205 /* 193 /*
206 * Workaround for libertas (only!), it puts the interface 194 * Workaround for libertas (only!), it puts the interface
207 * into mesh mode but doesn't implement join_mesh. Instead, 195 * into mesh mode but doesn't implement join_mesh. Instead,
@@ -210,21 +198,21 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
210 * compatible with 802.11 mesh. 198 * compatible with 802.11 mesh.
211 */ 199 */
212 if (rdev->ops->libertas_set_mesh_channel) { 200 if (rdev->ops->libertas_set_mesh_channel) {
213 if (channel_type != NL80211_CHAN_NO_HT) 201 if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT)
214 return -EINVAL; 202 return -EINVAL;
215 203
216 if (!netif_running(wdev->netdev)) 204 if (!netif_running(wdev->netdev))
217 return -ENETDOWN; 205 return -ENETDOWN;
218 206
219 err = cfg80211_can_use_chan(rdev, wdev, channel, 207 err = cfg80211_can_use_chan(rdev, wdev, chandef->chan,
220 CHAN_MODE_SHARED); 208 CHAN_MODE_SHARED);
221 if (err) 209 if (err)
222 return err; 210 return err;
223 211
224 err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, 212 err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
225 channel); 213 chandef->chan);
226 if (!err) 214 if (!err)
227 wdev->channel = channel; 215 wdev->channel = chandef->chan;
228 216
229 return err; 217 return err;
230 } 218 }
@@ -232,8 +220,7 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
232 if (wdev->mesh_id_len) 220 if (wdev->mesh_id_len)
233 return -EBUSY; 221 return -EBUSY;
234 222
235 wdev->preset_chan = channel; 223 wdev->preset_chandef = *chandef;
236 wdev->preset_chantype = channel_type;
237 return 0; 224 return 0;
238} 225}
239 226
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 4bfd14f7c59..5e8123ee63f 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -579,31 +579,25 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
579 579
580void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, 580void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
581 struct ieee80211_channel *chan, 581 struct ieee80211_channel *chan,
582 enum nl80211_channel_type channel_type,
583 unsigned int duration, gfp_t gfp) 582 unsigned int duration, gfp_t gfp)
584{ 583{
585 struct wiphy *wiphy = wdev->wiphy; 584 struct wiphy *wiphy = wdev->wiphy;
586 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 585 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
587 586
588 trace_cfg80211_ready_on_channel(wdev, cookie, chan, channel_type, 587 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
589 duration); 588 nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, duration, gfp);
590 nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, channel_type,
591 duration, gfp);
592} 589}
593EXPORT_SYMBOL(cfg80211_ready_on_channel); 590EXPORT_SYMBOL(cfg80211_ready_on_channel);
594 591
595void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, 592void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
596 struct ieee80211_channel *chan, 593 struct ieee80211_channel *chan,
597 enum nl80211_channel_type channel_type,
598 gfp_t gfp) 594 gfp_t gfp)
599{ 595{
600 struct wiphy *wiphy = wdev->wiphy; 596 struct wiphy *wiphy = wdev->wiphy;
601 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 597 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
602 598
603 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan, 599 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
604 channel_type); 600 nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan, gfp);
605 nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan,
606 channel_type, gfp);
607} 601}
608EXPORT_SYMBOL(cfg80211_remain_on_channel_expired); 602EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
609 603
@@ -758,10 +752,8 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
758int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 752int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
759 struct wireless_dev *wdev, 753 struct wireless_dev *wdev,
760 struct ieee80211_channel *chan, bool offchan, 754 struct ieee80211_channel *chan, bool offchan,
761 enum nl80211_channel_type channel_type, 755 unsigned int wait, const u8 *buf, size_t len,
762 bool channel_type_valid, unsigned int wait, 756 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
763 const u8 *buf, size_t len, bool no_cck,
764 bool dont_wait_for_ack, u64 *cookie)
765{ 757{
766 const struct ieee80211_mgmt *mgmt; 758 const struct ieee80211_mgmt *mgmt;
767 u16 stype; 759 u16 stype;
@@ -855,7 +847,6 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
855 847
856 /* Transmit the Action frame as requested by user space */ 848 /* Transmit the Action frame as requested by user space */
857 return rdev_mgmt_tx(rdev, wdev, chan, offchan, 849 return rdev_mgmt_tx(rdev, wdev, chan, offchan,
858 channel_type, channel_type_valid,
859 wait, buf, len, no_cck, dont_wait_for_ack, 850 wait, buf, len, no_cck, dont_wait_for_ack,
860 cookie); 851 cookie);
861} 852}
@@ -997,15 +988,14 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
997} 988}
998EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); 989EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
999 990
1000void cfg80211_ch_switch_notify(struct net_device *dev, int freq, 991void cfg80211_ch_switch_notify(struct net_device *dev,
1001 enum nl80211_channel_type type) 992 struct cfg80211_chan_def *chandef)
1002{ 993{
1003 struct wireless_dev *wdev = dev->ieee80211_ptr; 994 struct wireless_dev *wdev = dev->ieee80211_ptr;
1004 struct wiphy *wiphy = wdev->wiphy; 995 struct wiphy *wiphy = wdev->wiphy;
1005 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 996 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1006 struct ieee80211_channel *chan;
1007 997
1008 trace_cfg80211_ch_switch_notify(dev, freq, type); 998 trace_cfg80211_ch_switch_notify(dev, chandef);
1009 999
1010 wdev_lock(wdev); 1000 wdev_lock(wdev);
1011 1001
@@ -1013,12 +1003,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
1013 wdev->iftype != NL80211_IFTYPE_P2P_GO)) 1003 wdev->iftype != NL80211_IFTYPE_P2P_GO))
1014 goto out; 1004 goto out;
1015 1005
1016 chan = rdev_freq_to_chan(rdev, freq, type); 1006 wdev->channel = chandef->chan;
1017 if (WARN_ON(!chan)) 1007 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
1018 goto out;
1019
1020 wdev->channel = chan;
1021 nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL);
1022out: 1008out:
1023 wdev_unlock(wdev); 1009 wdev_unlock(wdev);
1024 return; 1010 return;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8c0857815a9..d038fa45ecd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -223,8 +223,13 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
223 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, 223 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
224 .len = 20-1 }, 224 .len = 20-1 },
225 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, 225 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
226
226 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, 227 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
227 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, 228 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
229 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
230 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
231 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
232
228 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 }, 233 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
229 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 }, 234 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
230 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, 235 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
@@ -1110,6 +1115,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
1110 goto nla_put_failure; 1115 goto nla_put_failure;
1111 } 1116 }
1112 CMD(start_p2p_device, START_P2P_DEVICE); 1117 CMD(start_p2p_device, START_P2P_DEVICE);
1118 CMD(set_mcast_rate, SET_MCAST_RATE);
1113 1119
1114#ifdef CONFIG_NL80211_TESTMODE 1120#ifdef CONFIG_NL80211_TESTMODE
1115 CMD(testmode_cmd, TESTMODE); 1121 CMD(testmode_cmd, TESTMODE);
@@ -1359,51 +1365,139 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
1359 wdev->iftype == NL80211_IFTYPE_P2P_GO; 1365 wdev->iftype == NL80211_IFTYPE_P2P_GO;
1360} 1366}
1361 1367
1362static bool nl80211_valid_channel_type(struct genl_info *info, 1368static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
1363 enum nl80211_channel_type *channel_type) 1369 struct genl_info *info,
1370 struct cfg80211_chan_def *chandef)
1364{ 1371{
1365 enum nl80211_channel_type tmp; 1372 struct ieee80211_sta_ht_cap *ht_cap;
1373 struct ieee80211_sta_vht_cap *vht_cap;
1374 u32 control_freq, width;
1366 1375
1367 if (!info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) 1376 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1368 return false; 1377 return -EINVAL;
1369 1378
1370 tmp = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); 1379 control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1371 if (tmp != NL80211_CHAN_NO_HT &&
1372 tmp != NL80211_CHAN_HT20 &&
1373 tmp != NL80211_CHAN_HT40PLUS &&
1374 tmp != NL80211_CHAN_HT40MINUS)
1375 return false;
1376 1380
1377 if (channel_type) 1381 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
1378 *channel_type = tmp; 1382 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
1383 chandef->center_freq1 = control_freq;
1384 chandef->center_freq2 = 0;
1379 1385
1380 return true; 1386 /* Primary channel not allowed */
1387 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED)
1388 return -EINVAL;
1389
1390 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
1391 enum nl80211_channel_type chantype;
1392
1393 chantype = nla_get_u32(
1394 info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
1395
1396 switch (chantype) {
1397 case NL80211_CHAN_NO_HT:
1398 case NL80211_CHAN_HT20:
1399 case NL80211_CHAN_HT40PLUS:
1400 case NL80211_CHAN_HT40MINUS:
1401 cfg80211_chandef_create(chandef, chandef->chan,
1402 chantype);
1403 break;
1404 default:
1405 return -EINVAL;
1406 }
1407 } else if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
1408 chandef->width =
1409 nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]);
1410 if (info->attrs[NL80211_ATTR_CENTER_FREQ1])
1411 chandef->center_freq1 =
1412 nla_get_u32(
1413 info->attrs[NL80211_ATTR_CENTER_FREQ1]);
1414 if (info->attrs[NL80211_ATTR_CENTER_FREQ2])
1415 chandef->center_freq2 =
1416 nla_get_u32(
1417 info->attrs[NL80211_ATTR_CENTER_FREQ2]);
1418 }
1419
1420 ht_cap = &rdev->wiphy.bands[chandef->chan->band]->ht_cap;
1421 vht_cap = &rdev->wiphy.bands[chandef->chan->band]->vht_cap;
1422
1423 if (!cfg80211_chan_def_valid(chandef))
1424 return -EINVAL;
1425
1426 switch (chandef->width) {
1427 case NL80211_CHAN_WIDTH_20:
1428 if (!ht_cap->ht_supported)
1429 return -EINVAL;
1430 case NL80211_CHAN_WIDTH_20_NOHT:
1431 width = 20;
1432 break;
1433 case NL80211_CHAN_WIDTH_40:
1434 width = 40;
1435 /* quick early regulatory check */
1436 if (chandef->center_freq1 < control_freq &&
1437 chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
1438 return -EINVAL;
1439 if (chandef->center_freq1 > control_freq &&
1440 chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
1441 return -EINVAL;
1442 if (!ht_cap->ht_supported)
1443 return -EINVAL;
1444 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
1445 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
1446 return -EINVAL;
1447 break;
1448 case NL80211_CHAN_WIDTH_80:
1449 width = 80;
1450 if (!vht_cap->vht_supported)
1451 return -EINVAL;
1452 break;
1453 case NL80211_CHAN_WIDTH_80P80:
1454 width = 80;
1455 if (!vht_cap->vht_supported)
1456 return -EINVAL;
1457 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
1458 return -EINVAL;
1459 break;
1460 case NL80211_CHAN_WIDTH_160:
1461 width = 160;
1462 if (!vht_cap->vht_supported)
1463 return -EINVAL;
1464 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
1465 return -EINVAL;
1466 break;
1467 default:
1468 return -EINVAL;
1469 }
1470
1471 if (!cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq1,
1472 width, IEEE80211_CHAN_DISABLED))
1473 return -EINVAL;
1474 if (chandef->center_freq2 &&
1475 !cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq2,
1476 width, IEEE80211_CHAN_DISABLED))
1477 return -EINVAL;
1478
1479 /* TODO: missing regulatory check on bandwidth */
1480
1481 return 0;
1381} 1482}
1382 1483
1383static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, 1484static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1384 struct wireless_dev *wdev, 1485 struct wireless_dev *wdev,
1385 struct genl_info *info) 1486 struct genl_info *info)
1386{ 1487{
1387 struct ieee80211_channel *channel; 1488 struct cfg80211_chan_def chandef;
1388 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
1389 u32 freq;
1390 int result; 1489 int result;
1391 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR; 1490 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
1392 1491
1393 if (wdev) 1492 if (wdev)
1394 iftype = wdev->iftype; 1493 iftype = wdev->iftype;
1395 1494
1396 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1397 return -EINVAL;
1398
1399 if (!nl80211_can_set_dev_channel(wdev)) 1495 if (!nl80211_can_set_dev_channel(wdev))
1400 return -EOPNOTSUPP; 1496 return -EOPNOTSUPP;
1401 1497
1402 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 1498 result = nl80211_parse_chandef(rdev, info, &chandef);
1403 !nl80211_valid_channel_type(info, &channel_type)) 1499 if (result)
1404 return -EINVAL; 1500 return result;
1405
1406 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1407 1501
1408 mutex_lock(&rdev->devlist_mtx); 1502 mutex_lock(&rdev->devlist_mtx);
1409 switch (iftype) { 1503 switch (iftype) {
@@ -1413,22 +1507,18 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1413 result = -EBUSY; 1507 result = -EBUSY;
1414 break; 1508 break;
1415 } 1509 }
1416 channel = rdev_freq_to_chan(rdev, freq, channel_type); 1510 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) {
1417 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
1418 channel,
1419 channel_type)) {
1420 result = -EINVAL; 1511 result = -EINVAL;
1421 break; 1512 break;
1422 } 1513 }
1423 wdev->preset_chan = channel; 1514 wdev->preset_chandef = chandef;
1424 wdev->preset_chantype = channel_type;
1425 result = 0; 1515 result = 0;
1426 break; 1516 break;
1427 case NL80211_IFTYPE_MESH_POINT: 1517 case NL80211_IFTYPE_MESH_POINT:
1428 result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type); 1518 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
1429 break; 1519 break;
1430 case NL80211_IFTYPE_MONITOR: 1520 case NL80211_IFTYPE_MONITOR:
1431 result = cfg80211_set_monitor_channel(rdev, freq, channel_type); 1521 result = cfg80211_set_monitor_channel(rdev, &chandef);
1432 break; 1522 break;
1433 default: 1523 default:
1434 result = -EINVAL; 1524 result = -EINVAL;
@@ -1516,10 +1606,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1516 result = 0; 1606 result = 0;
1517 1607
1518 mutex_lock(&rdev->mtx); 1608 mutex_lock(&rdev->mtx);
1519 } else if (nl80211_can_set_dev_channel(netdev->ieee80211_ptr)) 1609 } else
1520 wdev = netdev->ieee80211_ptr; 1610 wdev = netdev->ieee80211_ptr;
1521 else
1522 wdev = NULL;
1523 1611
1524 /* 1612 /*
1525 * end workaround code, by now the rdev is available 1613 * end workaround code, by now the rdev is available
@@ -1579,15 +1667,21 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1579 } 1667 }
1580 1668
1581 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 1669 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
1582 result = __nl80211_set_channel(rdev, wdev, info); 1670 result = __nl80211_set_channel(rdev,
1671 nl80211_can_set_dev_channel(wdev) ? wdev : NULL,
1672 info);
1583 if (result) 1673 if (result)
1584 goto bad_res; 1674 goto bad_res;
1585 } 1675 }
1586 1676
1587 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { 1677 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
1678 struct wireless_dev *txp_wdev = wdev;
1588 enum nl80211_tx_power_setting type; 1679 enum nl80211_tx_power_setting type;
1589 int idx, mbm = 0; 1680 int idx, mbm = 0;
1590 1681
1682 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
1683 txp_wdev = NULL;
1684
1591 if (!rdev->ops->set_tx_power) { 1685 if (!rdev->ops->set_tx_power) {
1592 result = -EOPNOTSUPP; 1686 result = -EOPNOTSUPP;
1593 goto bad_res; 1687 goto bad_res;
@@ -1607,7 +1701,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1607 mbm = nla_get_u32(info->attrs[idx]); 1701 mbm = nla_get_u32(info->attrs[idx]);
1608 } 1702 }
1609 1703
1610 result = rdev_set_tx_power(rdev, type, mbm); 1704 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
1611 if (result) 1705 if (result)
1612 goto bad_res; 1706 goto bad_res;
1613 } 1707 }
@@ -1744,6 +1838,35 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
1744 ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32); 1838 ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32);
1745} 1839}
1746 1840
1841static int nl80211_send_chandef(struct sk_buff *msg,
1842 struct cfg80211_chan_def *chandef)
1843{
1844 WARN_ON(!cfg80211_chan_def_valid(chandef));
1845
1846 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
1847 chandef->chan->center_freq))
1848 return -ENOBUFS;
1849 switch (chandef->width) {
1850 case NL80211_CHAN_WIDTH_20_NOHT:
1851 case NL80211_CHAN_WIDTH_20:
1852 case NL80211_CHAN_WIDTH_40:
1853 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
1854 cfg80211_get_chandef_type(chandef)))
1855 return -ENOBUFS;
1856 break;
1857 default:
1858 break;
1859 }
1860 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
1861 return -ENOBUFS;
1862 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
1863 return -ENOBUFS;
1864 if (chandef->center_freq2 &&
1865 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
1866 return -ENOBUFS;
1867 return 0;
1868}
1869
1747static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, 1870static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
1748 struct cfg80211_registered_device *rdev, 1871 struct cfg80211_registered_device *rdev,
1749 struct wireless_dev *wdev) 1872 struct wireless_dev *wdev)
@@ -1770,15 +1893,18 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
1770 goto nla_put_failure; 1893 goto nla_put_failure;
1771 1894
1772 if (rdev->ops->get_channel) { 1895 if (rdev->ops->get_channel) {
1773 struct ieee80211_channel *chan; 1896 int ret;
1774 enum nl80211_channel_type channel_type; 1897 struct cfg80211_chan_def chandef;
1775 1898
1776 chan = rdev_get_channel(rdev, wdev, &channel_type); 1899 ret = rdev_get_channel(rdev, wdev, &chandef);
1777 if (chan && 1900 if (ret == 0) {
1778 (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, 1901 if (nl80211_send_chandef(msg, &chandef))
1779 chan->center_freq) || 1902 goto nla_put_failure;
1780 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, 1903 }
1781 channel_type))) 1904 }
1905
1906 if (wdev->ssid_len) {
1907 if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
1782 goto nla_put_failure; 1908 goto nla_put_failure;
1783 } 1909 }
1784 1910
@@ -2482,11 +2608,10 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2482 wdev->iftype != NL80211_IFTYPE_P2P_GO) 2608 wdev->iftype != NL80211_IFTYPE_P2P_GO)
2483 continue; 2609 continue;
2484 2610
2485 if (!wdev->preset_chan) 2611 if (!wdev->preset_chandef.chan)
2486 continue; 2612 continue;
2487 2613
2488 params->channel = wdev->preset_chan; 2614 params->chandef = wdev->preset_chandef;
2489 params->channel_type = wdev->preset_chantype;
2490 ret = true; 2615 ret = true;
2491 break; 2616 break;
2492 } 2617 }
@@ -2608,30 +2733,19 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2608 } 2733 }
2609 2734
2610 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 2735 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2611 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 2736 err = nl80211_parse_chandef(rdev, info, &params.chandef);
2612 2737 if (err)
2613 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 2738 return err;
2614 !nl80211_valid_channel_type(info, &channel_type)) 2739 } else if (wdev->preset_chandef.chan) {
2615 return -EINVAL; 2740 params.chandef = wdev->preset_chandef;
2616
2617 params.channel = rdev_freq_to_chan(rdev,
2618 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
2619 channel_type);
2620 if (!params.channel)
2621 return -EINVAL;
2622 params.channel_type = channel_type;
2623 } else if (wdev->preset_chan) {
2624 params.channel = wdev->preset_chan;
2625 params.channel_type = wdev->preset_chantype;
2626 } else if (!nl80211_get_ap_channel(rdev, &params)) 2741 } else if (!nl80211_get_ap_channel(rdev, &params))
2627 return -EINVAL; 2742 return -EINVAL;
2628 2743
2629 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel, 2744 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
2630 params.channel_type))
2631 return -EINVAL; 2745 return -EINVAL;
2632 2746
2633 mutex_lock(&rdev->devlist_mtx); 2747 mutex_lock(&rdev->devlist_mtx);
2634 err = cfg80211_can_use_chan(rdev, wdev, params.channel, 2748 err = cfg80211_can_use_chan(rdev, wdev, params.chandef.chan,
2635 CHAN_MODE_SHARED); 2749 CHAN_MODE_SHARED);
2636 mutex_unlock(&rdev->devlist_mtx); 2750 mutex_unlock(&rdev->devlist_mtx);
2637 2751
@@ -2640,10 +2754,11 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2640 2754
2641 err = rdev_start_ap(rdev, dev, &params); 2755 err = rdev_start_ap(rdev, dev, &params);
2642 if (!err) { 2756 if (!err) {
2643 wdev->preset_chan = params.channel; 2757 wdev->preset_chandef = params.chandef;
2644 wdev->preset_chantype = params.channel_type;
2645 wdev->beacon_interval = params.beacon_interval; 2758 wdev->beacon_interval = params.beacon_interval;
2646 wdev->channel = params.channel; 2759 wdev->channel = params.chandef.chan;
2760 wdev->ssid_len = params.ssid_len;
2761 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
2647 } 2762 }
2648 return err; 2763 return err;
2649} 2764}
@@ -2775,29 +2890,52 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
2775 2890
2776 rate = nla_nest_start(msg, attr); 2891 rate = nla_nest_start(msg, attr);
2777 if (!rate) 2892 if (!rate)
2778 goto nla_put_failure; 2893 return false;
2779 2894
2780 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ 2895 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
2781 bitrate = cfg80211_calculate_bitrate(info); 2896 bitrate = cfg80211_calculate_bitrate(info);
2782 /* report 16-bit bitrate only if we can */ 2897 /* report 16-bit bitrate only if we can */
2783 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0; 2898 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
2784 if ((bitrate > 0 && 2899 if (bitrate > 0 &&
2785 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate)) || 2900 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
2786 (bitrate_compat > 0 && 2901 return false;
2787 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) || 2902 if (bitrate_compat > 0 &&
2788 ((info->flags & RATE_INFO_FLAGS_MCS) && 2903 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
2789 nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) || 2904 return false;
2790 ((info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) && 2905
2791 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) || 2906 if (info->flags & RATE_INFO_FLAGS_MCS) {
2792 ((info->flags & RATE_INFO_FLAGS_SHORT_GI) && 2907 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
2793 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))) 2908 return false;
2794 goto nla_put_failure; 2909 if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
2910 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
2911 return false;
2912 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
2913 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
2914 return false;
2915 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
2916 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
2917 return false;
2918 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
2919 return false;
2920 if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
2921 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
2922 return false;
2923 if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH &&
2924 nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH))
2925 return false;
2926 if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH &&
2927 nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH))
2928 return false;
2929 if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH &&
2930 nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH))
2931 return false;
2932 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
2933 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
2934 return false;
2935 }
2795 2936
2796 nla_nest_end(msg, rate); 2937 nla_nest_end(msg, rate);
2797 return true; 2938 return true;
2798
2799nla_put_failure:
2800 return false;
2801} 2939}
2802 2940
2803static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, 2941static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
@@ -5318,8 +5456,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5318 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 5456 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
5319 return -EINVAL; 5457 return -EINVAL;
5320 5458
5321 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || 5459 if (!info->attrs[NL80211_ATTR_SSID] ||
5322 !info->attrs[NL80211_ATTR_SSID] ||
5323 !nla_len(info->attrs[NL80211_ATTR_SSID])) 5460 !nla_len(info->attrs[NL80211_ATTR_SSID]))
5324 return -EINVAL; 5461 return -EINVAL;
5325 5462
@@ -5354,35 +5491,17 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5354 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 5491 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5355 } 5492 }
5356 5493
5357 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 5494 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
5358 enum nl80211_channel_type channel_type; 5495 if (err)
5359 5496 return err;
5360 if (!nl80211_valid_channel_type(info, &channel_type))
5361 return -EINVAL;
5362
5363 if (channel_type != NL80211_CHAN_NO_HT &&
5364 !(wiphy->features & NL80211_FEATURE_HT_IBSS))
5365 return -EINVAL;
5366
5367 ibss.channel_type = channel_type;
5368 } else {
5369 ibss.channel_type = NL80211_CHAN_NO_HT;
5370 }
5371 5497
5372 ibss.channel = rdev_freq_to_chan(rdev, 5498 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
5373 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
5374 ibss.channel_type);
5375 if (!ibss.channel ||
5376 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
5377 ibss.channel->flags & IEEE80211_CHAN_DISABLED)
5378 return -EINVAL; 5499 return -EINVAL;
5379 5500
5380 /* Both channels should be able to initiate communication */ 5501 if (ibss.chandef.width > NL80211_CHAN_WIDTH_40)
5381 if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
5382 ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
5383 !cfg80211_can_beacon_sec_chan(&rdev->wiphy, ibss.channel,
5384 ibss.channel_type))
5385 return -EINVAL; 5502 return -EINVAL;
5503 if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
5504 !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
5386 5505
5387 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 5506 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
5388 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 5507 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
@@ -5393,7 +5512,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5393 int n_rates = 5512 int n_rates =
5394 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 5513 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5395 struct ieee80211_supported_band *sband = 5514 struct ieee80211_supported_band *sband =
5396 wiphy->bands[ibss.channel->band]; 5515 wiphy->bands[ibss.chandef.chan->band];
5397 5516
5398 err = ieee80211_get_ratemask(sband, rates, n_rates, 5517 err = ieee80211_get_ratemask(sband, rates, n_rates,
5399 &ibss.basic_rates); 5518 &ibss.basic_rates);
@@ -5415,7 +5534,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5415 if (IS_ERR(connkeys)) 5534 if (IS_ERR(connkeys))
5416 return PTR_ERR(connkeys); 5535 return PTR_ERR(connkeys);
5417 5536
5418 if ((ibss.channel_type != NL80211_CHAN_NO_HT) && no_ht) { 5537 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
5538 no_ht) {
5419 kfree(connkeys); 5539 kfree(connkeys);
5420 return -EINVAL; 5540 return -EINVAL;
5421 } 5541 }
@@ -5444,6 +5564,36 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
5444 return cfg80211_leave_ibss(rdev, dev, false); 5564 return cfg80211_leave_ibss(rdev, dev, false);
5445} 5565}
5446 5566
5567static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
5568{
5569 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5570 struct net_device *dev = info->user_ptr[1];
5571 int mcast_rate[IEEE80211_NUM_BANDS];
5572 u32 nla_rate;
5573 int err;
5574
5575 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
5576 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5577 return -EOPNOTSUPP;
5578
5579 if (!rdev->ops->set_mcast_rate)
5580 return -EOPNOTSUPP;
5581
5582 memset(mcast_rate, 0, sizeof(mcast_rate));
5583
5584 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
5585 return -EINVAL;
5586
5587 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
5588 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
5589 return -EINVAL;
5590
5591 err = rdev->ops->set_mcast_rate(&rdev->wiphy, dev, mcast_rate);
5592
5593 return err;
5594}
5595
5596
5447#ifdef CONFIG_NL80211_TESTMODE 5597#ifdef CONFIG_NL80211_TESTMODE
5448static struct genl_multicast_group nl80211_testmode_mcgrp = { 5598static struct genl_multicast_group nl80211_testmode_mcgrp = {
5449 .name = "testmode", 5599 .name = "testmode",
@@ -5906,12 +6056,11 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5906{ 6056{
5907 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6057 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5908 struct wireless_dev *wdev = info->user_ptr[1]; 6058 struct wireless_dev *wdev = info->user_ptr[1];
5909 struct ieee80211_channel *chan; 6059 struct cfg80211_chan_def chandef;
5910 struct sk_buff *msg; 6060 struct sk_buff *msg;
5911 void *hdr; 6061 void *hdr;
5912 u64 cookie; 6062 u64 cookie;
5913 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 6063 u32 duration;
5914 u32 freq, duration;
5915 int err; 6064 int err;
5916 6065
5917 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || 6066 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
@@ -5932,14 +6081,9 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5932 duration > rdev->wiphy.max_remain_on_channel_duration) 6081 duration > rdev->wiphy.max_remain_on_channel_duration)
5933 return -EINVAL; 6082 return -EINVAL;
5934 6083
5935 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 6084 err = nl80211_parse_chandef(rdev, info, &chandef);
5936 !nl80211_valid_channel_type(info, &channel_type)) 6085 if (err)
5937 return -EINVAL; 6086 return err;
5938
5939 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
5940 chan = rdev_freq_to_chan(rdev, freq, channel_type);
5941 if (chan == NULL)
5942 return -EINVAL;
5943 6087
5944 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6088 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5945 if (!msg) 6089 if (!msg)
@@ -5953,8 +6097,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5953 goto free_msg; 6097 goto free_msg;
5954 } 6098 }
5955 6099
5956 err = rdev_remain_on_channel(rdev, wdev, chan, channel_type, duration, 6100 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
5957 &cookie); 6101 duration, &cookie);
5958 6102
5959 if (err) 6103 if (err)
5960 goto free_msg; 6104 goto free_msg;
@@ -6173,10 +6317,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6173{ 6317{
6174 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6318 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6175 struct wireless_dev *wdev = info->user_ptr[1]; 6319 struct wireless_dev *wdev = info->user_ptr[1];
6176 struct ieee80211_channel *chan; 6320 struct cfg80211_chan_def chandef;
6177 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
6178 bool channel_type_valid = false;
6179 u32 freq;
6180 int err; 6321 int err;
6181 void *hdr = NULL; 6322 void *hdr = NULL;
6182 u64 cookie; 6323 u64 cookie;
@@ -6186,8 +6327,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6186 6327
6187 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; 6328 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
6188 6329
6189 if (!info->attrs[NL80211_ATTR_FRAME] || 6330 if (!info->attrs[NL80211_ATTR_FRAME])
6190 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
6191 return -EINVAL; 6331 return -EINVAL;
6192 6332
6193 if (!rdev->ops->mgmt_tx) 6333 if (!rdev->ops->mgmt_tx)
@@ -6222,12 +6362,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6222 6362
6223 } 6363 }
6224 6364
6225 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
6226 if (!nl80211_valid_channel_type(info, &channel_type))
6227 return -EINVAL;
6228 channel_type_valid = true;
6229 }
6230
6231 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; 6365 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
6232 6366
6233 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) 6367 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
@@ -6235,10 +6369,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6235 6369
6236 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); 6370 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
6237 6371
6238 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 6372 err = nl80211_parse_chandef(rdev, info, &chandef);
6239 chan = rdev_freq_to_chan(rdev, freq, channel_type); 6373 if (err)
6240 if (chan == NULL) 6374 return err;
6241 return -EINVAL;
6242 6375
6243 if (!dont_wait_for_ack) { 6376 if (!dont_wait_for_ack) {
6244 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6377 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -6254,8 +6387,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6254 } 6387 }
6255 } 6388 }
6256 6389
6257 err = cfg80211_mlme_mgmt_tx(rdev, wdev, chan, offchan, channel_type, 6390 err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait,
6258 channel_type_valid, wait,
6259 nla_data(info->attrs[NL80211_ATTR_FRAME]), 6391 nla_data(info->attrs[NL80211_ATTR_FRAME]),
6260 nla_len(info->attrs[NL80211_ATTR_FRAME]), 6392 nla_len(info->attrs[NL80211_ATTR_FRAME]),
6261 no_cck, dont_wait_for_ack, &cookie); 6393 no_cck, dont_wait_for_ack, &cookie);
@@ -6519,21 +6651,12 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
6519 } 6651 }
6520 6652
6521 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 6653 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
6522 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 6654 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
6523 6655 if (err)
6524 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 6656 return err;
6525 !nl80211_valid_channel_type(info, &channel_type))
6526 return -EINVAL;
6527
6528 setup.channel = rdev_freq_to_chan(rdev,
6529 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
6530 channel_type);
6531 if (!setup.channel)
6532 return -EINVAL;
6533 setup.channel_type = channel_type;
6534 } else { 6657 } else {
6535 /* cfg80211_join_mesh() will sort it out */ 6658 /* cfg80211_join_mesh() will sort it out */
6536 setup.channel = NULL; 6659 setup.chandef.chan = NULL;
6537 } 6660 }
6538 6661
6539 return cfg80211_join_mesh(rdev, dev, &setup, &cfg); 6662 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
@@ -6899,16 +7022,35 @@ static int nl80211_probe_client(struct sk_buff *skb,
6899static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) 7022static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
6900{ 7023{
6901 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 7024 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7025 struct cfg80211_beacon_registration *reg, *nreg;
7026 int rv;
6902 7027
6903 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS)) 7028 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
6904 return -EOPNOTSUPP; 7029 return -EOPNOTSUPP;
6905 7030
6906 if (rdev->ap_beacons_nlportid) 7031 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
6907 return -EBUSY; 7032 if (!nreg)
7033 return -ENOMEM;
6908 7034
6909 rdev->ap_beacons_nlportid = info->snd_portid; 7035 /* First, check if already registered. */
7036 spin_lock_bh(&rdev->beacon_registrations_lock);
7037 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
7038 if (reg->nlportid == info->snd_portid) {
7039 rv = -EALREADY;
7040 goto out_err;
7041 }
7042 }
7043 /* Add it to the list */
7044 nreg->nlportid = info->snd_portid;
7045 list_add(&nreg->list, &rdev->beacon_registrations);
7046
7047 spin_unlock_bh(&rdev->beacon_registrations_lock);
6910 7048
6911 return 0; 7049 return 0;
7050out_err:
7051 spin_unlock_bh(&rdev->beacon_registrations_lock);
7052 kfree(nreg);
7053 return rv;
6912} 7054}
6913 7055
6914static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) 7056static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
@@ -7625,6 +7767,14 @@ static struct genl_ops nl80211_ops[] = {
7625 .internal_flags = NL80211_FLAG_NEED_WDEV_UP | 7767 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
7626 NL80211_FLAG_NEED_RTNL, 7768 NL80211_FLAG_NEED_RTNL,
7627 }, 7769 },
7770 {
7771 .cmd = NL80211_CMD_SET_MCAST_RATE,
7772 .doit = nl80211_set_mcast_rate,
7773 .policy = nl80211_policy,
7774 .flags = GENL_ADMIN_PERM,
7775 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7776 NL80211_FLAG_NEED_RTNL,
7777 },
7628}; 7778};
7629 7779
7630static struct genl_multicast_group nl80211_mlme_mcgrp = { 7780static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -8326,7 +8476,6 @@ static void nl80211_send_remain_on_chan_event(
8326 int cmd, struct cfg80211_registered_device *rdev, 8476 int cmd, struct cfg80211_registered_device *rdev,
8327 struct wireless_dev *wdev, u64 cookie, 8477 struct wireless_dev *wdev, u64 cookie,
8328 struct ieee80211_channel *chan, 8478 struct ieee80211_channel *chan,
8329 enum nl80211_channel_type channel_type,
8330 unsigned int duration, gfp_t gfp) 8479 unsigned int duration, gfp_t gfp)
8331{ 8480{
8332 struct sk_buff *msg; 8481 struct sk_buff *msg;
@@ -8347,7 +8496,8 @@ static void nl80211_send_remain_on_chan_event(
8347 wdev->netdev->ifindex)) || 8496 wdev->netdev->ifindex)) ||
8348 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || 8497 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
8349 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) || 8498 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
8350 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type) || 8499 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
8500 NL80211_CHAN_NO_HT) ||
8351 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) 8501 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
8352 goto nla_put_failure; 8502 goto nla_put_failure;
8353 8503
@@ -8369,23 +8519,20 @@ static void nl80211_send_remain_on_chan_event(
8369void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, 8519void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
8370 struct wireless_dev *wdev, u64 cookie, 8520 struct wireless_dev *wdev, u64 cookie,
8371 struct ieee80211_channel *chan, 8521 struct ieee80211_channel *chan,
8372 enum nl80211_channel_type channel_type,
8373 unsigned int duration, gfp_t gfp) 8522 unsigned int duration, gfp_t gfp)
8374{ 8523{
8375 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL, 8524 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
8376 rdev, wdev, cookie, chan, 8525 rdev, wdev, cookie, chan,
8377 channel_type, duration, gfp); 8526 duration, gfp);
8378} 8527}
8379 8528
8380void nl80211_send_remain_on_channel_cancel( 8529void nl80211_send_remain_on_channel_cancel(
8381 struct cfg80211_registered_device *rdev, 8530 struct cfg80211_registered_device *rdev,
8382 struct wireless_dev *wdev, 8531 struct wireless_dev *wdev,
8383 u64 cookie, struct ieee80211_channel *chan, 8532 u64 cookie, struct ieee80211_channel *chan, gfp_t gfp)
8384 enum nl80211_channel_type channel_type, gfp_t gfp)
8385{ 8533{
8386 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, 8534 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
8387 rdev, wdev, cookie, chan, 8535 rdev, wdev, cookie, chan, 0, gfp);
8388 channel_type, 0, gfp);
8389} 8536}
8390 8537
8391void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, 8538void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
@@ -8741,8 +8888,8 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
8741} 8888}
8742 8889
8743void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, 8890void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8744 struct net_device *netdev, int freq, 8891 struct net_device *netdev,
8745 enum nl80211_channel_type type, gfp_t gfp) 8892 struct cfg80211_chan_def *chandef, gfp_t gfp)
8746{ 8893{
8747 struct sk_buff *msg; 8894 struct sk_buff *msg;
8748 void *hdr; 8895 void *hdr;
@@ -8757,9 +8904,10 @@ void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8757 return; 8904 return;
8758 } 8905 }
8759 8906
8760 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || 8907 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
8761 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || 8908 goto nla_put_failure;
8762 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, type)) 8909
8910 if (nl80211_send_chandef(msg, chandef))
8763 goto nla_put_failure; 8911 goto nla_put_failure;
8764 8912
8765 genlmsg_end(msg, hdr); 8913 genlmsg_end(msg, hdr);
@@ -8914,46 +9062,96 @@ EXPORT_SYMBOL(cfg80211_probe_status);
8914 9062
8915void cfg80211_report_obss_beacon(struct wiphy *wiphy, 9063void cfg80211_report_obss_beacon(struct wiphy *wiphy,
8916 const u8 *frame, size_t len, 9064 const u8 *frame, size_t len,
8917 int freq, int sig_dbm, gfp_t gfp) 9065 int freq, int sig_dbm)
8918{ 9066{
8919 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 9067 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
8920 struct sk_buff *msg; 9068 struct sk_buff *msg;
8921 void *hdr; 9069 void *hdr;
8922 u32 nlportid = ACCESS_ONCE(rdev->ap_beacons_nlportid); 9070 struct cfg80211_beacon_registration *reg;
8923 9071
8924 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm); 9072 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
8925 9073
8926 if (!nlportid) 9074 spin_lock_bh(&rdev->beacon_registrations_lock);
8927 return; 9075 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
9076 msg = nlmsg_new(len + 100, GFP_ATOMIC);
9077 if (!msg) {
9078 spin_unlock_bh(&rdev->beacon_registrations_lock);
9079 return;
9080 }
9081
9082 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
9083 if (!hdr)
9084 goto nla_put_failure;
9085
9086 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
9087 (freq &&
9088 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
9089 (sig_dbm &&
9090 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
9091 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
9092 goto nla_put_failure;
9093
9094 genlmsg_end(msg, hdr);
8928 9095
8929 msg = nlmsg_new(len + 100, gfp); 9096 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
9097 }
9098 spin_unlock_bh(&rdev->beacon_registrations_lock);
9099 return;
9100
9101 nla_put_failure:
9102 spin_unlock_bh(&rdev->beacon_registrations_lock);
9103 if (hdr)
9104 genlmsg_cancel(msg, hdr);
9105 nlmsg_free(msg);
9106}
9107EXPORT_SYMBOL(cfg80211_report_obss_beacon);
9108
9109void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
9110 enum nl80211_tdls_operation oper,
9111 u16 reason_code, gfp_t gfp)
9112{
9113 struct wireless_dev *wdev = dev->ieee80211_ptr;
9114 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
9115 struct sk_buff *msg;
9116 void *hdr;
9117 int err;
9118
9119 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
9120 reason_code);
9121
9122 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
8930 if (!msg) 9123 if (!msg)
8931 return; 9124 return;
8932 9125
8933 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); 9126 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
8934 if (!hdr) { 9127 if (!hdr) {
8935 nlmsg_free(msg); 9128 nlmsg_free(msg);
8936 return; 9129 return;
8937 } 9130 }
8938 9131
8939 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 9132 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
8940 (freq && 9133 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
8941 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) || 9134 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
8942 (sig_dbm && 9135 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
8943 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || 9136 (reason_code > 0 &&
8944 nla_put(msg, NL80211_ATTR_FRAME, len, frame)) 9137 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
8945 goto nla_put_failure; 9138 goto nla_put_failure;
8946 9139
8947 genlmsg_end(msg, hdr); 9140 err = genlmsg_end(msg, hdr);
9141 if (err < 0) {
9142 nlmsg_free(msg);
9143 return;
9144 }
8948 9145
8949 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); 9146 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
9147 nl80211_mlme_mcgrp.id, gfp);
8950 return; 9148 return;
8951 9149
8952 nla_put_failure: 9150 nla_put_failure:
8953 genlmsg_cancel(msg, hdr); 9151 genlmsg_cancel(msg, hdr);
8954 nlmsg_free(msg); 9152 nlmsg_free(msg);
8955} 9153}
8956EXPORT_SYMBOL(cfg80211_report_obss_beacon); 9154EXPORT_SYMBOL(cfg80211_tdls_oper_request);
8957 9155
8958static int nl80211_netlink_notify(struct notifier_block * nb, 9156static int nl80211_netlink_notify(struct notifier_block * nb,
8959 unsigned long state, 9157 unsigned long state,
@@ -8962,6 +9160,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
8962 struct netlink_notify *notify = _notify; 9160 struct netlink_notify *notify = _notify;
8963 struct cfg80211_registered_device *rdev; 9161 struct cfg80211_registered_device *rdev;
8964 struct wireless_dev *wdev; 9162 struct wireless_dev *wdev;
9163 struct cfg80211_beacon_registration *reg, *tmp;
8965 9164
8966 if (state != NETLINK_URELEASE) 9165 if (state != NETLINK_URELEASE)
8967 return NOTIFY_DONE; 9166 return NOTIFY_DONE;
@@ -8971,8 +9170,17 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
8971 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { 9170 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
8972 list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) 9171 list_for_each_entry_rcu(wdev, &rdev->wdev_list, list)
8973 cfg80211_mlme_unregister_socket(wdev, notify->portid); 9172 cfg80211_mlme_unregister_socket(wdev, notify->portid);
8974 if (rdev->ap_beacons_nlportid == notify->portid) 9173
8975 rdev->ap_beacons_nlportid = 0; 9174 spin_lock_bh(&rdev->beacon_registrations_lock);
9175 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
9176 list) {
9177 if (reg->nlportid == notify->portid) {
9178 list_del(&reg->list);
9179 kfree(reg);
9180 break;
9181 }
9182 }
9183 spin_unlock_bh(&rdev->beacon_registrations_lock);
8976 } 9184 }
8977 9185
8978 rcu_read_unlock(); 9186 rcu_read_unlock();
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index f6153516068..2acba8477e9 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -76,13 +76,11 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
76void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, 76void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
77 struct wireless_dev *wdev, u64 cookie, 77 struct wireless_dev *wdev, u64 cookie,
78 struct ieee80211_channel *chan, 78 struct ieee80211_channel *chan,
79 enum nl80211_channel_type channel_type,
80 unsigned int duration, gfp_t gfp); 79 unsigned int duration, gfp_t gfp);
81void nl80211_send_remain_on_channel_cancel( 80void nl80211_send_remain_on_channel_cancel(
82 struct cfg80211_registered_device *rdev, 81 struct cfg80211_registered_device *rdev,
83 struct wireless_dev *wdev, 82 struct wireless_dev *wdev,
84 u64 cookie, struct ieee80211_channel *chan, 83 u64 cookie, struct ieee80211_channel *chan, gfp_t gfp);
85 enum nl80211_channel_type channel_type, gfp_t gfp);
86 84
87void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, 85void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
88 struct net_device *dev, const u8 *mac_addr, 86 struct net_device *dev, const u8 *mac_addr,
@@ -129,8 +127,8 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
129 const u8 *bssid, bool preauth, gfp_t gfp); 127 const u8 *bssid, bool preauth, gfp_t gfp);
130 128
131void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, 129void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
132 struct net_device *dev, int freq, 130 struct net_device *dev,
133 enum nl80211_channel_type type, gfp_t gfp); 131 struct cfg80211_chan_def *chandef, gfp_t gfp);
134 132
135bool nl80211_unexpected_frame(struct net_device *dev, 133bool nl80211_unexpected_frame(struct net_device *dev,
136 const u8 *addr, gfp_t gfp); 134 const u8 *addr, gfp_t gfp);
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index eb5f8974e14..6c0c8191f83 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -359,12 +359,11 @@ rdev_libertas_set_mesh_channel(struct cfg80211_registered_device *rdev,
359 359
360static inline int 360static inline int
361rdev_set_monitor_channel(struct cfg80211_registered_device *rdev, 361rdev_set_monitor_channel(struct cfg80211_registered_device *rdev,
362 struct ieee80211_channel *chan, 362 struct cfg80211_chan_def *chandef)
363 enum nl80211_channel_type channel_type)
364{ 363{
365 int ret; 364 int ret;
366 trace_rdev_set_monitor_channel(&rdev->wiphy, chan, channel_type); 365 trace_rdev_set_monitor_channel(&rdev->wiphy, chandef);
367 ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chan, channel_type); 366 ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chandef);
368 trace_rdev_return_int(&rdev->wiphy, ret); 367 trace_rdev_return_int(&rdev->wiphy, ret);
369 return ret; 368 return ret;
370} 369}
@@ -476,21 +475,22 @@ rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed)
476} 475}
477 476
478static inline int rdev_set_tx_power(struct cfg80211_registered_device *rdev, 477static inline int rdev_set_tx_power(struct cfg80211_registered_device *rdev,
478 struct wireless_dev *wdev,
479 enum nl80211_tx_power_setting type, int mbm) 479 enum nl80211_tx_power_setting type, int mbm)
480{ 480{
481 int ret; 481 int ret;
482 trace_rdev_set_tx_power(&rdev->wiphy, type, mbm); 482 trace_rdev_set_tx_power(&rdev->wiphy, wdev, type, mbm);
483 ret = rdev->ops->set_tx_power(&rdev->wiphy, type, mbm); 483 ret = rdev->ops->set_tx_power(&rdev->wiphy, wdev, type, mbm);
484 trace_rdev_return_int(&rdev->wiphy, ret); 484 trace_rdev_return_int(&rdev->wiphy, ret);
485 return ret; 485 return ret;
486} 486}
487 487
488static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev, 488static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev,
489 int *dbm) 489 struct wireless_dev *wdev, int *dbm)
490{ 490{
491 int ret; 491 int ret;
492 trace_rdev_get_tx_power(&rdev->wiphy); 492 trace_rdev_get_tx_power(&rdev->wiphy, wdev);
493 ret = rdev->ops->get_tx_power(&rdev->wiphy, dbm); 493 ret = rdev->ops->get_tx_power(&rdev->wiphy, wdev, dbm);
494 trace_rdev_return_int_int(&rdev->wiphy, ret, *dbm); 494 trace_rdev_return_int_int(&rdev->wiphy, ret, *dbm);
495 return ret; 495 return ret;
496} 496}
@@ -599,14 +599,12 @@ static inline int
599rdev_remain_on_channel(struct cfg80211_registered_device *rdev, 599rdev_remain_on_channel(struct cfg80211_registered_device *rdev,
600 struct wireless_dev *wdev, 600 struct wireless_dev *wdev,
601 struct ieee80211_channel *chan, 601 struct ieee80211_channel *chan,
602 enum nl80211_channel_type channel_type,
603 unsigned int duration, u64 *cookie) 602 unsigned int duration, u64 *cookie)
604{ 603{
605 int ret; 604 int ret;
606 trace_rdev_remain_on_channel(&rdev->wiphy, wdev, chan, channel_type, 605 trace_rdev_remain_on_channel(&rdev->wiphy, wdev, chan, duration);
607 duration);
608 ret = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan, 606 ret = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan,
609 channel_type, duration, cookie); 607 duration, cookie);
610 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); 608 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
611 return ret; 609 return ret;
612} 610}
@@ -625,17 +623,15 @@ rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev,
625static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev, 623static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
626 struct wireless_dev *wdev, 624 struct wireless_dev *wdev,
627 struct ieee80211_channel *chan, bool offchan, 625 struct ieee80211_channel *chan, bool offchan,
628 enum nl80211_channel_type channel_type, 626 unsigned int wait, const u8 *buf, size_t len,
629 bool channel_type_valid, unsigned int wait, 627 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
630 const u8 *buf, size_t len, bool no_cck,
631 bool dont_wait_for_ack, u64 *cookie)
632{ 628{
633 int ret; 629 int ret;
634 trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan, channel_type, 630 trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
635 channel_type_valid, wait, no_cck, dont_wait_for_ack); 631 wait, no_cck, dont_wait_for_ack);
636 ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan, 632 ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
637 channel_type, channel_type_valid, wait, buf, 633 wait, buf, len, no_cck,
638 len, no_cck, dont_wait_for_ack, cookie); 634 dont_wait_for_ack, cookie);
639 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); 635 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
640 return ret; 636 return ret;
641} 637}
@@ -847,14 +843,17 @@ static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev,
847 trace_rdev_return_void(&rdev->wiphy); 843 trace_rdev_return_void(&rdev->wiphy);
848} 844}
849 845
850static inline struct ieee80211_channel 846static inline int
851*rdev_get_channel(struct cfg80211_registered_device *rdev, 847rdev_get_channel(struct cfg80211_registered_device *rdev,
852 struct wireless_dev *wdev, enum nl80211_channel_type *type) 848 struct wireless_dev *wdev,
849 struct cfg80211_chan_def *chandef)
853{ 850{
854 struct ieee80211_channel *ret; 851 int ret;
852
855 trace_rdev_get_channel(&rdev->wiphy, wdev); 853 trace_rdev_get_channel(&rdev->wiphy, wdev);
856 ret = rdev->ops->get_channel(&rdev->wiphy, wdev, type); 854 ret = rdev->ops->get_channel(&rdev->wiphy, wdev, chandef);
857 trace_rdev_return_channel(&rdev->wiphy, ret, *type); 855 trace_rdev_return_chandef(&rdev->wiphy, ret, chandef);
856
858 return ret; 857 return ret;
859} 858}
860 859
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 7f97a087f45..9596015975d 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -771,6 +771,38 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
771 return found; 771 return found;
772} 772}
773 773
774static struct ieee80211_channel *
775cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
776 struct ieee80211_channel *channel)
777{
778 const u8 *tmp;
779 u32 freq;
780 int channel_number = -1;
781
782 tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen);
783 if (tmp && tmp[1] == 1) {
784 channel_number = tmp[2];
785 } else {
786 tmp = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie, ielen);
787 if (tmp && tmp[1] >= sizeof(struct ieee80211_ht_operation)) {
788 struct ieee80211_ht_operation *htop = (void *)(tmp + 2);
789
790 channel_number = htop->primary_chan;
791 }
792 }
793
794 if (channel_number < 0)
795 return channel;
796
797 freq = ieee80211_channel_to_frequency(channel_number, channel->band);
798 channel = ieee80211_get_channel(wiphy, freq);
799 if (!channel)
800 return NULL;
801 if (channel->flags & IEEE80211_CHAN_DISABLED)
802 return NULL;
803 return channel;
804}
805
774struct cfg80211_bss* 806struct cfg80211_bss*
775cfg80211_inform_bss(struct wiphy *wiphy, 807cfg80211_inform_bss(struct wiphy *wiphy,
776 struct ieee80211_channel *channel, 808 struct ieee80211_channel *channel,
@@ -790,6 +822,10 @@ cfg80211_inform_bss(struct wiphy *wiphy,
790 (signal < 0 || signal > 100))) 822 (signal < 0 || signal > 100)))
791 return NULL; 823 return NULL;
792 824
825 channel = cfg80211_get_bss_channel(wiphy, ie, ielen, channel);
826 if (!channel)
827 return NULL;
828
793 res = kzalloc(sizeof(*res) + privsz + ielen, gfp); 829 res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
794 if (!res) 830 if (!res)
795 return NULL; 831 return NULL;
@@ -839,11 +875,13 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
839 s32 signal, gfp_t gfp) 875 s32 signal, gfp_t gfp)
840{ 876{
841 struct cfg80211_internal_bss *res; 877 struct cfg80211_internal_bss *res;
842
843 size_t ielen = len - offsetof(struct ieee80211_mgmt, 878 size_t ielen = len - offsetof(struct ieee80211_mgmt,
844 u.probe_resp.variable); 879 u.probe_resp.variable);
845 size_t privsz; 880 size_t privsz;
846 881
882 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
883 offsetof(struct ieee80211_mgmt, u.beacon.variable));
884
847 trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal); 885 trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal);
848 886
849 if (WARN_ON(!mgmt)) 887 if (WARN_ON(!mgmt))
@@ -861,6 +899,11 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
861 899
862 privsz = wiphy->bss_priv_size; 900 privsz = wiphy->bss_priv_size;
863 901
902 channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
903 ielen, channel);
904 if (!channel)
905 return NULL;
906
864 res = kzalloc(sizeof(*res) + privsz + ielen, gfp); 907 res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
865 if (!res) 908 if (!res)
866 return NULL; 909 return NULL;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 0ca71caf85f..2134576f426 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -20,29 +20,26 @@
20#define MAC_PR_FMT "%pM" 20#define MAC_PR_FMT "%pM"
21#define MAC_PR_ARG(entry_mac) (__entry->entry_mac) 21#define MAC_PR_ARG(entry_mac) (__entry->entry_mac)
22 22
23#define WIPHY_ENTRY MAC_ENTRY(wiphy_mac) 23#define MAXNAME 32
24#define WIPHY_ASSIGN MAC_ASSIGN(wiphy_mac, wiphy->perm_addr) 24#define WIPHY_ENTRY __array(char, wiphy_name, 32)
25#define WIPHY_PR_FMT "wiphy " MAC_PR_FMT 25#define WIPHY_ASSIGN strlcpy(__entry->wiphy_name, wiphy_name(wiphy), MAXNAME)
26#define WIPHY_PR_ARG MAC_PR_ARG(wiphy_mac) 26#define WIPHY_PR_FMT "%s"
27 27#define WIPHY_PR_ARG __entry->wiphy_name
28#define WDEV_ENTRY __field(u32, id) 28
29#define WDEV_ASSIGN (__entry->id) = (wdev->identifier) 29#define WDEV_ENTRY __field(u32, id)
30#define WDEV_PR_FMT ", wdev id: %u" 30#define WDEV_ASSIGN (__entry->id) = (wdev ? wdev->identifier : 0)
31#define WDEV_PR_ARG (__entry->id) 31#define WDEV_PR_FMT "wdev(%u)"
32 32#define WDEV_PR_ARG (__entry->id)
33#define NETDEV_ENTRY __array(char, name, IFNAMSIZ) \ 33
34 MAC_ENTRY(netdev_addr) \ 34#define NETDEV_ENTRY __array(char, name, IFNAMSIZ) \
35 __field(int, ifindex) 35 __field(int, ifindex)
36#define NETDEV_ASSIGN \ 36#define NETDEV_ASSIGN \
37 do { \ 37 do { \
38 memcpy(__entry->name, netdev->name, IFNAMSIZ); \ 38 memcpy(__entry->name, netdev->name, IFNAMSIZ); \
39 MAC_ASSIGN(netdev_addr, netdev->dev_addr); \
40 (__entry->ifindex) = (netdev->ifindex); \ 39 (__entry->ifindex) = (netdev->ifindex); \
41 } while (0) 40 } while (0)
42#define NETDEV_PR_FMT ", netdev - name: %s, addr: " MAC_PR_FMT \ 41#define NETDEV_PR_FMT "netdev:%s(%d)"
43 ", intf index: %d" 42#define NETDEV_PR_ARG __entry->name, __entry->ifindex
44#define NETDEV_PR_ARG (__entry->name), MAC_PR_ARG(netdev_addr), \
45 (__entry->ifindex)
46 43
47#define MESH_CFG_ENTRY __field(u16, dot11MeshRetryTimeout) \ 44#define MESH_CFG_ENTRY __field(u16, dot11MeshRetryTimeout) \
48 __field(u16, dot11MeshConfirmTimeout) \ 45 __field(u16, dot11MeshConfirmTimeout) \
@@ -123,9 +120,37 @@
123 __entry->center_freq = 0; \ 120 __entry->center_freq = 0; \
124 } \ 121 } \
125 } while (0) 122 } while (0)
126#define CHAN_PR_FMT ", band: %d, freq: %u" 123#define CHAN_PR_FMT "band: %d, freq: %u"
127#define CHAN_PR_ARG __entry->band, __entry->center_freq 124#define CHAN_PR_ARG __entry->band, __entry->center_freq
128 125
126#define CHAN_DEF_ENTRY __field(enum ieee80211_band, band) \
127 __field(u32, control_freq) \
128 __field(u32, width) \
129 __field(u32, center_freq1) \
130 __field(u32, center_freq2)
131#define CHAN_DEF_ASSIGN(chandef) \
132 do { \
133 if ((chandef) && (chandef)->chan) { \
134 __entry->band = (chandef)->chan->band; \
135 __entry->control_freq = \
136 (chandef)->chan->center_freq; \
137 __entry->width = (chandef)->width; \
138 __entry->center_freq1 = (chandef)->center_freq1;\
139 __entry->center_freq2 = (chandef)->center_freq2;\
140 } else { \
141 __entry->band = 0; \
142 __entry->control_freq = 0; \
143 __entry->width = 0; \
144 __entry->center_freq1 = 0; \
145 __entry->center_freq2 = 0; \
146 } \
147 } while (0)
148#define CHAN_DEF_PR_FMT \
149 "band: %d, control freq: %u, width: %d, cf1: %u, cf2: %u"
150#define CHAN_DEF_PR_ARG __entry->band, __entry->control_freq, \
151 __entry->width, __entry->center_freq1, \
152 __entry->center_freq2
153
129#define SINFO_ENTRY __field(int, generation) \ 154#define SINFO_ENTRY __field(int, generation) \
130 __field(u32, connected_time) \ 155 __field(u32, connected_time) \
131 __field(u32, inactive_time) \ 156 __field(u32, inactive_time) \
@@ -260,11 +285,6 @@ DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna,
260 TP_ARGS(wiphy) 285 TP_ARGS(wiphy)
261); 286);
262 287
263DEFINE_EVENT(wiphy_only_evt, rdev_get_tx_power,
264 TP_PROTO(struct wiphy *wiphy),
265 TP_ARGS(wiphy)
266);
267
268DEFINE_EVENT(wiphy_only_evt, rdev_rfkill_poll, 288DEFINE_EVENT(wiphy_only_evt, rdev_rfkill_poll,
269 TP_PROTO(struct wiphy *wiphy), 289 TP_PROTO(struct wiphy *wiphy),
270 TP_ARGS(wiphy) 290 TP_ARGS(wiphy)
@@ -318,7 +338,7 @@ DECLARE_EVENT_CLASS(wiphy_wdev_evt,
318 WIPHY_ASSIGN; 338 WIPHY_ASSIGN;
319 WDEV_ASSIGN; 339 WDEV_ASSIGN;
320 ), 340 ),
321 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG) 341 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG)
322); 342);
323 343
324DEFINE_EVENT(wiphy_wdev_evt, rdev_return_wdev, 344DEFINE_EVENT(wiphy_wdev_evt, rdev_return_wdev,
@@ -345,7 +365,7 @@ TRACE_EVENT(rdev_change_virtual_intf,
345 NETDEV_ASSIGN; 365 NETDEV_ASSIGN;
346 __entry->type = type; 366 __entry->type = type;
347 ), 367 ),
348 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", type: %d", 368 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", type: %d",
349 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->type) 369 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->type)
350); 370);
351 371
@@ -367,7 +387,7 @@ DECLARE_EVENT_CLASS(key_handle,
367 __entry->key_index = key_index; 387 __entry->key_index = key_index;
368 __entry->pairwise = pairwise; 388 __entry->pairwise = pairwise;
369 ), 389 ),
370 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key_index: %u, pairwise: %s, mac addr: " MAC_PR_FMT, 390 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key_index: %u, pairwise: %s, mac addr: " MAC_PR_FMT,
371 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, 391 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index,
372 BOOL_TO_STR(__entry->pairwise), MAC_PR_ARG(mac_addr)) 392 BOOL_TO_STR(__entry->pairwise), MAC_PR_ARG(mac_addr))
373); 393);
@@ -408,7 +428,7 @@ TRACE_EVENT(rdev_set_default_key,
408 __entry->unicast = unicast; 428 __entry->unicast = unicast;
409 __entry->multicast = multicast; 429 __entry->multicast = multicast;
410 ), 430 ),
411 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key index: %u, unicast: %s, multicast: %s", 431 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u, unicast: %s, multicast: %s",
412 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, 432 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index,
413 BOOL_TO_STR(__entry->unicast), 433 BOOL_TO_STR(__entry->unicast),
414 BOOL_TO_STR(__entry->multicast)) 434 BOOL_TO_STR(__entry->multicast))
@@ -427,7 +447,7 @@ TRACE_EVENT(rdev_set_default_mgmt_key,
427 NETDEV_ASSIGN; 447 NETDEV_ASSIGN;
428 __entry->key_index = key_index; 448 __entry->key_index = key_index;
429 ), 449 ),
430 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key index: %u", 450 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u",
431 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index) 451 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
432); 452);
433 453
@@ -438,7 +458,7 @@ TRACE_EVENT(rdev_start_ap,
438 TP_STRUCT__entry( 458 TP_STRUCT__entry(
439 WIPHY_ENTRY 459 WIPHY_ENTRY
440 NETDEV_ENTRY 460 NETDEV_ENTRY
441 CHAN_ENTRY 461 CHAN_DEF_ENTRY
442 __field(int, beacon_interval) 462 __field(int, beacon_interval)
443 __field(int, dtim_period) 463 __field(int, dtim_period)
444 __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1) 464 __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1)
@@ -451,7 +471,7 @@ TRACE_EVENT(rdev_start_ap,
451 TP_fast_assign( 471 TP_fast_assign(
452 WIPHY_ASSIGN; 472 WIPHY_ASSIGN;
453 NETDEV_ASSIGN; 473 NETDEV_ASSIGN;
454 CHAN_ASSIGN(settings->channel); 474 CHAN_DEF_ASSIGN(&settings->chandef);
455 __entry->beacon_interval = settings->beacon_interval; 475 __entry->beacon_interval = settings->beacon_interval;
456 __entry->dtim_period = settings->dtim_period; 476 __entry->dtim_period = settings->dtim_period;
457 __entry->hidden_ssid = settings->hidden_ssid; 477 __entry->hidden_ssid = settings->hidden_ssid;
@@ -462,11 +482,11 @@ TRACE_EVENT(rdev_start_ap,
462 memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); 482 memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
463 memcpy(__entry->ssid, settings->ssid, settings->ssid_len); 483 memcpy(__entry->ssid, settings->ssid, settings->ssid_len);
464 ), 484 ),
465 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", AP settings - ssid: %s, " 485 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", AP settings - ssid: %s, "
466 CHAN_PR_FMT ", beacon interval: %d, dtim period: %d, " 486 CHAN_DEF_PR_FMT ", beacon interval: %d, dtim period: %d, "
467 "hidden ssid: %d, wpa versions: %u, privacy: %s, " 487 "hidden ssid: %d, wpa versions: %u, privacy: %s, "
468 "auth type: %d, inactivity timeout: %d", 488 "auth type: %d, inactivity timeout: %d",
469 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_PR_ARG, 489 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_DEF_PR_ARG,
470 __entry->beacon_interval, __entry->dtim_period, 490 __entry->beacon_interval, __entry->dtim_period,
471 __entry->hidden_ssid, __entry->wpa_ver, 491 __entry->hidden_ssid, __entry->wpa_ver,
472 BOOL_TO_STR(__entry->privacy), __entry->auth_type, 492 BOOL_TO_STR(__entry->privacy), __entry->auth_type,
@@ -515,7 +535,7 @@ TRACE_EVENT(rdev_change_beacon,
515 info->probe_resp, info->probe_resp_len); 535 info->probe_resp, info->probe_resp_len);
516 } 536 }
517 ), 537 ),
518 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) 538 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
519); 539);
520 540
521DECLARE_EVENT_CLASS(wiphy_netdev_evt, 541DECLARE_EVENT_CLASS(wiphy_netdev_evt,
@@ -529,7 +549,7 @@ DECLARE_EVENT_CLASS(wiphy_netdev_evt,
529 WIPHY_ASSIGN; 549 WIPHY_ASSIGN;
530 NETDEV_ASSIGN; 550 NETDEV_ASSIGN;
531 ), 551 ),
532 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) 552 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
533); 553);
534 554
535DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap, 555DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap,
@@ -607,7 +627,7 @@ DECLARE_EVENT_CLASS(station_add_change,
607 memcpy(__entry->ht_capa, params->ht_capa, 627 memcpy(__entry->ht_capa, params->ht_capa,
608 sizeof(struct ieee80211_ht_cap)); 628 sizeof(struct ieee80211_ht_cap));
609 ), 629 ),
610 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", station mac: " MAC_PR_FMT 630 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT
611 ", station flags mask: %u, station flags set: %u, " 631 ", station flags mask: %u, station flags set: %u, "
612 "station modify mask: %u, listen interval: %d, aid: %u, " 632 "station modify mask: %u, listen interval: %d, aid: %u, "
613 "plink action: %u, plink state: %u, uapsd queues: %u", 633 "plink action: %u, plink state: %u, uapsd queues: %u",
@@ -643,7 +663,7 @@ DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt,
643 NETDEV_ASSIGN; 663 NETDEV_ASSIGN;
644 MAC_ASSIGN(sta_mac, mac); 664 MAC_ASSIGN(sta_mac, mac);
645 ), 665 ),
646 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", mac: " MAC_PR_FMT, 666 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", mac: " MAC_PR_FMT,
647 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) 667 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac))
648); 668);
649 669
@@ -683,7 +703,7 @@ TRACE_EVENT(rdev_dump_station,
683 MAC_ASSIGN(sta_mac, mac); 703 MAC_ASSIGN(sta_mac, mac);
684 __entry->idx = idx; 704 __entry->idx = idx;
685 ), 705 ),
686 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", station mac: " MAC_PR_FMT ", idx: %d", 706 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT ", idx: %d",
687 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), 707 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac),
688 __entry->idx) 708 __entry->idx)
689); 709);
@@ -721,7 +741,7 @@ DECLARE_EVENT_CLASS(mpath_evt,
721 MAC_ASSIGN(dst, dst); 741 MAC_ASSIGN(dst, dst);
722 MAC_ASSIGN(next_hop, next_hop); 742 MAC_ASSIGN(next_hop, next_hop);
723 ), 743 ),
724 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", destination: " MAC_PR_FMT ", next hop: " MAC_PR_FMT, 744 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT ", next hop: " MAC_PR_FMT,
725 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dst), 745 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dst),
726 MAC_PR_ARG(next_hop)) 746 MAC_PR_ARG(next_hop))
727); 747);
@@ -762,7 +782,7 @@ TRACE_EVENT(rdev_dump_mpath,
762 MAC_ASSIGN(next_hop, next_hop); 782 MAC_ASSIGN(next_hop, next_hop);
763 __entry->idx = idx; 783 __entry->idx = idx;
764 ), 784 ),
765 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", index: %d, destination: " 785 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: "
766 MAC_PR_FMT ", next hop: " MAC_PR_FMT, 786 MAC_PR_FMT ", next hop: " MAC_PR_FMT,
767 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), 787 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst),
768 MAC_PR_ARG(next_hop)) 788 MAC_PR_ARG(next_hop))
@@ -839,7 +859,7 @@ TRACE_EVENT(rdev_update_mesh_config,
839 MESH_CFG_ASSIGN; 859 MESH_CFG_ASSIGN;
840 __entry->mask = mask; 860 __entry->mask = mask;
841 ), 861 ),
842 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", mask: %u", 862 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", mask: %u",
843 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->mask) 863 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->mask)
844); 864);
845 865
@@ -858,7 +878,7 @@ TRACE_EVENT(rdev_join_mesh,
858 NETDEV_ASSIGN; 878 NETDEV_ASSIGN;
859 MESH_CFG_ASSIGN; 879 MESH_CFG_ASSIGN;
860 ), 880 ),
861 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, 881 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
862 WIPHY_PR_ARG, NETDEV_PR_ARG) 882 WIPHY_PR_ARG, NETDEV_PR_ARG)
863); 883);
864 884
@@ -884,7 +904,7 @@ TRACE_EVENT(rdev_change_bss,
884 __entry->ap_isolate = params->ap_isolate; 904 __entry->ap_isolate = params->ap_isolate;
885 __entry->ht_opmode = params->ht_opmode; 905 __entry->ht_opmode = params->ht_opmode;
886 ), 906 ),
887 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", use cts prot: %d, " 907 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", use cts prot: %d, "
888 "use short preamble: %d, use short slot time: %d, " 908 "use short preamble: %d, use short slot time: %d, "
889 "ap isolate: %d, ht opmode: %d", 909 "ap isolate: %d, ht opmode: %d",
890 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->use_cts_prot, 910 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->use_cts_prot,
@@ -914,7 +934,7 @@ TRACE_EVENT(rdev_set_txq_params,
914 __entry->cwmax = params->cwmax; 934 __entry->cwmax = params->cwmax;
915 __entry->aifs = params->aifs; 935 __entry->aifs = params->aifs;
916 ), 936 ),
917 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", ac: %d, txop: %u, cwmin: %u, cwmax: %u, aifs: %u", 937 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", ac: %d, txop: %u, cwmin: %u, cwmax: %u, aifs: %u",
918 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ac, __entry->txop, 938 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ac, __entry->txop,
919 __entry->cwmin, __entry->cwmax, __entry->aifs) 939 __entry->cwmin, __entry->cwmax, __entry->aifs)
920); 940);
@@ -933,26 +953,24 @@ TRACE_EVENT(rdev_libertas_set_mesh_channel,
933 NETDEV_ASSIGN; 953 NETDEV_ASSIGN;
934 CHAN_ASSIGN(chan); 954 CHAN_ASSIGN(chan);
935 ), 955 ),
936 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT CHAN_PR_FMT, WIPHY_PR_ARG, 956 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_PR_FMT, WIPHY_PR_ARG,
937 NETDEV_PR_ARG, CHAN_PR_ARG) 957 NETDEV_PR_ARG, CHAN_PR_ARG)
938); 958);
939 959
940TRACE_EVENT(rdev_set_monitor_channel, 960TRACE_EVENT(rdev_set_monitor_channel,
941 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan, 961 TP_PROTO(struct wiphy *wiphy,
942 enum nl80211_channel_type chan_type), 962 struct cfg80211_chan_def *chandef),
943 TP_ARGS(wiphy, chan, chan_type), 963 TP_ARGS(wiphy, chandef),
944 TP_STRUCT__entry( 964 TP_STRUCT__entry(
945 WIPHY_ENTRY 965 WIPHY_ENTRY
946 CHAN_ENTRY 966 CHAN_DEF_ENTRY
947 __field(enum nl80211_channel_type, chan_type)
948 ), 967 ),
949 TP_fast_assign( 968 TP_fast_assign(
950 WIPHY_ASSIGN; 969 WIPHY_ASSIGN;
951 CHAN_ASSIGN(chan); 970 CHAN_DEF_ASSIGN(chandef);
952 __entry->chan_type = chan_type;
953 ), 971 ),
954 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type : %d", 972 TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
955 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->chan_type) 973 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
956); 974);
957 975
958TRACE_EVENT(rdev_auth, 976TRACE_EVENT(rdev_auth,
@@ -974,7 +992,7 @@ TRACE_EVENT(rdev_auth,
974 memset(__entry->bssid, 0, ETH_ALEN); 992 memset(__entry->bssid, 0, ETH_ALEN);
975 __entry->auth_type = req->auth_type; 993 __entry->auth_type = req->auth_type;
976 ), 994 ),
977 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", auth type: %d, bssid: " MAC_PR_FMT, 995 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", auth type: %d, bssid: " MAC_PR_FMT,
978 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->auth_type, 996 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->auth_type,
979 MAC_PR_ARG(bssid)) 997 MAC_PR_ARG(bssid))
980); 998);
@@ -1002,7 +1020,7 @@ TRACE_EVENT(rdev_assoc,
1002 __entry->use_mfp = req->use_mfp; 1020 __entry->use_mfp = req->use_mfp;
1003 __entry->flags = req->flags; 1021 __entry->flags = req->flags;
1004 ), 1022 ),
1005 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT 1023 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
1006 ", previous bssid: " MAC_PR_FMT ", use mfp: %s, flags: %u", 1024 ", previous bssid: " MAC_PR_FMT ", use mfp: %s, flags: %u",
1007 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), 1025 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid),
1008 MAC_PR_ARG(prev_bssid), BOOL_TO_STR(__entry->use_mfp), 1026 MAC_PR_ARG(prev_bssid), BOOL_TO_STR(__entry->use_mfp),
@@ -1025,7 +1043,7 @@ TRACE_EVENT(rdev_deauth,
1025 MAC_ASSIGN(bssid, req->bssid); 1043 MAC_ASSIGN(bssid, req->bssid);
1026 __entry->reason_code = req->reason_code; 1044 __entry->reason_code = req->reason_code;
1027 ), 1045 ),
1028 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", reason: %u", 1046 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", reason: %u",
1029 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), 1047 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid),
1030 __entry->reason_code) 1048 __entry->reason_code)
1031); 1049);
@@ -1051,7 +1069,7 @@ TRACE_EVENT(rdev_disassoc,
1051 __entry->reason_code = req->reason_code; 1069 __entry->reason_code = req->reason_code;
1052 __entry->local_state_change = req->local_state_change; 1070 __entry->local_state_change = req->local_state_change;
1053 ), 1071 ),
1054 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT 1072 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
1055 ", reason: %u, local state change: %s", 1073 ", reason: %u, local state change: %s",
1056 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), 1074 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid),
1057 __entry->reason_code, 1075 __entry->reason_code,
@@ -1072,7 +1090,7 @@ TRACE_EVENT(rdev_mgmt_tx_cancel_wait,
1072 WDEV_ASSIGN; 1090 WDEV_ASSIGN;
1073 __entry->cookie = cookie; 1091 __entry->cookie = cookie;
1074 ), 1092 ),
1075 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", cookie: %llu ", 1093 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", cookie: %llu ",
1076 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie) 1094 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie)
1077); 1095);
1078 1096
@@ -1092,7 +1110,7 @@ TRACE_EVENT(rdev_set_power_mgmt,
1092 __entry->enabled = enabled; 1110 __entry->enabled = enabled;
1093 __entry->timeout = timeout; 1111 __entry->timeout = timeout;
1094 ), 1112 ),
1095 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", %senabled, timeout: %d ", 1113 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", %senabled, timeout: %d ",
1096 WIPHY_PR_ARG, NETDEV_PR_ARG, 1114 WIPHY_PR_ARG, NETDEV_PR_ARG,
1097 __entry->enabled ? "" : "not ", __entry->timeout) 1115 __entry->enabled ? "" : "not ", __entry->timeout)
1098); 1116);
@@ -1122,7 +1140,7 @@ TRACE_EVENT(rdev_connect,
1122 __entry->wpa_versions = sme->crypto.wpa_versions; 1140 __entry->wpa_versions = sme->crypto.wpa_versions;
1123 __entry->flags = sme->flags; 1141 __entry->flags = sme->flags;
1124 ), 1142 ),
1125 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT 1143 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
1126 ", ssid: %s, auth type: %d, privacy: %s, wpa versions: %u, " 1144 ", ssid: %s, auth type: %d, privacy: %s, wpa versions: %u, "
1127 "flags: %u", 1145 "flags: %u",
1128 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid, 1146 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid,
@@ -1147,7 +1165,7 @@ TRACE_EVENT(rdev_set_cqm_rssi_config,
1147 __entry->rssi_thold = rssi_thold; 1165 __entry->rssi_thold = rssi_thold;
1148 __entry->rssi_hyst = rssi_hyst; 1166 __entry->rssi_hyst = rssi_hyst;
1149 ), 1167 ),
1150 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT 1168 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT
1151 ", rssi_thold: %d, rssi_hyst: %u ", 1169 ", rssi_thold: %d, rssi_hyst: %u ",
1152 WIPHY_PR_ARG, NETDEV_PR_ARG, 1170 WIPHY_PR_ARG, NETDEV_PR_ARG,
1153 __entry->rssi_thold, __entry->rssi_hyst) 1171 __entry->rssi_thold, __entry->rssi_hyst)
@@ -1171,7 +1189,7 @@ TRACE_EVENT(rdev_set_cqm_txe_config,
1171 __entry->pkts = pkts; 1189 __entry->pkts = pkts;
1172 __entry->intvl = intvl; 1190 __entry->intvl = intvl;
1173 ), 1191 ),
1174 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", rate: %u, packets: %u, interval: %u", 1192 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", rate: %u, packets: %u, interval: %u",
1175 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->rate, __entry->pkts, 1193 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->rate, __entry->pkts,
1176 __entry->intvl) 1194 __entry->intvl)
1177); 1195);
@@ -1190,7 +1208,7 @@ TRACE_EVENT(rdev_disconnect,
1190 NETDEV_ASSIGN; 1208 NETDEV_ASSIGN;
1191 __entry->reason_code = reason_code; 1209 __entry->reason_code = reason_code;
1192 ), 1210 ),
1193 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", reason code: %u", WIPHY_PR_ARG, 1211 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", reason code: %u", WIPHY_PR_ARG,
1194 NETDEV_PR_ARG, __entry->reason_code) 1212 NETDEV_PR_ARG, __entry->reason_code)
1195); 1213);
1196 1214
@@ -1211,7 +1229,7 @@ TRACE_EVENT(rdev_join_ibss,
1211 memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); 1229 memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
1212 memcpy(__entry->ssid, params->ssid, params->ssid_len); 1230 memcpy(__entry->ssid, params->ssid, params->ssid_len);
1213 ), 1231 ),
1214 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", ssid: %s", 1232 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", ssid: %s",
1215 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid) 1233 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid)
1216); 1234);
1217 1235
@@ -1230,22 +1248,29 @@ TRACE_EVENT(rdev_set_wiphy_params,
1230 WIPHY_PR_ARG, __entry->changed) 1248 WIPHY_PR_ARG, __entry->changed)
1231); 1249);
1232 1250
1251DEFINE_EVENT(wiphy_wdev_evt, rdev_get_tx_power,
1252 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
1253 TP_ARGS(wiphy, wdev)
1254);
1255
1233TRACE_EVENT(rdev_set_tx_power, 1256TRACE_EVENT(rdev_set_tx_power,
1234 TP_PROTO(struct wiphy *wiphy, enum nl80211_tx_power_setting type, 1257 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
1235 int mbm), 1258 enum nl80211_tx_power_setting type, int mbm),
1236 TP_ARGS(wiphy, type, mbm), 1259 TP_ARGS(wiphy, wdev, type, mbm),
1237 TP_STRUCT__entry( 1260 TP_STRUCT__entry(
1238 WIPHY_ENTRY 1261 WIPHY_ENTRY
1262 WDEV_ENTRY
1239 __field(enum nl80211_tx_power_setting, type) 1263 __field(enum nl80211_tx_power_setting, type)
1240 __field(int, mbm) 1264 __field(int, mbm)
1241 ), 1265 ),
1242 TP_fast_assign( 1266 TP_fast_assign(
1243 WIPHY_ASSIGN; 1267 WIPHY_ASSIGN;
1268 WDEV_ASSIGN;
1244 __entry->type = type; 1269 __entry->type = type;
1245 __entry->mbm = mbm; 1270 __entry->mbm = mbm;
1246 ), 1271 ),
1247 TP_printk(WIPHY_PR_FMT ", type: %d, mbm: %d", 1272 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", type: %u, mbm: %d",
1248 WIPHY_PR_ARG, __entry->type, __entry->mbm) 1273 WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm)
1249); 1274);
1250 1275
1251TRACE_EVENT(rdev_return_int_int, 1276TRACE_EVENT(rdev_return_int_int,
@@ -1305,7 +1330,7 @@ TRACE_EVENT(rdev_set_bitrate_mask,
1305 NETDEV_ASSIGN; 1330 NETDEV_ASSIGN;
1306 MAC_ASSIGN(peer, peer); 1331 MAC_ASSIGN(peer, peer);
1307 ), 1332 ),
1308 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", peer: " MAC_PR_FMT, 1333 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT,
1309 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer)) 1334 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
1310); 1335);
1311 1336
@@ -1325,7 +1350,7 @@ TRACE_EVENT(rdev_mgmt_frame_register,
1325 __entry->frame_type = frame_type; 1350 __entry->frame_type = frame_type;
1326 __entry->reg = reg; 1351 __entry->reg = reg;
1327 ), 1352 ),
1328 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", frame_type: %u, reg: %s ", 1353 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", frame_type: 0x%.2x, reg: %s ",
1329 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->frame_type, 1354 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->frame_type,
1330 __entry->reg ? "true" : "false") 1355 __entry->reg ? "true" : "false")
1331); 1356);
@@ -1411,7 +1436,7 @@ TRACE_EVENT(rdev_sched_scan_start,
1411 WIPHY_ASSIGN; 1436 WIPHY_ASSIGN;
1412 NETDEV_ASSIGN; 1437 NETDEV_ASSIGN;
1413 ), 1438 ),
1414 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, 1439 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
1415 WIPHY_PR_ARG, NETDEV_PR_ARG) 1440 WIPHY_PR_ARG, NETDEV_PR_ARG)
1416); 1441);
1417 1442
@@ -1439,7 +1464,7 @@ TRACE_EVENT(rdev_tdls_mgmt,
1439 __entry->status_code = status_code; 1464 __entry->status_code = status_code;
1440 memcpy(__get_dynamic_array(buf), buf, len); 1465 memcpy(__get_dynamic_array(buf), buf, len);
1441 ), 1466 ),
1442 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT ", action_code: %u, " 1467 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, "
1443 "dialog_token: %u, status_code: %u, buf: %#.2x ", 1468 "dialog_token: %u, status_code: %u, buf: %#.2x ",
1444 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), 1469 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
1445 __entry->action_code, __entry->dialog_token, 1470 __entry->action_code, __entry->dialog_token,
@@ -1459,7 +1484,7 @@ TRACE_EVENT(rdev_dump_survey,
1459 NETDEV_ASSIGN; 1484 NETDEV_ASSIGN;
1460 __entry->idx = idx; 1485 __entry->idx = idx;
1461 ), 1486 ),
1462 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", index: %d", 1487 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d",
1463 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx) 1488 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx)
1464); 1489);
1465 1490
@@ -1516,7 +1541,7 @@ TRACE_EVENT(rdev_tdls_oper,
1516 MAC_ASSIGN(peer, peer); 1541 MAC_ASSIGN(peer, peer);
1517 __entry->oper = oper; 1542 __entry->oper = oper;
1518 ), 1543 ),
1519 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT ", oper: %d", 1544 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", oper: %d",
1520 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->oper) 1545 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->oper)
1521); 1546);
1522 1547
@@ -1534,7 +1559,7 @@ DECLARE_EVENT_CLASS(rdev_pmksa,
1534 NETDEV_ASSIGN; 1559 NETDEV_ASSIGN;
1535 MAC_ASSIGN(bssid, pmksa->bssid); 1560 MAC_ASSIGN(bssid, pmksa->bssid);
1536 ), 1561 ),
1537 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT, 1562 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT,
1538 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid)) 1563 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid))
1539); 1564);
1540 1565
@@ -1552,7 +1577,7 @@ TRACE_EVENT(rdev_probe_client,
1552 NETDEV_ASSIGN; 1577 NETDEV_ASSIGN;
1553 MAC_ASSIGN(peer, peer); 1578 MAC_ASSIGN(peer, peer);
1554 ), 1579 ),
1555 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT, 1580 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT,
1556 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer)) 1581 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
1557); 1582);
1558 1583
@@ -1571,25 +1596,22 @@ DEFINE_EVENT(rdev_pmksa, rdev_del_pmksa,
1571TRACE_EVENT(rdev_remain_on_channel, 1596TRACE_EVENT(rdev_remain_on_channel,
1572 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, 1597 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
1573 struct ieee80211_channel *chan, 1598 struct ieee80211_channel *chan,
1574 enum nl80211_channel_type channel_type, unsigned int duration), 1599 unsigned int duration),
1575 TP_ARGS(wiphy, wdev, chan, channel_type, duration), 1600 TP_ARGS(wiphy, wdev, chan, duration),
1576 TP_STRUCT__entry( 1601 TP_STRUCT__entry(
1577 WIPHY_ENTRY 1602 WIPHY_ENTRY
1578 WDEV_ENTRY 1603 WDEV_ENTRY
1579 CHAN_ENTRY 1604 CHAN_ENTRY
1580 __field(enum nl80211_channel_type, channel_type)
1581 __field(unsigned int, duration) 1605 __field(unsigned int, duration)
1582 ), 1606 ),
1583 TP_fast_assign( 1607 TP_fast_assign(
1584 WIPHY_ASSIGN; 1608 WIPHY_ASSIGN;
1585 WDEV_ASSIGN; 1609 WDEV_ASSIGN;
1586 CHAN_ASSIGN(chan); 1610 CHAN_ASSIGN(chan);
1587 __entry->channel_type = channel_type;
1588 __entry->duration = duration; 1611 __entry->duration = duration;
1589 ), 1612 ),
1590 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT CHAN_PR_FMT ", channel type: %d, duration: %u", 1613 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", duration: %u",
1591 WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, __entry->channel_type, 1614 WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, __entry->duration)
1592 __entry->duration)
1593); 1615);
1594 1616
1595TRACE_EVENT(rdev_return_int_cookie, 1617TRACE_EVENT(rdev_return_int_cookie,
@@ -1622,25 +1644,20 @@ TRACE_EVENT(rdev_cancel_remain_on_channel,
1622 WDEV_ASSIGN; 1644 WDEV_ASSIGN;
1623 __entry->cookie = cookie; 1645 __entry->cookie = cookie;
1624 ), 1646 ),
1625 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", cookie: %llu", 1647 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", cookie: %llu",
1626 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie) 1648 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie)
1627); 1649);
1628 1650
1629TRACE_EVENT(rdev_mgmt_tx, 1651TRACE_EVENT(rdev_mgmt_tx,
1630 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, 1652 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
1631 struct ieee80211_channel *chan, bool offchan, 1653 struct ieee80211_channel *chan, bool offchan,
1632 enum nl80211_channel_type channel_type, 1654 unsigned int wait, bool no_cck, bool dont_wait_for_ack),
1633 bool channel_type_valid, unsigned int wait, bool no_cck, 1655 TP_ARGS(wiphy, wdev, chan, offchan, wait, no_cck, dont_wait_for_ack),
1634 bool dont_wait_for_ack),
1635 TP_ARGS(wiphy, wdev, chan, offchan, channel_type, channel_type_valid,
1636 wait, no_cck, dont_wait_for_ack),
1637 TP_STRUCT__entry( 1656 TP_STRUCT__entry(
1638 WIPHY_ENTRY 1657 WIPHY_ENTRY
1639 WDEV_ENTRY 1658 WDEV_ENTRY
1640 CHAN_ENTRY 1659 CHAN_ENTRY
1641 __field(bool, offchan) 1660 __field(bool, offchan)
1642 __field(enum nl80211_channel_type, channel_type)
1643 __field(bool, channel_type_valid)
1644 __field(unsigned int, wait) 1661 __field(unsigned int, wait)
1645 __field(bool, no_cck) 1662 __field(bool, no_cck)
1646 __field(bool, dont_wait_for_ack) 1663 __field(bool, dont_wait_for_ack)
@@ -1650,18 +1667,14 @@ TRACE_EVENT(rdev_mgmt_tx,
1650 WDEV_ASSIGN; 1667 WDEV_ASSIGN;
1651 CHAN_ASSIGN(chan); 1668 CHAN_ASSIGN(chan);
1652 __entry->offchan = offchan; 1669 __entry->offchan = offchan;
1653 __entry->channel_type = channel_type;
1654 __entry->channel_type_valid = channel_type_valid;
1655 __entry->wait = wait; 1670 __entry->wait = wait;
1656 __entry->no_cck = no_cck; 1671 __entry->no_cck = no_cck;
1657 __entry->dont_wait_for_ack = dont_wait_for_ack; 1672 __entry->dont_wait_for_ack = dont_wait_for_ack;
1658 ), 1673 ),
1659 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT CHAN_PR_FMT ", offchan: %s, " 1674 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s,"
1660 "channel type: %d, channel type valid: %s, wait: %u, " 1675 " wait: %u, no cck: %s, dont wait for ack: %s",
1661 "no cck: %s, dont wait for ack: %s",
1662 WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, 1676 WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG,
1663 BOOL_TO_STR(__entry->offchan), __entry->channel_type, 1677 BOOL_TO_STR(__entry->offchan), __entry->wait,
1664 BOOL_TO_STR(__entry->channel_type_valid), __entry->wait,
1665 BOOL_TO_STR(__entry->no_cck), 1678 BOOL_TO_STR(__entry->no_cck),
1666 BOOL_TO_STR(__entry->dont_wait_for_ack)) 1679 BOOL_TO_STR(__entry->dont_wait_for_ack))
1667); 1680);
@@ -1680,7 +1693,7 @@ TRACE_EVENT(rdev_set_noack_map,
1680 NETDEV_ASSIGN; 1693 NETDEV_ASSIGN;
1681 __entry->noack_map = noack_map; 1694 __entry->noack_map = noack_map;
1682 ), 1695 ),
1683 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", noack_map: %u", 1696 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", noack_map: %u",
1684 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map) 1697 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map)
1685); 1698);
1686 1699
@@ -1697,7 +1710,7 @@ TRACE_EVENT(rdev_get_et_sset_count,
1697 NETDEV_ASSIGN; 1710 NETDEV_ASSIGN;
1698 __entry->sset = sset; 1711 __entry->sset = sset;
1699 ), 1712 ),
1700 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", sset: %d", 1713 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %d",
1701 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) 1714 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
1702); 1715);
1703 1716
@@ -1714,7 +1727,7 @@ TRACE_EVENT(rdev_get_et_strings,
1714 NETDEV_ASSIGN; 1727 NETDEV_ASSIGN;
1715 __entry->sset = sset; 1728 __entry->sset = sset;
1716 ), 1729 ),
1717 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", sset: %u", 1730 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %u",
1718 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) 1731 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
1719); 1732);
1720 1733
@@ -1723,22 +1736,25 @@ DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel,
1723 TP_ARGS(wiphy, wdev) 1736 TP_ARGS(wiphy, wdev)
1724); 1737);
1725 1738
1726TRACE_EVENT(rdev_return_channel, 1739TRACE_EVENT(rdev_return_chandef,
1727 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan, 1740 TP_PROTO(struct wiphy *wiphy, int ret,
1728 enum nl80211_channel_type type), 1741 struct cfg80211_chan_def *chandef),
1729 TP_ARGS(wiphy, chan, type), 1742 TP_ARGS(wiphy, ret, chandef),
1730 TP_STRUCT__entry( 1743 TP_STRUCT__entry(
1731 WIPHY_ENTRY 1744 WIPHY_ENTRY
1732 CHAN_ENTRY 1745 __field(int, ret)
1733 __field(enum nl80211_channel_type, type) 1746 CHAN_DEF_ENTRY
1734 ), 1747 ),
1735 TP_fast_assign( 1748 TP_fast_assign(
1736 WIPHY_ASSIGN; 1749 WIPHY_ASSIGN;
1737 CHAN_ASSIGN(chan); 1750 if (ret == 0)
1738 __entry->type = type; 1751 CHAN_DEF_ASSIGN(chandef);
1752 else
1753 CHAN_DEF_ASSIGN((struct cfg80211_chan_def *)NULL);
1754 __entry->ret = ret;
1739 ), 1755 ),
1740 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type: %d", 1756 TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", ret: %d",
1741 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->type) 1757 WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->ret)
1742); 1758);
1743 1759
1744DEFINE_EVENT(wiphy_wdev_evt, rdev_start_p2p_device, 1760DEFINE_EVENT(wiphy_wdev_evt, rdev_start_p2p_device,
@@ -1817,7 +1833,7 @@ TRACE_EVENT(cfg80211_send_rx_assoc,
1817 MAC_ASSIGN(bssid, bss->bssid); 1833 MAC_ASSIGN(bssid, bss->bssid);
1818 CHAN_ASSIGN(bss->channel); 1834 CHAN_ASSIGN(bss->channel);
1819 ), 1835 ),
1820 TP_printk(NETDEV_PR_FMT MAC_PR_FMT CHAN_PR_FMT, 1836 TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", " CHAN_PR_FMT,
1821 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) 1837 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
1822); 1838);
1823 1839
@@ -1884,7 +1900,7 @@ TRACE_EVENT(cfg80211_michael_mic_failure,
1884 __entry->key_id = key_id; 1900 __entry->key_id = key_id;
1885 memcpy(__entry->tsc, tsc, 6); 1901 memcpy(__entry->tsc, tsc, 6);
1886 ), 1902 ),
1887 TP_printk(NETDEV_PR_FMT MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm", 1903 TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm",
1888 NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type, 1904 NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type,
1889 __entry->key_id, __entry->tsc) 1905 __entry->key_id, __entry->tsc)
1890); 1906);
@@ -1892,47 +1908,41 @@ TRACE_EVENT(cfg80211_michael_mic_failure,
1892TRACE_EVENT(cfg80211_ready_on_channel, 1908TRACE_EVENT(cfg80211_ready_on_channel,
1893 TP_PROTO(struct wireless_dev *wdev, u64 cookie, 1909 TP_PROTO(struct wireless_dev *wdev, u64 cookie,
1894 struct ieee80211_channel *chan, 1910 struct ieee80211_channel *chan,
1895 enum nl80211_channel_type channel_type, unsigned int duration), 1911 unsigned int duration),
1896 TP_ARGS(wdev, cookie, chan, channel_type, duration), 1912 TP_ARGS(wdev, cookie, chan, duration),
1897 TP_STRUCT__entry( 1913 TP_STRUCT__entry(
1898 WDEV_ENTRY 1914 WDEV_ENTRY
1899 __field(u64, cookie) 1915 __field(u64, cookie)
1900 CHAN_ENTRY 1916 CHAN_ENTRY
1901 __field(enum nl80211_channel_type, channel_type)
1902 __field(unsigned int, duration) 1917 __field(unsigned int, duration)
1903 ), 1918 ),
1904 TP_fast_assign( 1919 TP_fast_assign(
1905 WDEV_ASSIGN; 1920 WDEV_ASSIGN;
1906 __entry->cookie = cookie; 1921 __entry->cookie = cookie;
1907 CHAN_ASSIGN(chan); 1922 CHAN_ASSIGN(chan);
1908 __entry->channel_type = channel_type;
1909 __entry->duration = duration; 1923 __entry->duration = duration;
1910 ), 1924 ),
1911 TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", channel type: %d, duration: %u", 1925 TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", duration: %u",
1912 WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG, 1926 WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG,
1913 __entry->channel_type, __entry->duration) 1927 __entry->duration)
1914); 1928);
1915 1929
1916TRACE_EVENT(cfg80211_ready_on_channel_expired, 1930TRACE_EVENT(cfg80211_ready_on_channel_expired,
1917 TP_PROTO(struct wireless_dev *wdev, u64 cookie, 1931 TP_PROTO(struct wireless_dev *wdev, u64 cookie,
1918 struct ieee80211_channel *chan, 1932 struct ieee80211_channel *chan),
1919 enum nl80211_channel_type channel_type), 1933 TP_ARGS(wdev, cookie, chan),
1920 TP_ARGS(wdev, cookie, chan, channel_type),
1921 TP_STRUCT__entry( 1934 TP_STRUCT__entry(
1922 WDEV_ENTRY 1935 WDEV_ENTRY
1923 __field(u64, cookie) 1936 __field(u64, cookie)
1924 CHAN_ENTRY 1937 CHAN_ENTRY
1925 __field(enum nl80211_channel_type, channel_type)
1926 ), 1938 ),
1927 TP_fast_assign( 1939 TP_fast_assign(
1928 WDEV_ASSIGN; 1940 WDEV_ASSIGN;
1929 __entry->cookie = cookie; 1941 __entry->cookie = cookie;
1930 CHAN_ASSIGN(chan); 1942 CHAN_ASSIGN(chan);
1931 __entry->channel_type = channel_type;
1932 ), 1943 ),
1933 TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", channel type: %d", 1944 TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT,
1934 WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG, 1945 WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG)
1935 __entry->channel_type)
1936); 1946);
1937 1947
1938TRACE_EVENT(cfg80211_new_sta, 1948TRACE_EVENT(cfg80211_new_sta,
@@ -1949,7 +1959,7 @@ TRACE_EVENT(cfg80211_new_sta,
1949 MAC_ASSIGN(mac_addr, mac_addr); 1959 MAC_ASSIGN(mac_addr, mac_addr);
1950 SINFO_ASSIGN; 1960 SINFO_ASSIGN;
1951 ), 1961 ),
1952 TP_printk(NETDEV_PR_FMT MAC_PR_FMT, 1962 TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT,
1953 NETDEV_PR_ARG, MAC_PR_ARG(mac_addr)) 1963 NETDEV_PR_ARG, MAC_PR_ARG(mac_addr))
1954); 1964);
1955 1965
@@ -2008,40 +2018,35 @@ TRACE_EVENT(cfg80211_cqm_rssi_notify,
2008 NETDEV_PR_ARG, __entry->rssi_event) 2018 NETDEV_PR_ARG, __entry->rssi_event)
2009); 2019);
2010 2020
2011TRACE_EVENT(cfg80211_can_beacon_sec_chan, 2021TRACE_EVENT(cfg80211_reg_can_beacon,
2012 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, 2022 TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
2013 enum nl80211_channel_type channel_type), 2023 TP_ARGS(wiphy, chandef),
2014 TP_ARGS(wiphy, channel, channel_type),
2015 TP_STRUCT__entry( 2024 TP_STRUCT__entry(
2016 WIPHY_ENTRY 2025 WIPHY_ENTRY
2017 CHAN_ENTRY 2026 CHAN_DEF_ENTRY
2018 __field(enum nl80211_channel_type, channel_type)
2019 ), 2027 ),
2020 TP_fast_assign( 2028 TP_fast_assign(
2021 WIPHY_ASSIGN; 2029 WIPHY_ASSIGN;
2022 CHAN_ASSIGN(channel); 2030 CHAN_DEF_ASSIGN(chandef);
2023 __entry->channel_type = channel_type;
2024 ), 2031 ),
2025 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel_type: %d", 2032 TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
2026 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->channel_type) 2033 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
2027); 2034);
2028 2035
2029TRACE_EVENT(cfg80211_ch_switch_notify, 2036TRACE_EVENT(cfg80211_ch_switch_notify,
2030 TP_PROTO(struct net_device *netdev, int freq, 2037 TP_PROTO(struct net_device *netdev,
2031 enum nl80211_channel_type type), 2038 struct cfg80211_chan_def *chandef),
2032 TP_ARGS(netdev, freq, type), 2039 TP_ARGS(netdev, chandef),
2033 TP_STRUCT__entry( 2040 TP_STRUCT__entry(
2034 NETDEV_ENTRY 2041 NETDEV_ENTRY
2035 __field(int, freq) 2042 CHAN_DEF_ENTRY
2036 __field(enum nl80211_channel_type, type)
2037 ), 2043 ),
2038 TP_fast_assign( 2044 TP_fast_assign(
2039 NETDEV_ASSIGN; 2045 NETDEV_ASSIGN;
2040 __entry->freq = freq; 2046 CHAN_DEF_ASSIGN(chandef);
2041 __entry->type = type;
2042 ), 2047 ),
2043 TP_printk(NETDEV_PR_FMT ", freq: %d, type: %d", NETDEV_PR_ARG, 2048 TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT,
2044 __entry->freq, __entry->type) 2049 NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
2045); 2050);
2046 2051
2047DECLARE_EVENT_CLASS(cfg80211_rx_evt, 2052DECLARE_EVENT_CLASS(cfg80211_rx_evt,
@@ -2055,7 +2060,7 @@ DECLARE_EVENT_CLASS(cfg80211_rx_evt,
2055 NETDEV_ASSIGN; 2060 NETDEV_ASSIGN;
2056 MAC_ASSIGN(addr, addr); 2061 MAC_ASSIGN(addr, addr);
2057 ), 2062 ),
2058 TP_printk(NETDEV_PR_FMT MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr)) 2063 TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr))
2059); 2064);
2060 2065
2061DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined, 2066DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
@@ -2089,7 +2094,7 @@ TRACE_EVENT(cfg80211_probe_status,
2089 __entry->cookie = cookie; 2094 __entry->cookie = cookie;
2090 __entry->acked = acked; 2095 __entry->acked = acked;
2091 ), 2096 ),
2092 TP_printk(NETDEV_PR_FMT MAC_PR_FMT ", cookie: %llu, acked: %s", 2097 TP_printk(NETDEV_PR_FMT " addr:" MAC_PR_FMT ", cookie: %llu, acked: %s",
2093 NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->cookie, 2098 NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->cookie,
2094 BOOL_TO_STR(__entry->acked)) 2099 BOOL_TO_STR(__entry->acked))
2095); 2100);
@@ -2155,6 +2160,29 @@ TRACE_EVENT(cfg80211_report_obss_beacon,
2155 WIPHY_PR_ARG, __entry->freq, __entry->sig_dbm) 2160 WIPHY_PR_ARG, __entry->freq, __entry->sig_dbm)
2156); 2161);
2157 2162
2163TRACE_EVENT(cfg80211_tdls_oper_request,
2164 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *peer,
2165 enum nl80211_tdls_operation oper, u16 reason_code),
2166 TP_ARGS(wiphy, netdev, peer, oper, reason_code),
2167 TP_STRUCT__entry(
2168 WIPHY_ENTRY
2169 NETDEV_ENTRY
2170 MAC_ENTRY(peer)
2171 __field(enum nl80211_tdls_operation, oper)
2172 __field(u16, reason_code)
2173 ),
2174 TP_fast_assign(
2175 WIPHY_ASSIGN;
2176 NETDEV_ASSIGN;
2177 MAC_ASSIGN(peer, peer);
2178 __entry->oper = oper;
2179 __entry->reason_code = reason_code;
2180 ),
2181 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", oper: %d, reason_code %u",
2182 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->oper,
2183 __entry->reason_code)
2184 );
2185
2158TRACE_EVENT(cfg80211_scan_done, 2186TRACE_EVENT(cfg80211_scan_done,
2159 TP_PROTO(struct cfg80211_scan_request *request, bool aborted), 2187 TP_PROTO(struct cfg80211_scan_request *request, bool aborted),
2160 TP_ARGS(request, aborted), 2188 TP_ARGS(request, aborted),
@@ -2216,7 +2244,7 @@ TRACE_EVENT(cfg80211_get_bss,
2216 __entry->capa_mask = capa_mask; 2244 __entry->capa_mask = capa_mask;
2217 __entry->capa_val = capa_val; 2245 __entry->capa_val = capa_val;
2218 ), 2246 ),
2219 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT MAC_PR_FMT ", buf: %#.2x, " 2247 TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT ", " MAC_PR_FMT ", buf: %#.2x, "
2220 "capa_mask: %d, capa_val: %u", WIPHY_PR_ARG, CHAN_PR_ARG, 2248 "capa_mask: %d, capa_val: %u", WIPHY_PR_ARG, CHAN_PR_ARG,
2221 MAC_PR_ARG(bssid), ((u8 *)__get_dynamic_array(ssid))[0], 2249 MAC_PR_ARG(bssid), ((u8 *)__get_dynamic_array(ssid))[0],
2222 __entry->capa_mask, __entry->capa_val) 2250 __entry->capa_mask, __entry->capa_val)
@@ -2240,7 +2268,7 @@ TRACE_EVENT(cfg80211_inform_bss_frame,
2240 memcpy(__get_dynamic_array(mgmt), mgmt, len); 2268 memcpy(__get_dynamic_array(mgmt), mgmt, len);
2241 __entry->signal = signal; 2269 __entry->signal = signal;
2242 ), 2270 ),
2243 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT "signal: %d", 2271 TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT "signal: %d",
2244 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->signal) 2272 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->signal)
2245); 2273);
2246 2274
@@ -2255,7 +2283,7 @@ DECLARE_EVENT_CLASS(cfg80211_bss_evt,
2255 MAC_ASSIGN(bssid, pub->bssid); 2283 MAC_ASSIGN(bssid, pub->bssid);
2256 CHAN_ASSIGN(pub->channel); 2284 CHAN_ASSIGN(pub->channel);
2257 ), 2285 ),
2258 TP_printk(MAC_PR_FMT CHAN_PR_FMT, MAC_PR_ARG(bssid), CHAN_PR_ARG) 2286 TP_printk(MAC_PR_FMT ", " CHAN_PR_FMT, MAC_PR_ARG(bssid), CHAN_PR_ARG)
2259); 2287);
2260 2288
2261DEFINE_EVENT(cfg80211_bss_evt, cfg80211_return_bss, 2289DEFINE_EVENT(cfg80211_bss_evt, cfg80211_return_bss,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 5b6c1df72f3..3cce6e48621 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -944,14 +944,86 @@ static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate)
944 return __mcs2bitrate[rate->mcs]; 944 return __mcs2bitrate[rate->mcs];
945} 945}
946 946
947static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
948{
949 static const u32 base[4][10] = {
950 { 6500000,
951 13000000,
952 19500000,
953 26000000,
954 39000000,
955 52000000,
956 58500000,
957 65000000,
958 78000000,
959 0,
960 },
961 { 13500000,
962 27000000,
963 40500000,
964 54000000,
965 81000000,
966 108000000,
967 121500000,
968 135000000,
969 162000000,
970 180000000,
971 },
972 { 29300000,
973 58500000,
974 87800000,
975 117000000,
976 175500000,
977 234000000,
978 263300000,
979 292500000,
980 351000000,
981 390000000,
982 },
983 { 58500000,
984 117000000,
985 175500000,
986 234000000,
987 351000000,
988 468000000,
989 526500000,
990 585000000,
991 702000000,
992 780000000,
993 },
994 };
995 u32 bitrate;
996 int idx;
997
998 if (WARN_ON_ONCE(rate->mcs > 9))
999 return 0;
1000
1001 idx = rate->flags & (RATE_INFO_FLAGS_160_MHZ_WIDTH |
1002 RATE_INFO_FLAGS_80P80_MHZ_WIDTH) ? 3 :
1003 rate->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH ? 2 :
1004 rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH ? 1 : 0;
1005
1006 bitrate = base[idx][rate->mcs];
1007 bitrate *= rate->nss;
1008
1009 if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
1010 bitrate = (bitrate / 9) * 10;
1011
1012 /* do NOT round down here */
1013 return (bitrate + 50000) / 100000;
1014}
1015
947u32 cfg80211_calculate_bitrate(struct rate_info *rate) 1016u32 cfg80211_calculate_bitrate(struct rate_info *rate)
948{ 1017{
949 int modulation, streams, bitrate; 1018 int modulation, streams, bitrate;
950 1019
951 if (!(rate->flags & RATE_INFO_FLAGS_MCS)) 1020 if (!(rate->flags & RATE_INFO_FLAGS_MCS) &&
1021 !(rate->flags & RATE_INFO_FLAGS_VHT_MCS))
952 return rate->legacy; 1022 return rate->legacy;
953 if (rate->flags & RATE_INFO_FLAGS_60G) 1023 if (rate->flags & RATE_INFO_FLAGS_60G)
954 return cfg80211_calculate_bitrate_60g(rate); 1024 return cfg80211_calculate_bitrate_60g(rate);
1025 if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
1026 return cfg80211_calculate_bitrate_vht(rate);
955 1027
956 /* the formula below does only work for MCS values smaller than 32 */ 1028 /* the formula below does only work for MCS values smaller than 32 */
957 if (WARN_ON_ONCE(rate->mcs >= 32)) 1029 if (WARN_ON_ONCE(rate->mcs >= 32))
@@ -980,6 +1052,106 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
980} 1052}
981EXPORT_SYMBOL(cfg80211_calculate_bitrate); 1053EXPORT_SYMBOL(cfg80211_calculate_bitrate);
982 1054
1055int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
1056 enum ieee80211_p2p_attr_id attr,
1057 u8 *buf, unsigned int bufsize)
1058{
1059 u8 *out = buf;
1060 u16 attr_remaining = 0;
1061 bool desired_attr = false;
1062 u16 desired_len = 0;
1063
1064 while (len > 0) {
1065 unsigned int iedatalen;
1066 unsigned int copy;
1067 const u8 *iedata;
1068
1069 if (len < 2)
1070 return -EILSEQ;
1071 iedatalen = ies[1];
1072 if (iedatalen + 2 > len)
1073 return -EILSEQ;
1074
1075 if (ies[0] != WLAN_EID_VENDOR_SPECIFIC)
1076 goto cont;
1077
1078 if (iedatalen < 4)
1079 goto cont;
1080
1081 iedata = ies + 2;
1082
1083 /* check WFA OUI, P2P subtype */
1084 if (iedata[0] != 0x50 || iedata[1] != 0x6f ||
1085 iedata[2] != 0x9a || iedata[3] != 0x09)
1086 goto cont;
1087
1088 iedatalen -= 4;
1089 iedata += 4;
1090
1091 /* check attribute continuation into this IE */
1092 copy = min_t(unsigned int, attr_remaining, iedatalen);
1093 if (copy && desired_attr) {
1094 desired_len += copy;
1095 if (out) {
1096 memcpy(out, iedata, min(bufsize, copy));
1097 out += min(bufsize, copy);
1098 bufsize -= min(bufsize, copy);
1099 }
1100
1101
1102 if (copy == attr_remaining)
1103 return desired_len;
1104 }
1105
1106 attr_remaining -= copy;
1107 if (attr_remaining)
1108 goto cont;
1109
1110 iedatalen -= copy;
1111 iedata += copy;
1112
1113 while (iedatalen > 0) {
1114 u16 attr_len;
1115
1116 /* P2P attribute ID & size must fit */
1117 if (iedatalen < 3)
1118 return -EILSEQ;
1119 desired_attr = iedata[0] == attr;
1120 attr_len = get_unaligned_le16(iedata + 1);
1121 iedatalen -= 3;
1122 iedata += 3;
1123
1124 copy = min_t(unsigned int, attr_len, iedatalen);
1125
1126 if (desired_attr) {
1127 desired_len += copy;
1128 if (out) {
1129 memcpy(out, iedata, min(bufsize, copy));
1130 out += min(bufsize, copy);
1131 bufsize -= min(bufsize, copy);
1132 }
1133
1134 if (copy == attr_len)
1135 return desired_len;
1136 }
1137
1138 iedata += copy;
1139 iedatalen -= copy;
1140 attr_remaining = attr_len - copy;
1141 }
1142
1143 cont:
1144 len -= ies[1] + 2;
1145 ies += ies[1] + 2;
1146 }
1147
1148 if (attr_remaining && desired_attr)
1149 return -EILSEQ;
1150
1151 return -ENOENT;
1152}
1153EXPORT_SYMBOL(cfg80211_get_p2p_attr);
1154
983int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, 1155int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
984 u32 beacon_int) 1156 u32 beacon_int)
985{ 1157{
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 6488d2dbc1d..f9680c9cf9b 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -784,6 +784,9 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
784{ 784{
785 struct wireless_dev *wdev = dev->ieee80211_ptr; 785 struct wireless_dev *wdev = dev->ieee80211_ptr;
786 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 786 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
787 struct cfg80211_chan_def chandef = {
788 .width = NL80211_CHAN_WIDTH_20_NOHT,
789 };
787 int freq, err; 790 int freq, err;
788 791
789 switch (wdev->iftype) { 792 switch (wdev->iftype) {
@@ -797,8 +800,12 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
797 return freq; 800 return freq;
798 if (freq == 0) 801 if (freq == 0)
799 return -EINVAL; 802 return -EINVAL;
803 chandef.center_freq1 = freq;
804 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
805 if (!chandef.chan)
806 return -EINVAL;
800 mutex_lock(&rdev->devlist_mtx); 807 mutex_lock(&rdev->devlist_mtx);
801 err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT); 808 err = cfg80211_set_monitor_channel(rdev, &chandef);
802 mutex_unlock(&rdev->devlist_mtx); 809 mutex_unlock(&rdev->devlist_mtx);
803 return err; 810 return err;
804 case NL80211_IFTYPE_MESH_POINT: 811 case NL80211_IFTYPE_MESH_POINT:
@@ -807,9 +814,12 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
807 return freq; 814 return freq;
808 if (freq == 0) 815 if (freq == 0)
809 return -EINVAL; 816 return -EINVAL;
817 chandef.center_freq1 = freq;
818 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
819 if (!chandef.chan)
820 return -EINVAL;
810 mutex_lock(&rdev->devlist_mtx); 821 mutex_lock(&rdev->devlist_mtx);
811 err = cfg80211_set_mesh_freq(rdev, wdev, freq, 822 err = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
812 NL80211_CHAN_NO_HT);
813 mutex_unlock(&rdev->devlist_mtx); 823 mutex_unlock(&rdev->devlist_mtx);
814 return err; 824 return err;
815 default: 825 default:
@@ -823,8 +833,8 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
823{ 833{
824 struct wireless_dev *wdev = dev->ieee80211_ptr; 834 struct wireless_dev *wdev = dev->ieee80211_ptr;
825 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 835 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
826 struct ieee80211_channel *chan; 836 struct cfg80211_chan_def chandef;
827 enum nl80211_channel_type channel_type; 837 int ret;
828 838
829 switch (wdev->iftype) { 839 switch (wdev->iftype) {
830 case NL80211_IFTYPE_STATION: 840 case NL80211_IFTYPE_STATION:
@@ -835,10 +845,10 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
835 if (!rdev->ops->get_channel) 845 if (!rdev->ops->get_channel)
836 return -EINVAL; 846 return -EINVAL;
837 847
838 chan = rdev_get_channel(rdev, wdev, &channel_type); 848 ret = rdev_get_channel(rdev, wdev, &chandef);
839 if (!chan) 849 if (ret)
840 return -EINVAL; 850 return ret;
841 freq->m = chan->center_freq; 851 freq->m = chandef.chan->center_freq;
842 freq->e = 6; 852 freq->e = 6;
843 return 0; 853 return 0;
844 default: 854 default:
@@ -895,7 +905,7 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev,
895 return 0; 905 return 0;
896 } 906 }
897 907
898 return rdev_set_tx_power(rdev, type, DBM_TO_MBM(dbm)); 908 return rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm));
899} 909}
900 910
901static int cfg80211_wext_giwtxpower(struct net_device *dev, 911static int cfg80211_wext_giwtxpower(struct net_device *dev,
@@ -914,7 +924,7 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev,
914 if (!rdev->ops->get_tx_power) 924 if (!rdev->ops->get_tx_power)
915 return -EOPNOTSUPP; 925 return -EOPNOTSUPP;
916 926
917 err = rdev_get_tx_power(rdev, &val); 927 err = rdev_get_tx_power(rdev, wdev, &val);
918 if (err) 928 if (err)
919 return err; 929 return err;
920 930
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 1f773f668d1..873af63187c 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -119,7 +119,16 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
119 * channel we disconnected above and reconnect below. 119 * channel we disconnected above and reconnect below.
120 */ 120 */
121 if (chan && !wdev->wext.connect.ssid_len) { 121 if (chan && !wdev->wext.connect.ssid_len) {
122 err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT); 122 struct cfg80211_chan_def chandef = {
123 .width = NL80211_CHAN_WIDTH_20_NOHT,
124 .center_freq1 = freq,
125 };
126
127 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
128 if (chandef.chan)
129 err = cfg80211_set_monitor_channel(rdev, &chandef);
130 else
131 err = -EINVAL;
123 goto out; 132 goto out;
124 } 133 }
125 134