aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/bcma/core.c8
-rw-r--r--drivers/bcma/main.c5
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h3
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h3
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c20
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/Kconfig9
-rw-r--r--drivers/net/wireless/ath/ath6kl/Makefile5
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c15
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h3
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c72
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h11
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.c3
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_mbox.c21
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_pipe.c15
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c116
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c41
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c16
-rw-r--r--drivers/net/wireless/ath/ath6kl/target.h2
-rw-r--r--drivers/net/wireless/ath/ath6kl/trace.c23
-rw-r--r--drivers/net/wireless/ath/ath6kl/trace.h332
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c5
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c38
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h49
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c188
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c69
-rw-r--r--drivers/net/wireless/ath/wil6210/Makefile4
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c33
-rw-r--r--drivers/net/wireless/ath/wil6210/dbg_hexdump.h20
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c58
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c25
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c60
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c3
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c3
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c5
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h17
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c154
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h363
-rw-r--r--drivers/net/wireless/b43/Kconfig6
-rw-r--r--drivers/net/wireless/b43/b43.h6
-rw-r--r--drivers/net/wireless/b43/main.c7
-rw-r--r--drivers/net/wireless/b43/phy_ht.c610
-rw-r--r--drivers/net/wireless/b43/phy_ht.h77
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c30
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c33
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c42
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h34
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c39
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c28
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c382
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h25
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c22
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h87
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c37
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/Makefile4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/led.c126
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/led.h36
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c11
-rw-r--r--drivers/net/wireless/brcm80211/brcmutil/utils.c25
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_utils.h27
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c2
-rw-r--r--drivers/net/wireless/iwlegacy/3945.h4
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c29
-rw-r--r--drivers/net/wireless/iwlegacy/common.c2
-rw-r--r--drivers/net/wireless/iwlegacy/common.h4
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig11
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/debugfs.c26
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/testmode.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c13
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c (renamed from drivers/net/wireless/iwlwifi/pcie/1000.c)1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c (renamed from drivers/net/wireless/iwlwifi/pcie/2000.c)1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c (renamed from drivers/net/wireless/iwlwifi/pcie/5000.c)1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c (renamed from drivers/net/wireless/iwlwifi/pcie/6000.c)1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c (renamed from drivers/net/wireless/iwlwifi/pcie/7000.c)63
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.h17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-read.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-read.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-notif-wait.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-notif-wait.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c51
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-op-mode.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/binding.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c347
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c260
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c138
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h319
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h53
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c45
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c57
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h17
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c11
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c91
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/cfg.h115
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c4
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c25
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c3
-rw-r--r--drivers/net/wireless/mwifiex/Makefile1
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c218
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c2
-rw-r--r--drivers/net/wireless/mwifiex/ethtool.c70
-rw-r--r--drivers/net/wireless/mwifiex/fw.h72
-rw-r--r--drivers/net/wireless/mwifiex/init.c6
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h23
-rw-r--r--drivers/net/wireless/mwifiex/main.c15
-rw-r--r--drivers/net/wireless/mwifiex/main.h9
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c156
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c79
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c10
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c2
-rw-r--r--drivers/net/wireless/mwifiex/util.c5
-rw-r--r--drivers/net/wireless/mwl8k.c111
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c2
-rw-r--r--drivers/net/wireless/ray_cs.c6
-rw-r--r--drivers/net/wireless/rndis_wlan.c5
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig7
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h103
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c857
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c116
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c63
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c20
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c3
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c3
-rw-r--r--drivers/nfc/microread/mei.c2
-rw-r--r--drivers/ssb/driver_chipcommon.c2
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c41
-rw-r--r--drivers/ssb/driver_mipscore.c25
-rw-r--r--drivers/ssb/driver_pcicore.c15
-rw-r--r--drivers/ssb/embedded.c5
-rw-r--r--drivers/ssb/main.c51
-rw-r--r--drivers/ssb/pci.c97
-rw-r--r--drivers/ssb/pcmcia.c46
-rw-r--r--drivers/ssb/scan.c31
-rw-r--r--drivers/ssb/sprom.c4
-rw-r--r--drivers/ssb/ssb_private.h19
-rw-r--r--include/linux/ieee80211.h52
-rw-r--r--include/linux/socket.h1
-rw-r--r--include/linux/ssb/ssb.h6
-rw-r--r--include/net/cfg80211.h126
-rw-r--r--include/net/mac80211.h29
-rw-r--r--include/uapi/linux/nfc.h16
-rw-r--r--include/uapi/linux/nl80211.h117
-rw-r--r--net/mac80211/cfg.c151
-rw-r--r--net/mac80211/debugfs_sta.c31
-rw-r--r--net/mac80211/driver-ops.h7
-rw-r--r--net/mac80211/ht.c52
-rw-r--r--net/mac80211/ibss.c29
-rw-r--r--net/mac80211/ieee80211_i.h26
-rw-r--r--net/mac80211/iface.c14
-rw-r--r--net/mac80211/key.c103
-rw-r--r--net/mac80211/key.h5
-rw-r--r--net/mac80211/main.c55
-rw-r--r--net/mac80211/mesh.c59
-rw-r--r--net/mac80211/mesh.h12
-rw-r--r--net/mac80211/mesh_plink.c37
-rw-r--r--net/mac80211/mlme.c100
-rw-r--r--net/mac80211/offchannel.c2
-rw-r--r--net/mac80211/pm.c117
-rw-r--r--net/mac80211/rc80211_minstrel.c204
-rw-r--r--net/mac80211/rc80211_minstrel.h31
-rw-r--r--net/mac80211/rc80211_minstrel_debugfs.c12
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c79
-rw-r--r--net/mac80211/rc80211_minstrel_ht.h6
-rw-r--r--net/mac80211/rx.c61
-rw-r--r--net/mac80211/sta_info.c11
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/trace.h11
-rw-r--r--net/mac80211/util.c73
-rw-r--r--net/mac80211/vht.c212
-rw-r--r--net/nfc/llcp/commands.c205
-rw-r--r--net/nfc/llcp/llcp.c112
-rw-r--r--net/nfc/llcp/llcp.h36
-rw-r--r--net/nfc/llcp/sock.c130
-rw-r--r--net/nfc/netlink.c172
-rw-r--r--net/nfc/nfc.h14
-rw-r--r--net/rfkill/rfkill-regulator.c2
-rw-r--r--net/wireless/ap.c62
-rw-r--r--net/wireless/core.c73
-rw-r--r--net/wireless/core.h22
-rw-r--r--net/wireless/mesh.c15
-rw-r--r--net/wireless/mlme.c230
-rw-r--r--net/wireless/nl80211.c1857
-rw-r--r--net/wireless/nl80211.h68
-rw-r--r--net/wireless/rdev-ops.h20
-rw-r--r--net/wireless/reg.c6
-rw-r--r--net/wireless/sme.c26
-rw-r--r--net/wireless/sysfs.c25
-rw-r--r--net/wireless/trace.h46
263 files changed, 9520 insertions, 3400 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index fb89be1281c6..86c084321387 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8500,7 +8500,7 @@ F: drivers/usb/gadget/*uvc*.c
8500F: drivers/usb/gadget/webcam.c 8500F: drivers/usb/gadget/webcam.c
8501 8501
8502USB WIRELESS RNDIS DRIVER (rndis_wlan) 8502USB WIRELESS RNDIS DRIVER (rndis_wlan)
8503M: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> 8503M: Jussi Kivilinna <jussi.kivilinna@iki.fi>
8504L: linux-wireless@vger.kernel.org 8504L: linux-wireless@vger.kernel.org
8505S: Maintained 8505S: Maintained
8506F: drivers/net/wireless/rndis_wlan.c 8506F: drivers/net/wireless/rndis_wlan.c
diff --git a/drivers/bcma/core.c b/drivers/bcma/core.c
index 03bbe104338f..17b26ce7e051 100644
--- a/drivers/bcma/core.c
+++ b/drivers/bcma/core.c
@@ -104,7 +104,13 @@ void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
104 if (i) 104 if (i)
105 bcma_err(core->bus, "PLL enable timeout\n"); 105 bcma_err(core->bus, "PLL enable timeout\n");
106 } else { 106 } else {
107 bcma_warn(core->bus, "Disabling PLL not supported yet!\n"); 107 /*
108 * Mask the PLL but don't wait for it to be disabled. PLL may be
109 * shared between cores and will be still up if there is another
110 * core using it.
111 */
112 bcma_mask32(core, BCMA_CLKCTLST, ~req);
113 bcma_read32(core, BCMA_CLKCTLST);
108 } 114 }
109} 115}
110EXPORT_SYMBOL_GPL(bcma_core_pll_ctl); 116EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 9a6188add590..f72f52b4b1dd 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -120,6 +120,11 @@ static int bcma_register_cores(struct bcma_bus *bus)
120 continue; 120 continue;
121 } 121 }
122 122
123 /* Only first GMAC core on BCM4706 is connected and working */
124 if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
125 core->core_unit > 0)
126 continue;
127
123 core->dev.release = bcma_release_core_dev; 128 core->dev.release = bcma_release_core_dev;
124 core->dev.bus = &bcma_bus_type; 129 core->dev.bus = &bcma_bus_type;
125 dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id); 130 dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 3150def17193..2d691b8b95b9 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1523,7 +1523,8 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah);
1523/* EEPROM access functions */ 1523/* EEPROM access functions */
1524int ath5k_eeprom_init(struct ath5k_hw *ah); 1524int ath5k_eeprom_init(struct ath5k_hw *ah);
1525void ath5k_eeprom_detach(struct ath5k_hw *ah); 1525void ath5k_eeprom_detach(struct ath5k_hw *ah);
1526 1526int ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah,
1527 struct ieee80211_channel *channel);
1527 1528
1528/* Protocol Control Unit Functions */ 1529/* Protocol Control Unit Functions */
1529/* Helpers */ 1530/* Helpers */
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index b7e0258887e7..94d34ee02265 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -1779,7 +1779,8 @@ ath5k_eeprom_detach(struct ath5k_hw *ah)
1779} 1779}
1780 1780
1781int 1781int
1782ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel) 1782ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah,
1783 struct ieee80211_channel *channel)
1783{ 1784{
1784 switch (channel->hw_value) { 1785 switch (channel->hw_value) {
1785 case AR5K_MODE_11A: 1786 case AR5K_MODE_11A:
@@ -1789,6 +1790,7 @@ ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
1789 case AR5K_MODE_11B: 1790 case AR5K_MODE_11B:
1790 return AR5K_EEPROM_MODE_11B; 1791 return AR5K_EEPROM_MODE_11B;
1791 default: 1792 default:
1792 return -1; 1793 ATH5K_WARN(ah, "channel is not A/B/G!");
1794 return AR5K_EEPROM_MODE_11A;
1793 } 1795 }
1794} 1796}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 94a9bbea6874..693296ee9693 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -493,6 +493,3 @@ struct ath5k_eeprom_info {
493 /* Antenna raw switch tables */ 493 /* Antenna raw switch tables */
494 u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 494 u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
495}; 495};
496
497int
498ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel);
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index a78afa98c650..d6bc7cb61bfb 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1612,11 +1612,7 @@ ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1612 1612
1613 ah->ah_cal_mask |= AR5K_CALIBRATION_NF; 1613 ah->ah_cal_mask |= AR5K_CALIBRATION_NF;
1614 1614
1615 ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel); 1615 ee_mode = ath5k_eeprom_mode_from_channel(ah, ah->ah_current_channel);
1616 if (WARN_ON(ee_mode < 0)) {
1617 ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF;
1618 return;
1619 }
1620 1616
1621 /* completed NF calibration, test threshold */ 1617 /* completed NF calibration, test threshold */
1622 nf = ath5k_hw_read_measured_noise_floor(ah); 1618 nf = ath5k_hw_read_measured_noise_floor(ah);
@@ -2317,12 +2313,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
2317 2313
2318 def_ant = ah->ah_def_ant; 2314 def_ant = ah->ah_def_ant;
2319 2315
2320 ee_mode = ath5k_eeprom_mode_from_channel(channel); 2316 ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
2321 if (ee_mode < 0) {
2322 ATH5K_ERR(ah,
2323 "invalid channel: %d\n", channel->center_freq);
2324 return;
2325 }
2326 2317
2327 switch (ant_mode) { 2318 switch (ant_mode) {
2328 case AR5K_ANTMODE_DEFAULT: 2319 case AR5K_ANTMODE_DEFAULT:
@@ -3622,12 +3613,7 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3622 return -EINVAL; 3613 return -EINVAL;
3623 } 3614 }
3624 3615
3625 ee_mode = ath5k_eeprom_mode_from_channel(channel); 3616 ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
3626 if (ee_mode < 0) {
3627 ATH5K_ERR(ah,
3628 "invalid channel: %d\n", channel->center_freq);
3629 return -EINVAL;
3630 }
3631 3617
3632 /* Initialize TX power table */ 3618 /* Initialize TX power table */
3633 switch (ah->ah_radio) { 3619 switch (ah->ah_radio) {
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index e2d8b2cf19eb..a3399c4f13a9 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -984,9 +984,7 @@ ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
984 if (ah->ah_version == AR5K_AR5210) 984 if (ah->ah_version == AR5K_AR5210)
985 return; 985 return;
986 986
987 ee_mode = ath5k_eeprom_mode_from_channel(channel); 987 ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
988 if (WARN_ON(ee_mode < 0))
989 return;
990 988
991 /* Adjust power delta for channel 14 */ 989 /* Adjust power delta for channel 14 */
992 if (channel->center_freq == 2484) 990 if (channel->center_freq == 2484)
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
index 630c83db056e..e39e5860a2e9 100644
--- a/drivers/net/wireless/ath/ath6kl/Kconfig
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -30,6 +30,15 @@ config ATH6KL_DEBUG
30 ---help--- 30 ---help---
31 Enables debug support 31 Enables debug support
32 32
33config ATH6KL_TRACING
34 bool "Atheros ath6kl tracing support"
35 depends on ATH6KL
36 depends on EVENT_TRACING
37 ---help---
38 Select this to ath6kl use tracing infrastructure.
39
40 If unsure, say Y to make it easier to debug problems.
41
33config ATH6KL_REGDOMAIN 42config ATH6KL_REGDOMAIN
34 bool "Atheros ath6kl regdomain support" 43 bool "Atheros ath6kl regdomain support"
35 depends on ATH6KL 44 depends on ATH6KL
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
index cab0ec0d5380..dc2b3b46781e 100644
--- a/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -35,10 +35,15 @@ ath6kl_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-y += recovery.o
38
38ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o 39ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
40ath6kl_core-$(CONFIG_ATH6KL_TRACING) += trace.o
39 41
40obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o 42obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o
41ath6kl_sdio-y += sdio.o 43ath6kl_sdio-y += sdio.o
42 44
43obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o 45obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o
44ath6kl_usb-y += usb.o 46ath6kl_usb-y += usb.o
47
48# for tracing framework to find trace.h
49CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 752ffc4f4166..5c9736a94e54 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -402,7 +402,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
402 if (type == NL80211_IFTYPE_STATION || 402 if (type == NL80211_IFTYPE_STATION ||
403 type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) { 403 type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
404 for (i = 0; i < ar->vif_max; i++) { 404 for (i = 0; i < ar->vif_max; i++) {
405 if ((ar->avail_idx_map >> i) & BIT(0)) { 405 if ((ar->avail_idx_map) & BIT(i)) {
406 *if_idx = i; 406 *if_idx = i;
407 return true; 407 return true;
408 } 408 }
@@ -412,7 +412,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
412 if (type == NL80211_IFTYPE_P2P_CLIENT || 412 if (type == NL80211_IFTYPE_P2P_CLIENT ||
413 type == NL80211_IFTYPE_P2P_GO) { 413 type == NL80211_IFTYPE_P2P_GO) {
414 for (i = ar->max_norm_iface; i < ar->vif_max; i++) { 414 for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
415 if ((ar->avail_idx_map >> i) & BIT(0)) { 415 if ((ar->avail_idx_map) & BIT(i)) {
416 *if_idx = i; 416 *if_idx = i;
417 return true; 417 return true;
418 } 418 }
@@ -1535,7 +1535,9 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1535 1535
1536 ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag)); 1536 ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
1537 1537
1538 rtnl_lock();
1538 ath6kl_cfg80211_vif_cleanup(vif); 1539 ath6kl_cfg80211_vif_cleanup(vif);
1540 rtnl_unlock();
1539 1541
1540 return 0; 1542 return 0;
1541} 1543}
@@ -2990,13 +2992,15 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
2990{ 2992{
2991 struct ath6kl *ar = ath6kl_priv(dev); 2993 struct ath6kl *ar = ath6kl_priv(dev);
2992 struct ath6kl_vif *vif = netdev_priv(dev); 2994 struct ath6kl_vif *vif = netdev_priv(dev);
2995 int err;
2993 2996
2994 if (vif->nw_type != AP_NETWORK) 2997 if (vif->nw_type != AP_NETWORK)
2995 return -EOPNOTSUPP; 2998 return -EOPNOTSUPP;
2996 2999
2997 /* Use this only for authorizing/unauthorizing a station */ 3000 err = cfg80211_check_station_change(wiphy, params,
2998 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))) 3001 CFG80211_STA_AP_MLME_CLIENT);
2999 return -EOPNOTSUPP; 3002 if (err)
3003 return err;
3000 3004
3001 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED)) 3005 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3002 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, 3006 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
@@ -3659,7 +3663,6 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
3659 vif->sme_state = SME_DISCONNECTED; 3663 vif->sme_state = SME_DISCONNECTED;
3660 set_bit(WLAN_ENABLED, &vif->flags); 3664 set_bit(WLAN_ENABLED, &vif->flags);
3661 ar->wlan_pwr_state = WLAN_POWER_STATE_ON; 3665 ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
3662 set_bit(NETDEV_REGISTERED, &vif->flags);
3663 3666
3664 if (type == NL80211_IFTYPE_ADHOC) 3667 if (type == NL80211_IFTYPE_ADHOC)
3665 ar->ibss_if_active = true; 3668 ar->ibss_if_active = true;
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 61b2f98b4e77..26b0f92424e1 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -560,7 +560,6 @@ enum ath6kl_vif_state {
560 WMM_ENABLED, 560 WMM_ENABLED,
561 NETQ_STOPPED, 561 NETQ_STOPPED,
562 DTIM_EXPIRED, 562 DTIM_EXPIRED,
563 NETDEV_REGISTERED,
564 CLEAR_BSSFILTER_ON_BEACON, 563 CLEAR_BSSFILTER_ON_BEACON,
565 DTIM_PERIOD_AVAIL, 564 DTIM_PERIOD_AVAIL,
566 WLAN_ENABLED, 565 WLAN_ENABLED,
@@ -936,8 +935,6 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
936 u8 win_sz); 935 u8 win_sz);
937void ath6kl_wakeup_event(void *dev); 936void ath6kl_wakeup_event(void *dev);
938 937
939void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
940 bool wait_fot_compltn, bool cold_reset);
941void ath6kl_init_control_info(struct ath6kl_vif *vif); 938void ath6kl_init_control_info(struct ath6kl_vif *vif);
942struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); 939struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
943void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready); 940void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready);
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 15cfe30e54fd..fe38b836cb26 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -56,6 +56,60 @@ int ath6kl_printk(const char *level, const char *fmt, ...)
56} 56}
57EXPORT_SYMBOL(ath6kl_printk); 57EXPORT_SYMBOL(ath6kl_printk);
58 58
59int ath6kl_info(const char *fmt, ...)
60{
61 struct va_format vaf = {
62 .fmt = fmt,
63 };
64 va_list args;
65 int ret;
66
67 va_start(args, fmt);
68 vaf.va = &args;
69 ret = ath6kl_printk(KERN_INFO, "%pV", &vaf);
70 trace_ath6kl_log_info(&vaf);
71 va_end(args);
72
73 return ret;
74}
75EXPORT_SYMBOL(ath6kl_info);
76
77int ath6kl_err(const char *fmt, ...)
78{
79 struct va_format vaf = {
80 .fmt = fmt,
81 };
82 va_list args;
83 int ret;
84
85 va_start(args, fmt);
86 vaf.va = &args;
87 ret = ath6kl_printk(KERN_ERR, "%pV", &vaf);
88 trace_ath6kl_log_err(&vaf);
89 va_end(args);
90
91 return ret;
92}
93EXPORT_SYMBOL(ath6kl_err);
94
95int ath6kl_warn(const char *fmt, ...)
96{
97 struct va_format vaf = {
98 .fmt = fmt,
99 };
100 va_list args;
101 int ret;
102
103 va_start(args, fmt);
104 vaf.va = &args;
105 ret = ath6kl_printk(KERN_WARNING, "%pV", &vaf);
106 trace_ath6kl_log_warn(&vaf);
107 va_end(args);
108
109 return ret;
110}
111EXPORT_SYMBOL(ath6kl_warn);
112
59#ifdef CONFIG_ATH6KL_DEBUG 113#ifdef CONFIG_ATH6KL_DEBUG
60 114
61void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...) 115void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...)
@@ -63,15 +117,15 @@ void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...)
63 struct va_format vaf; 117 struct va_format vaf;
64 va_list args; 118 va_list args;
65 119
66 if (!(debug_mask & mask))
67 return;
68
69 va_start(args, fmt); 120 va_start(args, fmt);
70 121
71 vaf.fmt = fmt; 122 vaf.fmt = fmt;
72 vaf.va = &args; 123 vaf.va = &args;
73 124
74 ath6kl_printk(KERN_DEBUG, "%pV", &vaf); 125 if (debug_mask & mask)
126 ath6kl_printk(KERN_DEBUG, "%pV", &vaf);
127
128 trace_ath6kl_log_dbg(mask, &vaf);
75 129
76 va_end(args); 130 va_end(args);
77} 131}
@@ -87,6 +141,10 @@ void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
87 141
88 print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); 142 print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
89 } 143 }
144
145 /* tracing code doesn't like null strings :/ */
146 trace_ath6kl_log_dbg_dump(msg ? msg : "", prefix ? prefix : "",
147 buf, len);
90} 148}
91EXPORT_SYMBOL(ath6kl_dbg_dump); 149EXPORT_SYMBOL(ath6kl_dbg_dump);
92 150
@@ -1752,8 +1810,10 @@ int ath6kl_debug_init_fs(struct ath6kl *ar)
1752 debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar, 1810 debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar,
1753 &fops_tgt_stats); 1811 &fops_tgt_stats);
1754 1812
1755 debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar, 1813 if (ar->hif_type == ATH6KL_HIF_TYPE_SDIO)
1756 &fops_credit_dist_stats); 1814 debugfs_create_file("credit_dist_stats", S_IRUSR,
1815 ar->debugfs_phy, ar,
1816 &fops_credit_dist_stats);
1757 1817
1758 debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR, 1818 debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR,
1759 ar->debugfs_phy, ar, &fops_endpoint_stats); 1819 ar->debugfs_phy, ar, &fops_endpoint_stats);
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index f97cd4ead543..74369de00fb5 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -19,6 +19,7 @@
19#define DEBUG_H 19#define DEBUG_H
20 20
21#include "hif.h" 21#include "hif.h"
22#include "trace.h"
22 23
23enum ATH6K_DEBUG_MASK { 24enum ATH6K_DEBUG_MASK {
24 ATH6KL_DBG_CREDIT = BIT(0), 25 ATH6KL_DBG_CREDIT = BIT(0),
@@ -51,13 +52,9 @@ enum ATH6K_DEBUG_MASK {
51extern unsigned int debug_mask; 52extern unsigned int debug_mask;
52extern __printf(2, 3) 53extern __printf(2, 3)
53int ath6kl_printk(const char *level, const char *fmt, ...); 54int ath6kl_printk(const char *level, const char *fmt, ...);
54 55extern __printf(1, 2) int ath6kl_info(const char *fmt, ...);
55#define ath6kl_info(fmt, ...) \ 56extern __printf(1, 2) int ath6kl_err(const char *fmt, ...);
56 ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__) 57extern __printf(1, 2) int ath6kl_warn(const char *fmt, ...);
57#define ath6kl_err(fmt, ...) \
58 ath6kl_printk(KERN_ERR, fmt, ##__VA_ARGS__)
59#define ath6kl_warn(fmt, ...) \
60 ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__)
61 58
62enum ath6kl_war { 59enum ath6kl_war {
63 ATH6KL_WAR_INVALID_RATE, 60 ATH6KL_WAR_INVALID_RATE,
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
index a6b614421fa4..fea7709b5dda 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ b/drivers/net/wireless/ath/ath6kl/hif.c
@@ -22,6 +22,7 @@
22#include "target.h" 22#include "target.h"
23#include "hif-ops.h" 23#include "hif-ops.h"
24#include "debug.h" 24#include "debug.h"
25#include "trace.h"
25 26
26#define MAILBOX_FOR_BLOCK_SIZE 1 27#define MAILBOX_FOR_BLOCK_SIZE 1
27 28
@@ -436,6 +437,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
436 437
437 ath6kl_dump_registers(dev, &dev->irq_proc_reg, 438 ath6kl_dump_registers(dev, &dev->irq_proc_reg,
438 &dev->irq_en_reg); 439 &dev->irq_en_reg);
440 trace_ath6kl_sdio_irq(&dev->irq_en_reg,
441 sizeof(dev->irq_en_reg));
439 442
440 /* Update only those registers that are enabled */ 443 /* Update only those registers that are enabled */
441 host_int_status = dev->irq_proc_reg.host_int_status & 444 host_int_status = dev->irq_proc_reg.host_int_status &
diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index fbb78dfe078f..65e5b719093d 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -19,6 +19,8 @@
19#include "hif.h" 19#include "hif.h"
20#include "debug.h" 20#include "debug.h"
21#include "hif-ops.h" 21#include "hif-ops.h"
22#include "trace.h"
23
22#include <asm/unaligned.h> 24#include <asm/unaligned.h>
23 25
24#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) 26#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
@@ -537,6 +539,8 @@ static int ath6kl_htc_tx_issue(struct htc_target *target,
537 packet->buf, padded_len, 539 packet->buf, padded_len,
538 HIF_WR_ASYNC_BLOCK_INC, packet); 540 HIF_WR_ASYNC_BLOCK_INC, packet);
539 541
542 trace_ath6kl_htc_tx(status, packet->endpoint, packet->buf, send_len);
543
540 return status; 544 return status;
541} 545}
542 546
@@ -757,7 +761,8 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
757{ 761{
758 struct htc_target *target = endpoint->target; 762 struct htc_target *target = endpoint->target;
759 struct hif_scatter_req *scat_req = NULL; 763 struct hif_scatter_req *scat_req = NULL;
760 int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0; 764 int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0, i;
765 struct htc_packet *packet;
761 int status; 766 int status;
762 u32 txb_mask; 767 u32 txb_mask;
763 u8 ac = WMM_NUM_AC; 768 u8 ac = WMM_NUM_AC;
@@ -832,6 +837,13 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
832 ath6kl_dbg(ATH6KL_DBG_HTC, 837 ath6kl_dbg(ATH6KL_DBG_HTC,
833 "htc tx scatter bytes %d entries %d\n", 838 "htc tx scatter bytes %d entries %d\n",
834 scat_req->len, scat_req->scat_entries); 839 scat_req->len, scat_req->scat_entries);
840
841 for (i = 0; i < scat_req->scat_entries; i++) {
842 packet = scat_req->scat_list[i].packet;
843 trace_ath6kl_htc_tx(packet->status, packet->endpoint,
844 packet->buf, packet->act_len);
845 }
846
835 ath6kl_hif_submit_scat_req(target->dev, scat_req, false); 847 ath6kl_hif_submit_scat_req(target->dev, scat_req, false);
836 848
837 if (status) 849 if (status)
@@ -1903,6 +1915,7 @@ static void ath6kl_htc_rx_complete(struct htc_endpoint *endpoint,
1903 ath6kl_dbg(ATH6KL_DBG_HTC, 1915 ath6kl_dbg(ATH6KL_DBG_HTC,
1904 "htc rx complete ep %d packet 0x%p\n", 1916 "htc rx complete ep %d packet 0x%p\n",
1905 endpoint->eid, packet); 1917 endpoint->eid, packet);
1918
1906 endpoint->ep_cb.rx(endpoint->target, packet); 1919 endpoint->ep_cb.rx(endpoint->target, packet);
1907} 1920}
1908 1921
@@ -2011,6 +2024,9 @@ static int ath6kl_htc_rx_process_packets(struct htc_target *target,
2011 list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) { 2024 list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) {
2012 ep = &target->endpoint[packet->endpoint]; 2025 ep = &target->endpoint[packet->endpoint];
2013 2026
2027 trace_ath6kl_htc_rx(packet->status, packet->endpoint,
2028 packet->buf, packet->act_len);
2029
2014 /* process header for each of the recv packet */ 2030 /* process header for each of the recv packet */
2015 status = ath6kl_htc_rx_process_hdr(target, packet, lk_ahds, 2031 status = ath6kl_htc_rx_process_hdr(target, packet, lk_ahds,
2016 n_lk_ahd); 2032 n_lk_ahd);
@@ -2291,6 +2307,9 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
2291 if (ath6kl_htc_rx_packet(target, packet, packet->act_len)) 2307 if (ath6kl_htc_rx_packet(target, packet, packet->act_len))
2292 goto fail_ctrl_rx; 2308 goto fail_ctrl_rx;
2293 2309
2310 trace_ath6kl_htc_rx(packet->status, packet->endpoint,
2311 packet->buf, packet->act_len);
2312
2294 /* process receive header */ 2313 /* process receive header */
2295 packet->status = ath6kl_htc_rx_process_hdr(target, packet, NULL, NULL); 2314 packet->status = ath6kl_htc_rx_process_hdr(target, packet, NULL, NULL);
2296 2315
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
index 281390178e3d..67aa924ed8b3 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
@@ -988,8 +988,6 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
988 988
989 htc_hdr = (struct htc_frame_hdr *) netdata; 989 htc_hdr = (struct htc_frame_hdr *) netdata;
990 990
991 ep = &target->endpoint[htc_hdr->eid];
992
993 if (htc_hdr->eid >= ENDPOINT_MAX) { 991 if (htc_hdr->eid >= ENDPOINT_MAX) {
994 ath6kl_dbg(ATH6KL_DBG_HTC, 992 ath6kl_dbg(ATH6KL_DBG_HTC,
995 "HTC Rx: invalid EndpointID=%d\n", 993 "HTC Rx: invalid EndpointID=%d\n",
@@ -997,6 +995,7 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
997 status = -EINVAL; 995 status = -EINVAL;
998 goto free_skb; 996 goto free_skb;
999 } 997 }
998 ep = &target->endpoint[htc_hdr->eid];
1000 999
1001 payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len)); 1000 payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len));
1002 1001
@@ -1168,8 +1167,8 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target)
1168 } 1167 }
1169 1168
1170 if (count <= 0) { 1169 if (count <= 0) {
1171 ath6kl_dbg(ATH6KL_DBG_HTC, "%s: Timeout!\n", __func__); 1170 ath6kl_warn("htc pipe control receive timeout!\n");
1172 return -ECOMM; 1171 return -ETIMEDOUT;
1173 } 1172 }
1174 1173
1175 return 0; 1174 return 0;
@@ -1582,16 +1581,16 @@ static int ath6kl_htc_pipe_wait_target(struct htc_target *target)
1582 return status; 1581 return status;
1583 1582
1584 if (target->pipe.ctrl_response_len < sizeof(*ready_msg)) { 1583 if (target->pipe.ctrl_response_len < sizeof(*ready_msg)) {
1585 ath6kl_dbg(ATH6KL_DBG_HTC, "invalid htc ready msg len:%d!\n", 1584 ath6kl_warn("invalid htc pipe ready msg len: %d\n",
1586 target->pipe.ctrl_response_len); 1585 target->pipe.ctrl_response_len);
1587 return -ECOMM; 1586 return -ECOMM;
1588 } 1587 }
1589 1588
1590 ready_msg = (struct htc_ready_ext_msg *) target->pipe.ctrl_response_buf; 1589 ready_msg = (struct htc_ready_ext_msg *) target->pipe.ctrl_response_buf;
1591 1590
1592 if (ready_msg->ver2_0_info.msg_id != cpu_to_le16(HTC_MSG_READY_ID)) { 1591 if (ready_msg->ver2_0_info.msg_id != cpu_to_le16(HTC_MSG_READY_ID)) {
1593 ath6kl_dbg(ATH6KL_DBG_HTC, "invalid htc ready msg : 0x%X !\n", 1592 ath6kl_warn("invalid htc pipe ready msg: 0x%x\n",
1594 ready_msg->ver2_0_info.msg_id); 1593 ready_msg->ver2_0_info.msg_id);
1595 return -ECOMM; 1594 return -ECOMM;
1596 } 1595 }
1597 1596
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 5d434cf88f35..40ffee6184fd 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -201,8 +201,8 @@ struct sk_buff *ath6kl_buf_alloc(int size)
201 u16 reserved; 201 u16 reserved;
202 202
203 /* Add chacheline space at front and back of buffer */ 203 /* Add chacheline space at front and back of buffer */
204 reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET + 204 reserved = roundup((2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
205 sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES; 205 sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES, 4);
206 skb = dev_alloc_skb(size + reserved); 206 skb = dev_alloc_skb(size + reserved);
207 207
208 if (skb) 208 if (skb)
@@ -1549,10 +1549,89 @@ static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type)
1549 return NULL; 1549 return NULL;
1550} 1550}
1551 1551
1552
1553static const struct fw_capa_str_map {
1554 int id;
1555 const char *name;
1556} fw_capa_map[] = {
1557 { ATH6KL_FW_CAPABILITY_HOST_P2P, "host-p2p" },
1558 { ATH6KL_FW_CAPABILITY_SCHED_SCAN, "sched-scan" },
1559 { ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, "sta-p2pdev-duplex" },
1560 { ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, "inactivity-timeout" },
1561 { ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, "rsn-cap-override" },
1562 { ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, "wow-mc-filter" },
1563 { ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, "bmiss-enhance" },
1564 { ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, "sscan-match-list" },
1565 { ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, "rssi-scan-thold" },
1566 { ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, "custom-mac-addr" },
1567 { ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, "tx-err-notify" },
1568 { ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
1569 { ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
1570 { ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
1571};
1572
1573static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
1574{
1575 int i;
1576
1577 for (i = 0; i < ARRAY_SIZE(fw_capa_map); i++) {
1578 if (fw_capa_map[i].id == id)
1579 return fw_capa_map[i].name;
1580 }
1581
1582 return "<unknown>";
1583}
1584
1585static void ath6kl_init_get_fwcaps(struct ath6kl *ar, char *buf, size_t buf_len)
1586{
1587 u8 *data = (u8 *) ar->fw_capabilities;
1588 size_t trunc_len, len = 0;
1589 int i, index, bit;
1590 char *trunc = "...";
1591
1592 for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) {
1593 index = i / 8;
1594 bit = i % 8;
1595
1596 if (index >= sizeof(ar->fw_capabilities) * 4)
1597 break;
1598
1599 if (buf_len - len < 4) {
1600 ath6kl_warn("firmware capability buffer too small!\n");
1601
1602 /* add "..." to the end of string */
1603 trunc_len = strlen(trunc) + 1;
1604 strncpy(buf + buf_len - trunc_len, trunc, trunc_len);
1605
1606 return;
1607 }
1608
1609 if (data[index] & (1 << bit)) {
1610 len += scnprintf(buf + len, buf_len - len, "%s,",
1611 ath6kl_init_get_fw_capa_name(i));
1612 }
1613 }
1614
1615 /* overwrite the last comma */
1616 if (len > 0)
1617 len--;
1618
1619 buf[len] = '\0';
1620}
1621
1622static int ath6kl_init_hw_reset(struct ath6kl *ar)
1623{
1624 ath6kl_dbg(ATH6KL_DBG_BOOT, "cold resetting the device");
1625
1626 return ath6kl_diag_write32(ar, RESET_CONTROL_ADDRESS,
1627 cpu_to_le32(RESET_CONTROL_COLD_RST));
1628}
1629
1552static int __ath6kl_init_hw_start(struct ath6kl *ar) 1630static int __ath6kl_init_hw_start(struct ath6kl *ar)
1553{ 1631{
1554 long timeleft; 1632 long timeleft;
1555 int ret, i; 1633 int ret, i;
1634 char buf[200];
1556 1635
1557 ath6kl_dbg(ATH6KL_DBG_BOOT, "hw start\n"); 1636 ath6kl_dbg(ATH6KL_DBG_BOOT, "hw start\n");
1558 1637
@@ -1569,24 +1648,35 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar)
1569 goto err_power_off; 1648 goto err_power_off;
1570 1649
1571 /* Do we need to finish the BMI phase */ 1650 /* Do we need to finish the BMI phase */
1572 /* FIXME: return error from ath6kl_bmi_done() */ 1651 ret = ath6kl_bmi_done(ar);
1573 if (ath6kl_bmi_done(ar)) { 1652 if (ret)
1574 ret = -EIO;
1575 goto err_power_off; 1653 goto err_power_off;
1576 }
1577 1654
1578 /* 1655 /*
1579 * The reason we have to wait for the target here is that the 1656 * The reason we have to wait for the target here is that the
1580 * driver layer has to init BMI in order to set the host block 1657 * driver layer has to init BMI in order to set the host block
1581 * size. 1658 * size.
1582 */ 1659 */
1583 if (ath6kl_htc_wait_target(ar->htc_target)) { 1660 ret = ath6kl_htc_wait_target(ar->htc_target);
1584 ret = -EIO; 1661
1662 if (ret == -ETIMEDOUT) {
1663 /*
1664 * Most likely USB target is in odd state after reboot and
1665 * needs a reset. A cold reset makes the whole device
1666 * disappear from USB bus and initialisation starts from
1667 * beginning.
1668 */
1669 ath6kl_warn("htc wait target timed out, resetting device\n");
1670 ath6kl_init_hw_reset(ar);
1671 goto err_power_off;
1672 } else if (ret) {
1673 ath6kl_err("htc wait target failed: %d\n", ret);
1585 goto err_power_off; 1674 goto err_power_off;
1586 } 1675 }
1587 1676
1588 if (ath6kl_init_service_ep(ar)) { 1677 ret = ath6kl_init_service_ep(ar);
1589 ret = -EIO; 1678 if (ret) {
1679 ath6kl_err("Endpoint service initilisation failed: %d\n", ret);
1590 goto err_cleanup_scatter; 1680 goto err_cleanup_scatter;
1591 } 1681 }
1592 1682
@@ -1617,6 +1707,8 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar)
1617 ar->wiphy->fw_version, 1707 ar->wiphy->fw_version,
1618 ar->fw_api, 1708 ar->fw_api,
1619 test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); 1709 test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
1710 ath6kl_init_get_fwcaps(ar, buf, sizeof(buf));
1711 ath6kl_info("firmware supports: %s\n", buf);
1620 } 1712 }
1621 1713
1622 if (ar->version.abi_ver != ATH6KL_ABI_VERSION) { 1714 if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
@@ -1765,9 +1857,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
1765 * Try to reset the device if we can. The driver may have been 1857 * Try to reset the device if we can. The driver may have been
1766 * configure NOT to reset the target during a debug session. 1858 * configure NOT to reset the target during a debug session.
1767 */ 1859 */
1768 ath6kl_dbg(ATH6KL_DBG_TRC, 1860 ath6kl_init_hw_reset(ar);
1769 "attempting to reset target on instance destroy\n");
1770 ath6kl_reset_device(ar, ar->target_type, true, true);
1771 1861
1772 up(&ar->sem); 1862 up(&ar->sem);
1773} 1863}
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index bd50b6b7b492..d4fcfcad57d0 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -345,39 +345,6 @@ out:
345 return ret; 345 return ret;
346} 346}
347 347
348/* FIXME: move to a better place, target.h? */
349#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
350#define AR6004_RESET_CONTROL_ADDRESS 0x00004000
351
352void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
353 bool wait_fot_compltn, bool cold_reset)
354{
355 int status = 0;
356 u32 address;
357 __le32 data;
358
359 if (target_type != TARGET_TYPE_AR6003 &&
360 target_type != TARGET_TYPE_AR6004)
361 return;
362
363 data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) :
364 cpu_to_le32(RESET_CONTROL_MBOX_RST);
365
366 switch (target_type) {
367 case TARGET_TYPE_AR6003:
368 address = AR6003_RESET_CONTROL_ADDRESS;
369 break;
370 case TARGET_TYPE_AR6004:
371 address = AR6004_RESET_CONTROL_ADDRESS;
372 break;
373 }
374
375 status = ath6kl_diag_write32(ar, address, data);
376
377 if (status)
378 ath6kl_err("failed to reset target\n");
379}
380
381static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif) 348static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
382{ 349{
383 u8 index; 350 u8 index;
@@ -1327,9 +1294,11 @@ void init_netdev(struct net_device *dev)
1327 dev->watchdog_timeo = ATH6KL_TX_TIMEOUT; 1294 dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
1328 1295
1329 dev->needed_headroom = ETH_HLEN; 1296 dev->needed_headroom = ETH_HLEN;
1330 dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) + 1297 dev->needed_headroom += roundup(sizeof(struct ath6kl_llc_snap_hdr) +
1331 sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH 1298 sizeof(struct wmi_data_hdr) +
1332 + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES; 1299 HTC_HDR_LENGTH +
1300 WMI_MAX_TX_META_SZ +
1301 ATH6KL_HTC_ALIGN_BYTES, 4);
1333 1302
1334 dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; 1303 dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
1335 1304
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index d111980d44c0..fb141454c6d2 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -28,6 +28,7 @@
28#include "target.h" 28#include "target.h"
29#include "debug.h" 29#include "debug.h"
30#include "cfg80211.h" 30#include "cfg80211.h"
31#include "trace.h"
31 32
32struct ath6kl_sdio { 33struct ath6kl_sdio {
33 struct sdio_func *func; 34 struct sdio_func *func;
@@ -179,6 +180,8 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
179 request & HIF_FIXED_ADDRESS ? " (fixed)" : "", buf, len); 180 request & HIF_FIXED_ADDRESS ? " (fixed)" : "", buf, len);
180 ath6kl_dbg_dump(ATH6KL_DBG_SDIO_DUMP, NULL, "sdio ", buf, len); 181 ath6kl_dbg_dump(ATH6KL_DBG_SDIO_DUMP, NULL, "sdio ", buf, len);
181 182
183 trace_ath6kl_sdio(addr, request, buf, len);
184
182 return ret; 185 return ret;
183} 186}
184 187
@@ -309,6 +312,13 @@ static int ath6kl_sdio_scat_rw(struct ath6kl_sdio *ar_sdio,
309 sdio_claim_host(ar_sdio->func); 312 sdio_claim_host(ar_sdio->func);
310 313
311 mmc_set_data_timeout(&data, ar_sdio->func->card); 314 mmc_set_data_timeout(&data, ar_sdio->func->card);
315
316 trace_ath6kl_sdio_scat(scat_req->addr,
317 scat_req->req,
318 scat_req->len,
319 scat_req->scat_entries,
320 scat_req->scat_list);
321
312 /* synchronous call to process request */ 322 /* synchronous call to process request */
313 mmc_wait_for_req(ar_sdio->func->card->host, &mmc_req); 323 mmc_wait_for_req(ar_sdio->func->card->host, &mmc_req);
314 324
@@ -1123,10 +1133,12 @@ static int ath6kl_sdio_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
1123 1133
1124 ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len, 1134 ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len,
1125 HIF_WR_SYNC_BYTE_INC); 1135 HIF_WR_SYNC_BYTE_INC);
1126 if (ret) 1136 if (ret) {
1127 ath6kl_err("unable to send the bmi data to the device\n"); 1137 ath6kl_err("unable to send the bmi data to the device\n");
1138 return ret;
1139 }
1128 1140
1129 return ret; 1141 return 0;
1130} 1142}
1131 1143
1132static int ath6kl_sdio_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) 1144static int ath6kl_sdio_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
index a98c12ba70c1..a580a629a0da 100644
--- a/drivers/net/wireless/ath/ath6kl/target.h
+++ b/drivers/net/wireless/ath/ath6kl/target.h
@@ -25,7 +25,7 @@
25#define AR6004_BOARD_DATA_SZ 6144 25#define AR6004_BOARD_DATA_SZ 6144
26#define AR6004_BOARD_EXT_DATA_SZ 0 26#define AR6004_BOARD_EXT_DATA_SZ 0
27 27
28#define RESET_CONTROL_ADDRESS 0x00000000 28#define RESET_CONTROL_ADDRESS 0x00004000
29#define RESET_CONTROL_COLD_RST 0x00000100 29#define RESET_CONTROL_COLD_RST 0x00000100
30#define RESET_CONTROL_MBOX_RST 0x00000004 30#define RESET_CONTROL_MBOX_RST 0x00000004
31 31
diff --git a/drivers/net/wireless/ath/ath6kl/trace.c b/drivers/net/wireless/ath/ath6kl/trace.c
new file mode 100644
index 000000000000..e7d64b1285cb
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/trace.c
@@ -0,0 +1,23 @@
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 <linux/module.h>
18
19#define CREATE_TRACE_POINTS
20#include "trace.h"
21
22EXPORT_TRACEPOINT_SYMBOL(ath6kl_sdio);
23EXPORT_TRACEPOINT_SYMBOL(ath6kl_sdio_scat);
diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h
new file mode 100644
index 000000000000..1a1ea7881b4d
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/trace.h
@@ -0,0 +1,332 @@
1#if !defined(_ATH6KL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
2
3#include <net/cfg80211.h>
4#include <linux/skbuff.h>
5#include <linux/tracepoint.h>
6#include "wmi.h"
7#include "hif.h"
8
9#if !defined(_ATH6KL_TRACE_H)
10static inline unsigned int ath6kl_get_wmi_id(void *buf, size_t buf_len)
11{
12 struct wmi_cmd_hdr *hdr = buf;
13
14 if (buf_len < sizeof(*hdr))
15 return 0;
16
17 return le16_to_cpu(hdr->cmd_id);
18}
19#endif /* __ATH6KL_TRACE_H */
20
21#define _ATH6KL_TRACE_H
22
23/* create empty functions when tracing is disabled */
24#if !defined(CONFIG_ATH6KL_TRACING)
25#undef TRACE_EVENT
26#define TRACE_EVENT(name, proto, ...) \
27static inline void trace_ ## name(proto) {}
28#undef DECLARE_EVENT_CLASS
29#define DECLARE_EVENT_CLASS(...)
30#undef DEFINE_EVENT
31#define DEFINE_EVENT(evt_class, name, proto, ...) \
32static inline void trace_ ## name(proto) {}
33#endif /* !CONFIG_ATH6KL_TRACING || __CHECKER__ */
34
35#undef TRACE_SYSTEM
36#define TRACE_SYSTEM ath6kl
37
38TRACE_EVENT(ath6kl_wmi_cmd,
39 TP_PROTO(void *buf, size_t buf_len),
40
41 TP_ARGS(buf, buf_len),
42
43 TP_STRUCT__entry(
44 __field(unsigned int, id)
45 __field(size_t, buf_len)
46 __dynamic_array(u8, buf, buf_len)
47 ),
48
49 TP_fast_assign(
50 __entry->id = ath6kl_get_wmi_id(buf, buf_len);
51 __entry->buf_len = buf_len;
52 memcpy(__get_dynamic_array(buf), buf, buf_len);
53 ),
54
55 TP_printk(
56 "id %d len %zd",
57 __entry->id, __entry->buf_len
58 )
59);
60
61TRACE_EVENT(ath6kl_wmi_event,
62 TP_PROTO(void *buf, size_t buf_len),
63
64 TP_ARGS(buf, buf_len),
65
66 TP_STRUCT__entry(
67 __field(unsigned int, id)
68 __field(size_t, buf_len)
69 __dynamic_array(u8, buf, buf_len)
70 ),
71
72 TP_fast_assign(
73 __entry->id = ath6kl_get_wmi_id(buf, buf_len);
74 __entry->buf_len = buf_len;
75 memcpy(__get_dynamic_array(buf), buf, buf_len);
76 ),
77
78 TP_printk(
79 "id %d len %zd",
80 __entry->id, __entry->buf_len
81 )
82);
83
84TRACE_EVENT(ath6kl_sdio,
85 TP_PROTO(unsigned int addr, int flags,
86 void *buf, size_t buf_len),
87
88 TP_ARGS(addr, flags, buf, buf_len),
89
90 TP_STRUCT__entry(
91 __field(unsigned int, tx)
92 __field(unsigned int, addr)
93 __field(int, flags)
94 __field(size_t, buf_len)
95 __dynamic_array(u8, buf, buf_len)
96 ),
97
98 TP_fast_assign(
99 __entry->addr = addr;
100 __entry->flags = flags;
101 __entry->buf_len = buf_len;
102 memcpy(__get_dynamic_array(buf), buf, buf_len);
103
104 if (flags & HIF_WRITE)
105 __entry->tx = 1;
106 else
107 __entry->tx = 0;
108 ),
109
110 TP_printk(
111 "%s addr 0x%x flags 0x%x len %zd\n",
112 __entry->tx ? "tx" : "rx",
113 __entry->addr,
114 __entry->flags,
115 __entry->buf_len
116 )
117);
118
119TRACE_EVENT(ath6kl_sdio_scat,
120 TP_PROTO(unsigned int addr, int flags, unsigned int total_len,
121 unsigned int entries, struct hif_scatter_item *list),
122
123 TP_ARGS(addr, flags, total_len, entries, list),
124
125 TP_STRUCT__entry(
126 __field(unsigned int, tx)
127 __field(unsigned int, addr)
128 __field(int, flags)
129 __field(unsigned int, entries)
130 __field(size_t, total_len)
131 __dynamic_array(unsigned int, len_array, entries)
132 __dynamic_array(u8, data, total_len)
133 ),
134
135 TP_fast_assign(
136 unsigned int *len_array;
137 int i, offset = 0;
138 size_t len;
139
140 __entry->addr = addr;
141 __entry->flags = flags;
142 __entry->entries = entries;
143 __entry->total_len = total_len;
144
145 if (flags & HIF_WRITE)
146 __entry->tx = 1;
147 else
148 __entry->tx = 0;
149
150 len_array = __get_dynamic_array(len_array);
151
152 for (i = 0; i < entries; i++) {
153 len = list[i].len;
154
155 memcpy((u8 *) __get_dynamic_array(data) + offset,
156 list[i].buf, len);
157
158 len_array[i] = len;
159 offset += len;
160 }
161 ),
162
163 TP_printk(
164 "%s addr 0x%x flags 0x%x entries %d total_len %zd\n",
165 __entry->tx ? "tx" : "rx",
166 __entry->addr,
167 __entry->flags,
168 __entry->entries,
169 __entry->total_len
170 )
171);
172
173TRACE_EVENT(ath6kl_sdio_irq,
174 TP_PROTO(void *buf, size_t buf_len),
175
176 TP_ARGS(buf, buf_len),
177
178 TP_STRUCT__entry(
179 __field(size_t, buf_len)
180 __dynamic_array(u8, buf, buf_len)
181 ),
182
183 TP_fast_assign(
184 __entry->buf_len = buf_len;
185 memcpy(__get_dynamic_array(buf), buf, buf_len);
186 ),
187
188 TP_printk(
189 "irq len %zd\n", __entry->buf_len
190 )
191);
192
193TRACE_EVENT(ath6kl_htc_rx,
194 TP_PROTO(int status, int endpoint, void *buf,
195 size_t buf_len),
196
197 TP_ARGS(status, endpoint, buf, buf_len),
198
199 TP_STRUCT__entry(
200 __field(int, status)
201 __field(int, endpoint)
202 __field(size_t, buf_len)
203 __dynamic_array(u8, buf, buf_len)
204 ),
205
206 TP_fast_assign(
207 __entry->status = status;
208 __entry->endpoint = endpoint;
209 __entry->buf_len = buf_len;
210 memcpy(__get_dynamic_array(buf), buf, buf_len);
211 ),
212
213 TP_printk(
214 "status %d endpoint %d len %zd\n",
215 __entry->status,
216 __entry->endpoint,
217 __entry->buf_len
218 )
219);
220
221TRACE_EVENT(ath6kl_htc_tx,
222 TP_PROTO(int status, int endpoint, void *buf,
223 size_t buf_len),
224
225 TP_ARGS(status, endpoint, buf, buf_len),
226
227 TP_STRUCT__entry(
228 __field(int, status)
229 __field(int, endpoint)
230 __field(size_t, buf_len)
231 __dynamic_array(u8, buf, buf_len)
232 ),
233
234 TP_fast_assign(
235 __entry->status = status;
236 __entry->endpoint = endpoint;
237 __entry->buf_len = buf_len;
238 memcpy(__get_dynamic_array(buf), buf, buf_len);
239 ),
240
241 TP_printk(
242 "status %d endpoint %d len %zd\n",
243 __entry->status,
244 __entry->endpoint,
245 __entry->buf_len
246 )
247);
248
249#define ATH6KL_MSG_MAX 200
250
251DECLARE_EVENT_CLASS(ath6kl_log_event,
252 TP_PROTO(struct va_format *vaf),
253 TP_ARGS(vaf),
254 TP_STRUCT__entry(
255 __dynamic_array(char, msg, ATH6KL_MSG_MAX)
256 ),
257 TP_fast_assign(
258 WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
259 ATH6KL_MSG_MAX,
260 vaf->fmt,
261 *vaf->va) >= ATH6KL_MSG_MAX);
262 ),
263 TP_printk("%s", __get_str(msg))
264);
265
266DEFINE_EVENT(ath6kl_log_event, ath6kl_log_err,
267 TP_PROTO(struct va_format *vaf),
268 TP_ARGS(vaf)
269);
270
271DEFINE_EVENT(ath6kl_log_event, ath6kl_log_warn,
272 TP_PROTO(struct va_format *vaf),
273 TP_ARGS(vaf)
274);
275
276DEFINE_EVENT(ath6kl_log_event, ath6kl_log_info,
277 TP_PROTO(struct va_format *vaf),
278 TP_ARGS(vaf)
279);
280
281TRACE_EVENT(ath6kl_log_dbg,
282 TP_PROTO(unsigned int level, struct va_format *vaf),
283 TP_ARGS(level, vaf),
284 TP_STRUCT__entry(
285 __field(unsigned int, level)
286 __dynamic_array(char, msg, ATH6KL_MSG_MAX)
287 ),
288 TP_fast_assign(
289 __entry->level = level;
290 WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
291 ATH6KL_MSG_MAX,
292 vaf->fmt,
293 *vaf->va) >= ATH6KL_MSG_MAX);
294 ),
295 TP_printk("%s", __get_str(msg))
296);
297
298TRACE_EVENT(ath6kl_log_dbg_dump,
299 TP_PROTO(const char *msg, const char *prefix,
300 const void *buf, size_t buf_len),
301
302 TP_ARGS(msg, prefix, buf, buf_len),
303
304 TP_STRUCT__entry(
305 __string(msg, msg)
306 __string(prefix, prefix)
307 __field(size_t, buf_len)
308 __dynamic_array(u8, buf, buf_len)
309 ),
310
311 TP_fast_assign(
312 __assign_str(msg, msg);
313 __assign_str(prefix, prefix);
314 __entry->buf_len = buf_len;
315 memcpy(__get_dynamic_array(buf), buf, buf_len);
316 ),
317
318 TP_printk(
319 "%s/%s\n", __get_str(prefix), __get_str(msg)
320 )
321);
322
323#endif /* _ ATH6KL_TRACE_H || TRACE_HEADER_MULTI_READ*/
324
325/* we don't want to use include/trace/events */
326#undef TRACE_INCLUDE_PATH
327#define TRACE_INCLUDE_PATH .
328#undef TRACE_INCLUDE_FILE
329#define TRACE_INCLUDE_FILE trace
330
331/* This part must be outside protection */
332#include <trace/define_trace.h>
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 78b369286579..ebb24045a8ae 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -20,6 +20,7 @@
20#include "core.h" 20#include "core.h"
21#include "debug.h" 21#include "debug.h"
22#include "htc-ops.h" 22#include "htc-ops.h"
23#include "trace.h"
23 24
24/* 25/*
25 * tid - tid_mux0..tid_mux3 26 * tid - tid_mux0..tid_mux3
@@ -288,6 +289,8 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
288 int status = 0; 289 int status = 0;
289 struct ath6kl_cookie *cookie = NULL; 290 struct ath6kl_cookie *cookie = NULL;
290 291
292 trace_ath6kl_wmi_cmd(skb->data, skb->len);
293
291 if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) { 294 if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) {
292 dev_kfree_skb(skb); 295 dev_kfree_skb(skb);
293 return -EACCES; 296 return -EACCES;
@@ -1324,7 +1327,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1324 __func__, ar, ept, skb, packet->buf, 1327 __func__, ar, ept, skb, packet->buf,
1325 packet->act_len, status); 1328 packet->act_len, status);
1326 1329
1327 if (status || !(skb->data + HTC_HDR_LENGTH)) { 1330 if (status || packet->act_len < HTC_HDR_LENGTH) {
1328 dev_kfree_skb(skb); 1331 dev_kfree_skb(skb);
1329 return; 1332 return;
1330 } 1333 }
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index 5fcd342762de..bed0d337712d 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -856,11 +856,9 @@ static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
856 int ret; 856 int ret;
857 857
858 if (size > 0) { 858 if (size > 0) {
859 buf = kmalloc(size, GFP_KERNEL); 859 buf = kmemdup(data, size, GFP_KERNEL);
860 if (buf == NULL) 860 if (buf == NULL)
861 return -ENOMEM; 861 return -ENOMEM;
862
863 memcpy(buf, data, size);
864 } 862 }
865 863
866 /* note: if successful returns number of bytes transfered */ 864 /* note: if successful returns number of bytes transfered */
@@ -872,8 +870,9 @@ static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
872 size, 1000); 870 size, 1000);
873 871
874 if (ret < 0) { 872 if (ret < 0) {
875 ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", 873 ath6kl_warn("Failed to submit usb control message: %d\n", ret);
876 __func__, ret); 874 kfree(buf);
875 return ret;
877 } 876 }
878 877
879 kfree(buf); 878 kfree(buf);
@@ -903,8 +902,9 @@ static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb,
903 size, 2 * HZ); 902 size, 2 * HZ);
904 903
905 if (ret < 0) { 904 if (ret < 0) {
906 ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", 905 ath6kl_warn("Failed to read usb control message: %d\n", ret);
907 __func__, ret); 906 kfree(buf);
907 return ret;
908 } 908 }
909 909
910 memcpy((u8 *) data, buf, size); 910 memcpy((u8 *) data, buf, size);
@@ -961,8 +961,10 @@ static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
961 ATH6KL_USB_CONTROL_REQ_DIAG_RESP, 961 ATH6KL_USB_CONTROL_REQ_DIAG_RESP,
962 ar_usb->diag_resp_buffer, &resp_len); 962 ar_usb->diag_resp_buffer, &resp_len);
963 963
964 if (ret) 964 if (ret) {
965 ath6kl_warn("diag read32 failed: %d\n", ret);
965 return ret; 966 return ret;
967 }
966 968
967 resp = (struct ath6kl_usb_ctrl_diag_resp_read *) 969 resp = (struct ath6kl_usb_ctrl_diag_resp_read *)
968 ar_usb->diag_resp_buffer; 970 ar_usb->diag_resp_buffer;
@@ -976,6 +978,7 @@ static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
976{ 978{
977 struct ath6kl_usb *ar_usb = ar->hif_priv; 979 struct ath6kl_usb *ar_usb = ar->hif_priv;
978 struct ath6kl_usb_ctrl_diag_cmd_write *cmd; 980 struct ath6kl_usb_ctrl_diag_cmd_write *cmd;
981 int ret;
979 982
980 cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer; 983 cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer;
981 984
@@ -984,12 +987,17 @@ static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
984 cmd->address = cpu_to_le32(address); 987 cmd->address = cpu_to_le32(address);
985 cmd->value = data; 988 cmd->value = data;
986 989
987 return ath6kl_usb_ctrl_msg_exchange(ar_usb, 990 ret = ath6kl_usb_ctrl_msg_exchange(ar_usb,
988 ATH6KL_USB_CONTROL_REQ_DIAG_CMD, 991 ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
989 (u8 *) cmd, 992 (u8 *) cmd,
990 sizeof(*cmd), 993 sizeof(*cmd),
991 0, NULL, NULL); 994 0, NULL, NULL);
995 if (ret) {
996 ath6kl_warn("diag_write32 failed: %d\n", ret);
997 return ret;
998 }
992 999
1000 return 0;
993} 1001}
994 1002
995static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) 1003static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
@@ -1001,7 +1009,7 @@ static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
1001 ret = ath6kl_usb_submit_ctrl_in(ar_usb, 1009 ret = ath6kl_usb_submit_ctrl_in(ar_usb,
1002 ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP, 1010 ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP,
1003 0, 0, buf, len); 1011 0, 0, buf, len);
1004 if (ret != 0) { 1012 if (ret) {
1005 ath6kl_err("Unable to read the bmi data from the device: %d\n", 1013 ath6kl_err("Unable to read the bmi data from the device: %d\n",
1006 ret); 1014 ret);
1007 return ret; 1015 return ret;
@@ -1019,7 +1027,7 @@ static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
1019 ret = ath6kl_usb_submit_ctrl_out(ar_usb, 1027 ret = ath6kl_usb_submit_ctrl_out(ar_usb,
1020 ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD, 1028 ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD,
1021 0, 0, buf, len); 1029 0, 0, buf, len);
1022 if (ret != 0) { 1030 if (ret) {
1023 ath6kl_err("unable to send the bmi data to the device: %d\n", 1031 ath6kl_err("unable to send the bmi data to the device: %d\n",
1024 ret); 1032 ret);
1025 return ret; 1033 return ret;
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index d76b5bd81a0d..87aefb4c4c23 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -20,6 +20,7 @@
20#include "core.h" 20#include "core.h"
21#include "debug.h" 21#include "debug.h"
22#include "testmode.h" 22#include "testmode.h"
23#include "trace.h"
23#include "../regd.h" 24#include "../regd.h"
24#include "../regd_common.h" 25#include "../regd_common.h"
25 26
@@ -2028,6 +2029,9 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
2028 if (!sband) 2029 if (!sband)
2029 continue; 2030 continue;
2030 2031
2032 if (WARN_ON(band >= ATH6KL_NUM_BANDS))
2033 break;
2034
2031 ratemask = rates[band]; 2035 ratemask = rates[band];
2032 supp_rates = sc->supp_rates[band].rates; 2036 supp_rates = sc->supp_rates[band].rates;
2033 num_rates = 0; 2037 num_rates = 0;
@@ -4086,6 +4090,8 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
4086 return -EINVAL; 4090 return -EINVAL;
4087 } 4091 }
4088 4092
4093 trace_ath6kl_wmi_event(skb->data, skb->len);
4094
4089 return ath6kl_wmi_proc_events(wmi, skb); 4095 return ath6kl_wmi_proc_events(wmi, skb);
4090} 4096}
4091 4097
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 881e989ea470..e6b92ff265fd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3606,6 +3606,12 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3606 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); 3606 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3607 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); 3607 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3608 3608
3609 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3610 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
3611 REG_RMW_FIELD(ah, switch_chain_reg[0],
3612 AR_SWITCH_TABLE_ALL, value);
3613 }
3614
3609 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { 3615 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3610 if ((ah->rxchainmask & BIT(chain)) || 3616 if ((ah->rxchainmask & BIT(chain)) ||
3611 (ah->txchainmask & BIT(chain))) { 3617 (ah->txchainmask & BIT(chain))) {
@@ -3772,6 +3778,17 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3772 AR_PHY_EXT_ATTEN_CTL_2, 3778 AR_PHY_EXT_ATTEN_CTL_2,
3773 }; 3779 };
3774 3780
3781 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3782 value = ar9003_hw_atten_chain_get(ah, 1, chan);
3783 REG_RMW_FIELD(ah, ext_atten_reg[0],
3784 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3785
3786 value = ar9003_hw_atten_chain_get_margin(ah, 1, chan);
3787 REG_RMW_FIELD(ah, ext_atten_reg[0],
3788 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3789 value);
3790 }
3791
3775 /* Test value. if 0 then attenuation is unused. Don't load anything. */ 3792 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3776 for (i = 0; i < 3; i++) { 3793 for (i = 0; i < 3; i++) {
3777 if (ah->txchainmask & BIT(i)) { 3794 if (ah->txchainmask & BIT(i)) {
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index ccc42a71b436..999ab08c34e6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -37,28 +37,28 @@ static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = {
37 /* Addr allmodes */ 37 /* Addr allmodes */
38 {0x00018c00, 0x18253ede}, 38 {0x00018c00, 0x18253ede},
39 {0x00018c04, 0x000801d8}, 39 {0x00018c04, 0x000801d8},
40 {0x00018c08, 0x0003580c}, 40 {0x00018c08, 0x0003780c},
41}; 41};
42 42
43static const u32 ar9462_2p0_baseband_postamble[][5] = { 43static const u32 ar9462_2p0_baseband_postamble[][5] = {
44 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 44 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
45 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, 45 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
46 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae}, 46 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae},
47 {0x00009824, 0x5ac640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da}, 47 {0x00009824, 0x63c640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da},
48 {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x09143e81}, 48 {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x09143e81},
49 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, 49 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
50 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, 50 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
51 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, 51 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
52 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, 52 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a2},
53 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, 53 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
54 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, 54 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8},
55 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, 55 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e},
56 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x32395d5e}, 56 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e},
57 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 57 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
58 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, 58 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
59 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, 59 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
60 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, 60 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
61 {0x00009e3c, 0xcf946222, 0xcf946222, 0xcfd5c782, 0xcfd5c282}, 61 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
62 {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, 62 {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27},
63 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, 63 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
64 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, 64 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
@@ -82,9 +82,9 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
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},
85 {0x0000a3a4, 0x00000010, 0x00000010, 0x00000000, 0x00000000}, 85 {0x0000a3a4, 0x00000050, 0x00000050, 0x00000000, 0x00000000},
86 {0x0000a3a8, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}, 86 {0x0000a3a8, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa},
87 {0x0000a3ac, 0xaaaaaa00, 0xaaaaaa30, 0xaaaaaa00, 0xaaaaaa00}, 87 {0x0000a3ac, 0xaaaaaa00, 0xaa30aa30, 0xaaaaaa00, 0xaaaaaa00},
88 {0x0000a41c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, 88 {0x0000a41c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
89 {0x0000a420, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce}, 89 {0x0000a420, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce},
90 {0x0000a424, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, 90 {0x0000a424, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
@@ -363,14 +363,14 @@ static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = {
363 /* Addr allmodes */ 363 /* Addr allmodes */
364 {0x00018c00, 0x18213ede}, 364 {0x00018c00, 0x18213ede},
365 {0x00018c04, 0x000801d8}, 365 {0x00018c04, 0x000801d8},
366 {0x00018c08, 0x0003580c}, 366 {0x00018c08, 0x0003780c},
367}; 367};
368 368
369static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = { 369static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
370 /* Addr allmodes */ 370 /* Addr allmodes */
371 {0x00018c00, 0x18212ede}, 371 {0x00018c00, 0x18212ede},
372 {0x00018c04, 0x000801d8}, 372 {0x00018c04, 0x000801d8},
373 {0x00018c08, 0x0003580c}, 373 {0x00018c08, 0x0003780c},
374}; 374};
375 375
376static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { 376static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
@@ -775,7 +775,7 @@ static const u32 ar9462_2p0_baseband_core[][2] = {
775 {0x00009fc0, 0x803e4788}, 775 {0x00009fc0, 0x803e4788},
776 {0x00009fc4, 0x0001efb5}, 776 {0x00009fc4, 0x0001efb5},
777 {0x00009fcc, 0x40000014}, 777 {0x00009fcc, 0x40000014},
778 {0x00009fd0, 0x01193b93}, 778 {0x00009fd0, 0x0a193b93},
779 {0x0000a20c, 0x00000000}, 779 {0x0000a20c, 0x00000000},
780 {0x0000a220, 0x00000000}, 780 {0x0000a220, 0x00000000},
781 {0x0000a224, 0x00000000}, 781 {0x0000a224, 0x00000000},
@@ -850,7 +850,7 @@ static const u32 ar9462_2p0_baseband_core[][2] = {
850 {0x0000a7cc, 0x00000000}, 850 {0x0000a7cc, 0x00000000},
851 {0x0000a7d0, 0x00000000}, 851 {0x0000a7d0, 0x00000000},
852 {0x0000a7d4, 0x00000004}, 852 {0x0000a7d4, 0x00000004},
853 {0x0000a7dc, 0x00000001}, 853 {0x0000a7dc, 0x00000000},
854 {0x0000a7f0, 0x80000000}, 854 {0x0000a7f0, 0x80000000},
855 {0x0000a8d0, 0x004b6a8e}, 855 {0x0000a8d0, 0x004b6a8e},
856 {0x0000a8d4, 0x00000820}, 856 {0x0000a8d4, 0x00000820},
@@ -886,7 +886,7 @@ static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
886 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, 886 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
887 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, 887 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
888 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 888 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
889 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 889 {0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de},
890 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 890 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
891 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 891 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
892 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, 892 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
@@ -906,20 +906,20 @@ static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
906 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, 906 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
907 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, 907 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
908 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, 908 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
909 {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, 909 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81},
910 {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83}, 910 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83},
911 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84}, 911 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84},
912 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, 912 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
913 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, 913 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
914 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, 914 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
915 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, 915 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
916 {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 916 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec},
917 {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 917 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0},
918 {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 918 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4},
919 {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 919 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
920 {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 920 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
921 {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 921 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
922 {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 922 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
923 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 923 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
924 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 924 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
925 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 925 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -1053,7 +1053,6 @@ static const u32 ar9462_2p0_mac_core[][2] = {
1053 {0x00008044, 0x00000000}, 1053 {0x00008044, 0x00000000},
1054 {0x00008048, 0x00000000}, 1054 {0x00008048, 0x00000000},
1055 {0x0000804c, 0xffffffff}, 1055 {0x0000804c, 0xffffffff},
1056 {0x00008050, 0xffffffff},
1057 {0x00008054, 0x00000000}, 1056 {0x00008054, 0x00000000},
1058 {0x00008058, 0x00000000}, 1057 {0x00008058, 0x00000000},
1059 {0x0000805c, 0x000fc78f}, 1058 {0x0000805c, 0x000fc78f},
@@ -1117,9 +1116,9 @@ static const u32 ar9462_2p0_mac_core[][2] = {
1117 {0x000081f8, 0x00000000}, 1116 {0x000081f8, 0x00000000},
1118 {0x000081fc, 0x00000000}, 1117 {0x000081fc, 0x00000000},
1119 {0x00008240, 0x00100000}, 1118 {0x00008240, 0x00100000},
1120 {0x00008244, 0x0010f424}, 1119 {0x00008244, 0x0010f400},
1121 {0x00008248, 0x00000800}, 1120 {0x00008248, 0x00000800},
1122 {0x0000824c, 0x0001e848}, 1121 {0x0000824c, 0x0001e800},
1123 {0x00008250, 0x00000000}, 1122 {0x00008250, 0x00000000},
1124 {0x00008254, 0x00000000}, 1123 {0x00008254, 0x00000000},
1125 {0x00008258, 0x00000000}, 1124 {0x00008258, 0x00000000},
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 1e8508530e98..7bdd726c7a8f 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -369,7 +369,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
369 struct ieee80211_channel *c = chan->chan; 369 struct ieee80211_channel *c = chan->chan;
370 struct ath9k_hw_cal_data *caldata = ah->caldata; 370 struct ath9k_hw_cal_data *caldata = ah->caldata;
371 371
372 chan->channelFlags &= (~CHANNEL_CW_INT);
373 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { 372 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
374 ath_dbg(common, CALIBRATE, 373 ath_dbg(common, CALIBRATE,
375 "NF did not complete in calibration window\n"); 374 "NF did not complete in calibration window\n");
@@ -384,7 +383,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
384 ath_dbg(common, CALIBRATE, 383 ath_dbg(common, CALIBRATE,
385 "noise floor failed detected; detected %d, threshold %d\n", 384 "noise floor failed detected; detected %d, threshold %d\n",
386 nf, nfThresh); 385 nf, nfThresh);
387 chan->channelFlags |= CHANNEL_CW_INT;
388 } 386 }
389 387
390 if (!caldata) { 388 if (!caldata) {
@@ -410,7 +408,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
410 int i, j; 408 int i, j;
411 409
412 ah->caldata->channel = chan->channel; 410 ah->caldata->channel = chan->channel;
413 ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT; 411 ah->caldata->channelFlags = chan->channelFlags;
414 ah->caldata->chanmode = chan->chanmode; 412 ah->caldata->chanmode = chan->chanmode;
415 h = ah->caldata->nfCalHist; 413 h = ah->caldata->nfCalHist;
416 default_nf = ath9k_hw_get_default_nf(ah, chan); 414 default_nf = ath9k_hw_get_default_nf(ah, chan);
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 050ca4a4850d..6102476a65de 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -40,7 +40,7 @@
40 x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \ 40 x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \
41} while (0) 41} while (0)
42#define ATH_EP_RND(x, mul) \ 42#define ATH_EP_RND(x, mul) \
43 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) 43 (((x) + ((mul)/2)) / (mul))
44 44
45int ath9k_cmn_padpos(__le16 frame_control); 45int ath9k_cmn_padpos(__le16 frame_control);
46int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); 46int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 3714b971d18e..67a2a4b3b883 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -537,6 +537,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
537 PR("AMPDUs Completed:", a_completed); 537 PR("AMPDUs Completed:", a_completed);
538 PR("AMPDUs Retried: ", a_retries); 538 PR("AMPDUs Retried: ", a_retries);
539 PR("AMPDUs XRetried: ", a_xretries); 539 PR("AMPDUs XRetried: ", a_xretries);
540 PR("TXERR Filtered: ", txerr_filtered);
540 PR("FIFO Underrun: ", fifo_underrun); 541 PR("FIFO Underrun: ", fifo_underrun);
541 PR("TXOP Exceeded: ", xtxop); 542 PR("TXOP Exceeded: ", xtxop);
542 PR("TXTIMER Expiry: ", timer_exp); 543 PR("TXTIMER Expiry: ", timer_exp);
@@ -756,6 +757,8 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
756 TX_STAT_INC(qnum, completed); 757 TX_STAT_INC(qnum, completed);
757 } 758 }
758 759
760 if (ts->ts_status & ATH9K_TXERR_FILT)
761 TX_STAT_INC(qnum, txerr_filtered);
759 if (ts->ts_status & ATH9K_TXERR_FIFO) 762 if (ts->ts_status & ATH9K_TXERR_FIFO)
760 TX_STAT_INC(qnum, fifo_underrun); 763 TX_STAT_INC(qnum, fifo_underrun);
761 if (ts->ts_status & ATH9K_TXERR_XTXOP) 764 if (ts->ts_status & ATH9K_TXERR_XTXOP)
@@ -1909,6 +1912,7 @@ static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = {
1909 AMKSTR(d_tx_desc_cfg_err), 1912 AMKSTR(d_tx_desc_cfg_err),
1910 AMKSTR(d_tx_data_underrun), 1913 AMKSTR(d_tx_data_underrun),
1911 AMKSTR(d_tx_delim_underrun), 1914 AMKSTR(d_tx_delim_underrun),
1915 "d_rx_crc_err",
1912 "d_rx_decrypt_crc_err", 1916 "d_rx_decrypt_crc_err",
1913 "d_rx_phy_err", 1917 "d_rx_phy_err",
1914 "d_rx_mic_err", 1918 "d_rx_mic_err",
@@ -1989,6 +1993,7 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw,
1989 AWDATA(data_underrun); 1993 AWDATA(data_underrun);
1990 AWDATA(delim_underrun); 1994 AWDATA(delim_underrun);
1991 1995
1996 AWDATA_RX(crc_err);
1992 AWDATA_RX(decrypt_crc_err); 1997 AWDATA_RX(decrypt_crc_err);
1993 AWDATA_RX(phy_err); 1998 AWDATA_RX(phy_err);
1994 AWDATA_RX(mic_err); 1999 AWDATA_RX(mic_err);
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 410d6d8f1aa7..794a7ec83a24 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -142,6 +142,7 @@ struct ath_interrupt_stats {
142 * @a_completed: Total AMPDUs completed 142 * @a_completed: Total AMPDUs completed
143 * @a_retries: No. of AMPDUs retried (SW) 143 * @a_retries: No. of AMPDUs retried (SW)
144 * @a_xretries: No. of AMPDUs dropped due to xretries 144 * @a_xretries: No. of AMPDUs dropped due to xretries
145 * @txerr_filtered: No. of frames with TXERR_FILT flag set.
145 * @fifo_underrun: FIFO underrun occurrences 146 * @fifo_underrun: FIFO underrun occurrences
146 Valid only for: 147 Valid only for:
147 - non-aggregate condition. 148 - non-aggregate condition.
@@ -168,6 +169,7 @@ struct ath_tx_stats {
168 u32 a_completed; 169 u32 a_completed;
169 u32 a_retries; 170 u32 a_retries;
170 u32 a_xretries; 171 u32 a_xretries;
172 u32 txerr_filtered;
171 u32 fifo_underrun; 173 u32 fifo_underrun;
172 u32 xtxop; 174 u32 xtxop;
173 u32 timer_exp; 175 u32 timer_exp;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 07e25260c31d..4fa2bb167050 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1669,6 +1669,104 @@ bool ath9k_hw_check_alive(struct ath_hw *ah)
1669} 1669}
1670EXPORT_SYMBOL(ath9k_hw_check_alive); 1670EXPORT_SYMBOL(ath9k_hw_check_alive);
1671 1671
1672static void ath9k_hw_init_mfp(struct ath_hw *ah)
1673{
1674 /* Setup MFP options for CCMP */
1675 if (AR_SREV_9280_20_OR_LATER(ah)) {
1676 /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
1677 * frames when constructing CCMP AAD. */
1678 REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
1679 0xc7ff);
1680 ah->sw_mgmt_crypto = false;
1681 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
1682 /* Disable hardware crypto for management frames */
1683 REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
1684 AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
1685 REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
1686 AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
1687 ah->sw_mgmt_crypto = true;
1688 } else {
1689 ah->sw_mgmt_crypto = true;
1690 }
1691}
1692
1693static void ath9k_hw_reset_opmode(struct ath_hw *ah,
1694 u32 macStaId1, u32 saveDefAntenna)
1695{
1696 struct ath_common *common = ath9k_hw_common(ah);
1697
1698 ENABLE_REGWRITE_BUFFER(ah);
1699
1700 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
1701 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
1702 | macStaId1
1703 | AR_STA_ID1_RTS_USE_DEF
1704 | (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
1705 | ah->sta_id1_defaults);
1706 ath_hw_setbssidmask(common);
1707 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
1708 ath9k_hw_write_associd(ah);
1709 REG_WRITE(ah, AR_ISR, ~0);
1710 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
1711
1712 REGWRITE_BUFFER_FLUSH(ah);
1713
1714 ath9k_hw_set_operating_mode(ah, ah->opmode);
1715}
1716
1717static void ath9k_hw_init_queues(struct ath_hw *ah)
1718{
1719 int i;
1720
1721 ENABLE_REGWRITE_BUFFER(ah);
1722
1723 for (i = 0; i < AR_NUM_DCU; i++)
1724 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
1725
1726 REGWRITE_BUFFER_FLUSH(ah);
1727
1728 ah->intr_txqs = 0;
1729 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1730 ath9k_hw_resettxqueue(ah, i);
1731}
1732
1733/*
1734 * For big endian systems turn on swapping for descriptors
1735 */
1736static void ath9k_hw_init_desc(struct ath_hw *ah)
1737{
1738 struct ath_common *common = ath9k_hw_common(ah);
1739
1740 if (AR_SREV_9100(ah)) {
1741 u32 mask;
1742 mask = REG_READ(ah, AR_CFG);
1743 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
1744 ath_dbg(common, RESET, "CFG Byte Swap Set 0x%x\n",
1745 mask);
1746 } else {
1747 mask = INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
1748 REG_WRITE(ah, AR_CFG, mask);
1749 ath_dbg(common, RESET, "Setting CFG 0x%x\n",
1750 REG_READ(ah, AR_CFG));
1751 }
1752 } else {
1753 if (common->bus_ops->ath_bus_type == ATH_USB) {
1754 /* Configure AR9271 target WLAN */
1755 if (AR_SREV_9271(ah))
1756 REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB);
1757 else
1758 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
1759 }
1760#ifdef __BIG_ENDIAN
1761 else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
1762 AR_SREV_9550(ah))
1763 REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
1764 else
1765 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
1766#endif
1767 }
1768}
1769
1672/* 1770/*
1673 * Fast channel change: 1771 * Fast channel change:
1674 * (Change synthesizer based on channel freq without resetting chip) 1772 * (Change synthesizer based on channel freq without resetting chip)
@@ -1746,7 +1844,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1746 u32 saveDefAntenna; 1844 u32 saveDefAntenna;
1747 u32 macStaId1; 1845 u32 macStaId1;
1748 u64 tsf = 0; 1846 u64 tsf = 0;
1749 int i, r; 1847 int r;
1750 bool start_mci_reset = false; 1848 bool start_mci_reset = false;
1751 bool save_fullsleep = ah->chip_fullsleep; 1849 bool save_fullsleep = ah->chip_fullsleep;
1752 1850
@@ -1763,10 +1861,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1763 ath9k_hw_getnf(ah, ah->curchan); 1861 ath9k_hw_getnf(ah, ah->curchan);
1764 1862
1765 ah->caldata = caldata; 1863 ah->caldata = caldata;
1766 if (caldata && 1864 if (caldata && (chan->channel != caldata->channel ||
1767 (chan->channel != caldata->channel || 1865 chan->channelFlags != caldata->channelFlags)) {
1768 (chan->channelFlags & ~CHANNEL_CW_INT) !=
1769 (caldata->channelFlags & ~CHANNEL_CW_INT))) {
1770 /* Operating channel changed, reset channel calibration data */ 1866 /* Operating channel changed, reset channel calibration data */
1771 memset(caldata, 0, sizeof(*caldata)); 1867 memset(caldata, 0, sizeof(*caldata));
1772 ath9k_init_nfcal_hist_buffer(ah, chan); 1868 ath9k_init_nfcal_hist_buffer(ah, chan);
@@ -1853,22 +1949,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1853 ath9k_hw_settsf64(ah, tsf); 1949 ath9k_hw_settsf64(ah, tsf);
1854 } 1950 }
1855 1951
1856 /* Setup MFP options for CCMP */ 1952 ath9k_hw_init_mfp(ah);
1857 if (AR_SREV_9280_20_OR_LATER(ah)) {
1858 /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
1859 * frames when constructing CCMP AAD. */
1860 REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
1861 0xc7ff);
1862 ah->sw_mgmt_crypto = false;
1863 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
1864 /* Disable hardware crypto for management frames */
1865 REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
1866 AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
1867 REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
1868 AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
1869 ah->sw_mgmt_crypto = true;
1870 } else
1871 ah->sw_mgmt_crypto = true;
1872 1953
1873 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) 1954 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
1874 ath9k_hw_set_delta_slope(ah, chan); 1955 ath9k_hw_set_delta_slope(ah, chan);
@@ -1876,24 +1957,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1876 ath9k_hw_spur_mitigate_freq(ah, chan); 1957 ath9k_hw_spur_mitigate_freq(ah, chan);
1877 ah->eep_ops->set_board_values(ah, chan); 1958 ah->eep_ops->set_board_values(ah, chan);
1878 1959
1879 ENABLE_REGWRITE_BUFFER(ah); 1960 ath9k_hw_reset_opmode(ah, macStaId1, saveDefAntenna);
1880
1881 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
1882 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
1883 | macStaId1
1884 | AR_STA_ID1_RTS_USE_DEF
1885 | (ah->config.
1886 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
1887 | ah->sta_id1_defaults);
1888 ath_hw_setbssidmask(common);
1889 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
1890 ath9k_hw_write_associd(ah);
1891 REG_WRITE(ah, AR_ISR, ~0);
1892 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
1893
1894 REGWRITE_BUFFER_FLUSH(ah);
1895
1896 ath9k_hw_set_operating_mode(ah, ah->opmode);
1897 1961
1898 r = ath9k_hw_rf_set_freq(ah, chan); 1962 r = ath9k_hw_rf_set_freq(ah, chan);
1899 if (r) 1963 if (r)
@@ -1901,17 +1965,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1901 1965
1902 ath9k_hw_set_clockrate(ah); 1966 ath9k_hw_set_clockrate(ah);
1903 1967
1904 ENABLE_REGWRITE_BUFFER(ah); 1968 ath9k_hw_init_queues(ah);
1905
1906 for (i = 0; i < AR_NUM_DCU; i++)
1907 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
1908
1909 REGWRITE_BUFFER_FLUSH(ah);
1910
1911 ah->intr_txqs = 0;
1912 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1913 ath9k_hw_resettxqueue(ah, i);
1914
1915 ath9k_hw_init_interrupt_masks(ah, ah->opmode); 1969 ath9k_hw_init_interrupt_masks(ah, ah->opmode);
1916 ath9k_hw_ani_cache_ini_regs(ah); 1970 ath9k_hw_ani_cache_ini_regs(ah);
1917 ath9k_hw_init_qos(ah); 1971 ath9k_hw_init_qos(ah);
@@ -1966,38 +2020,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1966 2020
1967 REGWRITE_BUFFER_FLUSH(ah); 2021 REGWRITE_BUFFER_FLUSH(ah);
1968 2022
1969 /* 2023 ath9k_hw_init_desc(ah);
1970 * For big endian systems turn on swapping for descriptors
1971 */
1972 if (AR_SREV_9100(ah)) {
1973 u32 mask;
1974 mask = REG_READ(ah, AR_CFG);
1975 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
1976 ath_dbg(common, RESET, "CFG Byte Swap Set 0x%x\n",
1977 mask);
1978 } else {
1979 mask =
1980 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
1981 REG_WRITE(ah, AR_CFG, mask);
1982 ath_dbg(common, RESET, "Setting CFG 0x%x\n",
1983 REG_READ(ah, AR_CFG));
1984 }
1985 } else {
1986 if (common->bus_ops->ath_bus_type == ATH_USB) {
1987 /* Configure AR9271 target WLAN */
1988 if (AR_SREV_9271(ah))
1989 REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB);
1990 else
1991 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
1992 }
1993#ifdef __BIG_ENDIAN
1994 else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
1995 AR_SREV_9550(ah))
1996 REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
1997 else
1998 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
1999#endif
2000 }
2001 2024
2002 if (ath9k_hw_btcoex_is_enabled(ah)) 2025 if (ath9k_hw_btcoex_is_enabled(ah))
2003 ath9k_hw_btcoex_enable(ah); 2026 ath9k_hw_btcoex_enable(ah);
@@ -2010,7 +2033,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2010 2033
2011 if (AR_SREV_9300_20_OR_LATER(ah)) { 2034 if (AR_SREV_9300_20_OR_LATER(ah)) {
2012 ar9003_hw_bb_watchdog_config(ah); 2035 ar9003_hw_bb_watchdog_config(ah);
2013
2014 ar9003_hw_disable_phy_restart(ah); 2036 ar9003_hw_disable_phy_restart(ah);
2015 } 2037 }
2016 2038
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 784e81ccb903..30e62d92d46d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -363,7 +363,6 @@ enum ath9k_int {
363 ATH9K_INT_NOCARD = 0xffffffff 363 ATH9K_INT_NOCARD = 0xffffffff
364}; 364};
365 365
366#define CHANNEL_CW_INT 0x00002
367#define CHANNEL_CCK 0x00020 366#define CHANNEL_CCK 0x00020
368#define CHANNEL_OFDM 0x00040 367#define CHANNEL_OFDM 0x00040
369#define CHANNEL_2GHZ 0x00080 368#define CHANNEL_2GHZ 0x00080
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index 9c0b150d5b8e..c61cafa2665b 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -387,8 +387,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
387 u8 tid; 387 u8 tid;
388 388
389 if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || 389 if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
390 txinfo->flags & IEEE80211_TX_CTL_INJECTED || 390 txinfo->flags & IEEE80211_TX_CTL_INJECTED)
391 (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
392 return; 391 return;
393 392
394 rcu_read_lock(); 393 rcu_read_lock();
@@ -981,30 +980,6 @@ static int carl9170_tx_prepare(struct ar9170 *ar,
981 980
982 SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR, 981 SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR,
983 txc->s.ampdu_settings, factor); 982 txc->s.ampdu_settings, factor);
984
985 for (i = 0; i < CARL9170_TX_MAX_RATES; i++) {
986 txrate = &info->control.rates[i];
987 if (txrate->idx >= 0) {
988 txc->s.ri[i] =
989 CARL9170_TX_SUPER_RI_AMPDU;
990
991 if (WARN_ON(!(txrate->flags &
992 IEEE80211_TX_RC_MCS))) {
993 /*
994 * Not sure if it's even possible
995 * to aggregate non-ht rates with
996 * this HW.
997 */
998 goto err_out;
999 }
1000 continue;
1001 }
1002
1003 txrate->idx = 0;
1004 txrate->count = ar->hw->max_rate_tries;
1005 }
1006
1007 mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1008 } 983 }
1009 984
1010 /* 985 /*
@@ -1012,11 +987,31 @@ static int carl9170_tx_prepare(struct ar9170 *ar,
1012 * taken from mac_control. For all fallback rate, the firmware 987 * taken from mac_control. For all fallback rate, the firmware
1013 * updates the mac_control flags from the rate info field. 988 * updates the mac_control flags from the rate info field.
1014 */ 989 */
1015 for (i = 1; i < CARL9170_TX_MAX_RATES; i++) { 990 for (i = 0; i < CARL9170_TX_MAX_RATES; i++) {
991 __le32 phy_set;
1016 txrate = &info->control.rates[i]; 992 txrate = &info->control.rates[i];
1017 if (txrate->idx < 0) 993 if (txrate->idx < 0)
1018 break; 994 break;
1019 995
996 phy_set = carl9170_tx_physet(ar, info, txrate);
997 if (i == 0) {
998 /* first rate - part of the hw's frame header */
999 txc->f.phy_control = phy_set;
1000
1001 if (ampdu && txrate->flags & IEEE80211_TX_RC_MCS)
1002 mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1003 if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
1004 mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1005 else if (carl9170_tx_cts_check(ar, txrate))
1006 mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1007
1008 } else {
1009 /* fallback rates are stored in the firmware's
1010 * retry rate set array.
1011 */
1012 txc->s.rr[i - 1] = phy_set;
1013 }
1014
1020 SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i], 1015 SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i],
1021 txrate->count); 1016 txrate->count);
1022 1017
@@ -1027,21 +1022,13 @@ static int carl9170_tx_prepare(struct ar9170 *ar,
1027 txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS << 1022 txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS <<
1028 CARL9170_TX_SUPER_RI_ERP_PROT_S); 1023 CARL9170_TX_SUPER_RI_ERP_PROT_S);
1029 1024
1030 txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate); 1025 if (ampdu && (txrate->flags & IEEE80211_TX_RC_MCS))
1026 txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU;
1031 } 1027 }
1032 1028
1033 txrate = &info->control.rates[0];
1034 SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count);
1035
1036 if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
1037 mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1038 else if (carl9170_tx_cts_check(ar, txrate))
1039 mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1040
1041 txc->s.len = cpu_to_le16(skb->len); 1029 txc->s.len = cpu_to_le16(skb->len);
1042 txc->f.length = cpu_to_le16(len + FCS_LEN); 1030 txc->f.length = cpu_to_le16(len + FCS_LEN);
1043 txc->f.mac_control = mac_tmp; 1031 txc->f.mac_control = mac_tmp;
1044 txc->f.phy_control = carl9170_tx_physet(ar, info, txrate);
1045 1032
1046 arinfo = (void *)info->rate_driver_data; 1033 arinfo = (void *)info->rate_driver_data;
1047 arinfo->timeout = jiffies; 1034 arinfo->timeout = jiffies;
@@ -1381,9 +1368,9 @@ static void carl9170_tx(struct ar9170 *ar)
1381} 1368}
1382 1369
1383static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, 1370static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
1384 struct ieee80211_sta *sta, struct sk_buff *skb) 1371 struct ieee80211_sta *sta, struct sk_buff *skb,
1372 struct ieee80211_tx_info *txinfo)
1385{ 1373{
1386 struct _carl9170_tx_superframe *super = (void *) skb->data;
1387 struct carl9170_sta_info *sta_info; 1374 struct carl9170_sta_info *sta_info;
1388 struct carl9170_sta_tid *agg; 1375 struct carl9170_sta_tid *agg;
1389 struct sk_buff *iter; 1376 struct sk_buff *iter;
@@ -1450,7 +1437,7 @@ err_unlock:
1450 1437
1451err_unlock_rcu: 1438err_unlock_rcu:
1452 rcu_read_unlock(); 1439 rcu_read_unlock();
1453 super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR); 1440 txinfo->flags &= ~IEEE80211_TX_CTL_AMPDU;
1454 carl9170_tx_status(ar, skb, false); 1441 carl9170_tx_status(ar, skb, false);
1455 ar->tx_dropped++; 1442 ar->tx_dropped++;
1456 return false; 1443 return false;
@@ -1492,7 +1479,7 @@ void carl9170_op_tx(struct ieee80211_hw *hw,
1492 * sta == NULL checks are redundant in this 1479 * sta == NULL checks are redundant in this
1493 * special case. 1480 * special case.
1494 */ 1481 */
1495 run = carl9170_tx_ampdu_queue(ar, sta, skb); 1482 run = carl9170_tx_ampdu_queue(ar, sta, skb, info);
1496 if (run) 1483 if (run)
1497 carl9170_tx_ampdu(ar); 1484 carl9170_tx_ampdu(ar);
1498 1485
diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile
index 9396dc9fe3c5..d288eea0a26a 100644
--- a/drivers/net/wireless/ath/wil6210/Makefile
+++ b/drivers/net/wireless/ath/wil6210/Makefile
@@ -9,5 +9,7 @@ wil6210-objs += wmi.o
9wil6210-objs += interrupt.o 9wil6210-objs += interrupt.o
10wil6210-objs += txrx.o 10wil6210-objs += txrx.o
11 11
12subdir-ccflags-y += -Werror 12ifeq (, $(findstring -W,$(EXTRA_CFLAGS)))
13 subdir-ccflags-y += -Werror
14endif
13subdir-ccflags-y += -D__CHECK_ENDIAN__ 15subdir-ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 9ecc1968262c..c5d4a87abaaf 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -14,16 +14,6 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/kernel.h>
18#include <linux/netdevice.h>
19#include <linux/sched.h>
20#include <linux/etherdevice.h>
21#include <linux/wireless.h>
22#include <linux/ieee80211.h>
23#include <linux/slab.h>
24#include <linux/version.h>
25#include <net/cfg80211.h>
26
27#include "wil6210.h" 17#include "wil6210.h"
28#include "wmi.h" 18#include "wmi.h"
29 19
@@ -292,7 +282,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
292 282
293 /* WMI_CONNECT_CMD */ 283 /* WMI_CONNECT_CMD */
294 memset(&conn, 0, sizeof(conn)); 284 memset(&conn, 0, sizeof(conn));
295 switch (bss->capability & 0x03) { 285 switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) {
296 case WLAN_CAPABILITY_DMG_TYPE_AP: 286 case WLAN_CAPABILITY_DMG_TYPE_AP:
297 conn.network_type = WMI_NETTYPE_INFRA; 287 conn.network_type = WMI_NETTYPE_INFRA;
298 break; 288 break;
@@ -437,17 +427,18 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
437 if (rc) 427 if (rc)
438 return rc; 428 return rc;
439 429
440 rc = wmi_set_channel(wil, channel->hw_value);
441 if (rc)
442 return rc;
443
444 /* MAC address - pre-requisite for other commands */ 430 /* MAC address - pre-requisite for other commands */
445 wmi_set_mac_address(wil, ndev->dev_addr); 431 wmi_set_mac_address(wil, ndev->dev_addr);
446 432
447 /* IE's */ 433 /* IE's */
448 /* bcon 'head IE's are not relevant for 60g band */ 434 /* bcon 'head IE's are not relevant for 60g band */
449 wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len, 435 /*
450 bcon->beacon_ies); 436 * FW do not form regular beacon, so bcon IE's are not set
437 * For the DMG bcon, when it will be supported, bcon IE's will
438 * be reused; add something like:
439 * wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len,
440 * bcon->beacon_ies);
441 */
451 wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, bcon->proberesp_ies_len, 442 wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, bcon->proberesp_ies_len,
452 bcon->proberesp_ies); 443 bcon->proberesp_ies);
453 wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len, 444 wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len,
@@ -455,7 +446,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
455 446
456 wil->secure_pcp = info->privacy; 447 wil->secure_pcp = info->privacy;
457 448
458 rc = wmi_set_bcon(wil, info->beacon_interval, wmi_nettype); 449 rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype,
450 channel->hw_value);
459 if (rc) 451 if (rc)
460 return rc; 452 return rc;
461 453
@@ -472,11 +464,8 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
472{ 464{
473 int rc = 0; 465 int rc = 0;
474 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 466 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
475 struct wireless_dev *wdev = ndev->ieee80211_ptr;
476 u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
477 467
478 /* To stop beaconing, set BI to 0 */ 468 rc = wmi_pcp_stop(wil);
479 rc = wmi_set_bcon(wil, 0, wmi_nettype);
480 469
481 return rc; 470 return rc;
482} 471}
diff --git a/drivers/net/wireless/ath/wil6210/dbg_hexdump.h b/drivers/net/wireless/ath/wil6210/dbg_hexdump.h
deleted file mode 100644
index e5712f026c47..000000000000
--- a/drivers/net/wireless/ath/wil6210/dbg_hexdump.h
+++ /dev/null
@@ -1,20 +0,0 @@
1#ifndef WIL_DBG_HEXDUMP_H_
2#define WIL_DBG_HEXDUMP_H_
3
4#include <linux/printk.h>
5#include <linux/dynamic_debug.h>
6
7#if defined(CONFIG_DYNAMIC_DEBUG)
8#define wil_print_hex_dump_debug(prefix_str, prefix_type, rowsize, \
9 groupsize, buf, len, ascii) \
10 dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
11 groupsize, buf, len, ascii)
12
13#else /* defined(CONFIG_DYNAMIC_DEBUG) */
14#define wil_print_hex_dump_debug(prefix_str, prefix_type, rowsize, \
15 groupsize, buf, len, ascii) \
16 print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, rowsize, \
17 groupsize, buf, len, ascii)
18#endif /* defined(CONFIG_DYNAMIC_DEBUG) */
19
20#endif /* WIL_DBG_HEXDUMP_H_ */
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 65fc9683bfd8..4be07f5e22b9 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -312,14 +312,6 @@ static const struct file_operations fops_memread = {
312 .llseek = seq_lseek, 312 .llseek = seq_lseek,
313}; 313};
314 314
315static int wil_default_open(struct inode *inode, struct file *file)
316{
317 if (inode->i_private)
318 file->private_data = inode->i_private;
319
320 return 0;
321}
322
323static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, 315static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
324 size_t count, loff_t *ppos) 316 size_t count, loff_t *ppos)
325{ 317{
@@ -361,7 +353,7 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
361 353
362static const struct file_operations fops_ioblob = { 354static const struct file_operations fops_ioblob = {
363 .read = wil_read_file_ioblob, 355 .read = wil_read_file_ioblob,
364 .open = wil_default_open, 356 .open = simple_open,
365 .llseek = default_llseek, 357 .llseek = default_llseek,
366}; 358};
367 359
@@ -396,7 +388,7 @@ static ssize_t wil_write_file_reset(struct file *file, const char __user *buf,
396 388
397static const struct file_operations fops_reset = { 389static const struct file_operations fops_reset = {
398 .write = wil_write_file_reset, 390 .write = wil_write_file_reset,
399 .open = wil_default_open, 391 .open = simple_open,
400}; 392};
401/*---------Tx descriptor------------*/ 393/*---------Tx descriptor------------*/
402 394
@@ -526,7 +518,50 @@ static ssize_t wil_write_file_ssid(struct file *file, const char __user *buf,
526static const struct file_operations fops_ssid = { 518static const struct file_operations fops_ssid = {
527 .read = wil_read_file_ssid, 519 .read = wil_read_file_ssid,
528 .write = wil_write_file_ssid, 520 .write = wil_write_file_ssid,
529 .open = wil_default_open, 521 .open = simple_open,
522};
523
524/*---------temp------------*/
525static void print_temp(struct seq_file *s, const char *prefix, u32 t)
526{
527 switch (t) {
528 case 0:
529 case ~(u32)0:
530 seq_printf(s, "%s N/A\n", prefix);
531 break;
532 default:
533 seq_printf(s, "%s %d.%03d\n", prefix, t / 1000, t % 1000);
534 break;
535 }
536}
537
538static int wil_temp_debugfs_show(struct seq_file *s, void *data)
539{
540 struct wil6210_priv *wil = s->private;
541 u32 t_m, t_r;
542
543 int rc = wmi_get_temperature(wil, &t_m, &t_r);
544 if (rc) {
545 seq_printf(s, "Failed\n");
546 return 0;
547 }
548
549 print_temp(s, "MAC temperature :", t_m);
550 print_temp(s, "Radio temperature :", t_r);
551
552 return 0;
553}
554
555static int wil_temp_seq_open(struct inode *inode, struct file *file)
556{
557 return single_open(file, wil_temp_debugfs_show, inode->i_private);
558}
559
560static const struct file_operations fops_temp = {
561 .open = wil_temp_seq_open,
562 .release = single_release,
563 .read = seq_read,
564 .llseek = seq_lseek,
530}; 565};
531 566
532/*----------------*/ 567/*----------------*/
@@ -563,6 +598,7 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
563 debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread); 598 debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread);
564 599
565 debugfs_create_file("reset", S_IWUSR, dbg, wil, &fops_reset); 600 debugfs_create_file("reset", S_IWUSR, dbg, wil, &fops_reset);
601 debugfs_create_file("temp", S_IRUGO, dbg, wil, &fops_temp);
566 602
567 wil->rgf_blob.data = (void * __force)wil->csr + 0; 603 wil->rgf_blob.data = (void * __force)wil->csr + 0;
568 wil->rgf_blob.size = 0xa000; 604 wil->rgf_blob.size = 0xa000;
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index dc97e7b2609c..e3c1e7684f9c 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -240,6 +240,15 @@ static void wil_notify_fw_error(struct wil6210_priv *wil)
240 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 240 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
241} 241}
242 242
243static void wil_cache_mbox_regs(struct wil6210_priv *wil)
244{
245 /* make shadow copy of registers that should not change on run time */
246 wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
247 sizeof(struct wil6210_mbox_ctl));
248 wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
249 wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
250}
251
243static irqreturn_t wil6210_irq_misc(int irq, void *cookie) 252static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
244{ 253{
245 struct wil6210_priv *wil = cookie; 254 struct wil6210_priv *wil = cookie;
@@ -257,14 +266,19 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
257 wil6210_mask_irq_misc(wil); 266 wil6210_mask_irq_misc(wil);
258 267
259 if (isr & ISR_MISC_FW_ERROR) { 268 if (isr & ISR_MISC_FW_ERROR) {
260 wil_dbg_irq(wil, "IRQ: Firmware error\n"); 269 wil_err(wil, "Firmware error detected\n");
261 clear_bit(wil_status_fwready, &wil->status); 270 clear_bit(wil_status_fwready, &wil->status);
262 wil_notify_fw_error(wil); 271 /*
263 isr &= ~ISR_MISC_FW_ERROR; 272 * do not clear @isr here - we do 2-nd part in thread
273 * there, user space get notified, and it should be done
274 * in non-atomic context
275 */
264 } 276 }
265 277
266 if (isr & ISR_MISC_FW_READY) { 278 if (isr & ISR_MISC_FW_READY) {
267 wil_dbg_irq(wil, "IRQ: FW ready\n"); 279 wil_dbg_irq(wil, "IRQ: FW ready\n");
280 wil_cache_mbox_regs(wil);
281 set_bit(wil_status_reset_done, &wil->status);
268 /** 282 /**
269 * Actual FW ready indicated by the 283 * Actual FW ready indicated by the
270 * WMI_FW_READY_EVENTID 284 * WMI_FW_READY_EVENTID
@@ -289,6 +303,11 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
289 303
290 wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr); 304 wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr);
291 305
306 if (isr & ISR_MISC_FW_ERROR) {
307 wil_notify_fw_error(wil);
308 isr &= ~ISR_MISC_FW_ERROR;
309 }
310
292 if (isr & ISR_MISC_MBOX_EVT) { 311 if (isr & ISR_MISC_MBOX_EVT) {
293 wil_dbg_irq(wil, "MBOX event\n"); 312 wil_dbg_irq(wil, "MBOX event\n");
294 wmi_recv_cmd(wil); 313 wmi_recv_cmd(wil);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 761c389586d4..a0478e2f6868 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -14,12 +14,6 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/kernel.h>
18#include <linux/netdevice.h>
19#include <linux/sched.h>
20#include <linux/ieee80211.h>
21#include <linux/wireless.h>
22#include <linux/slab.h>
23#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
24#include <linux/if_arp.h> 18#include <linux/if_arp.h>
25 19
@@ -109,13 +103,24 @@ static void wil_connect_timer_fn(ulong x)
109 schedule_work(&wil->disconnect_worker); 103 schedule_work(&wil->disconnect_worker);
110} 104}
111 105
112static void wil_cache_mbox_regs(struct wil6210_priv *wil) 106static void wil_connect_worker(struct work_struct *work)
113{ 107{
114 /* make shadow copy of registers that should not change on run time */ 108 int rc;
115 wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX, 109 struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
116 sizeof(struct wil6210_mbox_ctl)); 110 connect_worker);
117 wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx); 111 int cid = wil->pending_connect_cid;
118 wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); 112
113 if (cid < 0) {
114 wil_err(wil, "No connection pending\n");
115 return;
116 }
117
118 wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid);
119
120 rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE, cid, 0);
121 wil->pending_connect_cid = -1;
122 if (rc == 0)
123 wil_link_on(wil);
119} 124}
120 125
121int wil_priv_init(struct wil6210_priv *wil) 126int wil_priv_init(struct wil6210_priv *wil)
@@ -130,7 +135,7 @@ int wil_priv_init(struct wil6210_priv *wil)
130 wil->pending_connect_cid = -1; 135 wil->pending_connect_cid = -1;
131 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); 136 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil);
132 137
133 INIT_WORK(&wil->wmi_connect_worker, wmi_connect_worker); 138 INIT_WORK(&wil->connect_worker, wil_connect_worker);
134 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); 139 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker);
135 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); 140 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
136 141
@@ -147,8 +152,6 @@ int wil_priv_init(struct wil6210_priv *wil)
147 return -EAGAIN; 152 return -EAGAIN;
148 } 153 }
149 154
150 wil_cache_mbox_regs(wil);
151
152 return 0; 155 return 0;
153} 156}
154 157
@@ -185,15 +188,11 @@ static void wil_target_reset(struct wil6210_priv *wil)
185 W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ 188 W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */
186 W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ 189 W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */
187 190
188 msleep(100);
189
190 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 191 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
191 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 192 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
192 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170); 193 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170);
193 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); 194 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00);
194 195
195 msleep(100);
196
197 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); 196 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
198 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); 197 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
199 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 198 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
@@ -203,12 +202,6 @@ static void wil_target_reset(struct wil6210_priv *wil)
203 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080); 202 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
204 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 203 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
205 204
206 msleep(2000);
207
208 W(RGF_USER_USER_CPU_0, BIT(0)); /* user_cpu_man_de_rst */
209
210 msleep(2000);
211
212 wil_dbg_misc(wil, "Reset completed\n"); 205 wil_dbg_misc(wil, "Reset completed\n");
213 206
214#undef W 207#undef W
@@ -265,8 +258,6 @@ int wil_reset(struct wil6210_priv *wil)
265 wil->pending_connect_cid = -1; 258 wil->pending_connect_cid = -1;
266 INIT_COMPLETION(wil->wmi_ready); 259 INIT_COMPLETION(wil->wmi_ready);
267 260
268 wil_cache_mbox_regs(wil);
269
270 /* TODO: release MAC reset */ 261 /* TODO: release MAC reset */
271 wil6210_enable_irq(wil); 262 wil6210_enable_irq(wil);
272 263
@@ -352,9 +343,9 @@ static int __wil_up(struct wil6210_priv *wil)
352 wil_err(wil, "SSID not set\n"); 343 wil_err(wil, "SSID not set\n");
353 return -EINVAL; 344 return -EINVAL;
354 } 345 }
355 wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid); 346 rc = wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid);
356 if (channel) 347 if (rc)
357 wmi_set_channel(wil, channel->hw_value); 348 return rc;
358 break; 349 break;
359 default: 350 default:
360 break; 351 break;
@@ -364,9 +355,12 @@ static int __wil_up(struct wil6210_priv *wil)
364 wmi_set_mac_address(wil, ndev->dev_addr); 355 wmi_set_mac_address(wil, ndev->dev_addr);
365 356
366 /* Set up beaconing if required. */ 357 /* Set up beaconing if required. */
367 rc = wmi_set_bcon(wil, bi, wmi_nettype); 358 if (bi > 0) {
368 if (rc) 359 rc = wmi_pcp_start(wil, bi, wmi_nettype,
369 return rc; 360 (channel ? channel->hw_value : 0));
361 if (rc)
362 return rc;
363 }
370 364
371 /* Rx VRING. After MAC and beacon */ 365 /* Rx VRING. After MAC and beacon */
372 wil_rx_init(wil); 366 wil_rx_init(wil);
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 8ce2e33dce20..098a8ec6b841 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -14,10 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/module.h>
18#include <linux/netdevice.h>
19#include <linux/etherdevice.h> 17#include <linux/etherdevice.h>
20#include <linux/slab.h>
21 18
22#include "wil6210.h" 19#include "wil6210.h"
23 20
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 81c35c6e3832..eb1dc7ad80fb 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -14,10 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/kernel.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/netdevice.h>
21#include <linux/debugfs.h> 18#include <linux/debugfs.h>
22#include <linux/pci.h> 19#include <linux/pci.h>
23#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 55dd95f9824f..79d4e3271b00 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -14,10 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/kernel.h>
18#include <linux/netdevice.h>
19#include <linux/etherdevice.h> 17#include <linux/etherdevice.h>
20#include <linux/hardirq.h>
21#include <net/ieee80211_radiotap.h> 18#include <net/ieee80211_radiotap.h>
22#include <linux/if_arp.h> 19#include <linux/if_arp.h>
23#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
@@ -558,7 +555,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
558 if (rc) 555 if (rc)
559 goto out_free; 556 goto out_free;
560 557
561 if (reply.cmd.status != WMI_VRING_CFG_SUCCESS) { 558 if (reply.cmd.status != WMI_FW_STATUS_SUCCESS) {
562 wil_err(wil, "Tx config failed, status 0x%02x\n", 559 wil_err(wil, "Tx config failed, status 0x%02x\n",
563 reply.cmd.status); 560 reply.cmd.status);
564 rc = -EINVAL; 561 rc = -EINVAL;
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index aea961ff8f08..8f76ecd8a7e5 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -21,8 +21,6 @@
21#include <linux/wireless.h> 21#include <linux/wireless.h>
22#include <net/cfg80211.h> 22#include <net/cfg80211.h>
23 23
24#include "dbg_hexdump.h"
25
26#define WIL_NAME "wil6210" 24#define WIL_NAME "wil6210"
27 25
28/** 26/**
@@ -188,6 +186,7 @@ enum { /* for wil6210_priv.status */
188 wil_status_fwready = 0, 186 wil_status_fwready = 0,
189 wil_status_fwconnected, 187 wil_status_fwconnected,
190 wil_status_dontscan, 188 wil_status_dontscan,
189 wil_status_reset_done,
191 wil_status_irqen, /* FIXME: interrupts enabled - for debug */ 190 wil_status_irqen, /* FIXME: interrupts enabled - for debug */
192}; 191};
193 192
@@ -210,6 +209,8 @@ struct wil6210_priv {
210 struct wireless_dev *wdev; 209 struct wireless_dev *wdev;
211 void __iomem *csr; 210 void __iomem *csr;
212 ulong status; 211 ulong status;
212 u32 fw_version;
213 u8 n_mids; /* number of additional MIDs as reported by FW */
213 /* profile */ 214 /* profile */
214 u32 monitor_flags; 215 u32 monitor_flags;
215 u32 secure_pcp; /* create secure PCP? */ 216 u32 secure_pcp; /* create secure PCP? */
@@ -227,7 +228,7 @@ struct wil6210_priv {
227 struct workqueue_struct *wmi_wq; /* for deferred calls */ 228 struct workqueue_struct *wmi_wq; /* for deferred calls */
228 struct work_struct wmi_event_worker; 229 struct work_struct wmi_event_worker;
229 struct workqueue_struct *wmi_wq_conn; /* for connect worker */ 230 struct workqueue_struct *wmi_wq_conn; /* for connect worker */
230 struct work_struct wmi_connect_worker; 231 struct work_struct connect_worker;
231 struct work_struct disconnect_worker; 232 struct work_struct disconnect_worker;
232 struct timer_list connect_timer; 233 struct timer_list connect_timer;
233 int pending_connect_cid; 234 int pending_connect_cid;
@@ -277,13 +278,13 @@ struct wil6210_priv {
277 278
278#define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \ 279#define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \
279 groupsize, buf, len, ascii) \ 280 groupsize, buf, len, ascii) \
280 wil_print_hex_dump_debug("DBG[TXRX]" prefix_str,\ 281 print_hex_dump_debug("DBG[TXRX]" prefix_str,\
281 prefix_type, rowsize, \ 282 prefix_type, rowsize, \
282 groupsize, buf, len, ascii) 283 groupsize, buf, len, ascii)
283 284
284#define wil_hex_dump_wmi(prefix_str, prefix_type, rowsize, \ 285#define wil_hex_dump_wmi(prefix_str, prefix_type, rowsize, \
285 groupsize, buf, len, ascii) \ 286 groupsize, buf, len, ascii) \
286 wil_print_hex_dump_debug("DBG[ WMI]" prefix_str,\ 287 print_hex_dump_debug("DBG[ WMI]" prefix_str,\
287 prefix_type, rowsize, \ 288 prefix_type, rowsize, \
288 groupsize, buf, len, ascii) 289 groupsize, buf, len, ascii)
289 290
@@ -313,7 +314,6 @@ int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len);
313void wmi_recv_cmd(struct wil6210_priv *wil); 314void wmi_recv_cmd(struct wil6210_priv *wil);
314int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, 315int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
315 u16 reply_id, void *reply, u8 reply_size, int to_msec); 316 u16 reply_id, void *reply, u8 reply_size, int to_msec);
316void wmi_connect_worker(struct work_struct *work);
317void wmi_event_worker(struct work_struct *work); 317void wmi_event_worker(struct work_struct *work);
318void wmi_event_flush(struct wil6210_priv *wil); 318void wmi_event_flush(struct wil6210_priv *wil);
319int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid); 319int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid);
@@ -328,6 +328,8 @@ int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
328int wmi_echo(struct wil6210_priv *wil); 328int wmi_echo(struct wil6210_priv *wil);
329int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie); 329int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
330int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring); 330int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
331int wmi_p2p_cfg(struct wil6210_priv *wil, int channel);
332int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
331 333
332int wil6210_init_irq(struct wil6210_priv *wil, int irq); 334int wil6210_init_irq(struct wil6210_priv *wil, int irq);
333void wil6210_fini_irq(struct wil6210_priv *wil, int irq); 335void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
@@ -341,7 +343,8 @@ struct wireless_dev *wil_cfg80211_init(struct device *dev);
341void wil_wdev_free(struct wil6210_priv *wil); 343void wil_wdev_free(struct wil6210_priv *wil);
342 344
343int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); 345int wmi_set_mac_address(struct wil6210_priv *wil, void *addr);
344int wmi_set_bcon(struct wil6210_priv *wil, int bi, u8 wmi_nettype); 346int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan);
347int wmi_pcp_stop(struct wil6210_priv *wil);
345void wil6210_disconnect(struct wil6210_priv *wil, void *bssid); 348void wil6210_disconnect(struct wil6210_priv *wil, void *bssid);
346 349
347int wil_rx_init(struct wil6210_priv *wil); 350int wil_rx_init(struct wil6210_priv *wil);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 0bb3b76b4b58..45b04e383f9a 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -14,9 +14,6 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/pci.h>
18#include <linux/io.h>
19#include <linux/list.h>
20#include <linux/etherdevice.h> 17#include <linux/etherdevice.h>
21#include <linux/if_arp.h> 18#include <linux/if_arp.h>
22 19
@@ -272,16 +269,18 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
272 struct net_device *ndev = wil_to_ndev(wil); 269 struct net_device *ndev = wil_to_ndev(wil);
273 struct wireless_dev *wdev = wil->wdev; 270 struct wireless_dev *wdev = wil->wdev;
274 struct wmi_ready_event *evt = d; 271 struct wmi_ready_event *evt = d;
275 u32 ver = le32_to_cpu(evt->sw_version); 272 wil->fw_version = le32_to_cpu(evt->sw_version);
273 wil->n_mids = evt->numof_additional_mids;
276 274
277 wil_dbg_wmi(wil, "FW ver. %d; MAC %pM\n", ver, evt->mac); 275 wil_dbg_wmi(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version,
276 evt->mac, wil->n_mids);
278 277
279 if (!is_valid_ether_addr(ndev->dev_addr)) { 278 if (!is_valid_ether_addr(ndev->dev_addr)) {
280 memcpy(ndev->dev_addr, evt->mac, ETH_ALEN); 279 memcpy(ndev->dev_addr, evt->mac, ETH_ALEN);
281 memcpy(ndev->perm_addr, evt->mac, ETH_ALEN); 280 memcpy(ndev->perm_addr, evt->mac, ETH_ALEN);
282 } 281 }
283 snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version), 282 snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version),
284 "%d", ver); 283 "%d", wil->fw_version);
285} 284}
286 285
287static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d, 286static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d,
@@ -324,17 +323,9 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
324 323
325 if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) { 324 if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) {
326 struct cfg80211_bss *bss; 325 struct cfg80211_bss *bss;
327 u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp); 326
328 u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info); 327 bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame,
329 u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int); 328 d_len, signal, GFP_KERNEL);
330 const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable;
331 size_t ie_len = d_len - offsetof(struct ieee80211_mgmt,
332 u.beacon.variable);
333 wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap);
334
335 bss = cfg80211_inform_bss(wiphy, channel, rx_mgmt_frame->bssid,
336 tsf, cap, bi, ie_buf, ie_len,
337 signal, GFP_KERNEL);
338 if (bss) { 329 if (bss) {
339 wil_dbg_wmi(wil, "Added BSS %pM\n", 330 wil_dbg_wmi(wil, "Added BSS %pM\n",
340 rx_mgmt_frame->bssid); 331 rx_mgmt_frame->bssid);
@@ -342,6 +333,9 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
342 } else { 333 } else {
343 wil_err(wil, "cfg80211_inform_bss() failed\n"); 334 wil_err(wil, "cfg80211_inform_bss() failed\n");
344 } 335 }
336 } else {
337 cfg80211_rx_mgmt(wil->wdev, freq, signal,
338 (void *)rx_mgmt_frame, d_len, GFP_KERNEL);
345 } 339 }
346} 340}
347 341
@@ -443,7 +437,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
443 memcpy(wil->dst_addr[0], evt->bssid, ETH_ALEN); 437 memcpy(wil->dst_addr[0], evt->bssid, ETH_ALEN);
444 438
445 wil->pending_connect_cid = evt->cid; 439 wil->pending_connect_cid = evt->cid;
446 queue_work(wil->wmi_wq_conn, &wil->wmi_connect_worker); 440 queue_work(wil->wmi_wq_conn, &wil->connect_worker);
447} 441}
448 442
449static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, 443static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
@@ -528,6 +522,37 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
528 } 522 }
529} 523}
530 524
525static void wmi_evt_linkup(struct wil6210_priv *wil, int id, void *d, int len)
526{
527 struct net_device *ndev = wil_to_ndev(wil);
528 struct wmi_data_port_open_event *evt = d;
529
530 wil_dbg_wmi(wil, "Link UP for CID %d\n", evt->cid);
531
532 netif_carrier_on(ndev);
533}
534
535static void wmi_evt_linkdown(struct wil6210_priv *wil, int id, void *d, int len)
536{
537 struct net_device *ndev = wil_to_ndev(wil);
538 struct wmi_wbe_link_down_event *evt = d;
539
540 wil_dbg_wmi(wil, "Link DOWN for CID %d, reason %d\n",
541 evt->cid, le32_to_cpu(evt->reason));
542
543 netif_carrier_off(ndev);
544}
545
546static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
547 int len)
548{
549 struct wmi_vring_ba_status_event *evt = d;
550
551 wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d\n",
552 evt->ringid, evt->status ? "N/A" : "OK", evt->agg_wsize,
553 __le16_to_cpu(evt->ba_timeout));
554}
555
531static const struct { 556static const struct {
532 int eventid; 557 int eventid;
533 void (*handler)(struct wil6210_priv *wil, int eventid, 558 void (*handler)(struct wil6210_priv *wil, int eventid,
@@ -541,6 +566,9 @@ static const struct {
541 {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect}, 566 {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect},
542 {WMI_NOTIFY_REQ_DONE_EVENTID, wmi_evt_notify}, 567 {WMI_NOTIFY_REQ_DONE_EVENTID, wmi_evt_notify},
543 {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx}, 568 {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx},
569 {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_linkup},
570 {WMI_WBE_LINKDOWN_EVENTID, wmi_evt_linkdown},
571 {WMI_BA_STATUS_EVENTID, wmi_evt_ba_status},
544}; 572};
545 573
546/* 574/*
@@ -559,6 +587,11 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
559 void __iomem *src; 587 void __iomem *src;
560 ulong flags; 588 ulong flags;
561 589
590 if (!test_bit(wil_status_reset_done, &wil->status)) {
591 wil_err(wil, "Reset not completed\n");
592 return;
593 }
594
562 for (;;) { 595 for (;;) {
563 u16 len; 596 u16 len;
564 597
@@ -683,18 +716,39 @@ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr)
683 return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd)); 716 return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd));
684} 717}
685 718
686int wmi_set_bcon(struct wil6210_priv *wil, int bi, u8 wmi_nettype) 719int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
687{ 720{
688 struct wmi_bcon_ctrl_cmd cmd = { 721 int rc;
722
723 struct wmi_pcp_start_cmd cmd = {
689 .bcon_interval = cpu_to_le16(bi), 724 .bcon_interval = cpu_to_le16(bi),
690 .network_type = wmi_nettype, 725 .network_type = wmi_nettype,
691 .disable_sec_offload = 1, 726 .disable_sec_offload = 1,
727 .channel = chan,
692 }; 728 };
729 struct {
730 struct wil6210_mbox_hdr_wmi wmi;
731 struct wmi_pcp_started_event evt;
732 } __packed reply;
693 733
694 if (!wil->secure_pcp) 734 if (!wil->secure_pcp)
695 cmd.disable_sec = 1; 735 cmd.disable_sec = 1;
696 736
697 return wmi_send(wil, WMI_BCON_CTRL_CMDID, &cmd, sizeof(cmd)); 737 rc = wmi_call(wil, WMI_PCP_START_CMDID, &cmd, sizeof(cmd),
738 WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 100);
739 if (rc)
740 return rc;
741
742 if (reply.evt.status != WMI_FW_STATUS_SUCCESS)
743 rc = -EINVAL;
744
745 return rc;
746}
747
748int wmi_pcp_stop(struct wil6210_priv *wil)
749{
750 return wmi_call(wil, WMI_PCP_STOP_CMDID, NULL, 0,
751 WMI_PCP_STOPPED_EVENTID, NULL, 0, 20);
698} 752}
699 753
700int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid) 754int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid)
@@ -765,6 +819,16 @@ int wmi_get_channel(struct wil6210_priv *wil, int *channel)
765 return 0; 819 return 0;
766} 820}
767 821
822int wmi_p2p_cfg(struct wil6210_priv *wil, int channel)
823{
824 struct wmi_p2p_cfg_cmd cmd = {
825 .discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD,
826 .channel = channel - 1,
827 };
828
829 return wmi_send(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd));
830}
831
768int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb) 832int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb)
769{ 833{
770 struct wmi_eapol_tx_cmd *cmd; 834 struct wmi_eapol_tx_cmd *cmd;
@@ -843,7 +907,7 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
843 /* BUG: FW API define ieLen as u8. Will fix FW */ 907 /* BUG: FW API define ieLen as u8. Will fix FW */
844 cmd->ie_len = cpu_to_le16(ie_len); 908 cmd->ie_len = cpu_to_le16(ie_len);
845 memcpy(cmd->ie_info, ie, ie_len); 909 memcpy(cmd->ie_info, ie, ie_len);
846 rc = wmi_send(wil, WMI_SET_APPIE_CMDID, &cmd, len); 910 rc = wmi_send(wil, WMI_SET_APPIE_CMDID, cmd, len);
847 kfree(cmd); 911 kfree(cmd);
848 912
849 return rc; 913 return rc;
@@ -898,6 +962,31 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
898 return rc; 962 return rc;
899} 963}
900 964
965int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r)
966{
967 int rc;
968 struct wmi_temp_sense_cmd cmd = {
969 .measure_marlon_m_en = cpu_to_le32(!!t_m),
970 .measure_marlon_r_en = cpu_to_le32(!!t_r),
971 };
972 struct {
973 struct wil6210_mbox_hdr_wmi wmi;
974 struct wmi_temp_sense_done_event evt;
975 } __packed reply;
976
977 rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, &cmd, sizeof(cmd),
978 WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100);
979 if (rc)
980 return rc;
981
982 if (t_m)
983 *t_m = le32_to_cpu(reply.evt.marlon_m_t1000);
984 if (t_r)
985 *t_r = le32_to_cpu(reply.evt.marlon_r_t1000);
986
987 return 0;
988}
989
901void wmi_event_flush(struct wil6210_priv *wil) 990void wmi_event_flush(struct wil6210_priv *wil)
902{ 991{
903 struct pending_wmi_event *evt, *t; 992 struct pending_wmi_event *evt, *t;
@@ -997,24 +1086,3 @@ void wmi_event_worker(struct work_struct *work)
997 kfree(evt); 1086 kfree(evt);
998 } 1087 }
999} 1088}
1000
1001void wmi_connect_worker(struct work_struct *work)
1002{
1003 int rc;
1004 struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
1005 wmi_connect_worker);
1006
1007 if (wil->pending_connect_cid < 0) {
1008 wil_err(wil, "No connection pending\n");
1009 return;
1010 }
1011
1012 wil_dbg_wmi(wil, "Configure for connection CID %d\n",
1013 wil->pending_connect_cid);
1014
1015 rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE,
1016 wil->pending_connect_cid, 0);
1017 wil->pending_connect_cid = -1;
1018 if (rc == 0)
1019 wil_link_on(wil);
1020}
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index 3bbf87572b07..50b8528394f4 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -36,6 +36,7 @@
36enum wmi_command_id { 36enum wmi_command_id {
37 WMI_CONNECT_CMDID = 0x0001, 37 WMI_CONNECT_CMDID = 0x0001,
38 WMI_DISCONNECT_CMDID = 0x0003, 38 WMI_DISCONNECT_CMDID = 0x0003,
39 WMI_DISCONNECT_STA_CMDID = 0x0004,
39 WMI_START_SCAN_CMDID = 0x0007, 40 WMI_START_SCAN_CMDID = 0x0007,
40 WMI_SET_BSS_FILTER_CMDID = 0x0009, 41 WMI_SET_BSS_FILTER_CMDID = 0x0009,
41 WMI_SET_PROBED_SSID_CMDID = 0x000a, 42 WMI_SET_PROBED_SSID_CMDID = 0x000a,
@@ -44,7 +45,6 @@ enum wmi_command_id {
44 WMI_ADD_CIPHER_KEY_CMDID = 0x0016, 45 WMI_ADD_CIPHER_KEY_CMDID = 0x0016,
45 WMI_DELETE_CIPHER_KEY_CMDID = 0x0017, 46 WMI_DELETE_CIPHER_KEY_CMDID = 0x0017,
46 WMI_SET_APPIE_CMDID = 0x003f, 47 WMI_SET_APPIE_CMDID = 0x003f,
47 WMI_GET_APPIE_CMDID = 0x0040,
48 WMI_SET_WSC_STATUS_CMDID = 0x0041, 48 WMI_SET_WSC_STATUS_CMDID = 0x0041,
49 WMI_PXMT_RANGE_CFG_CMDID = 0x0042, 49 WMI_PXMT_RANGE_CFG_CMDID = 0x0042,
50 WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x0043, 50 WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x0043,
@@ -55,11 +55,11 @@ enum wmi_command_id {
55 WMI_DEEP_ECHO_CMDID = 0x0804, 55 WMI_DEEP_ECHO_CMDID = 0x0804,
56 WMI_CONFIG_MAC_CMDID = 0x0805, 56 WMI_CONFIG_MAC_CMDID = 0x0805,
57 WMI_CONFIG_PHY_DEBUG_CMDID = 0x0806, 57 WMI_CONFIG_PHY_DEBUG_CMDID = 0x0806,
58 WMI_ADD_STATION_CMDID = 0x0807,
59 WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x0808, 58 WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x0808,
60 WMI_PHY_GET_STATISTICS_CMDID = 0x0809, 59 WMI_PHY_GET_STATISTICS_CMDID = 0x0809,
61 WMI_FS_TUNE_CMDID = 0x080a, 60 WMI_FS_TUNE_CMDID = 0x080a,
62 WMI_CORR_MEASURE_CMDID = 0x080b, 61 WMI_CORR_MEASURE_CMDID = 0x080b,
62 WMI_READ_RSSI_CMDID = 0x080c,
63 WMI_TEMP_SENSE_CMDID = 0x080e, 63 WMI_TEMP_SENSE_CMDID = 0x080e,
64 WMI_DC_CALIB_CMDID = 0x080f, 64 WMI_DC_CALIB_CMDID = 0x080f,
65 WMI_SEND_TONE_CMDID = 0x0810, 65 WMI_SEND_TONE_CMDID = 0x0810,
@@ -75,9 +75,9 @@ enum wmi_command_id {
75 MAC_IO_STATIC_PARAMS_CMDID = 0x081b, 75 MAC_IO_STATIC_PARAMS_CMDID = 0x081b,
76 MAC_IO_DYNAMIC_PARAMS_CMDID = 0x081c, 76 MAC_IO_DYNAMIC_PARAMS_CMDID = 0x081c,
77 WMI_SILENT_RSSI_CALIB_CMDID = 0x081d, 77 WMI_SILENT_RSSI_CALIB_CMDID = 0x081d,
78 WMI_RF_RX_TEST_CMDID = 0x081e,
78 WMI_CFG_RX_CHAIN_CMDID = 0x0820, 79 WMI_CFG_RX_CHAIN_CMDID = 0x0820,
79 WMI_VRING_CFG_CMDID = 0x0821, 80 WMI_VRING_CFG_CMDID = 0x0821,
80 WMI_RX_ON_CMDID = 0x0822,
81 WMI_VRING_BA_EN_CMDID = 0x0823, 81 WMI_VRING_BA_EN_CMDID = 0x0823,
82 WMI_VRING_BA_DIS_CMDID = 0x0824, 82 WMI_VRING_BA_DIS_CMDID = 0x0824,
83 WMI_RCP_ADDBA_RESP_CMDID = 0x0825, 83 WMI_RCP_ADDBA_RESP_CMDID = 0x0825,
@@ -87,7 +87,6 @@ enum wmi_command_id {
87 WMI_SET_PCP_CHANNEL_CMDID = 0x0829, 87 WMI_SET_PCP_CHANNEL_CMDID = 0x0829,
88 WMI_GET_PCP_CHANNEL_CMDID = 0x082a, 88 WMI_GET_PCP_CHANNEL_CMDID = 0x082a,
89 WMI_SW_TX_REQ_CMDID = 0x082b, 89 WMI_SW_TX_REQ_CMDID = 0x082b,
90 WMI_RX_OFF_CMDID = 0x082c,
91 WMI_READ_MAC_RXQ_CMDID = 0x0830, 90 WMI_READ_MAC_RXQ_CMDID = 0x0830,
92 WMI_READ_MAC_TXQ_CMDID = 0x0831, 91 WMI_READ_MAC_TXQ_CMDID = 0x0831,
93 WMI_WRITE_MAC_RXQ_CMDID = 0x0832, 92 WMI_WRITE_MAC_RXQ_CMDID = 0x0832,
@@ -112,6 +111,18 @@ enum wmi_command_id {
112 WMI_FLASH_READ_CMDID = 0x0902, 111 WMI_FLASH_READ_CMDID = 0x0902,
113 WMI_FLASH_WRITE_CMDID = 0x0903, 112 WMI_FLASH_WRITE_CMDID = 0x0903,
114 WMI_SECURITY_UNIT_TEST_CMDID = 0x0904, 113 WMI_SECURITY_UNIT_TEST_CMDID = 0x0904,
114 /*P2P*/
115 WMI_P2P_CFG_CMDID = 0x0910,
116 WMI_PORT_ALLOCATE_CMDID = 0x0911,
117 WMI_PORT_DELETE_CMDID = 0x0912,
118 WMI_POWER_MGMT_CFG_CMDID = 0x0913,
119 WMI_START_LISTEN_CMDID = 0x0914,
120 WMI_START_SEARCH_CMDID = 0x0915,
121 WMI_DISCOVERY_START_CMDID = 0x0916,
122 WMI_DISCOVERY_STOP_CMDID = 0x0917,
123 WMI_PCP_START_CMDID = 0x0918,
124 WMI_PCP_STOP_CMDID = 0x0919,
125 WMI_GET_PCP_FACTOR_CMDID = 0x091b,
115 126
116 WMI_SET_MAC_ADDRESS_CMDID = 0xf003, 127 WMI_SET_MAC_ADDRESS_CMDID = 0xf003,
117 WMI_ABORT_SCAN_CMDID = 0xf007, 128 WMI_ABORT_SCAN_CMDID = 0xf007,
@@ -132,18 +143,6 @@ enum wmi_command_id {
132 */ 143 */
133 144
134/* 145/*
135 * Frame Types
136 */
137enum wmi_mgmt_frame_type {
138 WMI_FRAME_BEACON = 0,
139 WMI_FRAME_PROBE_REQ = 1,
140 WMI_FRAME_PROBE_RESP = 2,
141 WMI_FRAME_ASSOC_REQ = 3,
142 WMI_FRAME_ASSOC_RESP = 4,
143 WMI_NUM_MGMT_FRAME,
144};
145
146/*
147 * WMI_CONNECT_CMDID 146 * WMI_CONNECT_CMDID
148 */ 147 */
149enum wmi_network_type { 148enum wmi_network_type {
@@ -184,7 +183,7 @@ enum wmi_crypto_type {
184enum wmi_connect_ctrl_flag_bits { 183enum wmi_connect_ctrl_flag_bits {
185 WMI_CONNECT_ASSOC_POLICY_USER = 0x0001, 184 WMI_CONNECT_ASSOC_POLICY_USER = 0x0001,
186 WMI_CONNECT_SEND_REASSOC = 0x0002, 185 WMI_CONNECT_SEND_REASSOC = 0x0002,
187 WMI_CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004, 186 WMI_CONNECT_IGNORE_WPA_GROUP_CIPHER = 0x0004,
188 WMI_CONNECT_PROFILE_MATCH_DONE = 0x0008, 187 WMI_CONNECT_PROFILE_MATCH_DONE = 0x0008,
189 WMI_CONNECT_IGNORE_AAC_BEACON = 0x0010, 188 WMI_CONNECT_IGNORE_AAC_BEACON = 0x0010,
190 WMI_CONNECT_CSA_FOLLOW_BSS = 0x0020, 189 WMI_CONNECT_CSA_FOLLOW_BSS = 0x0020,
@@ -212,6 +211,13 @@ struct wmi_connect_cmd {
212 u8 reserved1[2]; 211 u8 reserved1[2];
213} __packed; 212} __packed;
214 213
214/*
215 * WMI_DISCONNECT_STA_CMDID
216 */
217struct wmi_disconnect_sta_cmd {
218 u8 dst_mac[WMI_MAC_LEN];
219 __le16 disconnect_reason;
220} __packed;
215 221
216/* 222/*
217 * WMI_RECONNECT_CMDID 223 * WMI_RECONNECT_CMDID
@@ -289,10 +295,12 @@ struct wmi_delete_cipher_key_cmd {
289enum wmi_scan_type { 295enum wmi_scan_type {
290 WMI_LONG_SCAN = 0, 296 WMI_LONG_SCAN = 0,
291 WMI_SHORT_SCAN = 1, 297 WMI_SHORT_SCAN = 1,
298 WMI_PBC_SCAN = 2,
292}; 299};
293 300
294struct wmi_start_scan_cmd { 301struct wmi_start_scan_cmd {
295 u8 reserved[8]; 302 u8 reserved[8];
303
296 __le32 home_dwell_time; /* Max duration in the home channel(ms) */ 304 __le32 home_dwell_time; /* Max duration in the home channel(ms) */
297 __le32 force_scan_interval; /* Time interval between scans (ms)*/ 305 __le32 force_scan_interval; /* Time interval between scans (ms)*/
298 u8 scan_type; /* wmi_scan_type */ 306 u8 scan_type; /* wmi_scan_type */
@@ -309,7 +317,7 @@ struct wmi_start_scan_cmd {
309/* 317/*
310 * WMI_SET_PROBED_SSID_CMDID 318 * WMI_SET_PROBED_SSID_CMDID
311 */ 319 */
312#define MAX_PROBED_SSID_INDEX (15) 320#define MAX_PROBED_SSID_INDEX (3)
313 321
314enum wmi_ssid_flag { 322enum wmi_ssid_flag {
315 WMI_SSID_FLAG_DISABLE = 0, /* disables entry */ 323 WMI_SSID_FLAG_DISABLE = 0, /* disables entry */
@@ -328,6 +336,20 @@ struct wmi_probed_ssid_cmd {
328 * WMI_SET_APPIE_CMDID 336 * WMI_SET_APPIE_CMDID
329 * Add Application specified IE to a management frame 337 * Add Application specified IE to a management frame
330 */ 338 */
339#define WMI_MAX_IE_LEN (1024)
340
341/*
342 * Frame Types
343 */
344enum wmi_mgmt_frame_type {
345 WMI_FRAME_BEACON = 0,
346 WMI_FRAME_PROBE_REQ = 1,
347 WMI_FRAME_PROBE_RESP = 2,
348 WMI_FRAME_ASSOC_REQ = 3,
349 WMI_FRAME_ASSOC_RESP = 4,
350 WMI_NUM_MGMT_FRAME,
351};
352
331struct wmi_set_appie_cmd { 353struct wmi_set_appie_cmd {
332 u8 mgmt_frm_type; /* enum wmi_mgmt_frame_type */ 354 u8 mgmt_frm_type; /* enum wmi_mgmt_frame_type */
333 u8 reserved; 355 u8 reserved;
@@ -335,13 +357,18 @@ struct wmi_set_appie_cmd {
335 u8 ie_info[0]; 357 u8 ie_info[0];
336} __packed; 358} __packed;
337 359
338#define WMI_MAX_IE_LEN (1024)
339 360
361/*
362 * WMI_PXMT_RANGE_CFG_CMDID
363 */
340struct wmi_pxmt_range_cfg_cmd { 364struct wmi_pxmt_range_cfg_cmd {
341 u8 dst_mac[WMI_MAC_LEN]; 365 u8 dst_mac[WMI_MAC_LEN];
342 __le16 range; 366 __le16 range;
343} __packed; 367} __packed;
344 368
369/*
370 * WMI_PXMT_SNR2_RANGE_CFG_CMDID
371 */
345struct wmi_pxmt_snr2_range_cfg_cmd { 372struct wmi_pxmt_snr2_range_cfg_cmd {
346 s8 snr2range_arr[WMI_PROX_RANGE_NUM-1]; 373 s8 snr2range_arr[WMI_PROX_RANGE_NUM-1];
347} __packed; 374} __packed;
@@ -359,6 +386,23 @@ struct wmi_rf_mgmt_cmd {
359 __le32 rf_mgmt_type; 386 __le32 rf_mgmt_type;
360} __packed; 387} __packed;
361 388
389
390/*
391 * WMI_RF_RX_TEST_CMDID
392 */
393struct wmi_rf_rx_test_cmd {
394 __le32 sector;
395} __packed;
396
397/*
398 * WMI_CORR_MEASURE_CMDID
399 */
400struct wmi_corr_measure_cmd {
401 s32 freq_mhz;
402 __le32 length_samples;
403 __le32 iterations;
404} __packed;
405
362/* 406/*
363 * WMI_SET_SSID_CMDID 407 * WMI_SET_SSID_CMDID
364 */ 408 */
@@ -388,6 +432,74 @@ struct wmi_bcon_ctrl_cmd {
388 u8 disable_sec; 432 u8 disable_sec;
389} __packed; 433} __packed;
390 434
435
436/******* P2P ***********/
437
438/*
439 * WMI_PORT_ALLOCATE_CMDID
440 */
441enum wmi_port_role {
442 WMI_PORT_STA = 0,
443 WMI_PORT_PCP = 1,
444 WMI_PORT_AP = 2,
445 WMI_PORT_P2P_DEV = 3,
446 WMI_PORT_P2P_CLIENT = 4,
447 WMI_PORT_P2P_GO = 5,
448};
449
450struct wmi_port_allocate_cmd {
451 u8 mac[WMI_MAC_LEN];
452 u8 port_role;
453 u8 midid;
454} __packed;
455
456/*
457 * WMI_PORT_DELETE_CMDID
458 */
459struct wmi_delete_port_cmd {
460 u8 mid;
461 u8 reserved[3];
462} __packed;
463
464/*
465 * WMI_P2P_CFG_CMDID
466 */
467enum wmi_discovery_mode {
468 WMI_DISCOVERY_MODE_NON_OFFLOAD = 0,
469 WMI_DISCOVERY_MODE_OFFLOAD = 1,
470};
471
472struct wmi_p2p_cfg_cmd {
473 u8 discovery_mode; /* wmi_discovery_mode */
474 u8 channel;
475 __le16 bcon_interval; /* base to listen/search duration calculation */
476} __packed;
477
478/*
479 * WMI_POWER_MGMT_CFG_CMDID
480 */
481enum wmi_power_source_type {
482 WMI_POWER_SOURCE_BATTERY = 0,
483 WMI_POWER_SOURCE_OTHER = 1,
484};
485
486struct wmi_power_mgmt_cfg_cmd {
487 u8 power_source; /* wmi_power_source_type */
488 u8 reserved[3];
489} __packed;
490
491/*
492 * WMI_PCP_START_CMDID
493 */
494struct wmi_pcp_start_cmd {
495 __le16 bcon_interval;
496 u8 reserved0[10];
497 u8 network_type;
498 u8 channel;
499 u8 disable_sec_offload;
500 u8 disable_sec;
501} __packed;
502
391/* 503/*
392 * WMI_SW_TX_REQ_CMDID 504 * WMI_SW_TX_REQ_CMDID
393 */ 505 */
@@ -435,16 +547,17 @@ enum wmi_vring_cfg_schd_params_priority {
435 WMI_SCH_PRIO_HIGH = 1, 547 WMI_SCH_PRIO_HIGH = 1,
436}; 548};
437 549
550#define CIDXTID_CID_POS (0)
551#define CIDXTID_CID_LEN (4)
552#define CIDXTID_CID_MSK (0xF)
553#define CIDXTID_TID_POS (4)
554#define CIDXTID_TID_LEN (4)
555#define CIDXTID_TID_MSK (0xF0)
556
438struct wmi_vring_cfg { 557struct wmi_vring_cfg {
439 struct wmi_sw_ring_cfg tx_sw_ring; 558 struct wmi_sw_ring_cfg tx_sw_ring;
440 u8 ringid; /* 0-23 vrings */ 559 u8 ringid; /* 0-23 vrings */
441 560
442 #define CIDXTID_CID_POS (0)
443 #define CIDXTID_CID_LEN (4)
444 #define CIDXTID_CID_MSK (0xF)
445 #define CIDXTID_TID_POS (4)
446 #define CIDXTID_TID_LEN (4)
447 #define CIDXTID_TID_MSK (0xF0)
448 u8 cidxtid; 561 u8 cidxtid;
449 562
450 u8 encap_trans_type; 563 u8 encap_trans_type;
@@ -501,8 +614,14 @@ struct wmi_vring_ba_dis_cmd {
501 */ 614 */
502struct wmi_notify_req_cmd { 615struct wmi_notify_req_cmd {
503 u8 cid; 616 u8 cid;
504 u8 reserved[3]; 617 u8 year;
618 u8 month;
619 u8 day;
505 __le32 interval_usec; 620 __le32 interval_usec;
621 u8 hour;
622 u8 minute;
623 u8 second;
624 u8 miliseconds;
506} __packed; 625} __packed;
507 626
508/* 627/*
@@ -548,6 +667,11 @@ enum wmi_cfg_rx_chain_cmd_nwifi_ds_trans_type {
548 WMI_NWIFI_RX_TRANS_MODE_PBSS2STA = 2, 667 WMI_NWIFI_RX_TRANS_MODE_PBSS2STA = 2,
549}; 668};
550 669
670enum wmi_cfg_rx_chain_cmd_reorder_type {
671 WMI_RX_HW_REORDER = 0,
672 WMI_RX_SW_REORDER = 1,
673};
674
551struct wmi_cfg_rx_chain_cmd { 675struct wmi_cfg_rx_chain_cmd {
552 __le32 action; 676 __le32 action;
553 struct wmi_sw_ring_cfg rx_sw_ring; 677 struct wmi_sw_ring_cfg rx_sw_ring;
@@ -596,7 +720,8 @@ struct wmi_cfg_rx_chain_cmd {
596 __le16 wb_thrsh; 720 __le16 wb_thrsh;
597 __le32 itr_value; 721 __le32 itr_value;
598 __le16 host_thrsh; 722 __le16 host_thrsh;
599 u8 reserved[2]; 723 u8 reorder_type;
724 u8 reserved;
600 struct wmi_sniffer_cfg sniffer_cfg; 725 struct wmi_sniffer_cfg sniffer_cfg;
601} __packed; 726} __packed;
602 727
@@ -604,15 +729,7 @@ struct wmi_cfg_rx_chain_cmd {
604 * WMI_RCP_ADDBA_RESP_CMDID 729 * WMI_RCP_ADDBA_RESP_CMDID
605 */ 730 */
606struct wmi_rcp_addba_resp_cmd { 731struct wmi_rcp_addba_resp_cmd {
607
608 #define CIDXTID_CID_POS (0)
609 #define CIDXTID_CID_LEN (4)
610 #define CIDXTID_CID_MSK (0xF)
611 #define CIDXTID_TID_POS (4)
612 #define CIDXTID_TID_LEN (4)
613 #define CIDXTID_TID_MSK (0xF0)
614 u8 cidxtid; 732 u8 cidxtid;
615
616 u8 dialog_token; 733 u8 dialog_token;
617 __le16 status_code; 734 __le16 status_code;
618 __le16 ba_param_set; /* ieee80211_ba_parameterset field to send */ 735 __le16 ba_param_set; /* ieee80211_ba_parameterset field to send */
@@ -623,15 +740,7 @@ struct wmi_rcp_addba_resp_cmd {
623 * WMI_RCP_DELBA_CMDID 740 * WMI_RCP_DELBA_CMDID
624 */ 741 */
625struct wmi_rcp_delba_cmd { 742struct wmi_rcp_delba_cmd {
626
627 #define CIDXTID_CID_POS (0)
628 #define CIDXTID_CID_LEN (4)
629 #define CIDXTID_CID_MSK (0xF)
630 #define CIDXTID_TID_POS (4)
631 #define CIDXTID_TID_LEN (4)
632 #define CIDXTID_TID_MSK (0xF0)
633 u8 cidxtid; 743 u8 cidxtid;
634
635 u8 reserved; 744 u8 reserved;
636 __le16 reason; 745 __le16 reason;
637} __packed; 746} __packed;
@@ -640,15 +749,7 @@ struct wmi_rcp_delba_cmd {
640 * WMI_RCP_ADDBA_REQ_CMDID 749 * WMI_RCP_ADDBA_REQ_CMDID
641 */ 750 */
642struct wmi_rcp_addba_req_cmd { 751struct wmi_rcp_addba_req_cmd {
643
644 #define CIDXTID_CID_POS (0)
645 #define CIDXTID_CID_LEN (4)
646 #define CIDXTID_CID_MSK (0xF)
647 #define CIDXTID_TID_POS (4)
648 #define CIDXTID_TID_LEN (4)
649 #define CIDXTID_TID_MSK (0xF0)
650 u8 cidxtid; 752 u8 cidxtid;
651
652 u8 dialog_token; 753 u8 dialog_token;
653 /* ieee80211_ba_parameterset field as it received */ 754 /* ieee80211_ba_parameterset field as it received */
654 __le16 ba_param_set; 755 __le16 ba_param_set;
@@ -665,7 +766,6 @@ struct wmi_set_mac_address_cmd {
665 u8 reserved[2]; 766 u8 reserved[2];
666} __packed; 767} __packed;
667 768
668
669/* 769/*
670* WMI_EAPOL_TX_CMDID 770* WMI_EAPOL_TX_CMDID
671*/ 771*/
@@ -692,6 +792,17 @@ struct wmi_echo_cmd {
692} __packed; 792} __packed;
693 793
694/* 794/*
795 * WMI_TEMP_SENSE_CMDID
796 *
797 * Measure MAC and radio temperatures
798 */
799struct wmi_temp_sense_cmd {
800 __le32 measure_marlon_m_en;
801 __le32 measure_marlon_r_en;
802} __packed;
803
804
805/*
695 * WMI Events 806 * WMI Events
696 */ 807 */
697 808
@@ -699,7 +810,6 @@ struct wmi_echo_cmd {
699 * List of Events (target to host) 810 * List of Events (target to host)
700 */ 811 */
701enum wmi_event_id { 812enum wmi_event_id {
702 WMI_IMM_RSP_EVENTID = 0x0000,
703 WMI_READY_EVENTID = 0x1001, 813 WMI_READY_EVENTID = 0x1001,
704 WMI_CONNECT_EVENTID = 0x1002, 814 WMI_CONNECT_EVENTID = 0x1002,
705 WMI_DISCONNECT_EVENTID = 0x1003, 815 WMI_DISCONNECT_EVENTID = 0x1003,
@@ -709,13 +819,9 @@ enum wmi_event_id {
709 WMI_FW_READY_EVENTID = 0x1801, 819 WMI_FW_READY_EVENTID = 0x1801,
710 WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x0200, 820 WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x0200,
711 WMI_ECHO_RSP_EVENTID = 0x1803, 821 WMI_ECHO_RSP_EVENTID = 0x1803,
712 WMI_CONFIG_MAC_DONE_EVENTID = 0x1805,
713 WMI_CONFIG_PHY_DEBUG_DONE_EVENTID = 0x1806,
714 WMI_ADD_STATION_DONE_EVENTID = 0x1807,
715 WMI_ADD_DEBUG_TX_PCKT_DONE_EVENTID = 0x1808,
716 WMI_PHY_GET_STATISTICS_EVENTID = 0x1809,
717 WMI_FS_TUNE_DONE_EVENTID = 0x180a, 822 WMI_FS_TUNE_DONE_EVENTID = 0x180a,
718 WMI_CORR_MEASURE_DONE_EVENTID = 0x180b, 823 WMI_CORR_MEASURE_EVENTID = 0x180b,
824 WMI_READ_RSSI_EVENTID = 0x180c,
719 WMI_TEMP_SENSE_DONE_EVENTID = 0x180e, 825 WMI_TEMP_SENSE_DONE_EVENTID = 0x180e,
720 WMI_DC_CALIB_DONE_EVENTID = 0x180f, 826 WMI_DC_CALIB_DONE_EVENTID = 0x180f,
721 WMI_IQ_TX_CALIB_DONE_EVENTID = 0x1811, 827 WMI_IQ_TX_CALIB_DONE_EVENTID = 0x1811,
@@ -727,10 +833,9 @@ enum wmi_event_id {
727 WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819, 833 WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819,
728 WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181a, 834 WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181a,
729 WMI_SILENT_RSSI_CALIB_DONE_EVENTID = 0x181d, 835 WMI_SILENT_RSSI_CALIB_DONE_EVENTID = 0x181d,
730 836 WMI_RF_RX_TEST_DONE_EVENTID = 0x181e,
731 WMI_CFG_RX_CHAIN_DONE_EVENTID = 0x1820, 837 WMI_CFG_RX_CHAIN_DONE_EVENTID = 0x1820,
732 WMI_VRING_CFG_DONE_EVENTID = 0x1821, 838 WMI_VRING_CFG_DONE_EVENTID = 0x1821,
733 WMI_RX_ON_DONE_EVENTID = 0x1822,
734 WMI_BA_STATUS_EVENTID = 0x1823, 839 WMI_BA_STATUS_EVENTID = 0x1823,
735 WMI_RCP_ADDBA_REQ_EVENTID = 0x1824, 840 WMI_RCP_ADDBA_REQ_EVENTID = 0x1824,
736 WMI_ADDBA_RESP_SENT_EVENTID = 0x1825, 841 WMI_ADDBA_RESP_SENT_EVENTID = 0x1825,
@@ -738,7 +843,6 @@ enum wmi_event_id {
738 WMI_GET_SSID_EVENTID = 0x1828, 843 WMI_GET_SSID_EVENTID = 0x1828,
739 WMI_GET_PCP_CHANNEL_EVENTID = 0x182a, 844 WMI_GET_PCP_CHANNEL_EVENTID = 0x182a,
740 WMI_SW_TX_COMPLETE_EVENTID = 0x182b, 845 WMI_SW_TX_COMPLETE_EVENTID = 0x182b,
741 WMI_RX_OFF_DONE_EVENTID = 0x182c,
742 846
743 WMI_READ_MAC_RXQ_EVENTID = 0x1830, 847 WMI_READ_MAC_RXQ_EVENTID = 0x1830,
744 WMI_READ_MAC_TXQ_EVENTID = 0x1831, 848 WMI_READ_MAC_TXQ_EVENTID = 0x1831,
@@ -765,7 +869,16 @@ enum wmi_event_id {
765 WMI_UNIT_TEST_EVENTID = 0x1900, 869 WMI_UNIT_TEST_EVENTID = 0x1900,
766 WMI_FLASH_READ_DONE_EVENTID = 0x1902, 870 WMI_FLASH_READ_DONE_EVENTID = 0x1902,
767 WMI_FLASH_WRITE_DONE_EVENTID = 0x1903, 871 WMI_FLASH_WRITE_DONE_EVENTID = 0x1903,
768 872 /*P2P*/
873 WMI_PORT_ALLOCATED_EVENTID = 0x1911,
874 WMI_PORT_DELETED_EVENTID = 0x1912,
875 WMI_LISTEN_STARTED_EVENTID = 0x1914,
876 WMI_SEARCH_STARTED_EVENTID = 0x1915,
877 WMI_DISCOVERY_STARTED_EVENTID = 0x1916,
878 WMI_DISCOVERY_STOPPED_EVENTID = 0x1917,
879 WMI_PCP_STARTED_EVENTID = 0x1918,
880 WMI_PCP_STOPPED_EVENTID = 0x1919,
881 WMI_PCP_FACTOR_EVENTID = 0x191a,
769 WMI_SET_CHANNEL_EVENTID = 0x9000, 882 WMI_SET_CHANNEL_EVENTID = 0x9000,
770 WMI_ASSOC_REQ_EVENTID = 0x9001, 883 WMI_ASSOC_REQ_EVENTID = 0x9001,
771 WMI_EAPOL_RX_EVENTID = 0x9002, 884 WMI_EAPOL_RX_EVENTID = 0x9002,
@@ -777,6 +890,12 @@ enum wmi_event_id {
777 * Events data structures 890 * Events data structures
778 */ 891 */
779 892
893
894enum wmi_fw_status {
895 WMI_FW_STATUS_SUCCESS,
896 WMI_FW_STATUS_FAILURE,
897};
898
780/* 899/*
781 * WMI_RF_MGMT_STATUS_EVENTID 900 * WMI_RF_MGMT_STATUS_EVENTID
782 */ 901 */
@@ -857,7 +976,7 @@ struct wmi_ready_event {
857 __le32 abi_version; 976 __le32 abi_version;
858 u8 mac[WMI_MAC_LEN]; 977 u8 mac[WMI_MAC_LEN];
859 u8 phy_capability; /* enum wmi_phy_capability */ 978 u8 phy_capability; /* enum wmi_phy_capability */
860 u8 reserved; 979 u8 numof_additional_mids;
861} __packed; 980} __packed;
862 981
863/* 982/*
@@ -876,6 +995,8 @@ struct wmi_notify_req_done_event {
876 __le16 other_rx_sector; 995 __le16 other_rx_sector;
877 __le16 other_tx_sector; 996 __le16 other_tx_sector;
878 __le16 range; 997 __le16 range;
998 u8 sqi;
999 u8 reserved[3];
879} __packed; 1000} __packed;
880 1001
881/* 1002/*
@@ -951,27 +1072,15 @@ struct wmi_vring_ba_status_event {
951 * WMI_DELBA_EVENTID 1072 * WMI_DELBA_EVENTID
952 */ 1073 */
953struct wmi_delba_event { 1074struct wmi_delba_event {
954
955 #define CIDXTID_CID_POS (0)
956 #define CIDXTID_CID_LEN (4)
957 #define CIDXTID_CID_MSK (0xF)
958 #define CIDXTID_TID_POS (4)
959 #define CIDXTID_TID_LEN (4)
960 #define CIDXTID_TID_MSK (0xF0)
961 u8 cidxtid; 1075 u8 cidxtid;
962
963 u8 from_initiator; 1076 u8 from_initiator;
964 __le16 reason; 1077 __le16 reason;
965} __packed; 1078} __packed;
966 1079
1080
967/* 1081/*
968 * WMI_VRING_CFG_DONE_EVENTID 1082 * WMI_VRING_CFG_DONE_EVENTID
969 */ 1083 */
970enum wmi_vring_cfg_done_event_status {
971 WMI_VRING_CFG_SUCCESS = 0,
972 WMI_VRING_CFG_FAILURE = 1,
973};
974
975struct wmi_vring_cfg_done_event { 1084struct wmi_vring_cfg_done_event {
976 u8 ringid; 1085 u8 ringid;
977 u8 status; 1086 u8 status;
@@ -982,21 +1091,8 @@ struct wmi_vring_cfg_done_event {
982/* 1091/*
983 * WMI_ADDBA_RESP_SENT_EVENTID 1092 * WMI_ADDBA_RESP_SENT_EVENTID
984 */ 1093 */
985enum wmi_rcp_addba_resp_sent_event_status {
986 WMI_ADDBA_SUCCESS = 0,
987 WMI_ADDBA_FAIL = 1,
988};
989
990struct wmi_rcp_addba_resp_sent_event { 1094struct wmi_rcp_addba_resp_sent_event {
991
992 #define CIDXTID_CID_POS (0)
993 #define CIDXTID_CID_LEN (4)
994 #define CIDXTID_CID_MSK (0xF)
995 #define CIDXTID_TID_POS (4)
996 #define CIDXTID_TID_LEN (4)
997 #define CIDXTID_TID_MSK (0xF0)
998 u8 cidxtid; 1095 u8 cidxtid;
999
1000 u8 reserved; 1096 u8 reserved;
1001 __le16 status; 1097 __le16 status;
1002} __packed; 1098} __packed;
@@ -1005,15 +1101,7 @@ struct wmi_rcp_addba_resp_sent_event {
1005 * WMI_RCP_ADDBA_REQ_EVENTID 1101 * WMI_RCP_ADDBA_REQ_EVENTID
1006 */ 1102 */
1007struct wmi_rcp_addba_req_event { 1103struct wmi_rcp_addba_req_event {
1008
1009 #define CIDXTID_CID_POS (0)
1010 #define CIDXTID_CID_LEN (4)
1011 #define CIDXTID_CID_MSK (0xF)
1012 #define CIDXTID_TID_POS (4)
1013 #define CIDXTID_TID_LEN (4)
1014 #define CIDXTID_TID_MSK (0xF0)
1015 u8 cidxtid; 1104 u8 cidxtid;
1016
1017 u8 dialog_token; 1105 u8 dialog_token;
1018 __le16 ba_param_set; /* ieee80211_ba_parameterset as it received */ 1106 __le16 ba_param_set; /* ieee80211_ba_parameterset as it received */
1019 __le16 ba_timeout; 1107 __le16 ba_timeout;
@@ -1055,6 +1143,7 @@ struct wmi_data_port_open_event {
1055 u8 reserved[3]; 1143 u8 reserved[3];
1056} __packed; 1144} __packed;
1057 1145
1146
1058/* 1147/*
1059 * WMI_GET_PCP_CHANNEL_EVENTID 1148 * WMI_GET_PCP_CHANNEL_EVENTID
1060 */ 1149 */
@@ -1063,6 +1152,54 @@ struct wmi_get_pcp_channel_event {
1063 u8 reserved[3]; 1152 u8 reserved[3];
1064} __packed; 1153} __packed;
1065 1154
1155
1156/*
1157* WMI_PORT_ALLOCATED_EVENTID
1158*/
1159struct wmi_port_allocated_event {
1160 u8 status; /* wmi_fw_status */
1161 u8 reserved[3];
1162} __packed;
1163
1164/*
1165* WMI_PORT_DELETED_EVENTID
1166*/
1167struct wmi_port_deleted_event {
1168 u8 status; /* wmi_fw_status */
1169 u8 reserved[3];
1170} __packed;
1171
1172/*
1173 * WMI_LISTEN_STARTED_EVENTID
1174 */
1175struct wmi_listen_started_event {
1176 u8 status; /* wmi_fw_status */
1177 u8 reserved[3];
1178} __packed;
1179
1180/*
1181 * WMI_SEARCH_STARTED_EVENTID
1182 */
1183struct wmi_search_started_event {
1184 u8 status; /* wmi_fw_status */
1185 u8 reserved[3];
1186} __packed;
1187
1188/*
1189 * WMI_PCP_STARTED_EVENTID
1190 */
1191struct wmi_pcp_started_event {
1192 u8 status; /* wmi_fw_status */
1193 u8 reserved[3];
1194} __packed;
1195
1196/*
1197 * WMI_PCP_FACTOR_EVENTID
1198 */
1199struct wmi_pcp_factor_event {
1200 __le32 pcp_factor;
1201} __packed;
1202
1066/* 1203/*
1067 * WMI_SW_TX_COMPLETE_EVENTID 1204 * WMI_SW_TX_COMPLETE_EVENTID
1068 */ 1205 */
@@ -1078,6 +1215,23 @@ struct wmi_sw_tx_complete_event {
1078} __packed; 1215} __packed;
1079 1216
1080/* 1217/*
1218 * WMI_CORR_MEASURE_EVENTID
1219 */
1220struct wmi_corr_measure_event {
1221 s32 i;
1222 s32 q;
1223 s32 image_i;
1224 s32 image_q;
1225} __packed;
1226
1227/*
1228 * WMI_READ_RSSI_EVENTID
1229 */
1230struct wmi_read_rssi_event {
1231 __le32 ina_rssi_adc_dbm;
1232} __packed;
1233
1234/*
1081 * WMI_GET_SSID_EVENTID 1235 * WMI_GET_SSID_EVENTID
1082 */ 1236 */
1083struct wmi_get_ssid_event { 1237struct wmi_get_ssid_event {
@@ -1091,7 +1245,8 @@ struct wmi_get_ssid_event {
1091struct wmi_rx_mgmt_info { 1245struct wmi_rx_mgmt_info {
1092 u8 mcs; 1246 u8 mcs;
1093 s8 snr; 1247 s8 snr;
1094 __le16 range; 1248 u8 range;
1249 u8 sqi;
1095 __le16 stype; 1250 __le16 stype;
1096 __le16 status; 1251 __le16 status;
1097 __le32 len; 1252 __le32 len;
@@ -1113,4 +1268,14 @@ struct wmi_echo_event {
1113 __le32 echoed_value; 1268 __le32 echoed_value;
1114} __packed; 1269} __packed;
1115 1270
1271/*
1272 * WMI_TEMP_SENSE_DONE_EVENTID
1273 *
1274 * Measure MAC and radio temperatures
1275 */
1276struct wmi_temp_sense_done_event {
1277 __le32 marlon_m_t1000;
1278 __le32 marlon_r_t1000;
1279} __packed;
1280
1116#endif /* __WILOCITY_WMI_H__ */ 1281#endif /* __WILOCITY_WMI_H__ */
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 287c6b670a36..078e6f3477a9 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -131,7 +131,7 @@ config B43_PHY_LP
131 131
132config B43_PHY_HT 132config B43_PHY_HT
133 bool "Support for HT-PHY (high throughput) devices" 133 bool "Support for HT-PHY (high throughput) devices"
134 depends on B43 134 depends on B43 && B43_BCMA
135 ---help--- 135 ---help---
136 Support for the HT-PHY. 136 Support for the HT-PHY.
137 137
@@ -166,8 +166,8 @@ config B43_DEBUG
166 Broadcom 43xx debugging. 166 Broadcom 43xx debugging.
167 167
168 This adds additional runtime sanity checks and statistics to the driver. 168 This adds additional runtime sanity checks and statistics to the driver.
169 These checks and statistics might me expensive and hurt runtime performance 169 These checks and statistics might be expensive and hurt the runtime
170 of your system. 170 performance of your system.
171 This also adds the b43 debugfs interface. 171 This also adds the b43 debugfs interface.
172 172
173 Do not enable this, unless you are debugging the driver. 173 Do not enable this, unless you are debugging the driver.
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 10e288d470e7..fe4a77ee05c9 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -473,6 +473,12 @@ enum {
473#define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */ 473#define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */
474#define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */ 474#define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */
475 475
476/* See BCMA_CLKCTLST_EXTRESREQ and BCMA_CLKCTLST_EXTRESST */
477#define B43_BCMA_CLKCTLST_80211_PLL_REQ 0x00000100
478#define B43_BCMA_CLKCTLST_PHY_PLL_REQ 0x00000200
479#define B43_BCMA_CLKCTLST_80211_PLL_ST 0x01000000
480#define B43_BCMA_CLKCTLST_PHY_PLL_ST 0x02000000
481
476/* BCMA 802.11 core specific IO Control (BCMA_IOCTL) flags */ 482/* BCMA 802.11 core specific IO Control (BCMA_IOCTL) flags */
477#define B43_BCMA_IOCTL_PHY_CLKEN 0x00000004 /* PHY Clock Enable */ 483#define B43_BCMA_IOCTL_PHY_CLKEN 0x00000004 /* PHY Clock Enable */
478#define B43_BCMA_IOCTL_PHY_RESET 0x00000008 /* PHY Reset */ 484#define B43_BCMA_IOCTL_PHY_RESET 0x00000008 /* PHY Reset */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 05682736e466..c4d0cc582555 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1189,10 +1189,15 @@ static void b43_bcma_phy_reset(struct b43_wldev *dev)
1189 1189
1190static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode) 1190static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
1191{ 1191{
1192 u32 req = B43_BCMA_CLKCTLST_80211_PLL_REQ |
1193 B43_BCMA_CLKCTLST_PHY_PLL_REQ;
1194 u32 status = B43_BCMA_CLKCTLST_80211_PLL_ST |
1195 B43_BCMA_CLKCTLST_PHY_PLL_ST;
1196
1192 b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN); 1197 b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN);
1193 bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST); 1198 bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST);
1194 b43_bcma_phy_reset(dev); 1199 b43_bcma_phy_reset(dev);
1195 bcma_core_pll_ctl(dev->dev->bdev, 0x300, 0x3000000, true); 1200 bcma_core_pll_ctl(dev->dev->bdev, req, status, true);
1196} 1201}
1197#endif 1202#endif
1198 1203
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 7416c5e9154d..b8667706fc27 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -154,9 +154,84 @@ static void b43_radio_2059_init(struct b43_wldev *dev)
154} 154}
155 155
156/************************************************** 156/**************************************************
157 * RF
158 **************************************************/
159
160static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq)
161{
162 u8 i;
163
164 u16 save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE);
165 b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE, 0x3);
166
167 b43_phy_set(dev, B43_PHY_HT_RF_SEQ_TRIG, rf_seq);
168 for (i = 0; i < 200; i++) {
169 if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & rf_seq)) {
170 i = 0;
171 break;
172 }
173 msleep(1);
174 }
175 if (i)
176 b43err(dev->wl, "Forcing RF sequence timeout\n");
177
178 b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
179}
180
181static void b43_phy_ht_pa_override(struct b43_wldev *dev, bool enable)
182{
183 struct b43_phy_ht *htphy = dev->phy.ht;
184 static const u16 regs[3] = { B43_PHY_HT_RF_CTL_INT_C1,
185 B43_PHY_HT_RF_CTL_INT_C2,
186 B43_PHY_HT_RF_CTL_INT_C3 };
187 int i;
188
189 if (enable) {
190 for (i = 0; i < 3; i++)
191 b43_phy_write(dev, regs[i], htphy->rf_ctl_int_save[i]);
192 } else {
193 for (i = 0; i < 3; i++)
194 htphy->rf_ctl_int_save[i] = b43_phy_read(dev, regs[i]);
195 /* TODO: Does 5GHz band use different value (not 0x0400)? */
196 for (i = 0; i < 3; i++)
197 b43_phy_write(dev, regs[i], 0x0400);
198 }
199}
200
201/**************************************************
157 * Various PHY ops 202 * Various PHY ops
158 **************************************************/ 203 **************************************************/
159 204
205static u16 b43_phy_ht_classifier(struct b43_wldev *dev, u16 mask, u16 val)
206{
207 u16 tmp;
208 u16 allowed = B43_PHY_HT_CLASS_CTL_CCK_EN |
209 B43_PHY_HT_CLASS_CTL_OFDM_EN |
210 B43_PHY_HT_CLASS_CTL_WAITED_EN;
211
212 tmp = b43_phy_read(dev, B43_PHY_HT_CLASS_CTL);
213 tmp &= allowed;
214 tmp &= ~mask;
215 tmp |= (val & mask);
216 b43_phy_maskset(dev, B43_PHY_HT_CLASS_CTL, ~allowed, tmp);
217
218 return tmp;
219}
220
221static void b43_phy_ht_reset_cca(struct b43_wldev *dev)
222{
223 u16 bbcfg;
224
225 b43_phy_force_clock(dev, true);
226 bbcfg = b43_phy_read(dev, B43_PHY_HT_BBCFG);
227 b43_phy_write(dev, B43_PHY_HT_BBCFG, bbcfg | B43_PHY_HT_BBCFG_RSTCCA);
228 udelay(1);
229 b43_phy_write(dev, B43_PHY_HT_BBCFG, bbcfg & ~B43_PHY_HT_BBCFG_RSTCCA);
230 b43_phy_force_clock(dev, false);
231
232 b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX);
233}
234
160static void b43_phy_ht_zero_extg(struct b43_wldev *dev) 235static void b43_phy_ht_zero_extg(struct b43_wldev *dev)
161{ 236{
162 u8 i, j; 237 u8 i, j;
@@ -176,10 +251,10 @@ static void b43_phy_ht_afe_unk1(struct b43_wldev *dev)
176{ 251{
177 u8 i; 252 u8 i;
178 253
179 const u16 ctl_regs[3][2] = { 254 static const u16 ctl_regs[3][2] = {
180 { B43_PHY_HT_AFE_CTL1, B43_PHY_HT_AFE_CTL2 }, 255 { B43_PHY_HT_AFE_C1_OVER, B43_PHY_HT_AFE_C1 },
181 { B43_PHY_HT_AFE_CTL3, B43_PHY_HT_AFE_CTL4 }, 256 { B43_PHY_HT_AFE_C2_OVER, B43_PHY_HT_AFE_C2 },
182 { B43_PHY_HT_AFE_CTL5, B43_PHY_HT_AFE_CTL6}, 257 { B43_PHY_HT_AFE_C3_OVER, B43_PHY_HT_AFE_C3},
183 }; 258 };
184 259
185 for (i = 0; i < 3; i++) { 260 for (i = 0; i < 3; i++) {
@@ -193,27 +268,6 @@ static void b43_phy_ht_afe_unk1(struct b43_wldev *dev)
193 } 268 }
194} 269}
195 270
196static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq)
197{
198 u8 i;
199
200 u16 save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE);
201 b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE, 0x3);
202
203 b43_phy_set(dev, B43_PHY_HT_RF_SEQ_TRIG, rf_seq);
204 for (i = 0; i < 200; i++) {
205 if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & rf_seq)) {
206 i = 0;
207 break;
208 }
209 msleep(1);
210 }
211 if (i)
212 b43err(dev->wl, "Forcing RF sequence timeout\n");
213
214 b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
215}
216
217static void b43_phy_ht_read_clip_detection(struct b43_wldev *dev, u16 *clip_st) 271static void b43_phy_ht_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
218{ 272{
219 clip_st[0] = b43_phy_read(dev, B43_PHY_HT_C1_CLIP1THRES); 273 clip_st[0] = b43_phy_read(dev, B43_PHY_HT_C1_CLIP1THRES);
@@ -240,15 +294,426 @@ static void b43_phy_ht_bphy_init(struct b43_wldev *dev)
240} 294}
241 295
242/************************************************** 296/**************************************************
297 * Samples
298 **************************************************/
299
300static void b43_phy_ht_stop_playback(struct b43_wldev *dev)
301{
302 struct b43_phy_ht *phy_ht = dev->phy.ht;
303 u16 tmp;
304 int i;
305
306 tmp = b43_phy_read(dev, B43_PHY_HT_SAMP_STAT);
307 if (tmp & 0x1)
308 b43_phy_set(dev, B43_PHY_HT_SAMP_CMD, B43_PHY_HT_SAMP_CMD_STOP);
309 else if (tmp & 0x2)
310 b43_phy_mask(dev, B43_PHY_HT_IQLOCAL_CMDGCTL, 0x7FFF);
311
312 b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0x0004);
313
314 for (i = 0; i < 3; i++) {
315 if (phy_ht->bb_mult_save[i] >= 0) {
316 b43_httab_write(dev, B43_HTTAB16(13, 0x63 + i * 4),
317 phy_ht->bb_mult_save[i]);
318 b43_httab_write(dev, B43_HTTAB16(13, 0x67 + i * 4),
319 phy_ht->bb_mult_save[i]);
320 }
321 }
322}
323
324static u16 b43_phy_ht_load_samples(struct b43_wldev *dev)
325{
326 int i;
327 u16 len = 20 << 3;
328
329 b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, 0x4400);
330
331 for (i = 0; i < len; i++) {
332 b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI, 0);
333 b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, 0);
334 }
335
336 return len;
337}
338
339static void b43_phy_ht_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
340 u16 wait)
341{
342 struct b43_phy_ht *phy_ht = dev->phy.ht;
343 u16 save_seq_mode;
344 int i;
345
346 for (i = 0; i < 3; i++) {
347 if (phy_ht->bb_mult_save[i] < 0)
348 phy_ht->bb_mult_save[i] = b43_httab_read(dev, B43_HTTAB16(13, 0x63 + i * 4));
349 }
350
351 b43_phy_write(dev, B43_PHY_HT_SAMP_DEP_CNT, samps - 1);
352 if (loops != 0xFFFF)
353 loops--;
354 b43_phy_write(dev, B43_PHY_HT_SAMP_LOOP_CNT, loops);
355 b43_phy_write(dev, B43_PHY_HT_SAMP_WAIT_CNT, wait);
356
357 save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE);
358 b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE,
359 B43_PHY_HT_RF_SEQ_MODE_CA_OVER);
360
361 /* TODO: find out mask bits! Do we need more function arguments? */
362 b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0);
363 b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0);
364 b43_phy_mask(dev, B43_PHY_HT_IQLOCAL_CMDGCTL, ~0);
365 b43_phy_set(dev, B43_PHY_HT_SAMP_CMD, 0x1);
366
367 for (i = 0; i < 100; i++) {
368 if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & 1)) {
369 i = 0;
370 break;
371 }
372 udelay(10);
373 }
374 if (i)
375 b43err(dev->wl, "run samples timeout\n");
376
377 b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
378}
379
380static void b43_phy_ht_tx_tone(struct b43_wldev *dev)
381{
382 u16 samp;
383
384 samp = b43_phy_ht_load_samples(dev);
385 b43_phy_ht_run_samples(dev, samp, 0xFFFF, 0);
386}
387
388/**************************************************
389 * RSSI
390 **************************************************/
391
392static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel,
393 u8 rssi_type)
394{
395 static const u16 ctl_regs[3][2] = {
396 { B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, },
397 { B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, },
398 { B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, },
399 };
400 static const u16 radio_r[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1, };
401 int core;
402
403 if (core_sel == 0) {
404 b43err(dev->wl, "RSSI selection for core off not implemented yet\n");
405 } else {
406 for (core = 0; core < 3; core++) {
407 /* Check if caller requested a one specific core */
408 if ((core_sel == 1 && core != 0) ||
409 (core_sel == 2 && core != 1) ||
410 (core_sel == 3 && core != 2))
411 continue;
412
413 switch (rssi_type) {
414 case 4:
415 b43_phy_set(dev, ctl_regs[core][0], 0x3 << 8);
416 b43_phy_set(dev, ctl_regs[core][0], 0x3 << 10);
417 b43_phy_set(dev, ctl_regs[core][1], 0x1 << 9);
418 b43_phy_set(dev, ctl_regs[core][1], 0x1 << 10);
419
420 b43_radio_set(dev, R2059_RXRX1 | 0xbf, 0x1);
421 b43_radio_write(dev, radio_r[core] | 0x159,
422 0x11);
423 break;
424 default:
425 b43err(dev->wl, "RSSI selection for type %d not implemented yet\n",
426 rssi_type);
427 }
428 }
429 }
430}
431
432static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
433 u8 nsamp)
434{
435 u16 phy_regs_values[12];
436 static const u16 phy_regs_to_save[] = {
437 B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER,
438 0x848, 0x841,
439 B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER,
440 0x868, 0x861,
441 B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER,
442 0x888, 0x881,
443 };
444 u16 tmp[3];
445 int i;
446
447 for (i = 0; i < 12; i++)
448 phy_regs_values[i] = b43_phy_read(dev, phy_regs_to_save[i]);
449
450 b43_phy_ht_rssi_select(dev, 5, type);
451
452 for (i = 0; i < 6; i++)
453 buf[i] = 0;
454
455 for (i = 0; i < nsamp; i++) {
456 tmp[0] = b43_phy_read(dev, B43_PHY_HT_RSSI_C1);
457 tmp[1] = b43_phy_read(dev, B43_PHY_HT_RSSI_C2);
458 tmp[2] = b43_phy_read(dev, B43_PHY_HT_RSSI_C3);
459
460 buf[0] += ((s8)((tmp[0] & 0x3F) << 2)) >> 2;
461 buf[1] += ((s8)(((tmp[0] >> 8) & 0x3F) << 2)) >> 2;
462 buf[2] += ((s8)((tmp[1] & 0x3F) << 2)) >> 2;
463 buf[3] += ((s8)(((tmp[1] >> 8) & 0x3F) << 2)) >> 2;
464 buf[4] += ((s8)((tmp[2] & 0x3F) << 2)) >> 2;
465 buf[5] += ((s8)(((tmp[2] >> 8) & 0x3F) << 2)) >> 2;
466 }
467
468 for (i = 0; i < 12; i++)
469 b43_phy_write(dev, phy_regs_to_save[i], phy_regs_values[i]);
470}
471
472/**************************************************
473 * Tx/Rx
474 **************************************************/
475
476static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev)
477{
478 int i;
479
480 for (i = 0; i < 3; i++) {
481 u16 mask;
482 u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8));
483
484 if (0) /* FIXME */
485 mask = 0x2 << (i * 4);
486 else
487 mask = 0;
488 b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask);
489
490 b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16);
491 b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)),
492 tmp & 0xFF);
493 b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)),
494 tmp & 0xFF);
495 }
496}
497
498static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable)
499{
500 struct b43_phy_ht *phy_ht = dev->phy.ht;
501 u16 en_bits = B43_PHY_HT_TXPCTL_CMD_C1_COEFF |
502 B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN |
503 B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN;
504 static const u16 cmd_regs[3] = { B43_PHY_HT_TXPCTL_CMD_C1,
505 B43_PHY_HT_TXPCTL_CMD_C2,
506 B43_PHY_HT_TXPCTL_CMD_C3 };
507 int i;
508
509 if (!enable) {
510 if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) {
511 /* We disable enabled TX pwr ctl, save it's state */
512 /*
513 * TODO: find the registers. On N-PHY they were 0x1ed
514 * and 0x1ee, we need 3 such a registers for HT-PHY
515 */
516 }
517 b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits);
518 } else {
519 b43_phy_set(dev, B43_PHY_HT_TXPCTL_CMD_C1, en_bits);
520
521 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
522 for (i = 0; i < 3; i++)
523 b43_phy_write(dev, cmd_regs[i], 0x32);
524 }
525
526 for (i = 0; i < 3; i++)
527 if (phy_ht->tx_pwr_idx[i] <=
528 B43_PHY_HT_TXPCTL_CMD_C1_INIT)
529 b43_phy_write(dev, cmd_regs[i],
530 phy_ht->tx_pwr_idx[i]);
531 }
532
533 phy_ht->tx_pwr_ctl = enable;
534}
535
536static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
537{
538 struct b43_phy_ht *phy_ht = dev->phy.ht;
539 s32 rssi_buf[6];
540
541 /* TODO */
542
543 b43_phy_ht_tx_tone(dev);
544 udelay(20);
545 b43_phy_ht_poll_rssi(dev, 4, rssi_buf, 1);
546 b43_phy_ht_stop_playback(dev);
547 b43_phy_ht_reset_cca(dev);
548
549 phy_ht->idle_tssi[0] = rssi_buf[0] & 0xff;
550 phy_ht->idle_tssi[1] = rssi_buf[2] & 0xff;
551 phy_ht->idle_tssi[2] = rssi_buf[4] & 0xff;
552
553 /* TODO */
554}
555
556static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev)
557{
558 struct b43_phy_ht *phy_ht = dev->phy.ht;
559 struct ssb_sprom *sprom = dev->dev->bus_sprom;
560
561 u8 *idle = phy_ht->idle_tssi;
562 u8 target[3];
563 s16 a1[3], b0[3], b1[3];
564
565 u16 freq = dev->phy.channel_freq;
566 int i, c;
567
568 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
569 for (c = 0; c < 3; c++) {
570 target[c] = sprom->core_pwr_info[c].maxpwr_2g;
571 a1[c] = sprom->core_pwr_info[c].pa_2g[0];
572 b0[c] = sprom->core_pwr_info[c].pa_2g[1];
573 b1[c] = sprom->core_pwr_info[c].pa_2g[2];
574 }
575 } else if (freq >= 4900 && freq < 5100) {
576 for (c = 0; c < 3; c++) {
577 target[c] = sprom->core_pwr_info[c].maxpwr_5gl;
578 a1[c] = sprom->core_pwr_info[c].pa_5gl[0];
579 b0[c] = sprom->core_pwr_info[c].pa_5gl[1];
580 b1[c] = sprom->core_pwr_info[c].pa_5gl[2];
581 }
582 } else if (freq >= 5100 && freq < 5500) {
583 for (c = 0; c < 3; c++) {
584 target[c] = sprom->core_pwr_info[c].maxpwr_5g;
585 a1[c] = sprom->core_pwr_info[c].pa_5g[0];
586 b0[c] = sprom->core_pwr_info[c].pa_5g[1];
587 b1[c] = sprom->core_pwr_info[c].pa_5g[2];
588 }
589 } else if (freq >= 5500) {
590 for (c = 0; c < 3; c++) {
591 target[c] = sprom->core_pwr_info[c].maxpwr_5gh;
592 a1[c] = sprom->core_pwr_info[c].pa_5gh[0];
593 b0[c] = sprom->core_pwr_info[c].pa_5gh[1];
594 b1[c] = sprom->core_pwr_info[c].pa_5gh[2];
595 }
596 } else {
597 target[0] = target[1] = target[2] = 52;
598 a1[0] = a1[1] = a1[2] = -424;
599 b0[0] = b0[1] = b0[2] = 5612;
600 b1[0] = b1[1] = b1[2] = -1393;
601 }
602
603 b43_phy_set(dev, B43_PHY_HT_TSSIMODE, B43_PHY_HT_TSSIMODE_EN);
604 b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1,
605 ~B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN & 0xFFFF);
606
607 /* TODO: Does it depend on sprom->fem.ghz2.tssipos? */
608 b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, 0x4000);
609
610 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1,
611 ~B43_PHY_HT_TXPCTL_CMD_C1_INIT, 0x19);
612 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C2,
613 ~B43_PHY_HT_TXPCTL_CMD_C2_INIT, 0x19);
614 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C3,
615 ~B43_PHY_HT_TXPCTL_CMD_C3_INIT, 0x19);
616
617 b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
618 B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF);
619
620 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
621 ~B43_PHY_HT_TXPCTL_IDLE_TSSI_C1,
622 idle[0] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT);
623 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
624 ~B43_PHY_HT_TXPCTL_IDLE_TSSI_C2,
625 idle[1] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT);
626 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI2,
627 ~B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3,
628 idle[2] << B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT);
629
630 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_TSSID,
631 0xf0);
632 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_NPTIL2,
633 0x3 << B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT);
634#if 0
635 /* TODO: what to mask/set? */
636 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x800, 0)
637 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x400, 0)
638#endif
639
640 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR,
641 ~B43_PHY_HT_TXPCTL_TARG_PWR_C1,
642 target[0] << B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT);
643 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR,
644 ~B43_PHY_HT_TXPCTL_TARG_PWR_C2 & 0xFFFF,
645 target[1] << B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT);
646 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR2,
647 ~B43_PHY_HT_TXPCTL_TARG_PWR2_C3,
648 target[2] << B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT);
649
650 for (c = 0; c < 3; c++) {
651 s32 num, den, pwr;
652 u32 regval[64];
653
654 for (i = 0; i < 64; i++) {
655 num = 8 * (16 * b0[c] + b1[c] * i);
656 den = 32768 + a1[c] * i;
657 pwr = max((4 * num + den / 2) / den, -8);
658 regval[i] = pwr;
659 }
660 b43_httab_write_bulk(dev, B43_HTTAB16(26 + c, 0), 64, regval);
661 }
662}
663
664/**************************************************
243 * Channel switching ops. 665 * Channel switching ops.
244 **************************************************/ 666 **************************************************/
245 667
668static void b43_phy_ht_spur_avoid(struct b43_wldev *dev,
669 struct ieee80211_channel *new_channel)
670{
671 struct bcma_device *core = dev->dev->bdev;
672 int spuravoid = 0;
673 u16 tmp;
674
675 /* Check for 13 and 14 is just a guess, we don't have enough logs. */
676 if (new_channel->hw_value == 13 || new_channel->hw_value == 14)
677 spuravoid = 1;
678 bcma_core_pll_ctl(core, B43_BCMA_CLKCTLST_PHY_PLL_REQ, 0, false);
679 bcma_pmu_spuravoid_pllupdate(&core->bus->drv_cc, spuravoid);
680 bcma_core_pll_ctl(core,
681 B43_BCMA_CLKCTLST_80211_PLL_REQ |
682 B43_BCMA_CLKCTLST_PHY_PLL_REQ,
683 B43_BCMA_CLKCTLST_80211_PLL_ST |
684 B43_BCMA_CLKCTLST_PHY_PLL_ST, false);
685
686 /* Values has been taken from wlc_bmac_switch_macfreq comments */
687 switch (spuravoid) {
688 case 2: /* 126MHz */
689 tmp = 0x2082;
690 break;
691 case 1: /* 123MHz */
692 tmp = 0x5341;
693 break;
694 default: /* 120MHz */
695 tmp = 0x8889;
696 }
697
698 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, tmp);
699 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
700
701 /* TODO: reset PLL */
702
703 if (spuravoid)
704 b43_phy_set(dev, B43_PHY_HT_BBCFG, B43_PHY_HT_BBCFG_RSTRX);
705 else
706 b43_phy_mask(dev, B43_PHY_HT_BBCFG,
707 ~B43_PHY_HT_BBCFG_RSTRX & 0xFFFF);
708
709 b43_phy_ht_reset_cca(dev);
710}
711
246static void b43_phy_ht_channel_setup(struct b43_wldev *dev, 712static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
247 const struct b43_phy_ht_channeltab_e_phy *e, 713 const struct b43_phy_ht_channeltab_e_phy *e,
248 struct ieee80211_channel *new_channel) 714 struct ieee80211_channel *new_channel)
249{ 715{
250 bool old_band_5ghz; 716 bool old_band_5ghz;
251 u8 i;
252 717
253 old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */ 718 old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */
254 if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) { 719 if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
@@ -264,25 +729,20 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
264 b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5); 729 b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5);
265 b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6); 730 b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6);
266 731
267 /* TODO: some ops on PHY regs 0x0B0 and 0xC0A */ 732 if (new_channel->hw_value == 14) {
733 b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_OFDM_EN, 0);
734 b43_phy_set(dev, B43_PHY_HT_TEST, 0x0800);
735 } else {
736 b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_OFDM_EN,
737 B43_PHY_HT_CLASS_CTL_OFDM_EN);
738 if (new_channel->band == IEEE80211_BAND_2GHZ)
739 b43_phy_mask(dev, B43_PHY_HT_TEST, ~0x840);
740 }
268 741
269 /* TODO: separated function? */ 742 if (1) /* TODO: On N it's for early devices only, what about HT? */
270 for (i = 0; i < 3; i++) { 743 b43_phy_ht_tx_power_fix(dev);
271 u16 mask;
272 u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8));
273 744
274 if (0) /* FIXME */ 745 b43_phy_ht_spur_avoid(dev, new_channel);
275 mask = 0x2 << (i * 4);
276 else
277 mask = 0;
278 b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask);
279
280 b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16);
281 b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)),
282 tmp & 0xFF);
283 b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)),
284 tmp & 0xFF);
285 }
286 746
287 b43_phy_write(dev, 0x017e, 0x3830); 747 b43_phy_write(dev, 0x017e, 0x3830);
288} 748}
@@ -337,14 +797,29 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev)
337{ 797{
338 struct b43_phy *phy = &dev->phy; 798 struct b43_phy *phy = &dev->phy;
339 struct b43_phy_ht *phy_ht = phy->ht; 799 struct b43_phy_ht *phy_ht = phy->ht;
800 int i;
340 801
341 memset(phy_ht, 0, sizeof(*phy_ht)); 802 memset(phy_ht, 0, sizeof(*phy_ht));
803
804 phy_ht->tx_pwr_ctl = true;
805 for (i = 0; i < 3; i++)
806 phy_ht->tx_pwr_idx[i] = B43_PHY_HT_TXPCTL_CMD_C1_INIT + 1;
807
808 for (i = 0; i < 3; i++)
809 phy_ht->bb_mult_save[i] = -1;
342} 810}
343 811
344static int b43_phy_ht_op_init(struct b43_wldev *dev) 812static int b43_phy_ht_op_init(struct b43_wldev *dev)
345{ 813{
814 struct b43_phy_ht *phy_ht = dev->phy.ht;
346 u16 tmp; 815 u16 tmp;
347 u16 clip_state[3]; 816 u16 clip_state[3];
817 bool saved_tx_pwr_ctl;
818
819 if (dev->dev->bus_type != B43_BUS_BCMA) {
820 b43err(dev->wl, "HT-PHY is supported only on BCMA bus!\n");
821 return -EOPNOTSUPP;
822 }
348 823
349 b43_phy_ht_tables_init(dev); 824 b43_phy_ht_tables_init(dev);
350 825
@@ -357,9 +832,9 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
357 832
358 b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3); 833 b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3);
359 834
360 b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0); 835 b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0);
361 b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0); 836 b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0);
362 b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0); 837 b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0);
363 838
364 b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20); 839 b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20);
365 b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20); 840 b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20);
@@ -371,8 +846,11 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
371 if (0) /* TODO: condition */ 846 if (0) /* TODO: condition */
372 ; /* TODO: PHY op on reg 0x217 */ 847 ; /* TODO: PHY op on reg 0x217 */
373 848
374 b43_phy_read(dev, 0xb0); /* TODO: what for? */ 849 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
375 b43_phy_set(dev, 0xb0, 0x1); 850 b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_CCK_EN, 0);
851 else
852 b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_CCK_EN,
853 B43_PHY_HT_CLASS_CTL_CCK_EN);
376 854
377 b43_phy_set(dev, 0xb1, 0x91); 855 b43_phy_set(dev, 0xb1, 0x91);
378 b43_phy_write(dev, 0x32f, 0x0003); 856 b43_phy_write(dev, 0x32f, 0x0003);
@@ -448,12 +926,13 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
448 926
449 b43_mac_phy_clock_set(dev, true); 927 b43_mac_phy_clock_set(dev, true);
450 928
929 b43_phy_ht_pa_override(dev, false);
451 b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX); 930 b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX);
452 b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX); 931 b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX);
453 932 b43_phy_ht_pa_override(dev, true);
454 /* TODO: PHY op on reg 0xb0 */
455 933
456 /* TODO: Should we restore it? Or store it in global PHY info? */ 934 /* TODO: Should we restore it? Or store it in global PHY info? */
935 b43_phy_ht_classifier(dev, 0, 0);
457 b43_phy_ht_read_clip_detection(dev, clip_state); 936 b43_phy_ht_read_clip_detection(dev, clip_state);
458 937
459 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 938 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
@@ -462,6 +941,13 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
462 b43_httab_write_bulk(dev, B43_HTTAB32(0x1a, 0xc0), 941 b43_httab_write_bulk(dev, B43_HTTAB32(0x1a, 0xc0),
463 B43_HTTAB_1A_C0_LATE_SIZE, b43_httab_0x1a_0xc0_late); 942 B43_HTTAB_1A_C0_LATE_SIZE, b43_httab_0x1a_0xc0_late);
464 943
944 saved_tx_pwr_ctl = phy_ht->tx_pwr_ctl;
945 b43_phy_ht_tx_power_fix(dev);
946 b43_phy_ht_tx_power_ctl(dev, false);
947 b43_phy_ht_tx_power_ctl_idle_tssi(dev);
948 b43_phy_ht_tx_power_ctl_setup(dev);
949 b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl);
950
465 return 0; 951 return 0;
466} 952}
467 953
@@ -506,19 +992,19 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev,
506static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) 992static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on)
507{ 993{
508 if (on) { 994 if (on) {
509 b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00cd); 995 b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00cd);
510 b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x0000); 996 b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x0000);
511 b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00cd); 997 b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00cd);
512 b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x0000); 998 b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x0000);
513 b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00cd); 999 b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00cd);
514 b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x0000); 1000 b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x0000);
515 } else { 1001 } else {
516 b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x07ff); 1002 b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x07ff);
517 b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00fd); 1003 b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00fd);
518 b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x07ff); 1004 b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x07ff);
519 b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00fd); 1005 b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00fd);
520 b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x07ff); 1006 b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x07ff);
521 b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00fd); 1007 b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00fd);
522 } 1008 }
523} 1009}
524 1010
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 6544c4293b34..9b2408efb224 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -12,18 +12,60 @@
12#define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */ 12#define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */
13#define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */ 13#define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */
14#define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */ 14#define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */
15#define B43_PHY_HT_CLASS_CTL 0x0B0 /* Classifier control */
16#define B43_PHY_HT_CLASS_CTL_CCK_EN 0x0001 /* CCK enable */
17#define B43_PHY_HT_CLASS_CTL_OFDM_EN 0x0002 /* OFDM enable */
18#define B43_PHY_HT_CLASS_CTL_WAITED_EN 0x0004 /* Waited enable */
19#define B43_PHY_HT_IQLOCAL_CMDGCTL 0x0C2 /* I/Q LO cal command G control */
20#define B43_PHY_HT_SAMP_CMD 0x0C3 /* Sample command */
21#define B43_PHY_HT_SAMP_CMD_STOP 0x0002 /* Stop */
22#define B43_PHY_HT_SAMP_LOOP_CNT 0x0C4 /* Sample loop count */
23#define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */
24#define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */
25#define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */
26#define B43_PHY_HT_TSSIMODE 0x122 /* TSSI mode */
27#define B43_PHY_HT_TSSIMODE_EN 0x0001 /* TSSI enable */
28#define B43_PHY_HT_TSSIMODE_PDEN 0x0002 /* Power det enable */
15#define B43_PHY_HT_BW1 0x1CE 29#define B43_PHY_HT_BW1 0x1CE
16#define B43_PHY_HT_BW2 0x1CF 30#define B43_PHY_HT_BW2 0x1CF
17#define B43_PHY_HT_BW3 0x1D0 31#define B43_PHY_HT_BW3 0x1D0
18#define B43_PHY_HT_BW4 0x1D1 32#define B43_PHY_HT_BW4 0x1D1
19#define B43_PHY_HT_BW5 0x1D2 33#define B43_PHY_HT_BW5 0x1D2
20#define B43_PHY_HT_BW6 0x1D3 34#define B43_PHY_HT_BW6 0x1D3
35#define B43_PHY_HT_TXPCTL_CMD_C1 0x1E7 /* TX power control command */
36#define B43_PHY_HT_TXPCTL_CMD_C1_INIT 0x007F /* Init */
37#define B43_PHY_HT_TXPCTL_CMD_C1_COEFF 0x2000 /* Power control coefficients */
38#define B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN 0x4000 /* Hardware TX power control enable */
39#define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */
40#define B43_PHY_HT_TXPCTL_N 0x1E8 /* TX power control N num */
41#define B43_PHY_HT_TXPCTL_N_TSSID 0x00FF /* N TSSI delay */
42#define B43_PHY_HT_TXPCTL_N_TSSID_SHIFT 0
43#define B43_PHY_HT_TXPCTL_N_NPTIL2 0x0700 /* N PT integer log2 */
44#define B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT 8
45#define B43_PHY_HT_TXPCTL_IDLE_TSSI 0x1E9 /* TX power control idle TSSI */
46#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C1 0x003F
47#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT 0
48#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C2 0x3F00
49#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT 8
50#define B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF 0x8000 /* Raw TSSI offset bin format */
51#define B43_PHY_HT_TXPCTL_TARG_PWR 0x1EA /* TX power control target power */
52#define B43_PHY_HT_TXPCTL_TARG_PWR_C1 0x00FF /* Power 0 */
53#define B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT 0
54#define B43_PHY_HT_TXPCTL_TARG_PWR_C2 0xFF00 /* Power 1 */
55#define B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT 8
56#define B43_PHY_HT_TXPCTL_CMD_C2 0x222
57#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F
58#define B43_PHY_HT_RSSI_C1 0x219
59#define B43_PHY_HT_RSSI_C2 0x21A
60#define B43_PHY_HT_RSSI_C3 0x21B
21 61
22#define B43_PHY_HT_C1_CLIP1THRES B43_PHY_OFDM(0x00E) 62#define B43_PHY_HT_C1_CLIP1THRES B43_PHY_OFDM(0x00E)
23#define B43_PHY_HT_C2_CLIP1THRES B43_PHY_OFDM(0x04E) 63#define B43_PHY_HT_C2_CLIP1THRES B43_PHY_OFDM(0x04E)
24#define B43_PHY_HT_C3_CLIP1THRES B43_PHY_OFDM(0x08E) 64#define B43_PHY_HT_C3_CLIP1THRES B43_PHY_OFDM(0x08E)
25 65
26#define B43_PHY_HT_RF_SEQ_MODE B43_PHY_EXTG(0x000) 66#define B43_PHY_HT_RF_SEQ_MODE B43_PHY_EXTG(0x000)
67#define B43_PHY_HT_RF_SEQ_MODE_CA_OVER 0x0001 /* Core active override */
68#define B43_PHY_HT_RF_SEQ_MODE_TR_OVER 0x0002 /* Trigger override */
27#define B43_PHY_HT_RF_SEQ_TRIG B43_PHY_EXTG(0x003) 69#define B43_PHY_HT_RF_SEQ_TRIG B43_PHY_EXTG(0x003)
28#define B43_PHY_HT_RF_SEQ_TRIG_RX2TX 0x0001 /* RX2TX */ 70#define B43_PHY_HT_RF_SEQ_TRIG_RX2TX 0x0001 /* RX2TX */
29#define B43_PHY_HT_RF_SEQ_TRIG_TX2RX 0x0002 /* TX2RX */ 71#define B43_PHY_HT_RF_SEQ_TRIG_TX2RX 0x0002 /* TX2RX */
@@ -36,12 +78,27 @@
36 78
37#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010) 79#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010)
38 80
39#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110) 81#define B43_PHY_HT_RF_CTL_INT_C1 B43_PHY_EXTG(0x04c)
40#define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111) 82#define B43_PHY_HT_RF_CTL_INT_C2 B43_PHY_EXTG(0x06c)
41#define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114) 83#define B43_PHY_HT_RF_CTL_INT_C3 B43_PHY_EXTG(0x08c)
42#define B43_PHY_HT_AFE_CTL4 B43_PHY_EXTG(0x115) 84
43#define B43_PHY_HT_AFE_CTL5 B43_PHY_EXTG(0x118) 85#define B43_PHY_HT_AFE_C1_OVER B43_PHY_EXTG(0x110)
44#define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119) 86#define B43_PHY_HT_AFE_C1 B43_PHY_EXTG(0x111)
87#define B43_PHY_HT_AFE_C2_OVER B43_PHY_EXTG(0x114)
88#define B43_PHY_HT_AFE_C2 B43_PHY_EXTG(0x115)
89#define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118)
90#define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119)
91
92#define B43_PHY_HT_TXPCTL_CMD_C3 B43_PHY_EXTG(0x164)
93#define B43_PHY_HT_TXPCTL_CMD_C3_INIT 0x007F
94#define B43_PHY_HT_TXPCTL_IDLE_TSSI2 B43_PHY_EXTG(0x165) /* TX power control idle TSSI */
95#define B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3 0x003F
96#define B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT 0
97#define B43_PHY_HT_TXPCTL_TARG_PWR2 B43_PHY_EXTG(0x166) /* TX power control target power */
98#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3 0x00FF
99#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0
100
101#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A)
45 102
46 103
47/* Values for PHY registers used on channel switching */ 104/* Values for PHY registers used on channel switching */
@@ -56,6 +113,14 @@ struct b43_phy_ht_channeltab_e_phy {
56 113
57 114
58struct b43_phy_ht { 115struct b43_phy_ht {
116 u16 rf_ctl_int_save[3];
117
118 bool tx_pwr_ctl;
119 u8 tx_pwr_idx[3];
120
121 s32 bb_mult_save[3];
122
123 u8 idle_tssi[3];
59}; 124};
60 125
61 126
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index 1d92d874ebb6..747e9317dabd 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -12,8 +12,9 @@ config BRCMSMAC
12 select CORDIC 12 select CORDIC
13 ---help--- 13 ---help---
14 This module adds support for PCIe wireless adapters based on Broadcom 14 This module adds support for PCIe wireless adapters based on Broadcom
15 IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll 15 IEEE802.11n SoftMAC chipsets. It also has WLAN led support, which will
16 be called brcmsmac.ko. 16 be available if you select BCMA_DRIVER_GPIO. If you choose to build a
17 module, the driver will be called brcmsmac.ko.
17 18
18config BRCMFMAC 19config BRCMFMAC
19 tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver" 20 tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 756e19fc2795..598c8e2f8d2b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -26,6 +26,7 @@ brcmfmac-objs += \
26 wl_cfg80211.o \ 26 wl_cfg80211.o \
27 fwil.o \ 27 fwil.o \
28 fweh.o \ 28 fweh.o \
29 fwsignal.o \
29 p2p.o \ 30 p2p.o \
30 dhd_cdc.o \ 31 dhd_cdc.o \
31 dhd_common.o \ 32 dhd_common.o \
@@ -39,3 +40,5 @@ brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
39 usb.o 40 usb.o
40brcmfmac-$(CONFIG_BRCMDBG) += \ 41brcmfmac-$(CONFIG_BRCMDBG) += \
41 dhd_dbg.o 42 dhd_dbg.o
43brcmfmac-$(CONFIG_BRCM_TRACING) += \
44 tracepoint.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index ef6f23be6d32..c7fa20846b32 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -501,6 +501,7 @@ struct brcmf_dcmd {
501/* Forward decls for struct brcmf_pub (see below) */ 501/* Forward decls for struct brcmf_pub (see below) */
502struct brcmf_proto; /* device communication protocol info */ 502struct brcmf_proto; /* device communication protocol info */
503struct brcmf_cfg80211_dev; /* cfg80211 device info */ 503struct brcmf_cfg80211_dev; /* cfg80211 device info */
504struct brcmf_fws_info; /* firmware signalling info */
504 505
505/* Common structure for module and instance linkage */ 506/* Common structure for module and instance linkage */
506struct brcmf_pub { 507struct brcmf_pub {
@@ -527,6 +528,10 @@ struct brcmf_pub {
527 unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; 528 unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
528 529
529 struct brcmf_fweh_info fweh; 530 struct brcmf_fweh_info fweh;
531
532 bool fw_signals;
533 struct brcmf_fws_info *fws;
534 spinlock_t fws_spinlock;
530#ifdef DEBUG 535#ifdef DEBUG
531 struct dentry *dbgfs_dir; 536 struct dentry *dbgfs_dir;
532#endif 537#endif
@@ -582,7 +587,7 @@ extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
582 void *buf, uint len); 587 void *buf, uint len);
583 588
584/* Remove any protocol-specific data header. */ 589/* Remove any protocol-specific data header. */
585extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, 590extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
586 struct sk_buff *rxp); 591 struct sk_buff *rxp);
587 592
588extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); 593extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index ad25c3408b59..883ef9063e8a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -134,7 +134,7 @@ extern void brcmf_dev_reset(struct device *dev);
134/* Indication from bus module to change flow-control state */ 134/* Indication from bus module to change flow-control state */
135extern void brcmf_txflowblock(struct device *dev, bool state); 135extern void brcmf_txflowblock(struct device *dev, bool state);
136 136
137/* Notify tx completion */ 137/* Notify the bus has transferred the tx packet to firmware */
138extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, 138extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
139 bool success); 139 bool success);
140 140
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
index a2354d951dd7..e224bcb90024 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -28,6 +28,7 @@
28#include "dhd.h" 28#include "dhd.h"
29#include "dhd_proto.h" 29#include "dhd_proto.h"
30#include "dhd_bus.h" 30#include "dhd_bus.h"
31#include "fwsignal.h"
31#include "dhd_dbg.h" 32#include "dhd_dbg.h"
32 33
33struct brcmf_proto_cdc_dcmd { 34struct brcmf_proto_cdc_dcmd {
@@ -71,13 +72,26 @@ struct brcmf_proto_cdc_dcmd {
71 ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ 72 ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
72 ((idx) << BDC_FLAG2_IF_SHIFT))) 73 ((idx) << BDC_FLAG2_IF_SHIFT)))
73 74
75/**
76 * struct brcmf_proto_bdc_header - BDC header format
77 *
78 * @flags: flags contain protocol and checksum info.
79 * @priority: 802.1d priority and USB flow control info (bit 4:7).
80 * @flags2: additional flags containing dongle interface index.
81 * @data_offset: start of packet data. header is following by firmware signals.
82 */
74struct brcmf_proto_bdc_header { 83struct brcmf_proto_bdc_header {
75 u8 flags; 84 u8 flags;
76 u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */ 85 u8 priority;
77 u8 flags2; 86 u8 flags2;
78 u8 data_offset; 87 u8 data_offset;
79}; 88};
80 89
90/*
91 * maximum length of firmware signal data between
92 * the BDC header and packet data in the tx path.
93 */
94#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12
81 95
82#define RETRIES 2 /* # of retries to retrieve matching dcmd response */ 96#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
83#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE 97#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE
@@ -258,7 +272,7 @@ static void pkt_set_sum_good(struct sk_buff *skb, bool x)
258 skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE); 272 skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
259} 273}
260 274
261void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, 275void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
262 struct sk_buff *pktbuf) 276 struct sk_buff *pktbuf)
263{ 277{
264 struct brcmf_proto_bdc_header *h; 278 struct brcmf_proto_bdc_header *h;
@@ -266,7 +280,6 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
266 brcmf_dbg(CDC, "Enter\n"); 280 brcmf_dbg(CDC, "Enter\n");
267 281
268 /* Push BDC header used to convey priority for buses that don't */ 282 /* Push BDC header used to convey priority for buses that don't */
269
270 skb_push(pktbuf, BDC_HEADER_LEN); 283 skb_push(pktbuf, BDC_HEADER_LEN);
271 284
272 h = (struct brcmf_proto_bdc_header *)(pktbuf->data); 285 h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
@@ -277,11 +290,11 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
277 290
278 h->priority = (pktbuf->priority & BDC_PRIORITY_MASK); 291 h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
279 h->flags2 = 0; 292 h->flags2 = 0;
280 h->data_offset = 0; 293 h->data_offset = offset;
281 BDC_SET_IF_IDX(h, ifidx); 294 BDC_SET_IF_IDX(h, ifidx);
282} 295}
283 296
284int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, 297int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
285 struct sk_buff *pktbuf) 298 struct sk_buff *pktbuf)
286{ 299{
287 struct brcmf_proto_bdc_header *h; 300 struct brcmf_proto_bdc_header *h;
@@ -328,7 +341,10 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
328 pktbuf->priority = h->priority & BDC_PRIORITY_MASK; 341 pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
329 342
330 skb_pull(pktbuf, BDC_HEADER_LEN); 343 skb_pull(pktbuf, BDC_HEADER_LEN);
331 skb_pull(pktbuf, h->data_offset << 2); 344 if (do_fws)
345 brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
346 else
347 skb_pull(pktbuf, h->data_offset << 2);
332 348
333 if (pktbuf->len == 0) 349 if (pktbuf->len == 0)
334 return -ENODATA; 350 return -ENODATA;
@@ -350,7 +366,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr)
350 } 366 }
351 367
352 drvr->prot = cdc; 368 drvr->prot = cdc;
353 drvr->hdrlen += BDC_HEADER_LEN; 369 drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
354 drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + 370 drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
355 sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN; 371 sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
356 return 0; 372 return 0;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 4544342a0428..be0787cab24f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -24,6 +24,7 @@
24#include "dhd_proto.h" 24#include "dhd_proto.h"
25#include "dhd_dbg.h" 25#include "dhd_dbg.h"
26#include "fwil.h" 26#include "fwil.h"
27#include "tracepoint.h"
27 28
28#define PKTFILTER_BUF_SIZE 128 29#define PKTFILTER_BUF_SIZE 128
29#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ 30#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */
@@ -373,3 +374,35 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
373done: 374done:
374 return err; 375 return err;
375} 376}
377
378#ifdef CONFIG_BRCM_TRACING
379void __brcmf_err(const char *func, const char *fmt, ...)
380{
381 struct va_format vaf = {
382 .fmt = fmt,
383 };
384 va_list args;
385
386 va_start(args, fmt);
387 vaf.va = &args;
388 pr_err("%s: %pV", func, &vaf);
389 trace_brcmf_err(func, &vaf);
390 va_end(args);
391}
392#endif
393#if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
394void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
395{
396 struct va_format vaf = {
397 .fmt = fmt,
398 };
399 va_list args;
400
401 va_start(args, fmt);
402 vaf.va = &args;
403 if (brcmf_msg_level & level)
404 pr_debug("%s %pV", func, &vaf);
405 trace_brcmf_dbg(level, func, &vaf);
406 va_end(args);
407}
408#endif
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
index 57671eddf79d..ac792499b46a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -22,6 +22,7 @@
22#include "dhd.h" 22#include "dhd.h"
23#include "dhd_bus.h" 23#include "dhd_bus.h"
24#include "dhd_dbg.h" 24#include "dhd_dbg.h"
25#include "tracepoint.h"
25 26
26static struct dentry *root_folder; 27static struct dentry *root_folder;
27 28
@@ -123,3 +124,44 @@ void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
123 debugfs_create_file("counters", S_IRUGO, dentry, 124 debugfs_create_file("counters", S_IRUGO, dentry,
124 sdcnt, &brcmf_debugfs_sdio_counter_ops); 125 sdcnt, &brcmf_debugfs_sdio_counter_ops);
125} 126}
127
128static
129ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
130 size_t count, loff_t *ppos)
131{
132 struct brcmf_fws_stats *fwstats = f->private_data;
133 char buf[100];
134 int res;
135
136 /* only allow read from start */
137 if (*ppos > 0)
138 return 0;
139
140 res = scnprintf(buf, sizeof(buf),
141 "header_pulls: %u\n"
142 "header_only_pkt: %u\n"
143 "tlv_parse_failed: %u\n"
144 "tlv_invalid_type: %u\n",
145 fwstats->header_pulls,
146 fwstats->header_only_pkt,
147 fwstats->tlv_parse_failed,
148 fwstats->tlv_invalid_type);
149
150 return simple_read_from_buffer(data, count, ppos, buf, res);
151}
152
153static const struct file_operations brcmf_debugfs_fws_stats_ops = {
154 .owner = THIS_MODULE,
155 .open = simple_open,
156 .read = brcmf_debugfs_fws_stats_read
157};
158
159void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
160 struct brcmf_fws_stats *stats)
161{
162 struct dentry *dentry = drvr->dbgfs_dir;
163
164 if (!IS_ERR_OR_NULL(dentry))
165 debugfs_create_file("fws_stats", S_IRUGO, dentry,
166 stats, &brcmf_debugfs_fws_stats_ops);
167}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index bc013cbe06f6..4bc646bde16f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -43,6 +43,7 @@
43 * debugging is not selected. When debugging the driver error 43 * debugging is not selected. When debugging the driver error
44 * messages are as important as other tracing or even more so. 44 * messages are as important as other tracing or even more so.
45 */ 45 */
46#ifndef CONFIG_BRCM_TRACING
46#ifdef CONFIG_BRCMDBG 47#ifdef CONFIG_BRCMDBG
47#define brcmf_err(fmt, ...) pr_err("%s: " fmt, __func__, ##__VA_ARGS__) 48#define brcmf_err(fmt, ...) pr_err("%s: " fmt, __func__, ##__VA_ARGS__)
48#else 49#else
@@ -52,15 +53,21 @@
52 pr_err("%s: " fmt, __func__, ##__VA_ARGS__); \ 53 pr_err("%s: " fmt, __func__, ##__VA_ARGS__); \
53 } while (0) 54 } while (0)
54#endif 55#endif
56#else
57__printf(2, 3)
58void __brcmf_err(const char *func, const char *fmt, ...);
59#define brcmf_err(fmt, ...) \
60 __brcmf_err(__func__, fmt, ##__VA_ARGS__)
61#endif
55 62
56#if defined(DEBUG) 63#if defined(DEBUG) || defined(CONFIG_BRCM_TRACING)
57 64__printf(3, 4)
65void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...);
58#define brcmf_dbg(level, fmt, ...) \ 66#define brcmf_dbg(level, fmt, ...) \
59do { \ 67do { \
60 if (brcmf_msg_level & BRCMF_##level##_VAL) \ 68 __brcmf_dbg(BRCMF_##level##_VAL, __func__, \
61 pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ 69 fmt, ##__VA_ARGS__); \
62} while (0) 70} while (0)
63
64#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL) 71#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL)
65#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL) 72#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL)
66#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL) 73#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL)
@@ -69,7 +76,7 @@ do { \
69#define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL) 76#define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL)
70#define BRCMF_FIL_ON() (brcmf_msg_level & BRCMF_FIL_VAL) 77#define BRCMF_FIL_ON() (brcmf_msg_level & BRCMF_FIL_VAL)
71 78
72#else /* (defined DEBUG) || (defined DEBUG) */ 79#else /* defined(DEBUG) || defined(CONFIG_BRCM_TRACING) */
73 80
74#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__) 81#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
75 82
@@ -81,7 +88,7 @@ do { \
81#define BRCMF_EVENT_ON() 0 88#define BRCMF_EVENT_ON() 0
82#define BRCMF_FIL_ON() 0 89#define BRCMF_FIL_ON() 0
83 90
84#endif /* defined(DEBUG) */ 91#endif /* defined(DEBUG) || defined(CONFIG_BRCM_TRACING) */
85 92
86#define brcmf_dbg_hex_dump(test, data, len, fmt, ...) \ 93#define brcmf_dbg_hex_dump(test, data, len, fmt, ...) \
87do { \ 94do { \
@@ -125,6 +132,13 @@ struct brcmf_sdio_count {
125 ulong rx_readahead_cnt; /* packets where header read-ahead was used */ 132 ulong rx_readahead_cnt; /* packets where header read-ahead was used */
126}; 133};
127 134
135struct brcmf_fws_stats {
136 u32 tlv_parse_failed;
137 u32 tlv_invalid_type;
138 u32 header_only_pkt;
139 u32 header_pulls;
140};
141
128struct brcmf_pub; 142struct brcmf_pub;
129#ifdef DEBUG 143#ifdef DEBUG
130void brcmf_debugfs_init(void); 144void brcmf_debugfs_init(void);
@@ -134,6 +148,8 @@ void brcmf_debugfs_detach(struct brcmf_pub *drvr);
134struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); 148struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
135void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, 149void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
136 struct brcmf_sdio_count *sdcnt); 150 struct brcmf_sdio_count *sdcnt);
151void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
152 struct brcmf_fws_stats *stats);
137#else 153#else
138static inline void brcmf_debugfs_init(void) 154static inline void brcmf_debugfs_init(void)
139{ 155{
@@ -148,6 +164,10 @@ static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr)
148static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr) 164static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr)
149{ 165{
150} 166}
167static inline void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
168 struct brcmf_fws_stats *stats)
169{
170}
151#endif 171#endif
152 172
153#endif /* _BRCMF_DBG_H_ */ 173#endif /* _BRCMF_DBG_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index c06cea88df0d..fa5a2af04d46 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -30,17 +30,18 @@
30#include "p2p.h" 30#include "p2p.h"
31#include "wl_cfg80211.h" 31#include "wl_cfg80211.h"
32#include "fwil.h" 32#include "fwil.h"
33#include "fwsignal.h"
33 34
34MODULE_AUTHOR("Broadcom Corporation"); 35MODULE_AUTHOR("Broadcom Corporation");
35MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); 36MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
36MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards");
37MODULE_LICENSE("Dual BSD/GPL"); 37MODULE_LICENSE("Dual BSD/GPL");
38 38
39#define MAX_WAIT_FOR_8021X_TX 50 /* msecs */ 39#define MAX_WAIT_FOR_8021X_TX 50 /* msecs */
40 40
41/* Error bits */ 41/* Error bits */
42int brcmf_msg_level; 42int brcmf_msg_level;
43module_param(brcmf_msg_level, int, 0); 43module_param_named(debug, brcmf_msg_level, int, S_IRUSR | S_IWUSR);
44MODULE_PARM_DESC(debug, "level of debug output");
44 45
45/* P2P0 enable */ 46/* P2P0 enable */
46static int brcmf_p2p_enable; 47static int brcmf_p2p_enable;
@@ -230,7 +231,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
230 atomic_inc(&ifp->pend_8021x_cnt); 231 atomic_inc(&ifp->pend_8021x_cnt);
231 232
232 /* If the protocol uses a data header, apply it */ 233 /* If the protocol uses a data header, apply it */
233 brcmf_proto_hdrpush(drvr, ifp->ifidx, skb); 234 brcmf_proto_hdrpush(drvr, ifp->ifidx, 0, skb);
234 235
235 /* Use bus module to send data frame */ 236 /* Use bus module to send data frame */
236 ret = brcmf_bus_txdata(drvr->bus_if, skb); 237 ret = brcmf_bus_txdata(drvr->bus_if, skb);
@@ -283,7 +284,7 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
283 skb_unlink(skb, skb_list); 284 skb_unlink(skb, skb_list);
284 285
285 /* process and remove protocol-specific header */ 286 /* process and remove protocol-specific header */
286 ret = brcmf_proto_hdrpull(drvr, &ifidx, skb); 287 ret = brcmf_proto_hdrpull(drvr, drvr->fw_signals, &ifidx, skb);
287 ifp = drvr->iflist[ifidx]; 288 ifp = drvr->iflist[ifidx];
288 289
289 if (ret || !ifp || !ifp->ndev) { 290 if (ret || !ifp || !ifp->ndev) {
@@ -357,23 +358,29 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
357 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 358 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
358 struct brcmf_pub *drvr = bus_if->drvr; 359 struct brcmf_pub *drvr = bus_if->drvr;
359 struct brcmf_if *ifp; 360 struct brcmf_if *ifp;
361 int res;
360 362
361 brcmf_proto_hdrpull(drvr, &ifidx, txp); 363 res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
362 364
363 ifp = drvr->iflist[ifidx]; 365 ifp = drvr->iflist[ifidx];
364 if (!ifp) 366 if (!ifp)
365 return; 367 goto done;
366 368
367 eh = (struct ethhdr *)(txp->data); 369 if (res == 0) {
368 type = ntohs(eh->h_proto); 370 eh = (struct ethhdr *)(txp->data);
371 type = ntohs(eh->h_proto);
369 372
370 if (type == ETH_P_PAE) { 373 if (type == ETH_P_PAE) {
371 atomic_dec(&ifp->pend_8021x_cnt); 374 atomic_dec(&ifp->pend_8021x_cnt);
372 if (waitqueue_active(&ifp->pend_8021x_wait)) 375 if (waitqueue_active(&ifp->pend_8021x_wait))
373 wake_up(&ifp->pend_8021x_wait); 376 wake_up(&ifp->pend_8021x_wait);
377 }
374 } 378 }
375 if (!success) 379 if (!success)
376 ifp->stats.tx_errors++; 380 ifp->stats.tx_errors++;
381
382done:
383 brcmu_pkt_buf_free_skb(txp);
377} 384}
378 385
379static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) 386static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
@@ -873,6 +880,9 @@ int brcmf_bus_start(struct device *dev)
873 if (ret < 0) 880 if (ret < 0)
874 goto fail; 881 goto fail;
875 882
883 drvr->fw_signals = true;
884 (void)brcmf_fws_init(drvr);
885
876 drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev); 886 drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
877 if (drvr->config == NULL) { 887 if (drvr->config == NULL) {
878 ret = -ENOMEM; 888 ret = -ENOMEM;
@@ -889,6 +899,8 @@ fail:
889 brcmf_err("failed: %d\n", ret); 899 brcmf_err("failed: %d\n", ret);
890 if (drvr->config) 900 if (drvr->config)
891 brcmf_cfg80211_detach(drvr->config); 901 brcmf_cfg80211_detach(drvr->config);
902 if (drvr->fws)
903 brcmf_fws_deinit(drvr);
892 free_netdev(ifp->ndev); 904 free_netdev(ifp->ndev);
893 drvr->iflist[0] = NULL; 905 drvr->iflist[0] = NULL;
894 if (p2p_ifp) { 906 if (p2p_ifp) {
@@ -952,6 +964,9 @@ void brcmf_detach(struct device *dev)
952 if (drvr->prot) 964 if (drvr->prot)
953 brcmf_proto_detach(drvr); 965 brcmf_proto_detach(drvr);
954 966
967 if (drvr->fws)
968 brcmf_fws_deinit(drvr);
969
955 brcmf_debugfs_detach(drvr); 970 brcmf_debugfs_detach(drvr);
956 bus_if->drvr = NULL; 971 bus_if->drvr = NULL;
957 kfree(drvr); 972 kfree(drvr);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
index 48fa70302192..ef9179883748 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
@@ -33,7 +33,7 @@ extern void brcmf_proto_stop(struct brcmf_pub *drvr);
33/* Add any protocol-specific data header. 33/* Add any protocol-specific data header.
34 * Caller must reserve prot_hdrlen prepend space. 34 * Caller must reserve prot_hdrlen prepend space.
35 */ 35 */
36extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, 36extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset,
37 struct sk_buff *txp); 37 struct sk_buff *txp);
38 38
39/* Sets dongle media info (drv_version, mac address). */ 39/* Sets dongle media info (drv_version, mac address). */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 4469321c0eb3..9a2edd3f0a5c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1546,7 +1546,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1546 struct sk_buff_head pktlist; /* needed for bus interface */ 1546 struct sk_buff_head pktlist; /* needed for bus interface */
1547 u16 pad; /* Number of pad bytes to read */ 1547 u16 pad; /* Number of pad bytes to read */
1548 uint rxleft = 0; /* Remaining number of frames allowed */ 1548 uint rxleft = 0; /* Remaining number of frames allowed */
1549 int sdret; /* Return code from calls */ 1549 int ret; /* Return code from calls */
1550 uint rxcount = 0; /* Total frames read */ 1550 uint rxcount = 0; /* Total frames read */
1551 struct brcmf_sdio_read *rd = &bus->cur_read, rd_new; 1551 struct brcmf_sdio_read *rd = &bus->cur_read, rd_new;
1552 u8 head_read = 0; 1552 u8 head_read = 0;
@@ -1577,15 +1577,15 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1577 /* read header first for unknow frame length */ 1577 /* read header first for unknow frame length */
1578 sdio_claim_host(bus->sdiodev->func[1]); 1578 sdio_claim_host(bus->sdiodev->func[1]);
1579 if (!rd->len) { 1579 if (!rd->len) {
1580 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, 1580 ret = brcmf_sdcard_recv_buf(bus->sdiodev,
1581 bus->sdiodev->sbwad, 1581 bus->sdiodev->sbwad,
1582 SDIO_FUNC_2, F2SYNC, 1582 SDIO_FUNC_2, F2SYNC,
1583 bus->rxhdr, 1583 bus->rxhdr,
1584 BRCMF_FIRSTREAD); 1584 BRCMF_FIRSTREAD);
1585 bus->sdcnt.f2rxhdrs++; 1585 bus->sdcnt.f2rxhdrs++;
1586 if (sdret < 0) { 1586 if (ret < 0) {
1587 brcmf_err("RXHEADER FAILED: %d\n", 1587 brcmf_err("RXHEADER FAILED: %d\n",
1588 sdret); 1588 ret);
1589 bus->sdcnt.rx_hdrfail++; 1589 bus->sdcnt.rx_hdrfail++;
1590 brcmf_sdbrcm_rxfail(bus, true, true); 1590 brcmf_sdbrcm_rxfail(bus, true, true);
1591 sdio_release_host(bus->sdiodev->func[1]); 1591 sdio_release_host(bus->sdiodev->func[1]);
@@ -1637,14 +1637,14 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1637 skb_pull(pkt, head_read); 1637 skb_pull(pkt, head_read);
1638 pkt_align(pkt, rd->len_left, BRCMF_SDALIGN); 1638 pkt_align(pkt, rd->len_left, BRCMF_SDALIGN);
1639 1639
1640 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1640 ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
1641 SDIO_FUNC_2, F2SYNC, pkt); 1641 SDIO_FUNC_2, F2SYNC, pkt);
1642 bus->sdcnt.f2rxdata++; 1642 bus->sdcnt.f2rxdata++;
1643 sdio_release_host(bus->sdiodev->func[1]); 1643 sdio_release_host(bus->sdiodev->func[1]);
1644 1644
1645 if (sdret < 0) { 1645 if (ret < 0) {
1646 brcmf_err("read %d bytes from channel %d failed: %d\n", 1646 brcmf_err("read %d bytes from channel %d failed: %d\n",
1647 rd->len, rd->channel, sdret); 1647 rd->len, rd->channel, ret);
1648 brcmu_pkt_buf_free_skb(pkt); 1648 brcmu_pkt_buf_free_skb(pkt);
1649 sdio_claim_host(bus->sdiodev->func[1]); 1649 sdio_claim_host(bus->sdiodev->func[1]);
1650 brcmf_sdbrcm_rxfail(bus, true, 1650 brcmf_sdbrcm_rxfail(bus, true,
@@ -1775,7 +1775,7 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
1775/* Writes a HW/SW header into the packet and sends it. */ 1775/* Writes a HW/SW header into the packet and sends it. */
1776/* Assumes: (a) header space already there, (b) caller holds lock */ 1776/* Assumes: (a) header space already there, (b) caller holds lock */
1777static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, 1777static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1778 uint chan, bool free_pkt) 1778 uint chan)
1779{ 1779{
1780 int ret; 1780 int ret;
1781 u8 *frame; 1781 u8 *frame;
@@ -1805,10 +1805,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1805 1805
1806 pkt_align(new, pkt->len, BRCMF_SDALIGN); 1806 pkt_align(new, pkt->len, BRCMF_SDALIGN);
1807 memcpy(new->data, pkt->data, pkt->len); 1807 memcpy(new->data, pkt->data, pkt->len);
1808 if (free_pkt) 1808 brcmu_pkt_buf_free_skb(pkt);
1809 brcmu_pkt_buf_free_skb(pkt);
1810 /* free the pkt if canned one is not used */
1811 free_pkt = true;
1812 pkt = new; 1809 pkt = new;
1813 frame = (u8 *) (pkt->data); 1810 frame = (u8 *) (pkt->data);
1814 /* precondition: (frame % BRCMF_SDALIGN) == 0) */ 1811 /* precondition: (frame % BRCMF_SDALIGN) == 0) */
@@ -1901,10 +1898,6 @@ done:
1901 /* restore pkt buffer pointer before calling tx complete routine */ 1898 /* restore pkt buffer pointer before calling tx complete routine */
1902 skb_pull(pkt, SDPCM_HDRLEN + pad); 1899 skb_pull(pkt, SDPCM_HDRLEN + pad);
1903 brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); 1900 brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0);
1904
1905 if (free_pkt)
1906 brcmu_pkt_buf_free_skb(pkt);
1907
1908 return ret; 1901 return ret;
1909} 1902}
1910 1903
@@ -1932,7 +1925,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
1932 spin_unlock_bh(&bus->txqlock); 1925 spin_unlock_bh(&bus->txqlock);
1933 datalen = pkt->len - SDPCM_HDRLEN; 1926 datalen = pkt->len - SDPCM_HDRLEN;
1934 1927
1935 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); 1928 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL);
1936 1929
1937 /* In poll mode, need to check for other events */ 1930 /* In poll mode, need to check for other events */
1938 if (!bus->intr && cnt) { 1931 if (!bus->intr && cnt) {
@@ -2343,7 +2336,6 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
2343 if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { 2336 if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
2344 skb_pull(pkt, SDPCM_HDRLEN); 2337 skb_pull(pkt, SDPCM_HDRLEN);
2345 brcmf_txcomplete(bus->sdiodev->dev, pkt, false); 2338 brcmf_txcomplete(bus->sdiodev->dev, pkt, false);
2346 brcmu_pkt_buf_free_skb(pkt);
2347 brcmf_err("out of bus->txq !!!\n"); 2339 brcmf_err("out of bus->txq !!!\n");
2348 ret = -ENOSR; 2340 ret = -ENOSR;
2349 } else { 2341 } else {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
new file mode 100644
index 000000000000..071d55f9cd4d
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -0,0 +1,382 @@
1/*
2 * Copyright (c) 2010 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/types.h>
17#include <linux/if_ether.h>
18#include <linux/spinlock.h>
19#include <linux/skbuff.h>
20#include <linux/netdevice.h>
21#include <linux/err.h>
22#include <uapi/linux/nl80211.h>
23
24#include <brcmu_utils.h>
25#include <brcmu_wifi.h>
26#include "dhd.h"
27#include "dhd_dbg.h"
28#include "fwil.h"
29#include "fweh.h"
30#include "fwsignal.h"
31
32/**
33 * DOC: Firmware Signalling
34 *
35 * Firmware can send signals to host and vice versa, which are passed in the
36 * data packets using TLV based header. This signalling layer is on top of the
37 * BDC bus protocol layer.
38 */
39
40/*
41 * single definition for firmware-driver flow control tlv's.
42 *
43 * each tlv is specified by BRCMF_FWS_TLV_DEF(name, ID, length).
44 * A length value 0 indicates variable length tlv.
45 */
46#define BRCMF_FWS_TLV_DEFLIST \
47 BRCMF_FWS_TLV_DEF(MAC_OPEN, 1, 1) \
48 BRCMF_FWS_TLV_DEF(MAC_CLOSE, 2, 1) \
49 BRCMF_FWS_TLV_DEF(MAC_REQUEST_CREDIT, 3, 2) \
50 BRCMF_FWS_TLV_DEF(TXSTATUS, 4, 4) \
51 BRCMF_FWS_TLV_DEF(PKTTAG, 5, 4) \
52 BRCMF_FWS_TLV_DEF(MACDESC_ADD, 6, 8) \
53 BRCMF_FWS_TLV_DEF(MACDESC_DEL, 7, 8) \
54 BRCMF_FWS_TLV_DEF(RSSI, 8, 1) \
55 BRCMF_FWS_TLV_DEF(INTERFACE_OPEN, 9, 1) \
56 BRCMF_FWS_TLV_DEF(INTERFACE_CLOSE, 10, 1) \
57 BRCMF_FWS_TLV_DEF(FIFO_CREDITBACK, 11, 8) \
58 BRCMF_FWS_TLV_DEF(PENDING_TRAFFIC_BMP, 12, 2) \
59 BRCMF_FWS_TLV_DEF(MAC_REQUEST_PACKET, 13, 3) \
60 BRCMF_FWS_TLV_DEF(HOST_REORDER_RXPKTS, 14, 10) \
61 BRCMF_FWS_TLV_DEF(TRANS_ID, 18, 6) \
62 BRCMF_FWS_TLV_DEF(COMP_TXSTATUS, 19, 1) \
63 BRCMF_FWS_TLV_DEF(FILLER, 255, 0)
64
65/**
66 * enum brcmf_fws_tlv_type - definition of tlv identifiers.
67 */
68#define BRCMF_FWS_TLV_DEF(name, id, len) \
69 BRCMF_FWS_TYPE_ ## name = id,
70enum brcmf_fws_tlv_type {
71 BRCMF_FWS_TLV_DEFLIST
72 BRCMF_FWS_TYPE_INVALID
73};
74#undef BRCMF_FWS_TLV_DEF
75
76/**
77 * enum brcmf_fws_tlv_len - length values for tlvs.
78 */
79#define BRCMF_FWS_TLV_DEF(name, id, len) \
80 BRCMF_FWS_TYPE_ ## name ## _LEN = len,
81enum brcmf_fws_tlv_len {
82 BRCMF_FWS_TLV_DEFLIST
83};
84#undef BRCMF_FWS_TLV_DEF
85
86#ifdef DEBUG
87/**
88 * brcmf_fws_tlv_names - array of tlv names.
89 */
90#define BRCMF_FWS_TLV_DEF(name, id, len) \
91 { id, #name },
92static struct {
93 enum brcmf_fws_tlv_type id;
94 const char *name;
95} brcmf_fws_tlv_names[] = {
96 BRCMF_FWS_TLV_DEFLIST
97};
98#undef BRCMF_FWS_TLV_DEF
99
100static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
101{
102 int i;
103
104 for (i = 0; i < ARRAY_SIZE(brcmf_fws_tlv_names); i++)
105 if (brcmf_fws_tlv_names[i].id == id)
106 return brcmf_fws_tlv_names[i].name;
107
108 return "INVALID";
109}
110#else
111static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
112{
113 return "NODEBUG";
114}
115#endif /* DEBUG */
116
117/**
118 * flags used to enable tlv signalling from firmware.
119 */
120#define BRCMF_FWS_FLAGS_RSSI_SIGNALS 0x0001
121#define BRCMF_FWS_FLAGS_XONXOFF_SIGNALS 0x0002
122#define BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS 0x0004
123#define BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE 0x0008
124#define BRCMF_FWS_FLAGS_PSQ_GENERATIONFSM_ENABLE 0x0010
125#define BRCMF_FWS_FLAGS_PSQ_ZERO_BUFFER_ENABLE 0x0020
126#define BRCMF_FWS_FLAGS_HOST_RXREORDER_ACTIVE 0x0040
127
128#define BRCMF_FWS_HANGER_MAXITEMS 1024
129#define BRCMF_FWS_HANGER_ITEM_STATE_FREE 1
130#define BRCMF_FWS_HANGER_ITEM_STATE_INUSE 2
131#define BRCMF_FWS_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3
132
133#define BRCMF_FWS_STATE_OPEN 1
134#define BRCMF_FWS_STATE_CLOSE 2
135
136#define BRCMF_FWS_FCMODE_NONE 0
137#define BRCMF_FWS_FCMODE_IMPLIED_CREDIT 1
138#define BRCMF_FWS_FCMODE_EXPLICIT_CREDIT 2
139
140#define BRCMF_FWS_MAC_DESC_TABLE_SIZE 32
141#define BRCMF_FWS_MAX_IFNUM 16
142#define BRCMF_FWS_MAC_DESC_ID_INVALID 0xff
143
144#define BRCMF_FWS_HOSTIF_FLOWSTATE_OFF 0
145#define BRCMF_FWS_HOSTIF_FLOWSTATE_ON 1
146
147/**
148 * FWFC packet identifier
149 *
150 * 32-bit packet identifier used in PKTTAG tlv from host to dongle.
151 *
152 * - Generated at the host (e.g. dhd)
153 * - Seen as a generic sequence number by wlc except the flags field
154 *
155 * Generation : b[31] => generation number for this packet [host->fw]
156 * OR, current generation number [fw->host]
157 * Flags : b[30:27] => command, status flags
158 * FIFO-AC : b[26:24] => AC-FIFO id
159 * h-slot : b[23:8] => hanger-slot
160 * freerun : b[7:0] => A free running counter
161 */
162#define BRCMF_FWS_PKTTAG_GENERATION_MASK 0x80000000
163#define BRCMF_FWS_PKTTAG_GENERATION_SHIFT 31
164#define BRCMF_FWS_PKTTAG_FLAGS_MASK 0x78000000
165#define BRCMF_FWS_PKTTAG_FLAGS_SHIFT 27
166#define BRCMF_FWS_PKTTAG_FIFO_MASK 0x07000000
167#define BRCMF_FWS_PKTTAG_FIFO_SHIFT 24
168#define BRCMF_FWS_PKTTAG_HSLOT_MASK 0x00ffff00
169#define BRCMF_FWS_PKTTAG_HSLOT_SHIFT 8
170#define BRCMF_FWS_PKTTAG_FREERUN_MASK 0x000000ff
171#define BRCMF_FWS_PKTTAG_FREERUN_SHIFT 0
172
173#define brcmf_fws_pkttag_set_field(var, field, value) \
174 brcmu_maskset32((var), BRCMF_FWS_PKTTAG_ ## field ## _MASK, \
175 BRCMF_FWS_PKTTAG_ ## field ## _SHIFT, (value))
176#define brcmf_fws_pkttag_get_field(var, field) \
177 brcmu_maskget32((var), BRCMF_FWS_PKTTAG_ ## field ## _MASK, \
178 BRCMF_FWS_PKTTAG_ ## field ## _SHIFT)
179
180struct brcmf_fws_info {
181 struct brcmf_pub *drvr;
182 struct brcmf_fws_stats stats;
183};
184
185static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi)
186{
187 brcmf_dbg(CTL, "rssi %d\n", rssi);
188 return 0;
189}
190
191static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data)
192{
193 __le32 timestamp;
194
195 memcpy(&timestamp, &data[2], sizeof(timestamp));
196 brcmf_dbg(INFO, "received: seq %d, timestamp %d\n", data[1],
197 le32_to_cpu(timestamp));
198 return 0;
199}
200
201/* using macro so sparse checking does not complain
202 * about locking imbalance.
203 */
204#define brcmf_fws_lock(drvr, flags) \
205do { \
206 flags = 0; \
207 spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \
208} while (0)
209
210/* using macro so sparse checking does not complain
211 * about locking imbalance.
212 */
213#define brcmf_fws_unlock(drvr, flags) \
214 spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
215
216int brcmf_fws_init(struct brcmf_pub *drvr)
217{
218 u32 tlv;
219 int rc;
220
221 /* enable rssi signals */
222 tlv = drvr->fw_signals ? BRCMF_FWS_FLAGS_RSSI_SIGNALS : 0;
223
224 spin_lock_init(&drvr->fws_spinlock);
225
226 drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL);
227 if (!drvr->fws) {
228 rc = -ENOMEM;
229 goto fail;
230 }
231
232 /* enable proptxtstatus signaling by default */
233 rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv);
234 if (rc < 0) {
235 brcmf_err("failed to set bdcv2 tlv signaling\n");
236 goto fail;
237 }
238 /* set linkage back */
239 drvr->fws->drvr = drvr;
240
241 /* create debugfs file for statistics */
242 brcmf_debugfs_create_fws_stats(drvr, &drvr->fws->stats);
243
244 /* TODO: remove upon feature delivery */
245 brcmf_err("%s bdcv2 tlv signaling [%x]\n",
246 drvr->fw_signals ? "enabled" : "disabled", tlv);
247 return 0;
248
249fail:
250 /* disable flow control entirely */
251 drvr->fw_signals = false;
252 brcmf_fws_deinit(drvr);
253 return rc;
254}
255
256void brcmf_fws_deinit(struct brcmf_pub *drvr)
257{
258 /* free top structure */
259 kfree(drvr->fws);
260 drvr->fws = NULL;
261}
262
263int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
264 struct sk_buff *skb)
265{
266 struct brcmf_fws_info *fws = drvr->fws;
267 ulong flags;
268 u8 *signal_data;
269 s16 data_len;
270 u8 type;
271 u8 len;
272 u8 *data;
273
274 brcmf_dbg(TRACE, "enter: ifidx %d, skblen %u, sig %d\n",
275 ifidx, skb->len, signal_len);
276
277 WARN_ON(signal_len > skb->len);
278
279 /* if flow control disabled, skip to packet data and leave */
280 if (!signal_len || !drvr->fw_signals) {
281 skb_pull(skb, signal_len);
282 return 0;
283 }
284
285 /* lock during tlv parsing */
286 brcmf_fws_lock(drvr, flags);
287
288 fws->stats.header_pulls++;
289 data_len = signal_len;
290 signal_data = skb->data;
291
292 while (data_len > 0) {
293 /* extract tlv info */
294 type = signal_data[0];
295
296 /* FILLER type is actually not a TLV, but
297 * a single byte that can be skipped.
298 */
299 if (type == BRCMF_FWS_TYPE_FILLER) {
300 signal_data += 1;
301 data_len -= 1;
302 continue;
303 }
304 len = signal_data[1];
305 data = signal_data + 2;
306
307 /* abort parsing when length invalid */
308 if (data_len < len + 2)
309 break;
310
311 brcmf_dbg(INFO, "tlv type=%d (%s), len=%d\n", type,
312 brcmf_fws_get_tlv_name(type), len);
313 switch (type) {
314 case BRCMF_FWS_TYPE_MAC_OPEN:
315 case BRCMF_FWS_TYPE_MAC_CLOSE:
316 WARN_ON(len != BRCMF_FWS_TYPE_MAC_OPEN_LEN);
317 break;
318 case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT:
319 WARN_ON(len != BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT_LEN);
320 break;
321 case BRCMF_FWS_TYPE_TXSTATUS:
322 WARN_ON(len != BRCMF_FWS_TYPE_TXSTATUS_LEN);
323 break;
324 case BRCMF_FWS_TYPE_PKTTAG:
325 WARN_ON(len != BRCMF_FWS_TYPE_PKTTAG_LEN);
326 break;
327 case BRCMF_FWS_TYPE_MACDESC_ADD:
328 case BRCMF_FWS_TYPE_MACDESC_DEL:
329 WARN_ON(len != BRCMF_FWS_TYPE_MACDESC_ADD_LEN);
330 break;
331 case BRCMF_FWS_TYPE_RSSI:
332 WARN_ON(len != BRCMF_FWS_TYPE_RSSI_LEN);
333 brcmf_fws_rssi_indicate(fws, *(s8 *)data);
334 break;
335 case BRCMF_FWS_TYPE_INTERFACE_OPEN:
336 case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
337 WARN_ON(len != BRCMF_FWS_TYPE_INTERFACE_OPEN_LEN);
338 break;
339 case BRCMF_FWS_TYPE_FIFO_CREDITBACK:
340 WARN_ON(len != BRCMF_FWS_TYPE_FIFO_CREDITBACK_LEN);
341 break;
342 case BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP:
343 WARN_ON(len != BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN);
344 break;
345 case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET:
346 WARN_ON(len != BRCMF_FWS_TYPE_MAC_REQUEST_PACKET_LEN);
347 break;
348 case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
349 WARN_ON(len != BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS_LEN);
350 break;
351 case BRCMF_FWS_TYPE_TRANS_ID:
352 WARN_ON(len != BRCMF_FWS_TYPE_TRANS_ID_LEN);
353 brcmf_fws_dbg_seqnum_check(fws, data);
354 break;
355 case BRCMF_FWS_TYPE_COMP_TXSTATUS:
356 WARN_ON(len != BRCMF_FWS_TYPE_COMP_TXSTATUS_LEN);
357 break;
358 default:
359 fws->stats.tlv_invalid_type++;
360 break;
361 }
362
363 signal_data += len + 2;
364 data_len -= len + 2;
365 }
366
367 if (data_len != 0)
368 fws->stats.tlv_parse_failed++;
369
370 /* signalling processing result does
371 * not affect the actual ethernet packet.
372 */
373 skb_pull(skb, signal_len);
374
375 /* this may be a signal-only packet
376 */
377 if (skb->len == 0)
378 fws->stats.header_only_pkt++;
379
380 brcmf_fws_unlock(drvr, flags);
381 return 0;
382}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
new file mode 100644
index 000000000000..e728eea72bb4
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
@@ -0,0 +1,25 @@
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 FWSIGNAL_H_
19#define FWSIGNAL_H_
20
21int brcmf_fws_init(struct brcmf_pub *drvr);
22void brcmf_fws_deinit(struct brcmf_pub *drvr);
23int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
24 struct sk_buff *skb);
25#endif /* FWSIGNAL_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c
new file mode 100644
index 000000000000..b505db48c60d
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c
@@ -0,0 +1,22 @@
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#include <linux/module.h> /* bug in tracepoint.h, it should include this */
18
19#ifndef __CHECKER__
20#define CREATE_TRACE_POINTS
21#include "tracepoint.h"
22#endif
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
new file mode 100644
index 000000000000..35efc7a67644
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
@@ -0,0 +1,87 @@
1/*
2 * Copyright (c) 2013 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#if !defined(BRCMF_TRACEPOINT_H_) || defined(TRACE_HEADER_MULTI_READ)
17#define BRCMF_TRACEPOINT_H_
18
19#include <linux/types.h>
20#include <linux/tracepoint.h>
21
22#ifndef CONFIG_BRCM_TRACING
23
24#undef TRACE_EVENT
25#define TRACE_EVENT(name, proto, ...) \
26static inline void trace_ ## name(proto) {}
27
28#undef DECLARE_EVENT_CLASS
29#define DECLARE_EVENT_CLASS(...)
30
31#undef DEFINE_EVENT
32#define DEFINE_EVENT(evt_class, name, proto, ...) \
33static inline void trace_ ## name(proto) {}
34
35#endif /* CONFIG_BRCM_TRACING */
36
37#undef TRACE_SYSTEM
38#define TRACE_SYSTEM brcmfmac
39
40#define MAX_MSG_LEN 100
41
42TRACE_EVENT(brcmf_err,
43 TP_PROTO(const char *func, struct va_format *vaf),
44 TP_ARGS(func, vaf),
45 TP_STRUCT__entry(
46 __string(func, func)
47 __dynamic_array(char, msg, MAX_MSG_LEN)
48 ),
49 TP_fast_assign(
50 __assign_str(func, func);
51 WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
52 MAX_MSG_LEN, vaf->fmt,
53 *vaf->va) >= MAX_MSG_LEN);
54 ),
55 TP_printk("%s: %s", __get_str(func), __get_str(msg))
56);
57
58TRACE_EVENT(brcmf_dbg,
59 TP_PROTO(u32 level, const char *func, struct va_format *vaf),
60 TP_ARGS(level, func, vaf),
61 TP_STRUCT__entry(
62 __field(u32, level)
63 __string(func, func)
64 __dynamic_array(char, msg, MAX_MSG_LEN)
65 ),
66 TP_fast_assign(
67 __entry->level = level;
68 __assign_str(func, func);
69 WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
70 MAX_MSG_LEN, vaf->fmt,
71 *vaf->va) >= MAX_MSG_LEN);
72 ),
73 TP_printk("%s: %s", __get_str(func), __get_str(msg))
74);
75
76#ifdef CONFIG_BRCM_TRACING
77
78#undef TRACE_INCLUDE_PATH
79#define TRACE_INCLUDE_PATH .
80#undef TRACE_INCLUDE_FILE
81#define TRACE_INCLUDE_FILE tracepoint
82
83#include <trace/define_trace.h>
84
85#endif /* CONFIG_BRCM_TRACING */
86
87#endif /* BRCMF_TRACEPOINT_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 42289e9ea886..01aed7ad6bec 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -112,11 +112,6 @@ struct brcmf_usbdev_info {
112static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, 112static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
113 struct brcmf_usbreq *req); 113 struct brcmf_usbreq *req);
114 114
115MODULE_AUTHOR("Broadcom Corporation");
116MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac usb driver.");
117MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac usb cards");
118MODULE_LICENSE("Dual BSD/GPL");
119
120static struct brcmf_usbdev *brcmf_usb_get_buspub(struct device *dev) 115static struct brcmf_usbdev *brcmf_usb_get_buspub(struct device *dev)
121{ 116{
122 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 117 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -422,8 +417,6 @@ static void brcmf_usb_tx_complete(struct urb *urb)
422 brcmf_usb_del_fromq(devinfo, req); 417 brcmf_usb_del_fromq(devinfo, req);
423 418
424 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0); 419 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
425
426 brcmu_pkt_buf_free_skb(req->skb);
427 req->skb = NULL; 420 req->skb = NULL;
428 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount); 421 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
429 if (devinfo->tx_freecount > devinfo->tx_high_watermark && 422 if (devinfo->tx_freecount > devinfo->tx_high_watermark &&
@@ -577,15 +570,17 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
577 int ret; 570 int ret;
578 571
579 brcmf_dbg(USB, "Enter, skb=%p\n", skb); 572 brcmf_dbg(USB, "Enter, skb=%p\n", skb);
580 if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) 573 if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) {
581 return -EIO; 574 ret = -EIO;
575 goto fail;
576 }
582 577
583 req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq, 578 req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq,
584 &devinfo->tx_freecount); 579 &devinfo->tx_freecount);
585 if (!req) { 580 if (!req) {
586 brcmu_pkt_buf_free_skb(skb);
587 brcmf_err("no req to send\n"); 581 brcmf_err("no req to send\n");
588 return -ENOMEM; 582 ret = -ENOMEM;
583 goto fail;
589 } 584 }
590 585
591 req->skb = skb; 586 req->skb = skb;
@@ -598,18 +593,21 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
598 if (ret) { 593 if (ret) {
599 brcmf_err("brcmf_usb_tx usb_submit_urb FAILED\n"); 594 brcmf_err("brcmf_usb_tx usb_submit_urb FAILED\n");
600 brcmf_usb_del_fromq(devinfo, req); 595 brcmf_usb_del_fromq(devinfo, req);
601 brcmu_pkt_buf_free_skb(req->skb);
602 req->skb = NULL; 596 req->skb = NULL;
603 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, 597 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req,
604 &devinfo->tx_freecount); 598 &devinfo->tx_freecount);
605 } else { 599 goto fail;
606 if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
607 !devinfo->tx_flowblock) {
608 brcmf_txflowblock(dev, true);
609 devinfo->tx_flowblock = true;
610 }
611 } 600 }
612 601
602 if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
603 !devinfo->tx_flowblock) {
604 brcmf_txflowblock(dev, true);
605 devinfo->tx_flowblock = true;
606 }
607 return 0;
608
609fail:
610 brcmf_txcomplete(dev, skb, false);
613 return ret; 611 return ret;
614} 612}
615 613
@@ -1485,6 +1483,7 @@ static struct usb_device_id brcmf_usb_devid_table[] = {
1485 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) }, 1483 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
1486 { } 1484 { }
1487}; 1485};
1486
1488MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table); 1487MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
1489MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME); 1488MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME);
1490MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); 1489MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 2af9c0f0798d..804473fc5c5e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3052,16 +3052,16 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3052 int i; 3052 int i;
3053 int ret = 0; 3053 int ret = 0;
3054 3054
3055 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n", 3055 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3056 request->n_match_sets, request->n_ssids); 3056 request->n_match_sets, request->n_ssids);
3057 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { 3057 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3058 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); 3058 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3059 return -EAGAIN; 3059 return -EAGAIN;
3060 } 3060 }
3061 3061
3062 if (!request || !request->n_ssids || !request->n_match_sets) { 3062 if (!request->n_ssids || !request->n_match_sets) {
3063 brcmf_err("Invalid sched scan req!! n_ssids:%d\n", 3063 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3064 request ? request->n_ssids : 0); 3064 request->n_ssids);
3065 return -EINVAL; 3065 return -EINVAL;
3066 } 3066 }
3067 3067
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
index d3d4151c3eda..cba19d839b77 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
@@ -43,6 +43,10 @@ BRCMSMAC_OFILES := \
43 brcms_trace_events.o \ 43 brcms_trace_events.o \
44 debug.o 44 debug.o
45 45
46ifdef CONFIG_BCMA_DRIVER_GPIO
47BRCMSMAC_OFILES += led.o
48endif
49
46MODULEPFX := brcmsmac 50MODULEPFX := brcmsmac
47 51
48obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o 52obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/led.c b/drivers/net/wireless/brcm80211/brcmsmac/led.c
new file mode 100644
index 000000000000..74b17cecb189
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/led.c
@@ -0,0 +1,126 @@
1#include <net/mac80211.h>
2#include <linux/bcma/bcma_driver_chipcommon.h>
3#include <linux/gpio.h>
4
5#include "mac80211_if.h"
6#include "pub.h"
7#include "main.h"
8#include "led.h"
9
10 /* number of leds */
11#define BRCMS_LED_NO 4
12 /* behavior mask */
13#define BRCMS_LED_BEH_MASK 0x7f
14 /* activelow (polarity) bit */
15#define BRCMS_LED_AL_MASK 0x80
16 /* radio enabled */
17#define BRCMS_LED_RADIO 3
18
19static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state)
20{
21 if (wl->radio_led.gpio == -1)
22 return;
23
24 if (wl->radio_led.active_low)
25 state = !state;
26
27 if (state)
28 gpio_set_value(wl->radio_led.gpio, 1);
29 else
30 gpio_set_value(wl->radio_led.gpio, 0);
31}
32
33
34/* Callback from the LED subsystem. */
35static void brcms_led_brightness_set(struct led_classdev *led_dev,
36 enum led_brightness brightness)
37{
38 struct brcms_info *wl = container_of(led_dev,
39 struct brcms_info, led_dev);
40 brcms_radio_led_ctrl(wl, brightness);
41}
42
43void brcms_led_unregister(struct brcms_info *wl)
44{
45 if (wl->led_dev.dev)
46 led_classdev_unregister(&wl->led_dev);
47 if (wl->radio_led.gpio != -1)
48 gpio_free(wl->radio_led.gpio);
49}
50
51int brcms_led_register(struct brcms_info *wl)
52{
53 int i, err;
54 struct brcms_led *radio_led = &wl->radio_led;
55 /* get CC core */
56 struct bcma_drv_cc *cc_drv = &wl->wlc->hw->d11core->bus->drv_cc;
57 struct gpio_chip *bcma_gpio = &cc_drv->gpio;
58 struct ssb_sprom *sprom = &wl->wlc->hw->d11core->bus->sprom;
59 u8 *leds[] = { &sprom->gpio0,
60 &sprom->gpio1,
61 &sprom->gpio2,
62 &sprom->gpio3 };
63 unsigned gpio = -1;
64 bool active_low = false;
65
66 /* none by default */
67 radio_led->gpio = -1;
68 radio_led->active_low = false;
69
70 if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base))
71 return -ENODEV;
72
73 /* find radio enabled LED */
74 for (i = 0; i < BRCMS_LED_NO; i++) {
75 u8 led = *leds[i];
76 if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) {
77 gpio = bcma_gpio->base + i;
78 if (led & BRCMS_LED_AL_MASK)
79 active_low = true;
80 break;
81 }
82 }
83
84 if (gpio == -1 || !gpio_is_valid(gpio))
85 return -ENODEV;
86
87 /* request and configure LED gpio */
88 err = gpio_request_one(gpio,
89 active_low ? GPIOF_OUT_INIT_HIGH
90 : GPIOF_OUT_INIT_LOW,
91 "radio on");
92 if (err) {
93 wiphy_err(wl->wiphy, "requesting led gpio %d failed (err: %d)\n",
94 gpio, err);
95 return err;
96 }
97 err = gpio_direction_output(gpio, 1);
98 if (err) {
99 wiphy_err(wl->wiphy, "cannot set led gpio %d to output (err: %d)\n",
100 gpio, err);
101 return err;
102 }
103
104 snprintf(wl->radio_led.name, sizeof(wl->radio_led.name),
105 "brcmsmac-%s:radio", wiphy_name(wl->wiphy));
106
107 wl->led_dev.name = wl->radio_led.name;
108 wl->led_dev.default_trigger =
109 ieee80211_get_radio_led_name(wl->pub->ieee_hw);
110 wl->led_dev.brightness_set = brcms_led_brightness_set;
111 err = led_classdev_register(wiphy_dev(wl->wiphy), &wl->led_dev);
112
113 if (err) {
114 wiphy_err(wl->wiphy, "cannot register led device: %s (err: %d)\n",
115 wl->radio_led.name, err);
116 return err;
117 }
118
119 wiphy_info(wl->wiphy, "registered radio enabled led device: %s gpio: %d\n",
120 wl->radio_led.name,
121 gpio);
122 radio_led->gpio = gpio;
123 radio_led->active_low = active_low;
124
125 return 0;
126}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/led.h b/drivers/net/wireless/brcm80211/brcmsmac/led.h
new file mode 100644
index 000000000000..17a0b1f5dbcf
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/led.h
@@ -0,0 +1,36 @@
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#ifndef _BRCM_LED_H_
18#define _BRCM_LED_H_
19struct brcms_led {
20 char name[32];
21 unsigned gpio;
22 bool active_low;
23};
24
25#ifdef CONFIG_BCMA_DRIVER_GPIO
26void brcms_led_unregister(struct brcms_info *wl);
27int brcms_led_register(struct brcms_info *wl);
28#else
29static inline void brcms_led_unregister(struct brcms_info *wl) {};
30static inline int brcms_led_register(struct brcms_info *wl)
31{
32 return -ENOTSUPP;
33};
34#endif
35
36#endif /* _BRCM_LED_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index c6451c61407a..c70cf7b654cd 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -34,6 +34,7 @@
34#include "mac80211_if.h" 34#include "mac80211_if.h"
35#include "main.h" 35#include "main.h"
36#include "debug.h" 36#include "debug.h"
37#include "led.h"
37 38
38#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ 39#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */
39#define BRCMS_FLUSH_TIMEOUT 500 /* msec */ 40#define BRCMS_FLUSH_TIMEOUT 500 /* msec */
@@ -904,6 +905,7 @@ static void brcms_remove(struct bcma_device *pdev)
904 struct brcms_info *wl = hw->priv; 905 struct brcms_info *wl = hw->priv;
905 906
906 if (wl->wlc) { 907 if (wl->wlc) {
908 brcms_led_unregister(wl);
907 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); 909 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
908 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); 910 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
909 ieee80211_unregister_hw(hw); 911 ieee80211_unregister_hw(hw);
@@ -1151,6 +1153,8 @@ static int brcms_bcma_probe(struct bcma_device *pdev)
1151 pr_err("%s: brcms_attach failed!\n", __func__); 1153 pr_err("%s: brcms_attach failed!\n", __func__);
1152 return -ENODEV; 1154 return -ENODEV;
1153 } 1155 }
1156 brcms_led_register(wl);
1157
1154 return 0; 1158 return 0;
1155} 1159}
1156 1160
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
index 947ccacf43e6..4090032e81a2 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
@@ -20,8 +20,10 @@
20#include <linux/timer.h> 20#include <linux/timer.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/workqueue.h> 22#include <linux/workqueue.h>
23#include <linux/leds.h>
23 24
24#include "ucode_loader.h" 25#include "ucode_loader.h"
26#include "led.h"
25/* 27/*
26 * Starting index for 5G rates in the 28 * Starting index for 5G rates in the
27 * legacy rate table. 29 * legacy rate table.
@@ -81,6 +83,8 @@ struct brcms_info {
81 struct wiphy *wiphy; 83 struct wiphy *wiphy;
82 struct brcms_ucode ucode; 84 struct brcms_ucode ucode;
83 bool mute_tx; 85 bool mute_tx;
86 struct brcms_led radio_led;
87 struct led_classdev led_dev;
84}; 88};
85 89
86/* misc callbacks */ 90/* misc callbacks */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 8ef02dca8f8c..0c8e998bfb1e 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7810,9 +7810,14 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
7810 7810
7811 /* read the ucode version if we have not yet done so */ 7811 /* read the ucode version if we have not yet done so */
7812 if (wlc->ucode_rev == 0) { 7812 if (wlc->ucode_rev == 0) {
7813 wlc->ucode_rev = 7813 u16 rev;
7814 brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR) << NBITS(u16); 7814 u16 patch;
7815 wlc->ucode_rev |= brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR); 7815
7816 rev = brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR);
7817 patch = brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR);
7818 wlc->ucode_rev = (rev << NBITS(u16)) | patch;
7819 snprintf(wlc->wiphy->fw_version,
7820 sizeof(wlc->wiphy->fw_version), "%u.%u", rev, patch);
7816 } 7821 }
7817 7822
7818 /* ..now really unleash hell (allow the MAC out of suspend) */ 7823 /* ..now really unleash hell (allow the MAC out of suspend) */
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
index 3e6405e06ac0..bf5e50fc21ba 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/utils.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -116,6 +116,31 @@ struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec)
116} 116}
117EXPORT_SYMBOL(brcmu_pktq_pdeq); 117EXPORT_SYMBOL(brcmu_pktq_pdeq);
118 118
119/*
120 * precedence based dequeue with match function. Passing a NULL pointer
121 * for the match function parameter is considered to be a wildcard so
122 * any packet on the queue is returned. In that case it is no different
123 * from brcmu_pktq_pdeq() above.
124 */
125struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec,
126 bool (*match_fn)(struct sk_buff *skb,
127 void *arg), void *arg)
128{
129 struct sk_buff_head *q;
130 struct sk_buff *p, *next;
131
132 q = &pq->q[prec].skblist;
133 skb_queue_walk_safe(q, p, next) {
134 if (match_fn == NULL || match_fn(p, arg)) {
135 skb_unlink(p, q);
136 pq->len--;
137 return p;
138 }
139 }
140 return NULL;
141}
142EXPORT_SYMBOL(brcmu_pktq_pdeq_match);
143
119struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec) 144struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec)
120{ 145{
121 struct sk_buff_head *q; 146 struct sk_buff_head *q;
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
index 477b92ad3d62..898cacb8d01d 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -120,6 +120,10 @@ extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
120 struct sk_buff *p); 120 struct sk_buff *p);
121extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec); 121extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec);
122extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec); 122extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec);
123extern struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec,
124 bool (*match_fn)(struct sk_buff *p,
125 void *arg),
126 void *arg);
123 127
124/* packet primitives */ 128/* packet primitives */
125extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len); 129extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len);
@@ -173,6 +177,29 @@ extern void brcmu_pktq_flush(struct pktq *pq, bool dir,
173/* ip address */ 177/* ip address */
174struct ipv4_addr; 178struct ipv4_addr;
175 179
180/*
181 * bitfield macros using masking and shift
182 *
183 * remark: the mask parameter should be a shifted mask.
184 */
185static inline void brcmu_maskset32(u32 *var, u32 mask, u8 shift, u32 value)
186{
187 value = (value << shift) & mask;
188 *var = (*var & ~mask) | value;
189}
190static inline u32 brcmu_maskget32(u32 var, u32 mask, u8 shift)
191{
192 return (var & mask) >> shift;
193}
194static inline void brcmu_maskset16(u16 *var, u16 mask, u8 shift, u16 value)
195{
196 value = (value << shift) & mask;
197 *var = (*var & ~mask) | value;
198}
199static inline u16 brcmu_maskget16(u16 var, u16 mask, u8 shift)
200{
201 return (var & mask) >> shift;
202}
176 203
177/* externs */ 204/* externs */
178/* format/print */ 205/* format/print */
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index 3630a41df50d..df5a57c74808 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -3475,7 +3475,7 @@ static struct attribute_group il3945_attribute_group = {
3475 .attrs = il3945_sysfs_entries, 3475 .attrs = il3945_sysfs_entries,
3476}; 3476};
3477 3477
3478struct ieee80211_ops il3945_mac_ops = { 3478static struct ieee80211_ops il3945_mac_ops __read_mostly = {
3479 .tx = il3945_mac_tx, 3479 .tx = il3945_mac_tx,
3480 .start = il3945_mac_start, 3480 .start = il3945_mac_start,
3481 .stop = il3945_mac_stop, 3481 .stop = il3945_mac_stop,
diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h
index 1d45075e0d5b..9a8703def0ba 100644
--- a/drivers/net/wireless/iwlegacy/3945.h
+++ b/drivers/net/wireless/iwlegacy/3945.h
@@ -150,10 +150,6 @@ struct il3945_frame {
150 struct list_head list; 150 struct list_head list;
151}; 151};
152 152
153#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
154#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
155#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
156
157#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 153#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
158#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 154#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
159#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 155#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 238f52874f16..6affa7e8f017 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -612,7 +612,7 @@ il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
612 612
613/* Called for N_RX (legacy ABG frames), or 613/* Called for N_RX (legacy ABG frames), or
614 * N_RX_MPDU (HT high-throughput N frames). */ 614 * N_RX_MPDU (HT high-throughput N frames). */
615void 615static void
616il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) 616il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
617{ 617{
618 struct ieee80211_hdr *header; 618 struct ieee80211_hdr *header;
@@ -744,7 +744,7 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
744 744
745/* Cache phy data (Rx signal strength, etc) for HT frame (N_RX_PHY). 745/* Cache phy data (Rx signal strength, etc) for HT frame (N_RX_PHY).
746 * This will be used later in il_hdl_rx() for N_RX_MPDU. */ 746 * This will be used later in il_hdl_rx() for N_RX_MPDU. */
747void 747static void
748il4965_hdl_rx_phy(struct il_priv *il, struct il_rx_buf *rxb) 748il4965_hdl_rx_phy(struct il_priv *il, struct il_rx_buf *rxb)
749{ 749{
750 struct il_rx_pkt *pkt = rxb_addr(rxb); 750 struct il_rx_pkt *pkt = rxb_addr(rxb);
@@ -1250,7 +1250,7 @@ il4965_dump_fh(struct il_priv *il, char **buf, bool display)
1250 return 0; 1250 return 0;
1251} 1251}
1252 1252
1253void 1253static void
1254il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb) 1254il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb)
1255{ 1255{
1256 struct il_rx_pkt *pkt = rxb_addr(rxb); 1256 struct il_rx_pkt *pkt = rxb_addr(rxb);
@@ -1357,7 +1357,7 @@ il4965_accumulative_stats(struct il_priv *il, __le32 * stats)
1357} 1357}
1358#endif 1358#endif
1359 1359
1360void 1360static void
1361il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb) 1361il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
1362{ 1362{
1363 const int recalib_seconds = 60; 1363 const int recalib_seconds = 60;
@@ -1399,7 +1399,7 @@ il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
1399 il4965_temperature_calib(il); 1399 il4965_temperature_calib(il);
1400} 1400}
1401 1401
1402void 1402static void
1403il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb) 1403il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb)
1404{ 1404{
1405 struct il_rx_pkt *pkt = rxb_addr(rxb); 1405 struct il_rx_pkt *pkt = rxb_addr(rxb);
@@ -2050,7 +2050,7 @@ il4965_txq_ctx_reset(struct il_priv *il)
2050 il_tx_queue_reset(il, txq_id); 2050 il_tx_queue_reset(il, txq_id);
2051} 2051}
2052 2052
2053void 2053static void
2054il4965_txq_ctx_unmap(struct il_priv *il) 2054il4965_txq_ctx_unmap(struct il_priv *il)
2055{ 2055{
2056 int txq_id; 2056 int txq_id;
@@ -2258,7 +2258,7 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
2258 2258
2259 spin_lock_irqsave(&il->sta_lock, flags); 2259 spin_lock_irqsave(&il->sta_lock, flags);
2260 tid_data = &il->stations[sta_id].tid[tid]; 2260 tid_data = &il->stations[sta_id].tid[tid];
2261 *ssn = SEQ_TO_SN(tid_data->seq_number); 2261 *ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
2262 tid_data->agg.txq_id = txq_id; 2262 tid_data->agg.txq_id = txq_id;
2263 il_set_swq_id(&il->txq[txq_id], il4965_get_ac_from_tid(tid), txq_id); 2263 il_set_swq_id(&il->txq[txq_id], il4965_get_ac_from_tid(tid), txq_id);
2264 spin_unlock_irqrestore(&il->sta_lock, flags); 2264 spin_unlock_irqrestore(&il->sta_lock, flags);
@@ -2408,7 +2408,7 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
2408 /* aggregated HW queue */ 2408 /* aggregated HW queue */
2409 if (txq_id == tid_data->agg.txq_id && 2409 if (txq_id == tid_data->agg.txq_id &&
2410 q->read_ptr == q->write_ptr) { 2410 q->read_ptr == q->write_ptr) {
2411 u16 ssn = SEQ_TO_SN(tid_data->seq_number); 2411 u16 ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
2412 int tx_fifo = il4965_get_fifo_from_tid(tid); 2412 int tx_fifo = il4965_get_fifo_from_tid(tid);
2413 D_HT("HW queue empty: continue DELBA flow\n"); 2413 D_HT("HW queue empty: continue DELBA flow\n");
2414 il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo); 2414 il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo);
@@ -2627,7 +2627,8 @@ il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr)
2627static inline u32 2627static inline u32
2628il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp) 2628il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp)
2629{ 2629{
2630 return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; 2630 return le32_to_cpup(&tx_resp->u.status +
2631 tx_resp->frame_count) & IEEE80211_MAX_SN;
2631} 2632}
2632 2633
2633static inline u32 2634static inline u32
@@ -2717,15 +2718,15 @@ il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
2717 hdr = (struct ieee80211_hdr *) skb->data; 2718 hdr = (struct ieee80211_hdr *) skb->data;
2718 2719
2719 sc = le16_to_cpu(hdr->seq_ctrl); 2720 sc = le16_to_cpu(hdr->seq_ctrl);
2720 if (idx != (SEQ_TO_SN(sc) & 0xff)) { 2721 if (idx != (IEEE80211_SEQ_TO_SN(sc) & 0xff)) {
2721 IL_ERR("BUG_ON idx doesn't match seq control" 2722 IL_ERR("BUG_ON idx doesn't match seq control"
2722 " idx=%d, seq_idx=%d, seq=%d\n", idx, 2723 " idx=%d, seq_idx=%d, seq=%d\n", idx,
2723 SEQ_TO_SN(sc), hdr->seq_ctrl); 2724 IEEE80211_SEQ_TO_SN(sc), hdr->seq_ctrl);
2724 return -1; 2725 return -1;
2725 } 2726 }
2726 2727
2727 D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx, 2728 D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx,
2728 SEQ_TO_SN(sc)); 2729 IEEE80211_SEQ_TO_SN(sc));
2729 2730
2730 sh = idx - start; 2731 sh = idx - start;
2731 if (sh > 64) { 2732 if (sh > 64) {
@@ -2895,7 +2896,7 @@ il4965_hwrate_to_tx_control(struct il_priv *il, u32 rate_n_flags,
2895 * Handles block-acknowledge notification from device, which reports success 2896 * Handles block-acknowledge notification from device, which reports success
2896 * of frames sent via aggregation. 2897 * of frames sent via aggregation.
2897 */ 2898 */
2898void 2899static void
2899il4965_hdl_compressed_ba(struct il_priv *il, struct il_rx_buf *rxb) 2900il4965_hdl_compressed_ba(struct il_priv *il, struct il_rx_buf *rxb)
2900{ 2901{
2901 struct il_rx_pkt *pkt = rxb_addr(rxb); 2902 struct il_rx_pkt *pkt = rxb_addr(rxb);
@@ -6316,7 +6317,7 @@ il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq,
6316 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); 6317 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
6317} 6318}
6318 6319
6319const struct ieee80211_ops il4965_mac_ops = { 6320static const struct ieee80211_ops il4965_mac_ops = {
6320 .tx = il4965_mac_tx, 6321 .tx = il4965_mac_tx,
6321 .start = il4965_mac_start, 6322 .start = il4965_mac_start,
6322 .stop = il4965_mac_stop, 6323 .stop = il4965_mac_stop,
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index db2187124032..01e2d2b4ec59 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -1122,7 +1122,7 @@ il_set_power(struct il_priv *il, struct il_powertable_cmd *cmd)
1122 sizeof(struct il_powertable_cmd), cmd); 1122 sizeof(struct il_powertable_cmd), cmd);
1123} 1123}
1124 1124
1125int 1125static int
1126il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force) 1126il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force)
1127{ 1127{
1128 int ret; 1128 int ret;
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index 458e699c63cd..10986aaf9085 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -541,10 +541,6 @@ struct il_frame {
541 struct list_head list; 541 struct list_head list;
542}; 542};
543 543
544#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
545#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
546#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
547
548enum { 544enum {
549 CMD_SYNC = 0, 545 CMD_SYNC = 0,
550 CMD_SIZE_NORMAL = 0, 546 CMD_SIZE_NORMAL = 0,
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index ba319cba3f1e..56c2040a955b 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -6,7 +6,6 @@ config IWLWIFI
6 select LEDS_CLASS 6 select LEDS_CLASS
7 select LEDS_TRIGGERS 7 select LEDS_TRIGGERS
8 select MAC80211_LEDS 8 select MAC80211_LEDS
9 select IWLDVM
10 ---help--- 9 ---help---
11 Select to build the driver supporting the: 10 Select to build the driver supporting the:
12 11
@@ -45,6 +44,7 @@ config IWLWIFI
45config IWLDVM 44config IWLDVM
46 tristate "Intel Wireless WiFi DVM Firmware support" 45 tristate "Intel Wireless WiFi DVM Firmware support"
47 depends on IWLWIFI 46 depends on IWLWIFI
47 default IWLWIFI
48 help 48 help
49 This is the driver supporting the DVM firmware which is 49 This is the driver supporting the DVM firmware which is
50 currently the only firmware available for existing devices. 50 currently the only firmware available for existing devices.
@@ -58,6 +58,15 @@ config IWLMVM
58 58
59 Say yes if you have such a device. 59 Say yes if you have such a device.
60 60
61# don't call it _MODULE -- will confuse Kconfig/fixdep/...
62config IWLWIFI_OPMODE_MODULAR
63 bool
64 default y if IWLDVM=m
65 default y if IWLMVM=m
66
67comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM"
68 depends on IWLWIFI && IWLDVM=n && IWLMVM=n
69
61menu "Debugging Options" 70menu "Debugging Options"
62 depends on IWLWIFI 71 depends on IWLWIFI
63 72
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 6c7800044a04..3b5613ea458b 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -7,8 +7,7 @@ iwlwifi-objs += iwl-notif-wait.o
7iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o 7iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o
8iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o 8iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o
9iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o 9iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
10iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o 10iwlwifi-objs += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o iwl-7000.o
11iwlwifi-objs += pcie/7000.o
12 11
13iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 12iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
14iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o 13iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 41ec27cb6efe..019d433900ef 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c
index 6468de8634b0..d6c4cf2ad7c5 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h
index 65e920cab2b7..cfddde194940 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.h
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 84e2c0fcfef6..95ca026ecc9d 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -1526,6 +1526,7 @@ struct iwl_compressed_ba_resp {
1526 __le16 scd_ssn; 1526 __le16 scd_ssn;
1527 u8 txed; /* number of frames sent */ 1527 u8 txed; /* number of frames sent */
1528 u8 txed_2_done; /* number of frames acked */ 1528 u8 txed_2_done; /* number of frames acked */
1529 __le16 reserved1;
1529} __packed; 1530} __packed;
1530 1531
1531/* 1532/*
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
index 20806cae11b7..7b8178be119f 100644
--- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
@@ -19,7 +19,7 @@
19 * USA 19 * USA
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL. 22 * in the file called COPYING.
23 * 23 *
24 * Contact Information: 24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -2324,6 +2324,28 @@ static ssize_t iwl_dbgfs_calib_disabled_write(struct file *file,
2324 return count; 2324 return count;
2325} 2325}
2326 2326
2327static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
2328 const char __user *user_buf,
2329 size_t count, loff_t *ppos)
2330{
2331 struct iwl_priv *priv = file->private_data;
2332 bool restart_fw = iwlwifi_mod_params.restart_fw;
2333 int ret;
2334
2335 iwlwifi_mod_params.restart_fw = true;
2336
2337 mutex_lock(&priv->mutex);
2338
2339 /* take the return value to make compiler happy - it will fail anyway */
2340 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_ERROR, CMD_SYNC, 0, NULL);
2341
2342 mutex_unlock(&priv->mutex);
2343
2344 iwlwifi_mod_params.restart_fw = restart_fw;
2345
2346 return count;
2347}
2348
2327DEBUGFS_READ_FILE_OPS(ucode_rx_stats); 2349DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
2328DEBUGFS_READ_FILE_OPS(ucode_tx_stats); 2350DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
2329DEBUGFS_READ_FILE_OPS(ucode_general_stats); 2351DEBUGFS_READ_FILE_OPS(ucode_general_stats);
@@ -2343,6 +2365,7 @@ DEBUGFS_READ_FILE_OPS(bt_traffic);
2343DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); 2365DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
2344DEBUGFS_READ_FILE_OPS(reply_tx_error); 2366DEBUGFS_READ_FILE_OPS(reply_tx_error);
2345DEBUGFS_WRITE_FILE_OPS(echo_test); 2367DEBUGFS_WRITE_FILE_OPS(echo_test);
2368DEBUGFS_WRITE_FILE_OPS(fw_restart);
2346#ifdef CONFIG_IWLWIFI_DEBUG 2369#ifdef CONFIG_IWLWIFI_DEBUG
2347DEBUGFS_READ_WRITE_FILE_OPS(log_event); 2370DEBUGFS_READ_WRITE_FILE_OPS(log_event);
2348#endif 2371#endif
@@ -2400,6 +2423,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir)
2400 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); 2423 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
2401 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); 2424 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
2402 DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); 2425 DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR);
2426 DEBUGFS_ADD_FILE(fw_restart, dir_debug, S_IWUSR);
2403#ifdef CONFIG_IWLWIFI_DEBUG 2427#ifdef CONFIG_IWLWIFI_DEBUG
2404 DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); 2428 DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR);
2405#endif 2429#endif
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 86ea5f4c3939..cddf77c36b36 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -19,7 +19,7 @@
19 * USA 19 * USA
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL. 22 * in the file called COPYING.
23 * 23 *
24 * Contact Information: 24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 323e4a33fcac..c7cd2dffa5cd 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1137,7 +1137,8 @@ done:
1137static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, 1137static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
1138 struct ieee80211_vif *vif, 1138 struct ieee80211_vif *vif,
1139 struct ieee80211_channel *channel, 1139 struct ieee80211_channel *channel,
1140 int duration) 1140 int duration,
1141 enum ieee80211_roc_type type)
1141{ 1142{
1142 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1143 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1143 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; 1144 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c
index 3a4aa5239c45..d69b55866714 100644
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -19,7 +19,7 @@
19 * USA 19 * USA
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL. 22 * in the file called COPYING.
23 * 23 *
24 * Contact Information: 24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c
index dc6f965a123a..b89b9d9b9969 100644
--- a/drivers/net/wireless/iwlwifi/dvm/testmode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 6aec2df3bb27..cc1e0c1a6f48 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -19,7 +19,7 @@
19 * USA 19 * USA
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL. 22 * in the file called COPYING.
23 * 23 *
24 * Contact Information: 24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -418,7 +418,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
418 " Tx flags = 0x%08x, agg.state = %d", 418 " Tx flags = 0x%08x, agg.state = %d",
419 info->flags, tid_data->agg.state); 419 info->flags, tid_data->agg.state);
420 IWL_ERR(priv, "sta_id = %d, tid = %d seq_num = %d", 420 IWL_ERR(priv, "sta_id = %d, tid = %d seq_num = %d",
421 sta_id, tid, SEQ_TO_SN(tid_data->seq_number)); 421 sta_id, tid,
422 IEEE80211_SEQ_TO_SN(tid_data->seq_number));
422 goto drop_unlock_sta; 423 goto drop_unlock_sta;
423 } 424 }
424 425
@@ -569,7 +570,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
569 return 0; 570 return 0;
570 } 571 }
571 572
572 tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); 573 tid_data->agg.ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
573 574
574 /* There are still packets for this RA / TID in the HW */ 575 /* There are still packets for this RA / TID in the HW */
575 if (!test_bit(txq_id, priv->agg_q_alloc)) { 576 if (!test_bit(txq_id, priv->agg_q_alloc)) {
@@ -651,7 +652,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
651 652
652 spin_lock_bh(&priv->sta_lock); 653 spin_lock_bh(&priv->sta_lock);
653 tid_data = &priv->tid_data[sta_id][tid]; 654 tid_data = &priv->tid_data[sta_id][tid];
654 tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); 655 tid_data->agg.ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
655 tid_data->agg.txq_id = txq_id; 656 tid_data->agg.txq_id = txq_id;
656 657
657 *ssn = tid_data->agg.ssn; 658 *ssn = tid_data->agg.ssn;
@@ -911,7 +912,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
911static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp) 912static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp)
912{ 913{
913 return le32_to_cpup((__le32 *)&tx_resp->status + 914 return le32_to_cpup((__le32 *)&tx_resp->status +
914 tx_resp->frame_count) & MAX_SN; 915 tx_resp->frame_count) & IEEE80211_MAX_SN;
915} 916}
916 917
917static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, 918static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
@@ -1148,7 +1149,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1148 1149
1149 if (tx_resp->frame_count == 1) { 1150 if (tx_resp->frame_count == 1) {
1150 u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); 1151 u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl);
1151 next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); 1152 next_reclaimed = IEEE80211_SEQ_TO_SN(next_reclaimed + 0x10);
1152 1153
1153 if (is_agg) { 1154 if (is_agg) {
1154 /* If this is an aggregation queue, we can rely on the 1155 /* If this is an aggregation queue, we can rely on the
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 736fe9bb140e..166019afc2d0 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -19,7 +19,7 @@
19 * USA 19 * USA
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL. 22 * in the file called COPYING.
23 * 23 *
24 * Contact Information: 24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/pcie/1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index ff3389757281..c080ae3070b2 100644
--- a/drivers/net/wireless/iwlwifi/pcie/1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -29,7 +29,6 @@
29#include "iwl-config.h" 29#include "iwl-config.h"
30#include "iwl-csr.h" 30#include "iwl-csr.h"
31#include "iwl-agn-hw.h" 31#include "iwl-agn-hw.h"
32#include "cfg.h"
33 32
34/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
35#define IWL1000_UCODE_API_MAX 5 34#define IWL1000_UCODE_API_MAX 5
diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index e7de33128b16..a6ddd2f9fba0 100644
--- a/drivers/net/wireless/iwlwifi/pcie/2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -28,7 +28,6 @@
28#include <linux/stringify.h> 28#include <linux/stringify.h>
29#include "iwl-config.h" 29#include "iwl-config.h"
30#include "iwl-agn-hw.h" 30#include "iwl-agn-hw.h"
31#include "cfg.h"
32#include "dvm/commands.h" /* needed for BT for now */ 31#include "dvm/commands.h" /* needed for BT for now */
33 32
34/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
diff --git a/drivers/net/wireless/iwlwifi/pcie/5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 5096f7c96ab6..403f3f224bf6 100644
--- a/drivers/net/wireless/iwlwifi/pcie/5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -29,7 +29,6 @@
29#include "iwl-config.h" 29#include "iwl-config.h"
30#include "iwl-agn-hw.h" 30#include "iwl-agn-hw.h"
31#include "iwl-csr.h" 31#include "iwl-csr.h"
32#include "cfg.h"
33 32
34/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
35#define IWL5000_UCODE_API_MAX 5 34#define IWL5000_UCODE_API_MAX 5
diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 801ff49796dd..b5ab8d1bcac0 100644
--- a/drivers/net/wireless/iwlwifi/pcie/6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -28,7 +28,6 @@
28#include <linux/stringify.h> 28#include <linux/stringify.h>
29#include "iwl-config.h" 29#include "iwl-config.h"
30#include "iwl-agn-hw.h" 30#include "iwl-agn-hw.h"
31#include "cfg.h"
32#include "dvm/commands.h" /* needed for BT for now */ 31#include "dvm/commands.h" /* needed for BT for now */
33 32
34/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 6e35b2b72332..50263e87fe15 100644
--- a/drivers/net/wireless/iwlwifi/pcie/7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -1,34 +1,70 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify it 6 * GPL LICENSE SUMMARY
6 * under the terms of version 2 of the GNU General Public License as 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
8 * 13 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT 14 * This program is distributed in the hope that it will be useful, but
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * more details. 17 * General Public License for more details.
13 * 18 *
14 * You should have received a copy of the GNU General Public License along with 19 * You should have received a copy of the GNU General Public License
15 * this program; if not, write to the Free Software Foundation, Inc., 20 * along with this program; if not, write to the Free Software
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
17 * 23 *
18 * The full GNU General Public License is included in this distribution in the 24 * The full GNU General Public License is included in this distribution
19 * file called LICENSE. 25 * in the file called COPYING.
20 * 26 *
21 * Contact Information: 27 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 * 30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
25 *****************************************************************************/ 62 *****************************************************************************/
26 63
27#include <linux/module.h> 64#include <linux/module.h>
28#include <linux/stringify.h> 65#include <linux/stringify.h>
29#include "iwl-config.h" 66#include "iwl-config.h"
30#include "iwl-agn-hw.h" 67#include "iwl-agn-hw.h"
31#include "cfg.h"
32 68
33/* Highest firmware API version supported */ 69/* Highest firmware API version supported */
34#define IWL7260_UCODE_API_MAX 6 70#define IWL7260_UCODE_API_MAX 6
@@ -70,7 +106,6 @@ static const struct iwl_base_params iwl7000_base_params = {
70}; 106};
71 107
72static const struct iwl_ht_params iwl7000_ht_params = { 108static const struct iwl_ht_params iwl7000_ht_params = {
73 .ht_greenfield_support = true,
74 .use_rts_for_aggregation = true, /* use rts/cts protection */ 109 .use_rts_for_aggregation = true, /* use rts/cts protection */
75 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), 110 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
76}; 111};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index e9975c54c276..6d73f943cefa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 743b48343358..c38aa8f77554 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -275,4 +275,51 @@ struct iwl_cfg {
275 const bool temp_offset_v2; 275 const bool temp_offset_v2;
276}; 276};
277 277
278/*
279 * This list declares the config structures for all devices.
280 */
281extern const struct iwl_cfg iwl5300_agn_cfg;
282extern const struct iwl_cfg iwl5100_agn_cfg;
283extern const struct iwl_cfg iwl5350_agn_cfg;
284extern const struct iwl_cfg iwl5100_bgn_cfg;
285extern const struct iwl_cfg iwl5100_abg_cfg;
286extern const struct iwl_cfg iwl5150_agn_cfg;
287extern const struct iwl_cfg iwl5150_abg_cfg;
288extern const struct iwl_cfg iwl6005_2agn_cfg;
289extern const struct iwl_cfg iwl6005_2abg_cfg;
290extern const struct iwl_cfg iwl6005_2bg_cfg;
291extern const struct iwl_cfg iwl6005_2agn_sff_cfg;
292extern const struct iwl_cfg iwl6005_2agn_d_cfg;
293extern const struct iwl_cfg iwl6005_2agn_mow1_cfg;
294extern const struct iwl_cfg iwl6005_2agn_mow2_cfg;
295extern const struct iwl_cfg iwl1030_bgn_cfg;
296extern const struct iwl_cfg iwl1030_bg_cfg;
297extern const struct iwl_cfg iwl6030_2agn_cfg;
298extern const struct iwl_cfg iwl6030_2abg_cfg;
299extern const struct iwl_cfg iwl6030_2bgn_cfg;
300extern const struct iwl_cfg iwl6030_2bg_cfg;
301extern const struct iwl_cfg iwl6000i_2agn_cfg;
302extern const struct iwl_cfg iwl6000i_2abg_cfg;
303extern const struct iwl_cfg iwl6000i_2bg_cfg;
304extern const struct iwl_cfg iwl6000_3agn_cfg;
305extern const struct iwl_cfg iwl6050_2agn_cfg;
306extern const struct iwl_cfg iwl6050_2abg_cfg;
307extern const struct iwl_cfg iwl6150_bgn_cfg;
308extern const struct iwl_cfg iwl6150_bg_cfg;
309extern const struct iwl_cfg iwl1000_bgn_cfg;
310extern const struct iwl_cfg iwl1000_bg_cfg;
311extern const struct iwl_cfg iwl100_bgn_cfg;
312extern const struct iwl_cfg iwl100_bg_cfg;
313extern const struct iwl_cfg iwl130_bgn_cfg;
314extern const struct iwl_cfg iwl130_bg_cfg;
315extern const struct iwl_cfg iwl2000_2bgn_cfg;
316extern const struct iwl_cfg iwl2000_2bgn_d_cfg;
317extern const struct iwl_cfg iwl2030_2bgn_cfg;
318extern const struct iwl_cfg iwl6035_2agn_cfg;
319extern const struct iwl_cfg iwl105_bgn_cfg;
320extern const struct iwl_cfg iwl105_bgn_d_cfg;
321extern const struct iwl_cfg iwl135_bgn_cfg;
322extern const struct iwl_cfg iwl7260_2ac_cfg;
323extern const struct iwl_cfg iwl3160_ac_cfg;
324
278#endif /* __IWL_CONFIG_H__ */ 325#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index df3463a38704..20e845d4da04 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c
index 87535a67de76..8a44f594528d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -66,6 +66,7 @@
66#include <linux/device.h> 66#include <linux/device.h>
67#include <linux/interrupt.h> 67#include <linux/interrupt.h>
68#include <linux/export.h> 68#include <linux/export.h>
69#include "iwl-drv.h"
69#include "iwl-debug.h" 70#include "iwl-debug.h"
70#include "iwl-devtrace.h" 71#include "iwl-devtrace.h"
71 72
@@ -85,11 +86,11 @@ void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \
85} 86}
86 87
87__iwl_fn(warn) 88__iwl_fn(warn)
88EXPORT_SYMBOL_GPL(__iwl_warn); 89IWL_EXPORT_SYMBOL(__iwl_warn);
89__iwl_fn(info) 90__iwl_fn(info)
90EXPORT_SYMBOL_GPL(__iwl_info); 91IWL_EXPORT_SYMBOL(__iwl_info);
91__iwl_fn(crit) 92__iwl_fn(crit)
92EXPORT_SYMBOL_GPL(__iwl_crit); 93IWL_EXPORT_SYMBOL(__iwl_crit);
93 94
94void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, 95void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
95 const char *fmt, ...) 96 const char *fmt, ...)
@@ -110,7 +111,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
110 trace_iwlwifi_err(&vaf); 111 trace_iwlwifi_err(&vaf);
111 va_end(args); 112 va_end(args);
112} 113}
113EXPORT_SYMBOL_GPL(__iwl_err); 114IWL_EXPORT_SYMBOL(__iwl_err);
114 115
115#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) 116#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
116void __iwl_dbg(struct device *dev, 117void __iwl_dbg(struct device *dev,
@@ -133,5 +134,5 @@ void __iwl_dbg(struct device *dev,
133 trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); 134 trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf);
134 va_end(args); 135 va_end(args);
135} 136}
136EXPORT_SYMBOL_GPL(__iwl_dbg); 137IWL_EXPORT_SYMBOL(__iwl_dbg);
137#endif 138#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 81aa91fab5aa..4491c1c72cc7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -298,7 +298,7 @@ TRACE_EVENT(iwlwifi_dbg,
298 MAX_MSG_LEN, vaf->fmt, 298 MAX_MSG_LEN, vaf->fmt,
299 *vaf->va) >= MAX_MSG_LEN); 299 *vaf->va) >= MAX_MSG_LEN);
300 ), 300 ),
301 TP_printk("%s", (char *)__get_dynamic_array(msg)) 301 TP_printk("%s", __get_str(msg))
302); 302);
303 303
304#undef TRACE_SYSTEM 304#undef TRACE_SYSTEM
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index fbfd2d137117..3ce4e9d5082d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -1102,7 +1102,7 @@ void iwl_drv_stop(struct iwl_drv *drv)
1102 1102
1103/* shared module parameters */ 1103/* shared module parameters */
1104struct iwl_mod_params iwlwifi_mod_params = { 1104struct iwl_mod_params iwlwifi_mod_params = {
1105 .restart_fw = 1, 1105 .restart_fw = true,
1106 .plcp_check = true, 1106 .plcp_check = true,
1107 .bt_coex_active = true, 1107 .bt_coex_active = true,
1108 .power_level = IWL_POWER_INDEX_1, 1108 .power_level = IWL_POWER_INDEX_1,
@@ -1111,7 +1111,7 @@ struct iwl_mod_params iwlwifi_mod_params = {
1111 .wd_disable = true, 1111 .wd_disable = true,
1112 /* the rest are 0 by default */ 1112 /* the rest are 0 by default */
1113}; 1113};
1114EXPORT_SYMBOL_GPL(iwlwifi_mod_params); 1114IWL_EXPORT_SYMBOL(iwlwifi_mod_params);
1115 1115
1116int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) 1116int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops)
1117{ 1117{
@@ -1135,7 +1135,7 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops)
1135 mutex_unlock(&iwlwifi_opmode_table_mtx); 1135 mutex_unlock(&iwlwifi_opmode_table_mtx);
1136 return -EIO; 1136 return -EIO;
1137} 1137}
1138EXPORT_SYMBOL_GPL(iwl_opmode_register); 1138IWL_EXPORT_SYMBOL(iwl_opmode_register);
1139 1139
1140void iwl_opmode_deregister(const char *name) 1140void iwl_opmode_deregister(const char *name)
1141{ 1141{
@@ -1157,7 +1157,7 @@ void iwl_opmode_deregister(const char *name)
1157 } 1157 }
1158 mutex_unlock(&iwlwifi_opmode_table_mtx); 1158 mutex_unlock(&iwlwifi_opmode_table_mtx);
1159} 1159}
1160EXPORT_SYMBOL_GPL(iwl_opmode_deregister); 1160IWL_EXPORT_SYMBOL(iwl_opmode_deregister);
1161 1161
1162static int __init iwl_drv_init(void) 1162static int __init iwl_drv_init(void)
1163{ 1163{
@@ -1207,8 +1207,8 @@ MODULE_PARM_DESC(11n_disable,
1207module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, 1207module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K,
1208 int, S_IRUGO); 1208 int, S_IRUGO);
1209MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); 1209MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)");
1210module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO); 1210module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, bool, S_IRUGO);
1211MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); 1211MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)");
1212 1212
1213module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, 1213module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,
1214 int, S_IRUGO); 1214 int, S_IRUGO);
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h
index 594a5c71b272..7d1450916308 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.h
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -63,6 +63,8 @@
63#ifndef __iwl_drv_h__ 63#ifndef __iwl_drv_h__
64#define __iwl_drv_h__ 64#define __iwl_drv_h__
65 65
66#include <linux/module.h>
67
66/* for all modules */ 68/* for all modules */
67#define DRV_NAME "iwlwifi" 69#define DRV_NAME "iwlwifi"
68#define IWLWIFI_VERSION "in-tree:" 70#define IWLWIFI_VERSION "in-tree:"
@@ -123,4 +125,17 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
123 */ 125 */
124void iwl_drv_stop(struct iwl_drv *drv); 126void iwl_drv_stop(struct iwl_drv *drv);
125 127
128/*
129 * exported symbol management
130 *
131 * The driver can be split into multiple modules, in which case some symbols
132 * must be exported for the sub-modules. However, if it's not split and
133 * everything is built-in, then we can avoid that.
134 */
135#ifdef CONFIG_IWLWIFI_OPMODE_MODULAR
136#define IWL_EXPORT_SYMBOL(sym) EXPORT_SYMBOL_GPL(sym)
137#else
138#define IWL_EXPORT_SYMBOL(sym)
139#endif
140
126#endif /* __iwl_drv_h__ */ 141#endif /* __iwl_drv_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index 034f2ff4f43d..600c9fdd7f71 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -62,6 +62,7 @@
62#include <linux/types.h> 62#include <linux/types.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/export.h> 64#include <linux/export.h>
65#include "iwl-drv.h"
65#include "iwl-modparams.h" 66#include "iwl-modparams.h"
66#include "iwl-eeprom-parse.h" 67#include "iwl-eeprom-parse.h"
67 68
@@ -749,7 +750,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
749 } 750 }
750 751
751 ht_info->ht_supported = true; 752 ht_info->ht_supported = true;
752 ht_info->cap = 0; 753 ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40;
753 754
754 if (iwlwifi_mod_params.amsdu_size_8K) 755 if (iwlwifi_mod_params.amsdu_size_8K)
755 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; 756 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
@@ -909,7 +910,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
909 kfree(data); 910 kfree(data);
910 return NULL; 911 return NULL;
911} 912}
912EXPORT_SYMBOL_GPL(iwl_parse_eeprom_data); 913IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data);
913 914
914/* helper functions */ 915/* helper functions */
915int iwl_nvm_check_version(struct iwl_nvm_data *data, 916int iwl_nvm_check_version(struct iwl_nvm_data *data,
@@ -928,4 +929,4 @@ int iwl_nvm_check_version(struct iwl_nvm_data *data,
928 data->calib_version, trans->cfg->nvm_calib_ver); 929 data->calib_version, trans->cfg->nvm_calib_ver);
929 return -EINVAL; 930 return -EINVAL;
930} 931}
931EXPORT_SYMBOL_GPL(iwl_nvm_check_version); 932IWL_EXPORT_SYMBOL(iwl_nvm_check_version);
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index 683fe6a8c58f..37f115390b19 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
index ef4806f27cf8..e5f2e362ab0b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -63,6 +63,7 @@
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/export.h> 64#include <linux/export.h>
65 65
66#include "iwl-drv.h"
66#include "iwl-debug.h" 67#include "iwl-debug.h"
67#include "iwl-eeprom-read.h" 68#include "iwl-eeprom-read.h"
68#include "iwl-io.h" 69#include "iwl-io.h"
@@ -460,4 +461,4 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size)
460 461
461 return ret; 462 return ret;
462} 463}
463EXPORT_SYMBOL_GPL(iwl_read_eeprom); 464IWL_EXPORT_SYMBOL(iwl_read_eeprom);
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
index b2588c5cbf93..8e941f8bd7d6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index f5592fb3b1ed..484d318245fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 90873eca35f7..8b6c6fd95ed0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index b545178e46e3..435618574240 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -73,12 +73,14 @@
73 * treats good CRC threshold as a boolean 73 * treats good CRC threshold as a boolean
74 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). 74 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
75 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. 75 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
76 * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
76 */ 77 */
77enum iwl_ucode_tlv_flag { 78enum iwl_ucode_tlv_flag {
78 IWL_UCODE_TLV_FLAGS_PAN = BIT(0), 79 IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
79 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), 80 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
80 IWL_UCODE_TLV_FLAGS_MFP = BIT(2), 81 IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
81 IWL_UCODE_TLV_FLAGS_P2P = BIT(3), 82 IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
83 IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
82}; 84};
83 85
84/* The default calibrate table size if not specified by firmware file */ 86/* The default calibrate table size if not specified by firmware file */
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 276410d82de4..305c81f2c2b4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -29,6 +29,7 @@
29#include <linux/device.h> 29#include <linux/device.h>
30#include <linux/export.h> 30#include <linux/export.h>
31 31
32#include "iwl-drv.h"
32#include "iwl-io.h" 33#include "iwl-io.h"
33#include "iwl-csr.h" 34#include "iwl-csr.h"
34#include "iwl-debug.h" 35#include "iwl-debug.h"
@@ -49,7 +50,7 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
49 50
50 return -ETIMEDOUT; 51 return -ETIMEDOUT;
51} 52}
52EXPORT_SYMBOL_GPL(iwl_poll_bit); 53IWL_EXPORT_SYMBOL(iwl_poll_bit);
53 54
54u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) 55u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
55{ 56{
@@ -62,7 +63,7 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
62 63
63 return value; 64 return value;
64} 65}
65EXPORT_SYMBOL_GPL(iwl_read_direct32); 66IWL_EXPORT_SYMBOL(iwl_read_direct32);
66 67
67void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) 68void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
68{ 69{
@@ -73,7 +74,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
73 iwl_trans_release_nic_access(trans, &flags); 74 iwl_trans_release_nic_access(trans, &flags);
74 } 75 }
75} 76}
76EXPORT_SYMBOL_GPL(iwl_write_direct32); 77IWL_EXPORT_SYMBOL(iwl_write_direct32);
77 78
78int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, 79int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
79 int timeout) 80 int timeout)
@@ -89,7 +90,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
89 90
90 return -ETIMEDOUT; 91 return -ETIMEDOUT;
91} 92}
92EXPORT_SYMBOL_GPL(iwl_poll_direct_bit); 93IWL_EXPORT_SYMBOL(iwl_poll_direct_bit);
93 94
94static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs) 95static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs)
95{ 96{
@@ -115,7 +116,7 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
115 } 116 }
116 return val; 117 return val;
117} 118}
118EXPORT_SYMBOL_GPL(iwl_read_prph); 119IWL_EXPORT_SYMBOL(iwl_read_prph);
119 120
120void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) 121void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
121{ 122{
@@ -126,7 +127,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
126 iwl_trans_release_nic_access(trans, &flags); 127 iwl_trans_release_nic_access(trans, &flags);
127 } 128 }
128} 129}
129EXPORT_SYMBOL_GPL(iwl_write_prph); 130IWL_EXPORT_SYMBOL(iwl_write_prph);
130 131
131void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) 132void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
132{ 133{
@@ -138,7 +139,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
138 iwl_trans_release_nic_access(trans, &flags); 139 iwl_trans_release_nic_access(trans, &flags);
139 } 140 }
140} 141}
141EXPORT_SYMBOL_GPL(iwl_set_bits_prph); 142IWL_EXPORT_SYMBOL(iwl_set_bits_prph);
142 143
143void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, 144void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
144 u32 bits, u32 mask) 145 u32 bits, u32 mask)
@@ -151,7 +152,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
151 iwl_trans_release_nic_access(trans, &flags); 152 iwl_trans_release_nic_access(trans, &flags);
152 } 153 }
153} 154}
154EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph); 155IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph);
155 156
156void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) 157void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
157{ 158{
@@ -164,4 +165,4 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
164 iwl_trans_release_nic_access(trans, &flags); 165 iwl_trans_release_nic_access(trans, &flags);
165 } 166 }
166} 167}
167EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); 168IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index 2c2a729092f5..3cc39ffe8ba5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -109,7 +109,7 @@ struct iwl_mod_params {
109 int sw_crypto; 109 int sw_crypto;
110 unsigned int disable_11n; 110 unsigned int disable_11n;
111 int amsdu_size_8K; 111 int amsdu_size_8K;
112 int restart_fw; 112 bool restart_fw;
113 bool plcp_check; 113 bool plcp_check;
114 int wd_disable; 114 int wd_disable;
115 bool bt_coex_active; 115 bool bt_coex_active;
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
index c3affbc62cdf..940b8a9d5285 100644
--- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
+++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -63,6 +63,7 @@
63#include <linux/sched.h> 63#include <linux/sched.h>
64#include <linux/export.h> 64#include <linux/export.h>
65 65
66#include "iwl-drv.h"
66#include "iwl-notif-wait.h" 67#include "iwl-notif-wait.h"
67 68
68 69
@@ -72,7 +73,7 @@ void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait)
72 INIT_LIST_HEAD(&notif_wait->notif_waits); 73 INIT_LIST_HEAD(&notif_wait->notif_waits);
73 init_waitqueue_head(&notif_wait->notif_waitq); 74 init_waitqueue_head(&notif_wait->notif_waitq);
74} 75}
75EXPORT_SYMBOL_GPL(iwl_notification_wait_init); 76IWL_EXPORT_SYMBOL(iwl_notification_wait_init);
76 77
77void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, 78void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait,
78 struct iwl_rx_packet *pkt) 79 struct iwl_rx_packet *pkt)
@@ -117,7 +118,7 @@ void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait,
117 if (triggered) 118 if (triggered)
118 wake_up_all(&notif_wait->notif_waitq); 119 wake_up_all(&notif_wait->notif_waitq);
119} 120}
120EXPORT_SYMBOL_GPL(iwl_notification_wait_notify); 121IWL_EXPORT_SYMBOL(iwl_notification_wait_notify);
121 122
122void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) 123void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
123{ 124{
@@ -130,7 +131,7 @@ void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
130 131
131 wake_up_all(&notif_wait->notif_waitq); 132 wake_up_all(&notif_wait->notif_waitq);
132} 133}
133EXPORT_SYMBOL_GPL(iwl_abort_notification_waits); 134IWL_EXPORT_SYMBOL(iwl_abort_notification_waits);
134 135
135void 136void
136iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, 137iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait,
@@ -154,7 +155,7 @@ iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait,
154 list_add(&wait_entry->list, &notif_wait->notif_waits); 155 list_add(&wait_entry->list, &notif_wait->notif_waits);
155 spin_unlock_bh(&notif_wait->notif_wait_lock); 156 spin_unlock_bh(&notif_wait->notif_wait_lock);
156} 157}
157EXPORT_SYMBOL_GPL(iwl_init_notification_wait); 158IWL_EXPORT_SYMBOL(iwl_init_notification_wait);
158 159
159int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, 160int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
160 struct iwl_notification_wait *wait_entry, 161 struct iwl_notification_wait *wait_entry,
@@ -178,7 +179,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
178 return -ETIMEDOUT; 179 return -ETIMEDOUT;
179 return 0; 180 return 0;
180} 181}
181EXPORT_SYMBOL_GPL(iwl_wait_notification); 182IWL_EXPORT_SYMBOL(iwl_wait_notification);
182 183
183void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, 184void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
184 struct iwl_notification_wait *wait_entry) 185 struct iwl_notification_wait *wait_entry)
@@ -187,4 +188,4 @@ void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
187 list_del(&wait_entry->list); 188 list_del(&wait_entry->list);
188 spin_unlock_bh(&notif_wait->notif_wait_lock); 189 spin_unlock_bh(&notif_wait->notif_wait_lock);
189} 190}
190EXPORT_SYMBOL_GPL(iwl_remove_notification); 191IWL_EXPORT_SYMBOL(iwl_remove_notification);
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
index c2ce764463a3..2e2f1c8c99f9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
+++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index a70213bdb83c..6199a0a597a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -62,6 +62,7 @@
62#include <linux/types.h> 62#include <linux/types.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/export.h> 64#include <linux/export.h>
65#include "iwl-drv.h"
65#include "iwl-modparams.h" 66#include "iwl-modparams.h"
66#include "iwl-nvm-parse.h" 67#include "iwl-nvm-parse.h"
67 68
@@ -149,6 +150,8 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
149 * @NVM_CHANNEL_DFS: dynamic freq selection candidate 150 * @NVM_CHANNEL_DFS: dynamic freq selection candidate
150 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) 151 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
151 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) 152 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
153 * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
154 * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
152 */ 155 */
153enum iwl_nvm_channel_flags { 156enum iwl_nvm_channel_flags {
154 NVM_CHANNEL_VALID = BIT(0), 157 NVM_CHANNEL_VALID = BIT(0),
@@ -158,6 +161,8 @@ enum iwl_nvm_channel_flags {
158 NVM_CHANNEL_DFS = BIT(7), 161 NVM_CHANNEL_DFS = BIT(7),
159 NVM_CHANNEL_WIDE = BIT(8), 162 NVM_CHANNEL_WIDE = BIT(8),
160 NVM_CHANNEL_40MHZ = BIT(9), 163 NVM_CHANNEL_40MHZ = BIT(9),
164 NVM_CHANNEL_80MHZ = BIT(10),
165 NVM_CHANNEL_160MHZ = BIT(11),
161}; 166};
162 167
163#define CHECK_AND_PRINT_I(x) \ 168#define CHECK_AND_PRINT_I(x) \
@@ -210,6 +215,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
210 else 215 else
211 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; 216 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
212 } 217 }
218 if (!(ch_flags & NVM_CHANNEL_80MHZ))
219 channel->flags |= IEEE80211_CHAN_NO_80MHZ;
220 if (!(ch_flags & NVM_CHANNEL_160MHZ))
221 channel->flags |= IEEE80211_CHAN_NO_160MHZ;
213 222
214 if (!(ch_flags & NVM_CHANNEL_IBSS)) 223 if (!(ch_flags & NVM_CHANNEL_IBSS))
215 channel->flags |= IEEE80211_CHAN_NO_IBSS; 224 channel->flags |= IEEE80211_CHAN_NO_IBSS;
@@ -245,6 +254,43 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
245 return n_channels; 254 return n_channels;
246} 255}
247 256
257static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
258 struct iwl_nvm_data *data,
259 struct ieee80211_sta_vht_cap *vht_cap)
260{
261 /* For now, assume new devices with NVM are VHT capable */
262
263 vht_cap->vht_supported = true;
264
265 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
266 IEEE80211_VHT_CAP_RXSTBC_1 |
267 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
268 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
269
270 if (iwlwifi_mod_params.amsdu_size_8K)
271 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
272
273 vht_cap->vht_mcs.rx_mcs_map =
274 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
275 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
276 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
277 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
278 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
279 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
280 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
281 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
282
283 if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) {
284 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
285 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
286 /* this works because NOT_SUPPORTED == 3 */
287 vht_cap->vht_mcs.rx_mcs_map |=
288 cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
289 }
290
291 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
292}
293
248static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 294static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
249 struct iwl_nvm_data *data, const __le16 *nvm_sw) 295 struct iwl_nvm_data *data, const __le16 *nvm_sw)
250{ 296{
@@ -268,6 +314,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
268 n_used += iwl_init_sband_channels(data, sband, n_channels, 314 n_used += iwl_init_sband_channels(data, sband, n_channels,
269 IEEE80211_BAND_5GHZ); 315 IEEE80211_BAND_5GHZ);
270 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); 316 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ);
317 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
271 318
272 if (n_channels != n_used) 319 if (n_channels != n_used)
273 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", 320 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
@@ -343,4 +390,4 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
343 390
344 return data; 391 return data;
345} 392}
346EXPORT_SYMBOL_GPL(iwl_parse_nvm_data); 393IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
index b2692bd287fa..e57fb989661e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
index 4a680019e117..98c7aa7346da 100644
--- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
index 3392011a8768..25745daa0d5d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -65,6 +65,7 @@
65#include <linux/string.h> 65#include <linux/string.h>
66#include <linux/export.h> 66#include <linux/export.h>
67 67
68#include "iwl-drv.h"
68#include "iwl-phy-db.h" 69#include "iwl-phy-db.h"
69#include "iwl-debug.h" 70#include "iwl-debug.h"
70#include "iwl-op-mode.h" 71#include "iwl-op-mode.h"
@@ -149,7 +150,7 @@ struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans)
149 /* TODO: add default values of the phy db. */ 150 /* TODO: add default values of the phy db. */
150 return phy_db; 151 return phy_db;
151} 152}
152EXPORT_SYMBOL(iwl_phy_db_init); 153IWL_EXPORT_SYMBOL(iwl_phy_db_init);
153 154
154/* 155/*
155 * get phy db section: returns a pointer to a phy db section specified by 156 * get phy db section: returns a pointer to a phy db section specified by
@@ -215,7 +216,7 @@ void iwl_phy_db_free(struct iwl_phy_db *phy_db)
215 216
216 kfree(phy_db); 217 kfree(phy_db);
217} 218}
218EXPORT_SYMBOL(iwl_phy_db_free); 219IWL_EXPORT_SYMBOL(iwl_phy_db_free);
219 220
220int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, 221int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
221 gfp_t alloc_ctx) 222 gfp_t alloc_ctx)
@@ -260,7 +261,7 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
260 261
261 return 0; 262 return 0;
262} 263}
263EXPORT_SYMBOL(iwl_phy_db_set_section); 264IWL_EXPORT_SYMBOL(iwl_phy_db_set_section);
264 265
265static int is_valid_channel(u16 ch_id) 266static int is_valid_channel(u16 ch_id)
266{ 267{
@@ -495,4 +496,4 @@ int iwl_send_phy_db_data(struct iwl_phy_db *phy_db)
495 "Finished sending phy db non channel data\n"); 496 "Finished sending phy db non channel data\n");
496 return 0; 497 return 0;
497} 498}
498EXPORT_SYMBOL(iwl_send_phy_db_data); 499IWL_EXPORT_SYMBOL(iwl_send_phy_db_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
index d0e43d96ab38..ce983af79644 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index f76e9cad7757..386f2a7c87cb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c
index ce0c67b425ee..efff2986b5b4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-test.c
+++ b/drivers/net/wireless/iwlwifi/iwl-test.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -64,6 +64,7 @@
64#include <linux/export.h> 64#include <linux/export.h>
65#include <net/netlink.h> 65#include <net/netlink.h>
66 66
67#include "iwl-drv.h"
67#include "iwl-io.h" 68#include "iwl-io.h"
68#include "iwl-fh.h" 69#include "iwl-fh.h"
69#include "iwl-prph.h" 70#include "iwl-prph.h"
@@ -653,7 +654,7 @@ int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
653 } 654 }
654 return 0; 655 return 0;
655} 656}
656EXPORT_SYMBOL_GPL(iwl_test_parse); 657IWL_EXPORT_SYMBOL(iwl_test_parse);
657 658
658/* 659/*
659 * Handle test commands. 660 * Handle test commands.
@@ -715,7 +716,7 @@ int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb)
715 } 716 }
716 return result; 717 return result;
717} 718}
718EXPORT_SYMBOL_GPL(iwl_test_handle_cmd); 719IWL_EXPORT_SYMBOL(iwl_test_handle_cmd);
719 720
720static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb, 721static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb,
721 struct netlink_callback *cb) 722 struct netlink_callback *cb)
@@ -803,7 +804,7 @@ int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
803 } 804 }
804 return result; 805 return result;
805} 806}
806EXPORT_SYMBOL_GPL(iwl_test_dump); 807IWL_EXPORT_SYMBOL(iwl_test_dump);
807 808
808/* 809/*
809 * Multicast a spontaneous messages from the device to the user space. 810 * Multicast a spontaneous messages from the device to the user space.
@@ -849,4 +850,4 @@ void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb)
849 if (tst->notify) 850 if (tst->notify)
850 iwl_test_send_rx(tst, rxb); 851 iwl_test_send_rx(tst, rxb);
851} 852}
852EXPORT_SYMBOL_GPL(iwl_test_rx); 853IWL_EXPORT_SYMBOL(iwl_test_rx);
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h
index 7fbf4d717caa..8fbd21704840 100644
--- a/drivers/net/wireless/iwlwifi/iwl-test.h
+++ b/drivers/net/wireless/iwlwifi/iwl-test.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
index a963f45c6849..98f48a9afc98 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 0cac2b7af78b..7f9c254292a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -114,9 +114,6 @@
114 * completely agnostic to these differences. 114 * completely agnostic to these differences.
115 * The transport does provide helper functionnality (i.e. SYNC / ASYNC mode), 115 * The transport does provide helper functionnality (i.e. SYNC / ASYNC mode),
116 */ 116 */
117#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
118#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
119#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
120#define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) 117#define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f)
121#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) 118#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8)
122#define SEQ_TO_INDEX(s) ((s) & 0xff) 119#define SEQ_TO_INDEX(s) ((s) & 0xff)
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index 807b250ec396..2acc44b40986 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o
2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o 2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o 5iwlmvm-y += power.o bt-coex.o
6iwlmvm-y += led.o 6iwlmvm-y += led.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c
index 73d24aacb90a..93fd1457954b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/binding.c
+++ b/drivers/net/wireless/iwlwifi/mvm/binding.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
new file mode 100644
index 000000000000..47954deb6493
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -0,0 +1,347 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include "fw-api-bt-coex.h"
65#include "iwl-modparams.h"
66#include "mvm.h"
67#include "iwl-debug.h"
68
69#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \
70 [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \
71 ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS))
72
73static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
74 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1,
75 BT_COEX_PRIO_TBL_PRIO_BYPASS, 0),
76 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2,
77 BT_COEX_PRIO_TBL_PRIO_BYPASS, 1),
78 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1,
79 BT_COEX_PRIO_TBL_PRIO_LOW, 0),
80 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2,
81 BT_COEX_PRIO_TBL_PRIO_LOW, 1),
82 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1,
83 BT_COEX_PRIO_TBL_PRIO_HIGH, 0),
84 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2,
85 BT_COEX_PRIO_TBL_PRIO_HIGH, 1),
86 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM,
87 BT_COEX_PRIO_TBL_DISABLED, 0),
88 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52,
89 BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0),
90 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24,
91 BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0),
92 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE,
93 BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0),
94 0, 0, 0, 0, 0, 0,
95};
96
97#undef EVENT_PRIO_ANT
98
99int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
100{
101 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC,
102 sizeof(struct iwl_bt_coex_prio_tbl_cmd),
103 &iwl_bt_prio_tbl);
104}
105
106static int iwl_send_bt_env(struct iwl_mvm *mvm, u8 action, u8 type)
107{
108 struct iwl_bt_coex_prot_env_cmd env_cmd;
109 int ret;
110
111 env_cmd.action = action;
112 env_cmd.type = type;
113 ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PROT_ENV, CMD_SYNC,
114 sizeof(env_cmd), &env_cmd);
115 if (ret)
116 IWL_ERR(mvm, "failed to send BT env command\n");
117 return ret;
118}
119
120enum iwl_bt_kill_msk {
121 BT_KILL_MSK_DEFAULT,
122 BT_KILL_MSK_SCO_HID_A2DP,
123 BT_KILL_MSK_REDUCED_TXPOW,
124 BT_KILL_MSK_MAX,
125};
126
127static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {
128 0xffffffff,
129 0xfffffc00,
130 0,
131};
132
133static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = {
134 0xffffffff,
135 0xfffffc00,
136 0,
137};
138
139#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0)
140
141/* Tight Coex */
142static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = {
143 cpu_to_le32(0xaaaaaaaa),
144 cpu_to_le32(0xaaaaaaaa),
145 cpu_to_le32(0xaeaaaaaa),
146 cpu_to_le32(0xaaaaaaaa),
147 cpu_to_le32(0xcc00ff28),
148 cpu_to_le32(0x0000aaaa),
149 cpu_to_le32(0xcc00aaaa),
150 cpu_to_le32(0x0000aaaa),
151 cpu_to_le32(0xc0004000),
152 cpu_to_le32(0x00000000),
153 cpu_to_le32(0xf0005000),
154 cpu_to_le32(0xf0005000),
155};
156
157/* Loose Coex */
158static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = {
159 cpu_to_le32(0xaaaaaaaa),
160 cpu_to_le32(0xaaaaaaaa),
161 cpu_to_le32(0xaeaaaaaa),
162 cpu_to_le32(0xaaaaaaaa),
163 cpu_to_le32(0xcc00ff28),
164 cpu_to_le32(0x0000aaaa),
165 cpu_to_le32(0xcc00aaaa),
166 cpu_to_le32(0x0000aaaa),
167 cpu_to_le32(0x00000000),
168 cpu_to_le32(0x00000000),
169 cpu_to_le32(0xf0005000),
170 cpu_to_le32(0xf0005000),
171};
172
173/* Full concurrency */
174static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = {
175 cpu_to_le32(0xaaaaaaaa),
176 cpu_to_le32(0xaaaaaaaa),
177 cpu_to_le32(0xaaaaaaaa),
178 cpu_to_le32(0xaaaaaaaa),
179 cpu_to_le32(0xaaaaaaaa),
180 cpu_to_le32(0xaaaaaaaa),
181 cpu_to_le32(0xaaaaaaaa),
182 cpu_to_le32(0xaaaaaaaa),
183 cpu_to_le32(0x00000000),
184 cpu_to_le32(0x00000000),
185 cpu_to_le32(0x00000000),
186 cpu_to_le32(0x00000000),
187};
188
189/* BT Antenna Coupling Threshold (dB) */
190#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
191
192int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
193{
194 struct iwl_bt_coex_cmd cmd = {
195 .max_kill = 5,
196 .bt3_time_t7_value = 1,
197 .bt3_prio_sample_time = 2,
198 .bt3_timer_t2_value = 0xc,
199 };
200 int ret;
201
202 cmd.flags = iwlwifi_mod_params.bt_coex_active ?
203 BT_COEX_NW : BT_COEX_DISABLE;
204 cmd.flags |= iwlwifi_mod_params.bt_ch_announce ?
205 BT_CH_PRIMARY_EN | BT_CH_SECONDARY_EN : 0;
206 cmd.flags |= BT_SYNC_2_BT_DISABLE;
207
208 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE |
209 BT_VALID_BT_PRIO_BOOST |
210 BT_VALID_MAX_KILL |
211 BT_VALID_3W_TMRS |
212 BT_VALID_KILL_ACK |
213 BT_VALID_KILL_CTS |
214 BT_VALID_REDUCED_TX_POWER |
215 BT_VALID_LUT);
216
217 if (iwlwifi_mod_params.ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD)
218 memcpy(&cmd.decision_lut, iwl_loose_lookup,
219 sizeof(iwl_tight_lookup));
220 else
221 memcpy(&cmd.decision_lut, iwl_tight_lookup,
222 sizeof(iwl_tight_lookup));
223
224 cmd.bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST);
225 cmd.kill_ack_msk =
226 cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]);
227 cmd.kill_cts_msk =
228 cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]);
229
230 /* go to CALIB state in internal BT-Coex state machine */
231 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN,
232 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
233 if (ret)
234 return ret;
235
236 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE,
237 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
238 if (ret)
239 return ret;
240
241 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC,
242 sizeof(cmd), &cmd);
243}
244
245struct iwl_bt_notif_iterator_data {
246 struct iwl_mvm *mvm;
247 struct iwl_bt_coex_profile_notif *notif;
248};
249
250static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
251 struct ieee80211_vif *vif)
252{
253 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
254 struct iwl_bt_notif_iterator_data *data = _data;
255 struct ieee80211_chanctx_conf *chanctx_conf;
256 enum ieee80211_smps_mode smps_mode;
257 enum ieee80211_band band;
258
259 if (vif->type != NL80211_IFTYPE_STATION)
260 return;
261
262 rcu_read_lock();
263 chanctx_conf = rcu_dereference(vif->chanctx_conf);
264 if (chanctx_conf && chanctx_conf->def.chan)
265 band = chanctx_conf->def.chan->band;
266 else
267 band = -1;
268 rcu_read_unlock();
269
270 if (band != IEEE80211_BAND_2GHZ)
271 return;
272
273 smps_mode = IEEE80211_SMPS_AUTOMATIC;
274
275 if (data->notif->bt_status)
276 smps_mode = IEEE80211_SMPS_DYNAMIC;
277
278 if (data->notif->bt_traffic_load)
279 smps_mode = IEEE80211_SMPS_STATIC;
280
281 IWL_DEBUG_COEX(data->mvm,
282 "mac %d: bt_status %d traffic_load %d smps_req %d\n",
283 mvmvif->id, data->notif->bt_status,
284 data->notif->bt_traffic_load, smps_mode);
285
286 ieee80211_request_smps(vif, smps_mode);
287}
288
289int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
290 struct iwl_rx_cmd_buffer *rxb,
291 struct iwl_device_cmd *dev_cmd)
292{
293 struct iwl_rx_packet *pkt = rxb_addr(rxb);
294 struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
295 struct iwl_bt_notif_iterator_data data = {
296 .mvm = mvm,
297 .notif = notif,
298 };
299 struct iwl_bt_coex_cmd cmd = {};
300 enum iwl_bt_kill_msk bt_kill_msk;
301
302 IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
303 IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not ");
304 IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);
305 IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load);
306 IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",
307 notif->bt_agg_traffic_load);
308 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
309
310 /* remember this notification for future use: rssi fluctuations */
311 memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));
312
313 ieee80211_iterate_active_interfaces_atomic(
314 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
315 iwl_mvm_bt_notif_iterator, &data);
316
317 /* Low latency BT profile is active: give higher prio to BT */
318 if (BT_MBOX_MSG(notif, 3, SCO_STATE) ||
319 BT_MBOX_MSG(notif, 3, A2DP_STATE) ||
320 BT_MBOX_MSG(notif, 3, SNIFF_STATE))
321 bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP;
322 else
323 bt_kill_msk = BT_KILL_MSK_DEFAULT;
324
325 /* Don't send HCMD if there is no update */
326 if (bt_kill_msk == mvm->bt_kill_msk)
327 return 0;
328
329 IWL_DEBUG_COEX(mvm,
330 "Udpate kill_msk: %d\n\t SCO %sactive A2DP %sactive SNIFF %sactive\n",
331 bt_kill_msk,
332 BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",
333 BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",
334 BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in");
335
336 mvm->bt_kill_msk = bt_kill_msk;
337 cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
338 cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
339
340 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS);
341
342 if (iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd))
343 IWL_ERR(mvm, "Failed to sent BT Coex CMD\n");
344
345 /* This handler is ASYNC */
346 return 0;
347}
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 994c8c263dc0..d4578cefe445 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -62,8 +62,10 @@
62 *****************************************************************************/ 62 *****************************************************************************/
63 63
64#include <linux/etherdevice.h> 64#include <linux/etherdevice.h>
65#include <linux/ip.h>
65#include <net/cfg80211.h> 66#include <net/cfg80211.h>
66#include <net/ipv6.h> 67#include <net/ipv6.h>
68#include <net/tcp.h>
67#include "iwl-modparams.h" 69#include "iwl-modparams.h"
68#include "fw-api.h" 70#include "fw-api.h"
69#include "mvm.h" 71#include "mvm.h"
@@ -402,6 +404,233 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
402 sizeof(cmd), &cmd); 404 sizeof(cmd), &cmd);
403} 405}
404 406
407enum iwl_mvm_tcp_packet_type {
408 MVM_TCP_TX_SYN,
409 MVM_TCP_RX_SYNACK,
410 MVM_TCP_TX_DATA,
411 MVM_TCP_RX_ACK,
412 MVM_TCP_RX_WAKE,
413 MVM_TCP_TX_FIN,
414};
415
416static __le16 pseudo_hdr_check(int len, __be32 saddr, __be32 daddr)
417{
418 __sum16 check = tcp_v4_check(len, saddr, daddr, 0);
419 return cpu_to_le16(be16_to_cpu((__force __be16)check));
420}
421
422static void iwl_mvm_build_tcp_packet(struct iwl_mvm *mvm,
423 struct ieee80211_vif *vif,
424 struct cfg80211_wowlan_tcp *tcp,
425 void *_pkt, u8 *mask,
426 __le16 *pseudo_hdr_csum,
427 enum iwl_mvm_tcp_packet_type ptype)
428{
429 struct {
430 struct ethhdr eth;
431 struct iphdr ip;
432 struct tcphdr tcp;
433 u8 data[];
434 } __packed *pkt = _pkt;
435 u16 ip_tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr);
436 int i;
437
438 pkt->eth.h_proto = cpu_to_be16(ETH_P_IP),
439 pkt->ip.version = 4;
440 pkt->ip.ihl = 5;
441 pkt->ip.protocol = IPPROTO_TCP;
442
443 switch (ptype) {
444 case MVM_TCP_TX_SYN:
445 case MVM_TCP_TX_DATA:
446 case MVM_TCP_TX_FIN:
447 memcpy(pkt->eth.h_dest, tcp->dst_mac, ETH_ALEN);
448 memcpy(pkt->eth.h_source, vif->addr, ETH_ALEN);
449 pkt->ip.ttl = 128;
450 pkt->ip.saddr = tcp->src;
451 pkt->ip.daddr = tcp->dst;
452 pkt->tcp.source = cpu_to_be16(tcp->src_port);
453 pkt->tcp.dest = cpu_to_be16(tcp->dst_port);
454 /* overwritten for TX SYN later */
455 pkt->tcp.doff = sizeof(struct tcphdr) / 4;
456 pkt->tcp.window = cpu_to_be16(65000);
457 break;
458 case MVM_TCP_RX_SYNACK:
459 case MVM_TCP_RX_ACK:
460 case MVM_TCP_RX_WAKE:
461 memcpy(pkt->eth.h_dest, vif->addr, ETH_ALEN);
462 memcpy(pkt->eth.h_source, tcp->dst_mac, ETH_ALEN);
463 pkt->ip.saddr = tcp->dst;
464 pkt->ip.daddr = tcp->src;
465 pkt->tcp.source = cpu_to_be16(tcp->dst_port);
466 pkt->tcp.dest = cpu_to_be16(tcp->src_port);
467 break;
468 default:
469 WARN_ON(1);
470 return;
471 }
472
473 switch (ptype) {
474 case MVM_TCP_TX_SYN:
475 /* firmware assumes 8 option bytes - 8 NOPs for now */
476 memset(pkt->data, 0x01, 8);
477 ip_tot_len += 8;
478 pkt->tcp.doff = (sizeof(struct tcphdr) + 8) / 4;
479 pkt->tcp.syn = 1;
480 break;
481 case MVM_TCP_TX_DATA:
482 ip_tot_len += tcp->payload_len;
483 memcpy(pkt->data, tcp->payload, tcp->payload_len);
484 pkt->tcp.psh = 1;
485 pkt->tcp.ack = 1;
486 break;
487 case MVM_TCP_TX_FIN:
488 pkt->tcp.fin = 1;
489 pkt->tcp.ack = 1;
490 break;
491 case MVM_TCP_RX_SYNACK:
492 pkt->tcp.syn = 1;
493 pkt->tcp.ack = 1;
494 break;
495 case MVM_TCP_RX_ACK:
496 pkt->tcp.ack = 1;
497 break;
498 case MVM_TCP_RX_WAKE:
499 ip_tot_len += tcp->wake_len;
500 pkt->tcp.psh = 1;
501 pkt->tcp.ack = 1;
502 memcpy(pkt->data, tcp->wake_data, tcp->wake_len);
503 break;
504 }
505
506 switch (ptype) {
507 case MVM_TCP_TX_SYN:
508 case MVM_TCP_TX_DATA:
509 case MVM_TCP_TX_FIN:
510 pkt->ip.tot_len = cpu_to_be16(ip_tot_len);
511 pkt->ip.check = ip_fast_csum(&pkt->ip, pkt->ip.ihl);
512 break;
513 case MVM_TCP_RX_WAKE:
514 for (i = 0; i < DIV_ROUND_UP(tcp->wake_len, 8); i++) {
515 u8 tmp = tcp->wake_mask[i];
516 mask[i + 6] |= tmp << 6;
517 if (i + 1 < DIV_ROUND_UP(tcp->wake_len, 8))
518 mask[i + 7] = tmp >> 2;
519 }
520 /* fall through for ethernet/IP/TCP headers mask */
521 case MVM_TCP_RX_SYNACK:
522 case MVM_TCP_RX_ACK:
523 mask[0] = 0xff; /* match ethernet */
524 /*
525 * match ethernet, ip.version, ip.ihl
526 * the ip.ihl half byte is really masked out by firmware
527 */
528 mask[1] = 0x7f;
529 mask[2] = 0x80; /* match ip.protocol */
530 mask[3] = 0xfc; /* match ip.saddr, ip.daddr */
531 mask[4] = 0x3f; /* match ip.daddr, tcp.source, tcp.dest */
532 mask[5] = 0x80; /* match tcp flags */
533 /* leave rest (0 or set for MVM_TCP_RX_WAKE) */
534 break;
535 };
536
537 *pseudo_hdr_csum = pseudo_hdr_check(ip_tot_len - sizeof(struct iphdr),
538 pkt->ip.saddr, pkt->ip.daddr);
539}
540
541static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm,
542 struct ieee80211_vif *vif,
543 struct cfg80211_wowlan_tcp *tcp)
544{
545 struct iwl_wowlan_remote_wake_config *cfg;
546 struct iwl_host_cmd cmd = {
547 .id = REMOTE_WAKE_CONFIG_CMD,
548 .len = { sizeof(*cfg), },
549 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
550 .flags = CMD_SYNC,
551 };
552 int ret;
553
554 if (!tcp)
555 return 0;
556
557 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
558 if (!cfg)
559 return -ENOMEM;
560 cmd.data[0] = cfg;
561
562 cfg->max_syn_retries = 10;
563 cfg->max_data_retries = 10;
564 cfg->tcp_syn_ack_timeout = 1; /* seconds */
565 cfg->tcp_ack_timeout = 1; /* seconds */
566
567 /* SYN (TX) */
568 iwl_mvm_build_tcp_packet(
569 mvm, vif, tcp, cfg->syn_tx.data, NULL,
570 &cfg->syn_tx.info.tcp_pseudo_header_checksum,
571 MVM_TCP_TX_SYN);
572 cfg->syn_tx.info.tcp_payload_length = 0;
573
574 /* SYN/ACK (RX) */
575 iwl_mvm_build_tcp_packet(
576 mvm, vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask,
577 &cfg->synack_rx.info.tcp_pseudo_header_checksum,
578 MVM_TCP_RX_SYNACK);
579 cfg->synack_rx.info.tcp_payload_length = 0;
580
581 /* KEEPALIVE/ACK (TX) */
582 iwl_mvm_build_tcp_packet(
583 mvm, vif, tcp, cfg->keepalive_tx.data, NULL,
584 &cfg->keepalive_tx.info.tcp_pseudo_header_checksum,
585 MVM_TCP_TX_DATA);
586 cfg->keepalive_tx.info.tcp_payload_length =
587 cpu_to_le16(tcp->payload_len);
588 cfg->sequence_number_offset = tcp->payload_seq.offset;
589 /* length must be 0..4, the field is little endian */
590 cfg->sequence_number_length = tcp->payload_seq.len;
591 cfg->initial_sequence_number = cpu_to_le32(tcp->payload_seq.start);
592 cfg->keepalive_interval = cpu_to_le16(tcp->data_interval);
593 if (tcp->payload_tok.len) {
594 cfg->token_offset = tcp->payload_tok.offset;
595 cfg->token_length = tcp->payload_tok.len;
596 cfg->num_tokens =
597 cpu_to_le16(tcp->tokens_size % tcp->payload_tok.len);
598 memcpy(cfg->tokens, tcp->payload_tok.token_stream,
599 tcp->tokens_size);
600 } else {
601 /* set tokens to max value to almost never run out */
602 cfg->num_tokens = cpu_to_le16(65535);
603 }
604
605 /* ACK (RX) */
606 iwl_mvm_build_tcp_packet(
607 mvm, vif, tcp, cfg->keepalive_ack_rx.data,
608 cfg->keepalive_ack_rx.rx_mask,
609 &cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum,
610 MVM_TCP_RX_ACK);
611 cfg->keepalive_ack_rx.info.tcp_payload_length = 0;
612
613 /* WAKEUP (RX) */
614 iwl_mvm_build_tcp_packet(
615 mvm, vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask,
616 &cfg->wake_rx.info.tcp_pseudo_header_checksum,
617 MVM_TCP_RX_WAKE);
618 cfg->wake_rx.info.tcp_payload_length =
619 cpu_to_le16(tcp->wake_len);
620
621 /* FIN */
622 iwl_mvm_build_tcp_packet(
623 mvm, vif, tcp, cfg->fin_tx.data, NULL,
624 &cfg->fin_tx.info.tcp_pseudo_header_checksum,
625 MVM_TCP_TX_FIN);
626 cfg->fin_tx.info.tcp_payload_length = 0;
627
628 ret = iwl_mvm_send_cmd(mvm, &cmd);
629 kfree(cfg);
630
631 return ret;
632}
633
405struct iwl_d3_iter_data { 634struct iwl_d3_iter_data {
406 struct iwl_mvm *mvm; 635 struct iwl_mvm *mvm;
407 struct ieee80211_vif *vif; 636 struct ieee80211_vif *vif;
@@ -640,6 +869,22 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
640 d3_cfg_cmd.wakeup_flags |= 869 d3_cfg_cmd.wakeup_flags |=
641 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); 870 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
642 871
872 if (wowlan->tcp) {
873 /*
874 * The firmware currently doesn't really look at these, only
875 * the IWL_WOWLAN_WAKEUP_LINK_CHANGE bit. We have to set that
876 * reason bit since losing the connection to the AP implies
877 * losing the TCP connection.
878 * Set the flags anyway as long as they exist, in case this
879 * will be changed in the firmware.
880 */
881 wowlan_config_cmd.wakeup_filter |=
882 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
883 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |
884 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET |
885 IWL_WOWLAN_WAKEUP_LINK_CHANGE);
886 }
887
643 iwl_mvm_cancel_scan(mvm); 888 iwl_mvm_cancel_scan(mvm);
644 889
645 iwl_trans_stop_device(mvm->trans); 890 iwl_trans_stop_device(mvm->trans);
@@ -755,6 +1000,10 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
755 if (ret) 1000 if (ret)
756 goto out; 1001 goto out;
757 1002
1003 ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp);
1004 if (ret)
1005 goto out;
1006
758 /* must be last -- this switches firmware state */ 1007 /* must be last -- this switches firmware state */
759 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, 1008 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC,
760 sizeof(d3_cfg_cmd), &d3_cfg_cmd); 1009 sizeof(d3_cfg_cmd), &d3_cfg_cmd);
@@ -874,6 +1123,15 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
874 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) 1123 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
875 wakeup.four_way_handshake = true; 1124 wakeup.four_way_handshake = true;
876 1125
1126 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS)
1127 wakeup.tcp_connlost = true;
1128
1129 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE)
1130 wakeup.tcp_nomoretokens = true;
1131
1132 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)
1133 wakeup.tcp_match = true;
1134
877 if (status->wake_packet_bufsize) { 1135 if (status->wake_packet_bufsize) {
878 int pktsize = le32_to_cpu(status->wake_packet_bufsize); 1136 int pktsize = le32_to_cpu(status->wake_packet_bufsize);
879 int pktlen = le32_to_cpu(status->wake_packet_length); 1137 int pktlen = le32_to_cpu(status->wake_packet_length);
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index c1bdb5582126..b080b4ba5458 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -69,12 +69,6 @@ struct iwl_dbgfs_mvm_ctx {
69 struct ieee80211_vif *vif; 69 struct ieee80211_vif *vif;
70}; 70};
71 71
72static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
73{
74 file->private_data = inode->i_private;
75 return 0;
76}
77
78static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, 72static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
79 const char __user *user_buf, 73 const char __user *user_buf,
80 size_t count, loff_t *ppos) 74 size_t count, loff_t *ppos)
@@ -306,10 +300,130 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
306 return count; 300 return count;
307} 301}
308 302
303#define BT_MBOX_MSG(_notif, _num, _field) \
304 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
305 >> BT_MBOX##_num##_##_field##_POS)
306
307
308#define BT_MBOX_PRINT(_num, _field, _end) \
309 pos += scnprintf(buf + pos, bufsz - pos, \
310 "\t%s: %d%s", \
311 #_field, \
312 BT_MBOX_MSG(notif, _num, _field), \
313 true ? "\n" : ", ");
314
315static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
316 size_t count, loff_t *ppos)
317{
318 struct iwl_mvm *mvm = file->private_data;
319 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
320 char *buf;
321 int ret, pos = 0, bufsz = sizeof(char) * 1024;
322
323 buf = kmalloc(bufsz, GFP_KERNEL);
324 if (!buf)
325 return -ENOMEM;
326
327 mutex_lock(&mvm->mutex);
328
329 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
330
331 BT_MBOX_PRINT(0, LE_SLAVE_LAT, false);
332 BT_MBOX_PRINT(0, LE_PROF1, false);
333 BT_MBOX_PRINT(0, LE_PROF2, false);
334 BT_MBOX_PRINT(0, LE_PROF_OTHER, false);
335 BT_MBOX_PRINT(0, CHL_SEQ_N, false);
336 BT_MBOX_PRINT(0, INBAND_S, false);
337 BT_MBOX_PRINT(0, LE_MIN_RSSI, false);
338 BT_MBOX_PRINT(0, LE_SCAN, false);
339 BT_MBOX_PRINT(0, LE_ADV, false);
340 BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false);
341 BT_MBOX_PRINT(0, OPEN_CON_1, true);
342
343 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n");
344
345 BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false);
346 BT_MBOX_PRINT(1, IP_SR, false);
347 BT_MBOX_PRINT(1, LE_MSTR, false);
348 BT_MBOX_PRINT(1, AGGR_TRFC_LD, false);
349 BT_MBOX_PRINT(1, MSG_TYPE, false);
350 BT_MBOX_PRINT(1, SSN, true);
351
352 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n");
353
354 BT_MBOX_PRINT(2, SNIFF_ACT, false);
355 BT_MBOX_PRINT(2, PAG, false);
356 BT_MBOX_PRINT(2, INQUIRY, false);
357 BT_MBOX_PRINT(2, CONN, false);
358 BT_MBOX_PRINT(2, SNIFF_INTERVAL, false);
359 BT_MBOX_PRINT(2, DISC, false);
360 BT_MBOX_PRINT(2, SCO_TX_ACT, false);
361 BT_MBOX_PRINT(2, SCO_RX_ACT, false);
362 BT_MBOX_PRINT(2, ESCO_RE_TX, false);
363 BT_MBOX_PRINT(2, SCO_DURATION, true);
364
365 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n");
366
367 BT_MBOX_PRINT(3, SCO_STATE, false);
368 BT_MBOX_PRINT(3, SNIFF_STATE, false);
369 BT_MBOX_PRINT(3, A2DP_STATE, false);
370 BT_MBOX_PRINT(3, ACL_STATE, false);
371 BT_MBOX_PRINT(3, MSTR_STATE, false);
372 BT_MBOX_PRINT(3, OBX_STATE, false);
373 BT_MBOX_PRINT(3, OPEN_CON_2, false);
374 BT_MBOX_PRINT(3, TRAFFIC_LOAD, false);
375 BT_MBOX_PRINT(3, CHL_SEQN_LSB, false);
376 BT_MBOX_PRINT(3, INBAND_P, false);
377 BT_MBOX_PRINT(3, MSG_TYPE_2, false);
378 BT_MBOX_PRINT(3, SSN_2, false);
379 BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
380
381 pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n",
382 notif->bt_status);
383 pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n",
384 notif->bt_open_conn);
385 pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n",
386 notif->bt_traffic_load);
387 pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n",
388 notif->bt_agg_traffic_load);
389 pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n",
390 notif->bt_ci_compliance);
391
392 mutex_unlock(&mvm->mutex);
393
394 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
395 kfree(buf);
396
397 return ret;
398}
399#undef BT_MBOX_PRINT
400
401static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
402 const char __user *user_buf,
403 size_t count, loff_t *ppos)
404{
405 struct iwl_mvm *mvm = file->private_data;
406 bool restart_fw = iwlwifi_mod_params.restart_fw;
407 int ret;
408
409 iwlwifi_mod_params.restart_fw = true;
410
411 mutex_lock(&mvm->mutex);
412
413 /* take the return value to make compiler happy - it will fail anyway */
414 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, CMD_SYNC, 0, NULL);
415
416 mutex_unlock(&mvm->mutex);
417
418 iwlwifi_mod_params.restart_fw = restart_fw;
419
420 return count;
421}
422
309#define MVM_DEBUGFS_READ_FILE_OPS(name) \ 423#define MVM_DEBUGFS_READ_FILE_OPS(name) \
310static const struct file_operations iwl_dbgfs_##name##_ops = { \ 424static const struct file_operations iwl_dbgfs_##name##_ops = { \
311 .read = iwl_dbgfs_##name##_read, \ 425 .read = iwl_dbgfs_##name##_read, \
312 .open = iwl_dbgfs_open_file_generic, \ 426 .open = simple_open, \
313 .llseek = generic_file_llseek, \ 427 .llseek = generic_file_llseek, \
314} 428}
315 429
@@ -317,14 +431,14 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
317static const struct file_operations iwl_dbgfs_##name##_ops = { \ 431static const struct file_operations iwl_dbgfs_##name##_ops = { \
318 .write = iwl_dbgfs_##name##_write, \ 432 .write = iwl_dbgfs_##name##_write, \
319 .read = iwl_dbgfs_##name##_read, \ 433 .read = iwl_dbgfs_##name##_read, \
320 .open = iwl_dbgfs_open_file_generic, \ 434 .open = simple_open, \
321 .llseek = generic_file_llseek, \ 435 .llseek = generic_file_llseek, \
322}; 436};
323 437
324#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \ 438#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \
325static const struct file_operations iwl_dbgfs_##name##_ops = { \ 439static const struct file_operations iwl_dbgfs_##name##_ops = { \
326 .write = iwl_dbgfs_##name##_write, \ 440 .write = iwl_dbgfs_##name##_write, \
327 .open = iwl_dbgfs_open_file_generic, \ 441 .open = simple_open, \
328 .llseek = generic_file_llseek, \ 442 .llseek = generic_file_llseek, \
329}; 443};
330 444
@@ -345,8 +459,10 @@ MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush);
345MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); 459MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain);
346MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); 460MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram);
347MVM_DEBUGFS_READ_FILE_OPS(stations); 461MVM_DEBUGFS_READ_FILE_OPS(stations);
462MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
348MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); 463MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
349MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); 464MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
465MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
350 466
351int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 467int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
352{ 468{
@@ -358,8 +474,10 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
358 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); 474 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR);
359 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); 475 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
360 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); 476 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
477 MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
361 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); 478 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR);
362 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); 479 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR);
480 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
363 481
364 /* 482 /*
365 * Create a symlink with mac80211. It will be removed when mac80211 483 * Create a symlink with mac80211. It will be removed when mac80211
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
new file mode 100644
index 000000000000..05c61d6f384e
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
@@ -0,0 +1,319 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __fw_api_bt_coex_h__
64#define __fw_api_bt_coex_h__
65
66#include <linux/types.h>
67#include <linux/bitops.h>
68
69#define BITS(nb) (BIT(nb) - 1)
70
71/**
72 * enum iwl_bt_coex_flags - flags for BT_COEX command
73 * @BT_CH_PRIMARY_EN:
74 * @BT_CH_SECONDARY_EN:
75 * @BT_NOTIF_COEX_OFF:
76 * @BT_COEX_MODE_POS:
77 * @BT_COEX_MODE_MSK:
78 * @BT_COEX_DISABLE:
79 * @BT_COEX_2W:
80 * @BT_COEX_3W:
81 * @BT_COEX_NW:
82 * @BT_USE_DEFAULTS:
83 * @BT_SYNC_2_BT_DISABLE:
84 * @BT_COEX_CORUNNING_TBL_EN:
85 */
86enum iwl_bt_coex_flags {
87 BT_CH_PRIMARY_EN = BIT(0),
88 BT_CH_SECONDARY_EN = BIT(1),
89 BT_NOTIF_COEX_OFF = BIT(2),
90 BT_COEX_MODE_POS = 3,
91 BT_COEX_MODE_MSK = BITS(3) << BT_COEX_MODE_POS,
92 BT_COEX_DISABLE = 0x0 << BT_COEX_MODE_POS,
93 BT_COEX_2W = 0x1 << BT_COEX_MODE_POS,
94 BT_COEX_3W = 0x2 << BT_COEX_MODE_POS,
95 BT_COEX_NW = 0x3 << BT_COEX_MODE_POS,
96 BT_USE_DEFAULTS = BIT(6),
97 BT_SYNC_2_BT_DISABLE = BIT(7),
98 /*
99 * For future use - when the flags will be enlarged
100 * BT_COEX_CORUNNING_TBL_EN = BIT(8),
101 */
102};
103
104/*
105 * indicates what has changed in the BT_COEX command.
106 */
107enum iwl_bt_coex_valid_bit_msk {
108 BT_VALID_ENABLE = BIT(0),
109 BT_VALID_BT_PRIO_BOOST = BIT(1),
110 BT_VALID_MAX_KILL = BIT(2),
111 BT_VALID_3W_TMRS = BIT(3),
112 BT_VALID_KILL_ACK = BIT(4),
113 BT_VALID_KILL_CTS = BIT(5),
114 BT_VALID_REDUCED_TX_POWER = BIT(6),
115 BT_VALID_LUT = BIT(7),
116 BT_VALID_WIFI_RX_SW_PRIO_BOOST = BIT(8),
117 BT_VALID_WIFI_TX_SW_PRIO_BOOST = BIT(9),
118 BT_VALID_MULTI_PRIO_LUT = BIT(10),
119 BT_VALID_TRM_KICK_FILTER = BIT(11),
120 BT_VALID_CORUN_LUT_20 = BIT(12),
121 BT_VALID_CORUN_LUT_40 = BIT(13),
122 BT_VALID_ANT_ISOLATION = BIT(14),
123 BT_VALID_ANT_ISOLATION_THRS = BIT(15),
124 /*
125 * For future use - when the valid flags will be enlarged
126 * BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),
127 * BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),
128 */
129};
130
131/**
132 * enum iwl_bt_reduced_tx_power - allows to reduce txpower for WiFi frames.
133 * @BT_REDUCED_TX_POWER_CTL: reduce Tx power for control frames
134 * @BT_REDUCED_TX_POWER_DATA: reduce Tx power for data frames
135 *
136 * This mechanism allows to have BT and WiFi run concurrently. Since WiFi
137 * reduces its Tx power, it can work along with BT, hence reducing the amount
138 * of WiFi frames being killed by BT.
139 */
140enum iwl_bt_reduced_tx_power {
141 BT_REDUCED_TX_POWER_CTL = BIT(0),
142 BT_REDUCED_TX_POWER_DATA = BIT(1),
143};
144
145#define BT_COEX_LUT_SIZE (12)
146
147/**
148 * struct iwl_bt_coex_cmd - bt coex configuration command
149 * @flags:&enum iwl_bt_coex_flags
150 * @lead_time:
151 * @max_kill:
152 * @bt3_time_t7_value:
153 * @kill_ack_msk:
154 * @kill_cts_msk:
155 * @bt3_prio_sample_time:
156 * @bt3_timer_t2_value:
157 * @bt4_reaction_time:
158 * @decision_lut[12]:
159 * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power
160 * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk
161 * @bt_prio_boost: values for PTA boost register
162 * @wifi_tx_prio_boost: SW boost of wifi tx priority
163 * @wifi_rx_prio_boost: SW boost of wifi rx priority
164 *
165 * The structure is used for the BT_COEX command.
166 */
167struct iwl_bt_coex_cmd {
168 u8 flags;
169 u8 lead_time;
170 u8 max_kill;
171 u8 bt3_time_t7_value;
172 __le32 kill_ack_msk;
173 __le32 kill_cts_msk;
174 u8 bt3_prio_sample_time;
175 u8 bt3_timer_t2_value;
176 __le16 bt4_reaction_time;
177 __le32 decision_lut[BT_COEX_LUT_SIZE];
178 u8 bt_reduced_tx_power;
179 u8 reserved;
180 __le16 valid_bit_msk;
181 __le32 bt_prio_boost;
182 u8 reserved2;
183 u8 wifi_tx_prio_boost;
184 __le16 wifi_rx_prio_boost;
185} __packed; /* BT_COEX_CMD_API_S_VER_3 */
186
187#define BT_MBOX(n_dw, _msg, _pos, _nbits) \
188 BT_MBOX##n_dw##_##_msg##_POS = (_pos), \
189 BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS
190
191enum iwl_bt_mxbox_dw0 {
192 BT_MBOX(0, LE_SLAVE_LAT, 0, 3),
193 BT_MBOX(0, LE_PROF1, 3, 1),
194 BT_MBOX(0, LE_PROF2, 4, 1),
195 BT_MBOX(0, LE_PROF_OTHER, 5, 1),
196 BT_MBOX(0, CHL_SEQ_N, 8, 4),
197 BT_MBOX(0, INBAND_S, 13, 1),
198 BT_MBOX(0, LE_MIN_RSSI, 16, 4),
199 BT_MBOX(0, LE_SCAN, 20, 1),
200 BT_MBOX(0, LE_ADV, 21, 1),
201 BT_MBOX(0, LE_MAX_TX_POWER, 24, 4),
202 BT_MBOX(0, OPEN_CON_1, 28, 2),
203};
204
205enum iwl_bt_mxbox_dw1 {
206 BT_MBOX(1, BR_MAX_TX_POWER, 0, 4),
207 BT_MBOX(1, IP_SR, 4, 1),
208 BT_MBOX(1, LE_MSTR, 5, 1),
209 BT_MBOX(1, AGGR_TRFC_LD, 8, 6),
210 BT_MBOX(1, MSG_TYPE, 16, 3),
211 BT_MBOX(1, SSN, 19, 2),
212};
213
214enum iwl_bt_mxbox_dw2 {
215 BT_MBOX(2, SNIFF_ACT, 0, 3),
216 BT_MBOX(2, PAG, 3, 1),
217 BT_MBOX(2, INQUIRY, 4, 1),
218 BT_MBOX(2, CONN, 5, 1),
219 BT_MBOX(2, SNIFF_INTERVAL, 8, 5),
220 BT_MBOX(2, DISC, 13, 1),
221 BT_MBOX(2, SCO_TX_ACT, 16, 2),
222 BT_MBOX(2, SCO_RX_ACT, 18, 2),
223 BT_MBOX(2, ESCO_RE_TX, 20, 2),
224 BT_MBOX(2, SCO_DURATION, 24, 6),
225};
226
227enum iwl_bt_mxbox_dw3 {
228 BT_MBOX(3, SCO_STATE, 0, 1),
229 BT_MBOX(3, SNIFF_STATE, 1, 1),
230 BT_MBOX(3, A2DP_STATE, 2, 1),
231 BT_MBOX(3, ACL_STATE, 3, 1),
232 BT_MBOX(3, MSTR_STATE, 4, 1),
233 BT_MBOX(3, OBX_STATE, 5, 1),
234 BT_MBOX(3, OPEN_CON_2, 8, 2),
235 BT_MBOX(3, TRAFFIC_LOAD, 10, 2),
236 BT_MBOX(3, CHL_SEQN_LSB, 12, 1),
237 BT_MBOX(3, INBAND_P, 13, 1),
238 BT_MBOX(3, MSG_TYPE_2, 16, 3),
239 BT_MBOX(3, SSN_2, 19, 2),
240 BT_MBOX(3, UPDATE_REQUEST, 21, 1),
241};
242
243#define BT_MBOX_MSG(_notif, _num, _field) \
244 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
245 >> BT_MBOX##_num##_##_field##_POS)
246
247/**
248 * struct iwl_bt_coex_profile_notif - notification about BT coex
249 * @mbox_msg: message from BT to WiFi
250 * @:bt_status: 0 - off, 1 - on
251 * @:bt_open_conn: number of BT connections open
252 * @:bt_traffic_load: load of BT traffic
253 * @:bt_agg_traffic_load: aggregated load of BT traffic
254 * @:bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
255 */
256struct iwl_bt_coex_profile_notif {
257 __le32 mbox_msg[4];
258 u8 bt_status;
259 u8 bt_open_conn;
260 u8 bt_traffic_load;
261 u8 bt_agg_traffic_load;
262 u8 bt_ci_compliance;
263 u8 reserved[3];
264} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */
265
266enum iwl_bt_coex_prio_table_event {
267 BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0,
268 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1,
269 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2,
270 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3,
271 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4,
272 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5,
273 BT_COEX_PRIO_TBL_EVT_DTIM = 6,
274 BT_COEX_PRIO_TBL_EVT_SCAN52 = 7,
275 BT_COEX_PRIO_TBL_EVT_SCAN24 = 8,
276 BT_COEX_PRIO_TBL_EVT_IDLE = 9,
277 BT_COEX_PRIO_TBL_EVT_MAX = 16,
278}; /* BT_COEX_PRIO_TABLE_EVENTS_API_E_VER_1 */
279
280enum iwl_bt_coex_prio_table_prio {
281 BT_COEX_PRIO_TBL_DISABLED = 0,
282 BT_COEX_PRIO_TBL_PRIO_LOW = 1,
283 BT_COEX_PRIO_TBL_PRIO_HIGH = 2,
284 BT_COEX_PRIO_TBL_PRIO_BYPASS = 3,
285 BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4,
286 BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5,
287 BT_COEX_PRIO_TBL_PRIO_COEX_IDLE = 6,
288 BT_COEX_PRIO_TBL_MAX = 8,
289}; /* BT_COEX_PRIO_TABLE_PRIORITIES_API_E_VER_1 */
290
291#define BT_COEX_PRIO_TBL_SHRD_ANT_POS (0)
292#define BT_COEX_PRIO_TBL_PRIO_POS (1)
293#define BT_COEX_PRIO_TBL_RESERVED_POS (4)
294
295/**
296 * struct iwl_bt_coex_prio_tbl_cmd - priority table for BT coex
297 * @prio_tbl:
298 */
299struct iwl_bt_coex_prio_tbl_cmd {
300 u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];
301} __packed;
302
303enum iwl_bt_coex_env_action {
304 BT_COEX_ENV_CLOSE = 0,
305 BT_COEX_ENV_OPEN = 1,
306}; /* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */
307
308/**
309 * struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope
310 * @action: enum %iwl_bt_coex_env_action
311 * @type: enum %iwl_bt_coex_prio_table_event
312 */
313struct iwl_bt_coex_prot_env_cmd {
314 u8 action; /* 0 = closed, 1 = open */
315 u8 type; /* 0 .. 15 */
316 u8 reserved[2];
317} __packed;
318
319#endif /* __fw_api_bt_coex_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index cf6f9a02fb74..51e015d1dfb2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -258,7 +258,7 @@ enum iwl_wowlan_wakeup_reason {
258 IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8), 258 IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8),
259 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9), 259 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9),
260 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10), 260 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10),
261 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_TCP_EXTERNAL = BIT(11), 261 /* BIT(11) reserved */
262 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), 262 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12),
263}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ 263}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
264 264
@@ -277,6 +277,55 @@ struct iwl_wowlan_status {
277 u8 wake_packet[]; /* can be truncated from _length to _bufsize */ 277 u8 wake_packet[]; /* can be truncated from _length to _bufsize */
278} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ 278} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */
279 279
280#define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64
281#define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128
282#define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048
283
284struct iwl_tcp_packet_info {
285 __le16 tcp_pseudo_header_checksum;
286 __le16 tcp_payload_length;
287} __packed; /* TCP_PACKET_INFO_API_S_VER_2 */
288
289struct iwl_tcp_packet {
290 struct iwl_tcp_packet_info info;
291 u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];
292 u8 data[IWL_WOWLAN_TCP_MAX_PACKET_LEN];
293} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */
294
295struct iwl_remote_wake_packet {
296 struct iwl_tcp_packet_info info;
297 u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];
298 u8 data[IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN];
299} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */
300
301struct iwl_wowlan_remote_wake_config {
302 __le32 connection_max_time; /* unused */
303 /* TCP_PROTOCOL_CONFIG_API_S_VER_1 */
304 u8 max_syn_retries;
305 u8 max_data_retries;
306 u8 tcp_syn_ack_timeout;
307 u8 tcp_ack_timeout;
308
309 struct iwl_tcp_packet syn_tx;
310 struct iwl_tcp_packet synack_rx;
311 struct iwl_tcp_packet keepalive_ack_rx;
312 struct iwl_tcp_packet fin_tx;
313
314 struct iwl_remote_wake_packet keepalive_tx;
315 struct iwl_remote_wake_packet wake_rx;
316
317 /* REMOTE_WAKE_OFFSET_INFO_API_S_VER_1 */
318 u8 sequence_number_offset;
319 u8 sequence_number_length;
320 u8 token_offset;
321 u8 token_length;
322 /* REMOTE_WAKE_PROTOCOL_PARAMS_API_S_VER_1 */
323 __le32 initial_sequence_number;
324 __le16 keepalive_interval;
325 __le16 num_tokens;
326 u8 tokens[IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS];
327} __packed; /* REMOTE_WAKE_CONFIG_API_S_VER_2 */
328
280/* TODO: NetDetect API */ 329/* TODO: NetDetect API */
281 330
282#endif /* __fw_api_d3_h__ */ 331#endif /* __fw_api_d3_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
index ae39b7dfda7b..d68640ea41d4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index be36b7604b7f..127051891e9b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index aa3474d08231..fdd33bc0a594 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 670ac8f95e26..b60d14151721 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index 0acb53dda22d..a30691a8a85b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 2677914bf0a6..6d53850c5448 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 2adb61f103f4..f8d7e88234e4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -70,6 +70,7 @@
70#include "fw-api-mac.h" 70#include "fw-api-mac.h"
71#include "fw-api-power.h" 71#include "fw-api-power.h"
72#include "fw-api-d3.h" 72#include "fw-api-d3.h"
73#include "fw-api-bt-coex.h"
73 74
74/* queue and FIFO numbers by usage */ 75/* queue and FIFO numbers by usage */
75enum { 76enum {
@@ -152,6 +153,7 @@ enum {
152 153
153 BEACON_TEMPLATE_CMD = 0x91, 154 BEACON_TEMPLATE_CMD = 0x91,
154 TX_ANT_CONFIGURATION_CMD = 0x98, 155 TX_ANT_CONFIGURATION_CMD = 0x98,
156 BT_CONFIG = 0x9b,
155 STATISTICS_NOTIFICATION = 0x9d, 157 STATISTICS_NOTIFICATION = 0x9d,
156 158
157 /* RF-KILL commands and notifications */ 159 /* RF-KILL commands and notifications */
@@ -162,6 +164,11 @@ enum {
162 REPLY_RX_MPDU_CMD = 0xc1, 164 REPLY_RX_MPDU_CMD = 0xc1,
163 BA_NOTIF = 0xc5, 165 BA_NOTIF = 0xc5,
164 166
167 /* BT Coex */
168 BT_COEX_PRIO_TABLE = 0xcc,
169 BT_COEX_PROT_ENV = 0xcd,
170 BT_PROFILE_NOTIFICATION = 0xce,
171
165 REPLY_DEBUG_CMD = 0xf0, 172 REPLY_DEBUG_CMD = 0xf0,
166 DEBUG_LOG_MSG = 0xf7, 173 DEBUG_LOG_MSG = 0xf7,
167 174
@@ -794,6 +801,7 @@ struct iwl_phy_context_cmd {
794 * @byte_count: frame's byte-count 801 * @byte_count: frame's byte-count
795 * @frame_time: frame's time on the air, based on byte count and frame rate 802 * @frame_time: frame's time on the air, based on byte count and frame rate
796 * calculation 803 * calculation
804 * @mac_active_msk: what MACs were active when the frame was received
797 * 805 *
798 * Before each Rx, the device sends this data. It contains PHY information 806 * Before each Rx, the device sends this data. It contains PHY information
799 * about the reception of the packet. 807 * about the reception of the packet.
@@ -811,7 +819,7 @@ struct iwl_rx_phy_info {
811 __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT]; 819 __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT];
812 __le32 rate_n_flags; 820 __le32 rate_n_flags;
813 __le32 byte_count; 821 __le32 byte_count;
814 __le16 reserved2; 822 __le16 mac_active_msk;
815 __le16 frame_time; 823 __le16 frame_time;
816} __packed; 824} __packed;
817 825
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 500f818dba04..1006b3204e7b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -309,6 +309,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
309 goto error; 309 goto error;
310 } 310 }
311 311
312 ret = iwl_send_bt_prio_tbl(mvm);
313 if (ret)
314 goto error;
315
312 if (read_nvm) { 316 if (read_nvm) {
313 /* Read nvm */ 317 /* Read nvm */
314 ret = iwl_nvm_init(mvm); 318 ret = iwl_nvm_init(mvm);
@@ -414,6 +418,14 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
414 if (ret) 418 if (ret)
415 goto error; 419 goto error;
416 420
421 ret = iwl_send_bt_prio_tbl(mvm);
422 if (ret)
423 goto error;
424
425 ret = iwl_send_bt_init_conf(mvm);
426 if (ret)
427 goto error;
428
417 /* Send phy db control command and then phy db calibration*/ 429 /* Send phy db control command and then phy db calibration*/
418 ret = iwl_send_phy_db_data(mvm->phy_db); 430 ret = iwl_send_phy_db_data(mvm->phy_db);
419 if (ret) 431 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c
index 011906e73a05..2269a9e5cc67 100644
--- a/drivers/net/wireless/iwlwifi/mvm/led.c
+++ b/drivers/net/wireless/iwlwifi/mvm/led.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 341dbc0237ea..2779235daa35 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -553,9 +553,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
553 if (vif->bss_conf.qos) 553 if (vif->bss_conf.qos)
554 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); 554 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
555 555
556 /* Don't use cts to self as the fw doesn't support it currently. */
556 if (vif->bss_conf.use_cts_prot) 557 if (vif->bss_conf.use_cts_prot)
557 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT | 558 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
558 MAC_PROT_FLG_SELF_CTS_EN);
559 559
560 /* 560 /*
561 * I think that we should enable these 2 flags regardless the HT PROT 561 * I think that we should enable these 2 flags regardless the HT PROT
@@ -651,6 +651,13 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm,
651 /* Fill the common data for all mac context types */ 651 /* Fill the common data for all mac context types */
652 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 652 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
653 653
654 /* Allow beacons to pass through as long as we are not associated,or we
655 * do not have dtim period information */
656 if (!vif->bss_conf.assoc || !vif->bss_conf.dtim_period)
657 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_BEACON);
658 else
659 cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON);
660
654 /* Fill the data specific for station mode */ 661 /* Fill the data specific for station mode */
655 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); 662 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta);
656 663
@@ -714,7 +721,9 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,
714 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 721 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
715 722
716 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); 723 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
717 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROMISC); 724
725 /* Override the filter flags to accept only probe requests */
726 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
718 727
719 /* 728 /*
720 * This flag should be set to true when the P2P Device is 729 * This flag should be set to true when the P2P Device is
@@ -846,10 +855,10 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
846 */ 855 */
847static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, 856static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
848 struct ieee80211_vif *vif, 857 struct ieee80211_vif *vif,
849 struct iwl_mac_data_ap *ctxt_ap) 858 struct iwl_mac_data_ap *ctxt_ap,
859 bool add)
850{ 860{
851 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 861 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
852 u32 curr_dev_time;
853 862
854 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); 863 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
855 ctxt_ap->bi_reciprocal = 864 ctxt_ap->bi_reciprocal =
@@ -861,10 +870,19 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
861 vif->bss_conf.dtim_period)); 870 vif->bss_conf.dtim_period));
862 871
863 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); 872 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);
864 curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
865 ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time);
866 873
867 ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time); 874 /*
875 * Only read the system time when the MAC is being added, when we
876 * just modify the MAC then we should keep the time -- the firmware
877 * can otherwise have a "jumping" TBTT.
878 */
879 if (add)
880 mvmvif->ap_beacon_time =
881 iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
882
883 ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time);
884
885 ctxt_ap->beacon_tsf = 0; /* unused */
868 886
869 /* TODO: Assume that the beacon id == mac context id */ 887 /* TODO: Assume that the beacon id == mac context id */
870 ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id); 888 ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id);
@@ -881,8 +899,12 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm,
881 /* Fill the common data for all mac context types */ 899 /* Fill the common data for all mac context types */
882 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 900 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
883 901
902 /* Also enable probe requests to pass */
903 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
904
884 /* Fill the data specific for ap mode */ 905 /* Fill the data specific for ap mode */
885 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap); 906 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap,
907 action == FW_CTXT_ACTION_ADD);
886 908
887 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 909 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
888} 910}
@@ -899,7 +921,8 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
899 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 921 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
900 922
901 /* Fill the data specific for GO mode */ 923 /* Fill the data specific for GO mode */
902 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap); 924 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap,
925 action == FW_CTXT_ACTION_ADD);
903 926
904 cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow); 927 cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);
905 cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps); 928 cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 7e169b085afe..14dd5ee9a01e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -65,7 +65,9 @@
65#include <linux/skbuff.h> 65#include <linux/skbuff.h>
66#include <linux/netdevice.h> 66#include <linux/netdevice.h>
67#include <linux/etherdevice.h> 67#include <linux/etherdevice.h>
68#include <linux/ip.h>
68#include <net/mac80211.h> 69#include <net/mac80211.h>
70#include <net/tcp.h>
69 71
70#include "iwl-op-mode.h" 72#include "iwl-op-mode.h"
71#include "iwl-io.h" 73#include "iwl-io.h"
@@ -102,10 +104,33 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
102 }, 104 },
103}; 105};
104 106
107#ifdef CONFIG_PM_SLEEP
108static const struct nl80211_wowlan_tcp_data_token_feature
109iwl_mvm_wowlan_tcp_token_feature = {
110 .min_len = 0,
111 .max_len = 255,
112 .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS,
113};
114
115static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
116 .tok = &iwl_mvm_wowlan_tcp_token_feature,
117 .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN -
118 sizeof(struct ethhdr) -
119 sizeof(struct iphdr) -
120 sizeof(struct tcphdr),
121 .data_interval_max = 65535, /* __le16 in API */
122 .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN -
123 sizeof(struct ethhdr) -
124 sizeof(struct iphdr) -
125 sizeof(struct tcphdr),
126 .seq = true,
127};
128#endif
129
105int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 130int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
106{ 131{
107 struct ieee80211_hw *hw = mvm->hw; 132 struct ieee80211_hw *hw = mvm->hw;
108 int num_mac, ret; 133 int num_mac, ret, i;
109 134
110 /* Tell mac80211 our characteristics */ 135 /* Tell mac80211 our characteristics */
111 hw->flags = IEEE80211_HW_SIGNAL_DBM | 136 hw->flags = IEEE80211_HW_SIGNAL_DBM |
@@ -156,11 +181,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
156 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); 181 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
157 hw->wiphy->addresses = mvm->addresses; 182 hw->wiphy->addresses = mvm->addresses;
158 hw->wiphy->n_addresses = 1; 183 hw->wiphy->n_addresses = 1;
159 num_mac = mvm->nvm_data->n_hw_addrs; 184
160 if (num_mac > 1) { 185 /* Extract additional MAC addresses if available */
161 memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr, 186 num_mac = (mvm->nvm_data->n_hw_addrs > 1) ?
187 min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1;
188
189 for (i = 1; i < num_mac; i++) {
190 memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr,
162 ETH_ALEN); 191 ETH_ALEN);
163 mvm->addresses[1].addr[5]++; 192 mvm->addresses[i].addr[5]++;
164 hw->wiphy->n_addresses++; 193 hw->wiphy->n_addresses++;
165 } 194 }
166 195
@@ -206,6 +235,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
206 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; 235 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
207 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; 236 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
208 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; 237 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
238 hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
209 } 239 }
210#endif 240#endif
211 241
@@ -273,12 +303,18 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
273 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); 303 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
274 break; 304 break;
275 case IEEE80211_AMPDU_TX_START: 305 case IEEE80211_AMPDU_TX_START:
306 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) {
307 ret = -EINVAL;
308 break;
309 }
276 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn); 310 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
277 break; 311 break;
278 case IEEE80211_AMPDU_TX_STOP_CONT: 312 case IEEE80211_AMPDU_TX_STOP_CONT:
313 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
314 break;
279 case IEEE80211_AMPDU_TX_STOP_FLUSH: 315 case IEEE80211_AMPDU_TX_STOP_FLUSH:
280 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 316 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
281 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); 317 ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid);
282 break; 318 break;
283 case IEEE80211_AMPDU_TX_OPERATIONAL: 319 case IEEE80211_AMPDU_TX_OPERATIONAL:
284 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size); 320 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size);
@@ -1090,7 +1126,8 @@ static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
1090static int iwl_mvm_roc(struct ieee80211_hw *hw, 1126static int iwl_mvm_roc(struct ieee80211_hw *hw,
1091 struct ieee80211_vif *vif, 1127 struct ieee80211_vif *vif,
1092 struct ieee80211_channel *channel, 1128 struct ieee80211_channel *channel,
1093 int duration) 1129 int duration,
1130 enum ieee80211_roc_type type)
1094{ 1131{
1095 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1132 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1096 struct cfg80211_chan_def chandef; 1133 struct cfg80211_chan_def chandef;
@@ -1101,8 +1138,8 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
1101 return -EINVAL; 1138 return -EINVAL;
1102 } 1139 }
1103 1140
1104 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d)\n", channel->hw_value, 1141 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
1105 duration); 1142 duration, type);
1106 1143
1107 mutex_lock(&mvm->mutex); 1144 mutex_lock(&mvm->mutex);
1108 1145
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index bdae700c769e..203eb85e03d3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -79,7 +79,7 @@
79#include "fw-api.h" 79#include "fw-api.h"
80 80
81#define IWL_INVALID_MAC80211_QUEUE 0xff 81#define IWL_INVALID_MAC80211_QUEUE 0xff
82#define IWL_MVM_MAX_ADDRESSES 2 82#define IWL_MVM_MAX_ADDRESSES 5
83/* RSSI offset for WkP */ 83/* RSSI offset for WkP */
84#define IWL_RSSI_OFFSET 50 84#define IWL_RSSI_OFFSET 50
85 85
@@ -174,6 +174,8 @@ struct iwl_mvm_vif {
174 bool uploaded; 174 bool uploaded;
175 bool ap_active; 175 bool ap_active;
176 176
177 u32 ap_beacon_time;
178
177 enum iwl_tsf_id tsf_id; 179 enum iwl_tsf_id tsf_id;
178 180
179 /* 181 /*
@@ -332,6 +334,10 @@ struct iwl_mvm {
332#ifdef CONFIG_PM_SLEEP 334#ifdef CONFIG_PM_SLEEP
333 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; 335 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
334#endif 336#endif
337
338 /* BT-Coex */
339 u8 bt_kill_msk;
340 struct iwl_bt_coex_profile_notif last_bt_notif;
335}; 341};
336 342
337/* Extract MVM priv from op_mode and _hw */ 343/* Extract MVM priv from op_mode and _hw */
@@ -502,4 +508,11 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
502void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, 508void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
503 struct ieee80211_vif *vif, int idx); 509 struct ieee80211_vif *vif, int idx);
504 510
511/* BT Coex */
512int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
513int iwl_send_bt_init_conf(struct iwl_mvm *mvm);
514int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
515 struct iwl_rx_cmd_buffer *rxb,
516 struct iwl_device_cmd *cmd);
517
505#endif /* __IWL_MVM_H__ */ 518#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 20016bcbdeab..93e3d0f174cc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -74,6 +74,9 @@ static const int nvm_to_read[] = {
74 NVM_SECTION_TYPE_PRODUCTION, 74 NVM_SECTION_TYPE_PRODUCTION,
75}; 75};
76 76
77/* Default NVM size to read */
78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024);
79
77/* used to simplify the shared operations on NCM_ACCESS_CMD versions */ 80/* used to simplify the shared operations on NCM_ACCESS_CMD versions */
78union iwl_nvm_access_cmd { 81union iwl_nvm_access_cmd {
79 struct iwl_nvm_access_cmd_ver1 ver1; 82 struct iwl_nvm_access_cmd_ver1 ver1;
@@ -193,9 +196,9 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
193 int ret; 196 int ret;
194 bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000; 197 bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000;
195 198
196 length = (iwlwifi_mod_params.amsdu_size_8K ? (8 * 1024) : (4 * 1024)) 199 /* Set nvm section read length */
197 - sizeof(union iwl_nvm_access_cmd) 200 length = IWL_NVM_DEFAULT_CHUNK_SIZE;
198 - sizeof(struct iwl_rx_packet); 201
199 /* 202 /*
200 * if length is greater than EEPROM size, truncate it because uCode 203 * if length is greater than EEPROM size, truncate it because uCode
201 * doesn't check it by itself, and exit the loop when reached. 204 * doesn't check it by itself, and exit the loop when reached.
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index d0f9c1e0475e..828bdddd07e9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -230,6 +230,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
230 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 230 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
231 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), 231 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
232 232
233 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
234
233 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 235 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
234 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), 236 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
235 237
@@ -293,6 +295,11 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
293 CMD(NET_DETECT_PROFILES_CMD), 295 CMD(NET_DETECT_PROFILES_CMD),
294 CMD(NET_DETECT_HOTSPOTS_CMD), 296 CMD(NET_DETECT_HOTSPOTS_CMD),
295 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), 297 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
298 CMD(CARD_STATE_NOTIFICATION),
299 CMD(BT_COEX_PRIO_TABLE),
300 CMD(BT_COEX_PROT_ENV),
301 CMD(BT_PROFILE_NOTIFICATION),
302 CMD(BT_CONFIG),
296}; 303};
297#undef CMD 304#undef CMD
298 305
@@ -363,8 +370,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
363 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); 370 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
364 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; 371 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
365 372
366 /* TODO: this should really be a TLV */ 373 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE)
367 if (cfg->device_family == IWL_DEVICE_FAMILY_7000)
368 trans_cfg.bc_table_dword = true; 374 trans_cfg.bc_table_dword = true;
369 375
370 if (!iwlwifi_mod_params.wd_disable) 376 if (!iwlwifi_mod_params.wd_disable)
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index b428448f8ddf..0d537e035ef0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 5a92a4978795..efb9a6f3faac 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 925628468146..df85c49dc599 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 56b636d9ab30..a01a6612677e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -680,12 +680,14 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
680 */ 680 */
681static bool rs_use_green(struct ieee80211_sta *sta) 681static bool rs_use_green(struct ieee80211_sta *sta)
682{ 682{
683 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 683 /*
684 684 * There's a bug somewhere in this code that causes the
685 bool use_green = !(sta_priv->vif->bss_conf.ht_operation_mode & 685 * scaling to get stuck because GF+SGI can't be combined
686 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); 686 * in SISO rates. Until we find that bug, disable GF, it
687 687 * has only limited benefit and we still interoperate with
688 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && use_green; 688 * GF APs since we can always receive GF transmissions.
689 */
690 return false;
689} 691}
690 692
691/** 693/**
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index b0b190d0ec23..4dfc21a3e83e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 9b21b92aa8d1..0d3c76b29242 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 274f44e2ef60..4d872d69577f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -101,8 +101,55 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
101 } 101 }
102 add_sta_cmd.add_modify = update ? 1 : 0; 102 add_sta_cmd.add_modify = update ? 1 : 0;
103 103
104 /* STA_FLG_FAT_EN_MSK ? */ 104 add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_EN_MSK |
105 /* STA_FLG_MIMO_EN_MSK ? */ 105 STA_FLG_MIMO_EN_MSK);
106
107 switch (sta->bandwidth) {
108 case IEEE80211_STA_RX_BW_160:
109 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_160MHZ);
110 /* fall through */
111 case IEEE80211_STA_RX_BW_80:
112 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_80MHZ);
113 /* fall through */
114 case IEEE80211_STA_RX_BW_40:
115 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_40MHZ);
116 /* fall through */
117 case IEEE80211_STA_RX_BW_20:
118 if (sta->ht_cap.ht_supported)
119 add_sta_cmd.station_flags |=
120 cpu_to_le32(STA_FLG_FAT_EN_20MHZ);
121 break;
122 }
123
124 switch (sta->rx_nss) {
125 case 1:
126 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO);
127 break;
128 case 2:
129 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO2);
130 break;
131 case 3 ... 8:
132 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO3);
133 break;
134 }
135
136 switch (sta->smps_mode) {
137 case IEEE80211_SMPS_AUTOMATIC:
138 case IEEE80211_SMPS_NUM_MODES:
139 WARN_ON(1);
140 break;
141 case IEEE80211_SMPS_STATIC:
142 /* override NSS */
143 add_sta_cmd.station_flags &= ~cpu_to_le32(STA_FLG_MIMO_EN_MSK);
144 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO);
145 break;
146 case IEEE80211_SMPS_DYNAMIC:
147 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_RTS_MIMO_PROT);
148 break;
149 case IEEE80211_SMPS_OFF:
150 /* nothing */
151 break;
152 }
106 153
107 if (sta->ht_cap.ht_supported) { 154 if (sta->ht_cap.ht_supported) {
108 add_sta_cmd.station_flags_msk |= 155 add_sta_cmd.station_flags_msk |=
@@ -340,6 +387,9 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
340 387
341 if (vif->type == NL80211_IFTYPE_STATION && 388 if (vif->type == NL80211_IFTYPE_STATION &&
342 mvmvif->ap_sta_id == mvm_sta->sta_id) { 389 mvmvif->ap_sta_id == mvm_sta->sta_id) {
390 /* flush its queues here since we are freeing mvm_sta */
391 ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);
392
343 /* 393 /*
344 * Put a non-NULL since the fw station isn't removed. 394 * Put a non-NULL since the fw station isn't removed.
345 * It will be removed after the MAC will be set as 395 * It will be removed after the MAC will be set as
@@ -348,9 +398,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
348 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], 398 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
349 ERR_PTR(-EINVAL)); 399 ERR_PTR(-EINVAL));
350 400
351 /* flush its queues here since we are freeing mvm_sta */
352 ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);
353
354 /* if we are associated - we can't remove the AP STA now */ 401 /* if we are associated - we can't remove the AP STA now */
355 if (vif->bss_conf.assoc) 402 if (vif->bss_conf.assoc)
356 return ret; 403 return ret;
@@ -686,7 +733,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
686 733
687 spin_lock_bh(&mvmsta->lock); 734 spin_lock_bh(&mvmsta->lock);
688 tid_data = &mvmsta->tid_data[tid]; 735 tid_data = &mvmsta->tid_data[tid];
689 tid_data->ssn = SEQ_TO_SN(tid_data->seq_number); 736 tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
690 tid_data->txq_id = txq_id; 737 tid_data->txq_id = txq_id;
691 *ssn = tid_data->ssn; 738 *ssn = tid_data->ssn;
692 739
@@ -789,7 +836,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
789 836
790 switch (tid_data->state) { 837 switch (tid_data->state) {
791 case IWL_AGG_ON: 838 case IWL_AGG_ON:
792 tid_data->ssn = SEQ_TO_SN(tid_data->seq_number); 839 tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
793 840
794 IWL_DEBUG_TX_QUEUES(mvm, 841 IWL_DEBUG_TX_QUEUES(mvm,
795 "ssn = %d, next_recl = %d\n", 842 "ssn = %d, next_recl = %d\n",
@@ -834,6 +881,34 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
834 return err; 881 return err;
835} 882}
836 883
884int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
885 struct ieee80211_sta *sta, u16 tid)
886{
887 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
888 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
889 u16 txq_id;
890
891 /*
892 * First set the agg state to OFF to avoid calling
893 * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty.
894 */
895 spin_lock_bh(&mvmsta->lock);
896 txq_id = tid_data->txq_id;
897 IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
898 mvmsta->sta_id, tid, txq_id, tid_data->state);
899 tid_data->state = IWL_AGG_OFF;
900 spin_unlock_bh(&mvmsta->lock);
901
902 if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
903 IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
904
905 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
906 mvm->queue_to_mac80211[tid_data->txq_id] =
907 IWL_INVALID_MAC80211_QUEUE;
908
909 return 0;
910}
911
837static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm) 912static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
838{ 913{
839 int i; 914 int i;
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index 896f88ac8145..b0352df981e4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -348,6 +348,8 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
348 struct ieee80211_sta *sta, u16 tid, u8 buf_size); 348 struct ieee80211_sta *sta, u16 tid, u8 buf_size);
349int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 349int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
350 struct ieee80211_sta *sta, u16 tid); 350 struct ieee80211_sta *sta, u16 tid);
351int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
352 struct ieee80211_sta *sta, u16 tid);
351 353
352int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); 354int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
353int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, 355int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index e437e02c7149..c2c7f5176027 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index 64fb57a5ab43..b36424eda361 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 6645efe5c03e..0556d5e16f4e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -637,7 +637,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
637 next_reclaimed = ssn; 637 next_reclaimed = ssn;
638 } else { 638 } else {
639 /* The next packet to be reclaimed is the one after this one */ 639 /* The next packet to be reclaimed is the one after this one */
640 next_reclaimed = SEQ_TO_SN(seq_ctl + 0x10); 640 next_reclaimed = IEEE80211_SEQ_TO_SN(seq_ctl + 0x10);
641 } 641 }
642 642
643 IWL_DEBUG_TX_REPLY(mvm, 643 IWL_DEBUG_TX_REPLY(mvm,
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 000e842c2edd..e308ad93aa9e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/pcie/cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h
deleted file mode 100644
index c6f8e83c3551..000000000000
--- a/drivers/net/wireless/iwlwifi/pcie/cfg.h
+++ /dev/null
@@ -1,115 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#ifndef __iwl_pci_h__
64#define __iwl_pci_h__
65
66
67/*
68 * This file declares the config structures for all devices.
69 */
70
71extern const struct iwl_cfg iwl5300_agn_cfg;
72extern const struct iwl_cfg iwl5100_agn_cfg;
73extern const struct iwl_cfg iwl5350_agn_cfg;
74extern const struct iwl_cfg iwl5100_bgn_cfg;
75extern const struct iwl_cfg iwl5100_abg_cfg;
76extern const struct iwl_cfg iwl5150_agn_cfg;
77extern const struct iwl_cfg iwl5150_abg_cfg;
78extern const struct iwl_cfg iwl6005_2agn_cfg;
79extern const struct iwl_cfg iwl6005_2abg_cfg;
80extern const struct iwl_cfg iwl6005_2bg_cfg;
81extern const struct iwl_cfg iwl6005_2agn_sff_cfg;
82extern const struct iwl_cfg iwl6005_2agn_d_cfg;
83extern const struct iwl_cfg iwl6005_2agn_mow1_cfg;
84extern const struct iwl_cfg iwl6005_2agn_mow2_cfg;
85extern const struct iwl_cfg iwl1030_bgn_cfg;
86extern const struct iwl_cfg iwl1030_bg_cfg;
87extern const struct iwl_cfg iwl6030_2agn_cfg;
88extern const struct iwl_cfg iwl6030_2abg_cfg;
89extern const struct iwl_cfg iwl6030_2bgn_cfg;
90extern const struct iwl_cfg iwl6030_2bg_cfg;
91extern const struct iwl_cfg iwl6000i_2agn_cfg;
92extern const struct iwl_cfg iwl6000i_2abg_cfg;
93extern const struct iwl_cfg iwl6000i_2bg_cfg;
94extern const struct iwl_cfg iwl6000_3agn_cfg;
95extern const struct iwl_cfg iwl6050_2agn_cfg;
96extern const struct iwl_cfg iwl6050_2abg_cfg;
97extern const struct iwl_cfg iwl6150_bgn_cfg;
98extern const struct iwl_cfg iwl6150_bg_cfg;
99extern const struct iwl_cfg iwl1000_bgn_cfg;
100extern const struct iwl_cfg iwl1000_bg_cfg;
101extern const struct iwl_cfg iwl100_bgn_cfg;
102extern const struct iwl_cfg iwl100_bg_cfg;
103extern const struct iwl_cfg iwl130_bgn_cfg;
104extern const struct iwl_cfg iwl130_bg_cfg;
105extern const struct iwl_cfg iwl2000_2bgn_cfg;
106extern const struct iwl_cfg iwl2000_2bgn_d_cfg;
107extern const struct iwl_cfg iwl2030_2bgn_cfg;
108extern const struct iwl_cfg iwl6035_2agn_cfg;
109extern const struct iwl_cfg iwl105_bgn_cfg;
110extern const struct iwl_cfg iwl105_bgn_d_cfg;
111extern const struct iwl_cfg iwl135_bgn_cfg;
112extern const struct iwl_cfg iwl7260_2ac_cfg;
113extern const struct iwl_cfg iwl3160_ac_cfg;
114
115#endif /* __iwl_pci_h__ */
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 7bc0fb9128dd..46ca91f77c9c 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -69,8 +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
73#include "cfg.h"
74#include "internal.h" 72#include "internal.h"
75 73
76#define IWL_PCI_DEVICE(dev, subdev, cfg) \ 74#define IWL_PCI_DEVICE(dev, subdev, cfg) \
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 17bedc50e753..6649e377e9cd 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -715,7 +715,8 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs)
715 715
716static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg) 716static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg)
717{ 717{
718 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); 718 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR,
719 ((reg & 0x000FFFFF) | (3 << 24)));
719 return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT); 720 return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT);
720} 721}
721 722
@@ -723,7 +724,7 @@ static void iwl_trans_pcie_write_prph(struct iwl_trans *trans, u32 addr,
723 u32 val) 724 u32 val)
724{ 725{
725 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR, 726 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR,
726 ((addr & 0x0000FFFF) | (3 << 24))); 727 ((addr & 0x000FFFFF) | (3 << 24)));
727 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val); 728 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val);
728} 729}
729 730
@@ -1370,28 +1371,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
1370 return ret; 1371 return ret;
1371} 1372}
1372 1373
1373static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
1374 const char __user *user_buf,
1375 size_t count, loff_t *ppos)
1376{
1377 struct iwl_trans *trans = file->private_data;
1378
1379 if (!trans->op_mode)
1380 return -EAGAIN;
1381
1382 local_bh_disable();
1383 iwl_op_mode_nic_error(trans->op_mode);
1384 local_bh_enable();
1385
1386 return count;
1387}
1388
1389DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 1374DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
1390DEBUGFS_READ_FILE_OPS(fh_reg); 1375DEBUGFS_READ_FILE_OPS(fh_reg);
1391DEBUGFS_READ_FILE_OPS(rx_queue); 1376DEBUGFS_READ_FILE_OPS(rx_queue);
1392DEBUGFS_READ_FILE_OPS(tx_queue); 1377DEBUGFS_READ_FILE_OPS(tx_queue);
1393DEBUGFS_WRITE_FILE_OPS(csr); 1378DEBUGFS_WRITE_FILE_OPS(csr);
1394DEBUGFS_WRITE_FILE_OPS(fw_restart);
1395 1379
1396/* 1380/*
1397 * Create the debugfs files and directories 1381 * Create the debugfs files and directories
@@ -1405,7 +1389,6 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
1405 DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); 1389 DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);
1406 DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); 1390 DEBUGFS_ADD_FILE(csr, dir, S_IWUSR);
1407 DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); 1391 DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR);
1408 DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR);
1409 return 0; 1392 return 0;
1410 1393
1411err: 1394err:
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 7a508d835f5a..005e2cfb2f41 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1607,7 +1607,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1607 * Check here that the packets are in the right place on the ring. 1607 * Check here that the packets are in the right place on the ring.
1608 */ 1608 */
1609#ifdef CONFIG_IWLWIFI_DEBUG 1609#ifdef CONFIG_IWLWIFI_DEBUG
1610 wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); 1610 wifi_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
1611 WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) && 1611 WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) &&
1612 ((wifi_seq & 0xff) != q->write_ptr), 1612 ((wifi_seq & 0xff) != q->write_ptr),
1613 "Q: %d WiFi Seq %d tfdNum %d", 1613 "Q: %d WiFi Seq %d tfdNum %d",
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index cffdf4fbf161..7490c4fc7177 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1535,7 +1535,8 @@ static void hw_roc_done(struct work_struct *work)
1535static int mac80211_hwsim_roc(struct ieee80211_hw *hw, 1535static int mac80211_hwsim_roc(struct ieee80211_hw *hw,
1536 struct ieee80211_vif *vif, 1536 struct ieee80211_vif *vif,
1537 struct ieee80211_channel *chan, 1537 struct ieee80211_channel *chan,
1538 int duration) 1538 int duration,
1539 enum ieee80211_roc_type type)
1539{ 1540{
1540 struct mac80211_hwsim_data *hwsim = hw->priv; 1541 struct mac80211_hwsim_data *hwsim = hw->priv;
1541 1542
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index 97b245cbafd8..ecf28464367f 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -39,6 +39,7 @@ mwifiex-y += sta_tx.o
39mwifiex-y += sta_rx.o 39mwifiex-y += sta_rx.o
40mwifiex-y += uap_txrx.o 40mwifiex-y += uap_txrx.o
41mwifiex-y += cfg80211.o 41mwifiex-y += cfg80211.o
42mwifiex-y += ethtool.o
42mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o 43mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o
43obj-$(CONFIG_MWIFIEX) += mwifiex.o 44obj-$(CONFIG_MWIFIEX) += mwifiex.o
44 45
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index a44023a7bd57..dbf5b1289516 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1932,66 +1932,10 @@ static void mwifiex_setup_vht_caps(struct ieee80211_sta_vht_cap *vht_info,
1932 struct mwifiex_private *priv) 1932 struct mwifiex_private *priv)
1933{ 1933{
1934 struct mwifiex_adapter *adapter = priv->adapter; 1934 struct mwifiex_adapter *adapter = priv->adapter;
1935 u32 vht_cap = 0, cap = adapter->hw_dot_11ac_dev_cap;
1936 1935
1937 vht_info->vht_supported = true; 1936 vht_info->vht_supported = true;
1938 1937
1939 switch (GET_VHTCAP_MAXMPDULEN(cap)) { 1938 vht_info->cap = adapter->hw_dot_11ac_dev_cap;
1940 case 0x00:
1941 vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1942 break;
1943 case 0x01:
1944 vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1945 break;
1946 case 0x10:
1947 vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1948 break;
1949 default:
1950 dev_err(adapter->dev, "unsupported MAX MPDU len\n");
1951 break;
1952 }
1953
1954 if (ISSUPP_11ACVHTHTCVHT(cap))
1955 vht_cap |= IEEE80211_VHT_CAP_HTC_VHT;
1956
1957 if (ISSUPP_11ACVHTTXOPPS(cap))
1958 vht_cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1959
1960 if (ISSUPP_11ACMURXBEAMFORMEE(cap))
1961 vht_cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1962
1963 if (ISSUPP_11ACMUTXBEAMFORMEE(cap))
1964 vht_cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1965
1966 if (ISSUPP_11ACSUBEAMFORMER(cap))
1967 vht_cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1968
1969 if (ISSUPP_11ACSUBEAMFORMEE(cap))
1970 vht_cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1971
1972 if (ISSUPP_11ACRXSTBC(cap))
1973 vht_cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1974
1975 if (ISSUPP_11ACTXSTBC(cap))
1976 vht_cap |= IEEE80211_VHT_CAP_TXSTBC;
1977
1978 if (ISSUPP_11ACSGI160(cap))
1979 vht_cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1980
1981 if (ISSUPP_11ACSGI80(cap))
1982 vht_cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1983
1984 if (ISSUPP_11ACLDPC(cap))
1985 vht_cap |= IEEE80211_VHT_CAP_RXLDPC;
1986
1987 if (ISSUPP_11ACBW8080(cap))
1988 vht_cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
1989
1990 if (ISSUPP_11ACBW160(cap))
1991 vht_cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
1992
1993 vht_info->cap = vht_cap;
1994
1995 /* Update MCS support for VHT */ 1939 /* Update MCS support for VHT */
1996 vht_info->vht_mcs.rx_mcs_map = cpu_to_le16( 1940 vht_info->vht_mcs.rx_mcs_map = cpu_to_le16(
1997 adapter->hw_dot_11ac_mcs_support & 0xFFFF); 1941 adapter->hw_dot_11ac_mcs_support & 0xFFFF);
@@ -2235,6 +2179,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2235 dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 2179 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
2236 dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT; 2180 dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
2237 dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN; 2181 dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN;
2182 dev->ethtool_ops = &mwifiex_ethtool_ops;
2238 2183
2239 mdev_priv = netdev_priv(dev); 2184 mdev_priv = netdev_priv(dev);
2240 *((unsigned long *) mdev_priv) = (unsigned long) priv; 2185 *((unsigned long *) mdev_priv) = (unsigned long) priv;
@@ -2293,6 +2238,152 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2293} 2238}
2294EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf); 2239EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
2295 2240
2241#ifdef CONFIG_PM
2242static bool
2243mwifiex_is_pattern_supported(struct cfg80211_wowlan_trig_pkt_pattern *pat,
2244 s8 *byte_seq)
2245{
2246 int j, k, valid_byte_cnt = 0;
2247 bool dont_care_byte = false;
2248
2249 for (j = 0; j < DIV_ROUND_UP(pat->pattern_len, 8); j++) {
2250 for (k = 0; k < 8; k++) {
2251 if (pat->mask[j] & 1 << k) {
2252 memcpy(byte_seq + valid_byte_cnt,
2253 &pat->pattern[j * 8 + k], 1);
2254 valid_byte_cnt++;
2255 if (dont_care_byte)
2256 return false;
2257 } else {
2258 if (valid_byte_cnt)
2259 dont_care_byte = true;
2260 }
2261
2262 if (valid_byte_cnt > MAX_BYTESEQ)
2263 return false;
2264 }
2265 }
2266
2267 byte_seq[MAX_BYTESEQ] = valid_byte_cnt;
2268
2269 return true;
2270}
2271
2272static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2273 struct cfg80211_wowlan *wowlan)
2274{
2275 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
2276 struct mwifiex_ds_mef_cfg mef_cfg;
2277 struct mwifiex_mef_entry *mef_entry;
2278 int i, filt_num = 0, ret;
2279 bool first_pat = true;
2280 u8 byte_seq[MAX_BYTESEQ + 1];
2281 const u8 ipv4_mc_mac[] = {0x33, 0x33};
2282 const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
2283 struct mwifiex_private *priv =
2284 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
2285
2286 if (!wowlan) {
2287 dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
2288 return 0;
2289 }
2290
2291 if (!priv->media_connected) {
2292 dev_warn(adapter->dev,
2293 "Can not configure WOWLAN in disconnected state\n");
2294 return 0;
2295 }
2296
2297 mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL);
2298 if (!mef_entry)
2299 return -ENOMEM;
2300
2301 memset(&mef_cfg, 0, sizeof(mef_cfg));
2302 mef_cfg.num_entries = 1;
2303 mef_cfg.mef_entry = mef_entry;
2304 mef_entry->mode = MEF_MODE_HOST_SLEEP;
2305 mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST;
2306
2307 for (i = 0; i < wowlan->n_patterns; i++) {
2308 memset(byte_seq, 0, sizeof(byte_seq));
2309 if (!mwifiex_is_pattern_supported(&wowlan->patterns[i],
2310 byte_seq)) {
2311 wiphy_err(wiphy, "Pattern not supported\n");
2312 kfree(mef_entry);
2313 return -EOPNOTSUPP;
2314 }
2315
2316 if (!wowlan->patterns[i].pkt_offset) {
2317 if (!(byte_seq[0] & 0x01) &&
2318 (byte_seq[MAX_BYTESEQ] == 1)) {
2319 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST;
2320 continue;
2321 } else if (is_broadcast_ether_addr(byte_seq)) {
2322 mef_cfg.criteria |= MWIFIEX_CRITERIA_BROADCAST;
2323 continue;
2324 } else if ((!memcmp(byte_seq, ipv4_mc_mac, 2) &&
2325 (byte_seq[MAX_BYTESEQ] == 2)) ||
2326 (!memcmp(byte_seq, ipv6_mc_mac, 3) &&
2327 (byte_seq[MAX_BYTESEQ] == 3))) {
2328 mef_cfg.criteria |= MWIFIEX_CRITERIA_MULTICAST;
2329 continue;
2330 }
2331 }
2332
2333 mef_entry->filter[filt_num].repeat = 1;
2334 mef_entry->filter[filt_num].offset =
2335 wowlan->patterns[i].pkt_offset;
2336 memcpy(mef_entry->filter[filt_num].byte_seq, byte_seq,
2337 sizeof(byte_seq));
2338 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2339
2340 if (first_pat)
2341 first_pat = false;
2342 else
2343 mef_entry->filter[filt_num].filt_action = TYPE_AND;
2344
2345 filt_num++;
2346 }
2347
2348 if (wowlan->magic_pkt) {
2349 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST;
2350 mef_entry->filter[filt_num].repeat = 16;
2351 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2352 ETH_ALEN);
2353 mef_entry->filter[filt_num].byte_seq[MAX_BYTESEQ] = ETH_ALEN;
2354 mef_entry->filter[filt_num].offset = 14;
2355 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2356 if (filt_num)
2357 mef_entry->filter[filt_num].filt_action = TYPE_OR;
2358 }
2359
2360 if (!mef_cfg.criteria)
2361 mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST |
2362 MWIFIEX_CRITERIA_UNICAST |
2363 MWIFIEX_CRITERIA_MULTICAST;
2364
2365 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MEF_CFG,
2366 HostCmd_ACT_GEN_SET, 0,
2367 &mef_cfg);
2368
2369 kfree(mef_entry);
2370 return ret;
2371}
2372
2373static int mwifiex_cfg80211_resume(struct wiphy *wiphy)
2374{
2375 return 0;
2376}
2377
2378static void mwifiex_cfg80211_set_wakeup(struct wiphy *wiphy,
2379 bool enabled)
2380{
2381 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
2382
2383 device_set_wakeup_enable(adapter->dev, enabled);
2384}
2385#endif
2386
2296/* station cfg80211 operations */ 2387/* station cfg80211 operations */
2297static struct cfg80211_ops mwifiex_cfg80211_ops = { 2388static struct cfg80211_ops mwifiex_cfg80211_ops = {
2298 .add_virtual_intf = mwifiex_add_virtual_intf, 2389 .add_virtual_intf = mwifiex_add_virtual_intf,
@@ -2321,6 +2412,11 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
2321 .change_beacon = mwifiex_cfg80211_change_beacon, 2412 .change_beacon = mwifiex_cfg80211_change_beacon,
2322 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config, 2413 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
2323 .set_antenna = mwifiex_cfg80211_set_antenna, 2414 .set_antenna = mwifiex_cfg80211_set_antenna,
2415#ifdef CONFIG_PM
2416 .suspend = mwifiex_cfg80211_suspend,
2417 .resume = mwifiex_cfg80211_resume,
2418 .set_wakeup = mwifiex_cfg80211_set_wakeup,
2419#endif
2324}; 2420};
2325 2421
2326/* 2422/*
@@ -2379,6 +2475,14 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2379 2475
2380 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom); 2476 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
2381 2477
2478#ifdef CONFIG_PM
2479 wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
2480 wiphy->wowlan.n_patterns = MWIFIEX_MAX_FILTERS;
2481 wiphy->wowlan.pattern_min_len = 1;
2482 wiphy->wowlan.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN;
2483 wiphy->wowlan.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN;
2484#endif
2485
2382 wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | 2486 wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
2383 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | 2487 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
2384 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; 2488 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 20a6c5555873..d19a88c47a4d 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1139,7 +1139,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
1139 phs_cfg->params.hs_config.gpio, 1139 phs_cfg->params.hs_config.gpio,
1140 phs_cfg->params.hs_config.gap); 1140 phs_cfg->params.hs_config.gap);
1141 } 1141 }
1142 if (conditions != HOST_SLEEP_CFG_CANCEL) { 1142 if (conditions != HS_CFG_CANCEL) {
1143 adapter->is_hs_configured = true; 1143 adapter->is_hs_configured = true;
1144 if (adapter->iface_type == MWIFIEX_USB || 1144 if (adapter->iface_type == MWIFIEX_USB ||
1145 adapter->iface_type == MWIFIEX_PCIE) 1145 adapter->iface_type == MWIFIEX_PCIE)
diff --git a/drivers/net/wireless/mwifiex/ethtool.c b/drivers/net/wireless/mwifiex/ethtool.c
new file mode 100644
index 000000000000..bfb39908b2c6
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/ethtool.c
@@ -0,0 +1,70 @@
1/*
2 * Marvell Wireless LAN device driver: ethtool
3 *
4 * Copyright (C) 2013, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "main.h"
21
22static void mwifiex_ethtool_get_wol(struct net_device *dev,
23 struct ethtool_wolinfo *wol)
24{
25 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
26 u32 conditions = le32_to_cpu(priv->adapter->hs_cfg.conditions);
27
28 wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY;
29
30 if (conditions == HS_CFG_COND_DEF)
31 return;
32
33 if (conditions & HS_CFG_COND_UNICAST_DATA)
34 wol->wolopts |= WAKE_UCAST;
35 if (conditions & HS_CFG_COND_MULTICAST_DATA)
36 wol->wolopts |= WAKE_MCAST;
37 if (conditions & HS_CFG_COND_BROADCAST_DATA)
38 wol->wolopts |= WAKE_BCAST;
39 if (conditions & HS_CFG_COND_MAC_EVENT)
40 wol->wolopts |= WAKE_PHY;
41}
42
43static int mwifiex_ethtool_set_wol(struct net_device *dev,
44 struct ethtool_wolinfo *wol)
45{
46 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
47 u32 conditions = 0;
48
49 if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
50 return -EOPNOTSUPP;
51
52 if (wol->wolopts & WAKE_UCAST)
53 conditions |= HS_CFG_COND_UNICAST_DATA;
54 if (wol->wolopts & WAKE_MCAST)
55 conditions |= HS_CFG_COND_MULTICAST_DATA;
56 if (wol->wolopts & WAKE_BCAST)
57 conditions |= HS_CFG_COND_BROADCAST_DATA;
58 if (wol->wolopts & WAKE_PHY)
59 conditions |= HS_CFG_COND_MAC_EVENT;
60 if (wol->wolopts == 0)
61 conditions |= HS_CFG_COND_DEF;
62 priv->adapter->hs_cfg.conditions = cpu_to_le32(conditions);
63
64 return 0;
65}
66
67const struct ethtool_ops mwifiex_ethtool_ops = {
68 .get_wol = mwifiex_ethtool_get_wol,
69 .set_wol = mwifiex_ethtool_set_wol,
70};
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 25acb0682c56..57c5defe1f9d 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -230,40 +230,12 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
230 230
231#define ISSUPP_11ACENABLED(fw_cap_info) (fw_cap_info & (BIT(13)|BIT(14))) 231#define ISSUPP_11ACENABLED(fw_cap_info) (fw_cap_info & (BIT(13)|BIT(14)))
232 232
233#define GET_VHTCAP_MAXMPDULEN(vht_cap_info) (vht_cap_info & 0x3)
234#define GET_VHTCAP_CHWDSET(vht_cap_info) ((vht_cap_info >> 2) & 0x3) 233#define GET_VHTCAP_CHWDSET(vht_cap_info) ((vht_cap_info >> 2) & 0x3)
235#define GET_VHTNSSMCS(mcs_mapset, nss) ((mcs_mapset >> (2 * (nss - 1))) & 0x3) 234#define GET_VHTNSSMCS(mcs_mapset, nss) ((mcs_mapset >> (2 * (nss - 1))) & 0x3)
236#define SET_VHTNSSMCS(mcs_mapset, nss, value) (mcs_mapset |= (value & 0x3) << \ 235#define SET_VHTNSSMCS(mcs_mapset, nss, value) (mcs_mapset |= (value & 0x3) << \
237 (2 * (nss - 1))) 236 (2 * (nss - 1)))
238#define NO_NSS_SUPPORT 0x3 237#define NO_NSS_SUPPORT 0x3
239 238
240/* HW_SPEC: HTC-VHT supported */
241#define ISSUPP_11ACVHTHTCVHT(Dot11acDevCap) (Dot11acDevCap & BIT(22))
242/* HW_SPEC: VHT TXOP PS support */
243#define ISSUPP_11ACVHTTXOPPS(Dot11acDevCap) (Dot11acDevCap & BIT(21))
244/* HW_SPEC: MU RX beamformee support */
245#define ISSUPP_11ACMURXBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(20))
246/* HW_SPEC: MU TX beamformee support */
247#define ISSUPP_11ACMUTXBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(19))
248/* HW_SPEC: SU Beamformee support */
249#define ISSUPP_11ACSUBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(10))
250/* HW_SPEC: SU Beamformer support */
251#define ISSUPP_11ACSUBEAMFORMER(Dot11acDevCap) (Dot11acDevCap & BIT(9))
252/* HW_SPEC: Rx STBC support */
253#define ISSUPP_11ACRXSTBC(Dot11acDevCap) (Dot11acDevCap & BIT(8))
254/* HW_SPEC: Tx STBC support */
255#define ISSUPP_11ACTXSTBC(Dot11acDevCap) (Dot11acDevCap & BIT(7))
256/* HW_SPEC: Short GI support for 160MHz BW */
257#define ISSUPP_11ACSGI160(Dot11acDevCap) (Dot11acDevCap & BIT(6))
258/* HW_SPEC: Short GI support for 80MHz BW */
259#define ISSUPP_11ACSGI80(Dot11acDevCap) (Dot11acDevCap & BIT(5))
260/* HW_SPEC: LDPC coding support */
261#define ISSUPP_11ACLDPC(Dot11acDevCap) (Dot11acDevCap & BIT(4))
262/* HW_SPEC: Channel BW 20/40/80/160/80+80 MHz support */
263#define ISSUPP_11ACBW8080(Dot11acDevCap) (Dot11acDevCap & BIT(3))
264/* HW_SPEC: Channel BW 20/40/80/160 MHz support */
265#define ISSUPP_11ACBW160(Dot11acDevCap) (Dot11acDevCap & BIT(2))
266
267#define GET_DEVTXMCSMAP(dev_mcs_map) (dev_mcs_map >> 16) 239#define GET_DEVTXMCSMAP(dev_mcs_map) (dev_mcs_map >> 16)
268#define GET_DEVRXMCSMAP(dev_mcs_map) (dev_mcs_map & 0xFFFF) 240#define GET_DEVRXMCSMAP(dev_mcs_map) (dev_mcs_map & 0xFFFF)
269 241
@@ -300,6 +272,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
300#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f 272#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f
301#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083 273#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083
302#define HostCmd_CMD_VERSION_EXT 0x0097 274#define HostCmd_CMD_VERSION_EXT 0x0097
275#define HostCmd_CMD_MEF_CFG 0x009a
303#define HostCmd_CMD_RSSI_INFO 0x00a4 276#define HostCmd_CMD_RSSI_INFO 0x00a4
304#define HostCmd_CMD_FUNC_INIT 0x00a9 277#define HostCmd_CMD_FUNC_INIT 0x00a9
305#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa 278#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa
@@ -376,10 +349,14 @@ enum P2P_MODES {
376#define HostCmd_SCAN_RADIO_TYPE_BG 0 349#define HostCmd_SCAN_RADIO_TYPE_BG 0
377#define HostCmd_SCAN_RADIO_TYPE_A 1 350#define HostCmd_SCAN_RADIO_TYPE_A 1
378 351
379#define HOST_SLEEP_CFG_CANCEL 0xffffffff 352#define HS_CFG_CANCEL 0xffffffff
380#define HOST_SLEEP_CFG_COND_DEF 0x00000000 353#define HS_CFG_COND_DEF 0x00000000
381#define HOST_SLEEP_CFG_GPIO_DEF 0xff 354#define HS_CFG_GPIO_DEF 0xff
382#define HOST_SLEEP_CFG_GAP_DEF 0 355#define HS_CFG_GAP_DEF 0
356#define HS_CFG_COND_BROADCAST_DATA 0x00000001
357#define HS_CFG_COND_UNICAST_DATA 0x00000002
358#define HS_CFG_COND_MAC_EVENT 0x00000004
359#define HS_CFG_COND_MULTICAST_DATA 0x00000008
383 360
384#define MWIFIEX_TIMEOUT_FOR_AP_RESP 0xfffc 361#define MWIFIEX_TIMEOUT_FOR_AP_RESP 0xfffc
385#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 362#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2
@@ -469,6 +446,23 @@ enum P2P_MODES {
469#define EVENT_GET_BSS_TYPE(event_cause) \ 446#define EVENT_GET_BSS_TYPE(event_cause) \
470 (((event_cause) >> 24) & 0x00ff) 447 (((event_cause) >> 24) & 0x00ff)
471 448
449#define MWIFIEX_MAX_PATTERN_LEN 20
450#define MWIFIEX_MAX_OFFSET_LEN 50
451#define STACK_NBYTES 100
452#define TYPE_DNUM 1
453#define TYPE_BYTESEQ 2
454#define MAX_OPERAND 0x40
455#define TYPE_EQ (MAX_OPERAND+1)
456#define TYPE_EQ_DNUM (MAX_OPERAND+2)
457#define TYPE_EQ_BIT (MAX_OPERAND+3)
458#define TYPE_AND (MAX_OPERAND+4)
459#define TYPE_OR (MAX_OPERAND+5)
460#define MEF_MODE_HOST_SLEEP 1
461#define MEF_ACTION_ALLOW_AND_WAKEUP_HOST 3
462#define MWIFIEX_CRITERIA_BROADCAST BIT(0)
463#define MWIFIEX_CRITERIA_UNICAST BIT(1)
464#define MWIFIEX_CRITERIA_MULTICAST BIT(3)
465
472struct mwifiex_ie_types_header { 466struct mwifiex_ie_types_header {
473 __le16 type; 467 __le16 type;
474 __le16 len; 468 __le16 len;
@@ -1499,6 +1493,19 @@ struct host_cmd_ds_802_11_ibss_status {
1499 __le16 use_g_rate_protect; 1493 __le16 use_g_rate_protect;
1500} __packed; 1494} __packed;
1501 1495
1496struct mwifiex_fw_mef_entry {
1497 u8 mode;
1498 u8 action;
1499 __le16 exprsize;
1500 u8 expr[0];
1501} __packed;
1502
1503struct host_cmd_ds_mef_cfg {
1504 __le32 criteria;
1505 __le16 num_entries;
1506 struct mwifiex_fw_mef_entry mef_entry[0];
1507} __packed;
1508
1502#define CONNECTION_TYPE_INFRA 0 1509#define CONNECTION_TYPE_INFRA 0
1503#define CONNECTION_TYPE_ADHOC 1 1510#define CONNECTION_TYPE_ADHOC 1
1504#define CONNECTION_TYPE_AP 2 1511#define CONNECTION_TYPE_AP 2
@@ -1603,6 +1610,7 @@ struct host_cmd_ds_command {
1603 struct host_cmd_ds_remain_on_chan roc_cfg; 1610 struct host_cmd_ds_remain_on_chan roc_cfg;
1604 struct host_cmd_ds_p2p_mode_cfg mode_cfg; 1611 struct host_cmd_ds_p2p_mode_cfg mode_cfg;
1605 struct host_cmd_ds_802_11_ibss_status ibss_coalescing; 1612 struct host_cmd_ds_802_11_ibss_status ibss_coalescing;
1613 struct host_cmd_ds_mef_cfg mef_cfg;
1606 struct host_cmd_ds_mac_reg_access mac_reg; 1614 struct host_cmd_ds_mac_reg_access mac_reg;
1607 struct host_cmd_ds_bbp_reg_access bbp_reg; 1615 struct host_cmd_ds_bbp_reg_access bbp_reg;
1608 struct host_cmd_ds_rf_reg_access rf_reg; 1616 struct host_cmd_ds_rf_reg_access rf_reg;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index e38aa9b3663d..cab3434d0d52 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -318,9 +318,9 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
318 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; 318 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
319 319
320 adapter->is_hs_configured = false; 320 adapter->is_hs_configured = false;
321 adapter->hs_cfg.conditions = cpu_to_le32(HOST_SLEEP_CFG_COND_DEF); 321 adapter->hs_cfg.conditions = cpu_to_le32(HS_CFG_COND_DEF);
322 adapter->hs_cfg.gpio = HOST_SLEEP_CFG_GPIO_DEF; 322 adapter->hs_cfg.gpio = HS_CFG_GPIO_DEF;
323 adapter->hs_cfg.gap = HOST_SLEEP_CFG_GAP_DEF; 323 adapter->hs_cfg.gap = HS_CFG_GAP_DEF;
324 adapter->hs_activated = false; 324 adapter->hs_activated = false;
325 325
326 memset(adapter->event_body, 0, sizeof(adapter->event_body)); 326 memset(adapter->event_body, 0, sizeof(adapter->event_body));
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index d85e6eb1f58a..91d522c746ed 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -354,6 +354,29 @@ struct mwifiex_ds_misc_subsc_evt {
354 struct subsc_evt_cfg bcn_h_rssi_cfg; 354 struct subsc_evt_cfg bcn_h_rssi_cfg;
355}; 355};
356 356
357#define MAX_BYTESEQ 6 /* non-adjustable */
358#define MWIFIEX_MAX_FILTERS 10
359
360struct mwifiex_mef_filter {
361 u16 repeat;
362 u16 offset;
363 s8 byte_seq[MAX_BYTESEQ + 1];
364 u8 filt_type;
365 u8 filt_action;
366};
367
368struct mwifiex_mef_entry {
369 u8 mode;
370 u8 action;
371 struct mwifiex_mef_filter filter[MWIFIEX_MAX_FILTERS];
372};
373
374struct mwifiex_ds_mef_cfg {
375 u32 criteria;
376 u16 num_entries;
377 struct mwifiex_mef_entry *mef_entry;
378};
379
357#define MWIFIEX_MAX_VSIE_LEN (256) 380#define MWIFIEX_MAX_VSIE_LEN (256)
358#define MWIFIEX_MAX_VSIE_NUM (8) 381#define MWIFIEX_MAX_VSIE_NUM (8)
359#define MWIFIEX_VSIE_MASK_CLEAR 0x00 382#define MWIFIEX_VSIE_MASK_CLEAR 0x00
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 9c802ede9c3b..121443a0f2a1 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -588,10 +588,19 @@ mwifiex_tx_timeout(struct net_device *dev)
588{ 588{
589 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 589 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
590 590
591 dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n",
592 jiffies, priv->bss_type, priv->bss_num);
593 mwifiex_set_trans_start(dev);
594 priv->num_tx_timeout++; 591 priv->num_tx_timeout++;
592 priv->tx_timeout_cnt++;
593 dev_err(priv->adapter->dev,
594 "%lu : Tx timeout(#%d), bss_type-num = %d-%d\n",
595 jiffies, priv->tx_timeout_cnt, priv->bss_type, priv->bss_num);
596 mwifiex_set_trans_start(dev);
597
598 if (priv->tx_timeout_cnt > TX_TIMEOUT_THRESHOLD &&
599 priv->adapter->if_ops.card_reset) {
600 dev_err(priv->adapter->dev,
601 "tx_timeout_cnt exceeds threshold. Triggering card reset!\n");
602 priv->adapter->if_ops.card_reset(priv->adapter);
603 }
595} 604}
596 605
597/* 606/*
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 553adfb0aa81..920657587fff 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -130,6 +130,9 @@ enum {
130#define MWIFIEX_USB_TYPE_DATA 0xBEADC0DE 130#define MWIFIEX_USB_TYPE_DATA 0xBEADC0DE
131#define MWIFIEX_USB_TYPE_EVENT 0xBEEFFACE 131#define MWIFIEX_USB_TYPE_EVENT 0xBEEFFACE
132 132
133/* Threshold for tx_timeout_cnt before we trigger a card reset */
134#define TX_TIMEOUT_THRESHOLD 6
135
133struct mwifiex_dbg { 136struct mwifiex_dbg {
134 u32 num_cmd_host_to_card_failure; 137 u32 num_cmd_host_to_card_failure;
135 u32 num_cmd_sleep_cfm_host_to_card_failure; 138 u32 num_cmd_sleep_cfm_host_to_card_failure;
@@ -394,6 +397,8 @@ struct mwifiex_private {
394 u8 curr_addr[ETH_ALEN]; 397 u8 curr_addr[ETH_ALEN];
395 u8 media_connected; 398 u8 media_connected;
396 u32 num_tx_timeout; 399 u32 num_tx_timeout;
400 /* track consecutive timeout */
401 u8 tx_timeout_cnt;
397 struct net_device *netdev; 402 struct net_device *netdev;
398 struct net_device_stats stats; 403 struct net_device_stats stats;
399 u16 curr_pkt_filter; 404 u16 curr_pkt_filter;
@@ -1098,11 +1103,15 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev);
1098 1103
1099void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config); 1104void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config);
1100 1105
1106int mwifiex_add_wowlan_magic_pkt_filter(struct mwifiex_adapter *adapter);
1107
1101int mwifiex_set_mgmt_ies(struct mwifiex_private *priv, 1108int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
1102 struct cfg80211_beacon_data *data); 1109 struct cfg80211_beacon_data *data);
1103int mwifiex_del_mgmt_ies(struct mwifiex_private *priv); 1110int mwifiex_del_mgmt_ies(struct mwifiex_private *priv);
1104u8 *mwifiex_11d_code_2_region(u8 code); 1111u8 *mwifiex_11d_code_2_region(u8 code);
1105 1112
1113extern const struct ethtool_ops mwifiex_ethtool_ops;
1114
1106#ifdef CONFIG_DEBUG_FS 1115#ifdef CONFIG_DEBUG_FS
1107void mwifiex_debugfs_init(void); 1116void mwifiex_debugfs_init(void);
1108void mwifiex_debugfs_remove(void); 1117void mwifiex_debugfs_remove(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 5c395e2e6a2b..6283294398bf 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -36,8 +36,6 @@ static u8 user_rmmod;
36static struct mwifiex_if_ops pcie_ops; 36static struct mwifiex_if_ops pcie_ops;
37 37
38static struct semaphore add_remove_card_sem; 38static struct semaphore add_remove_card_sem;
39static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter);
40static int mwifiex_pcie_resume(struct pci_dev *pdev);
41 39
42static int 40static int
43mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, 41mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
@@ -78,6 +76,82 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
78 return false; 76 return false;
79} 77}
80 78
79#ifdef CONFIG_PM
80/*
81 * Kernel needs to suspend all functions separately. Therefore all
82 * registered functions must have drivers with suspend and resume
83 * methods. Failing that the kernel simply removes the whole card.
84 *
85 * If already not suspended, this function allocates and sends a host
86 * sleep activate request to the firmware and turns off the traffic.
87 */
88static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
89{
90 struct mwifiex_adapter *adapter;
91 struct pcie_service_card *card;
92 int hs_actived;
93
94 if (pdev) {
95 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
96 if (!card || !card->adapter) {
97 pr_err("Card or adapter structure is not valid\n");
98 return 0;
99 }
100 } else {
101 pr_err("PCIE device is not specified\n");
102 return 0;
103 }
104
105 adapter = card->adapter;
106
107 hs_actived = mwifiex_enable_hs(adapter);
108
109 /* Indicate device suspended */
110 adapter->is_suspended = true;
111
112 return 0;
113}
114
115/*
116 * Kernel needs to suspend all functions separately. Therefore all
117 * registered functions must have drivers with suspend and resume
118 * methods. Failing that the kernel simply removes the whole card.
119 *
120 * If already not resumed, this function turns on the traffic and
121 * sends a host sleep cancel request to the firmware.
122 */
123static int mwifiex_pcie_resume(struct pci_dev *pdev)
124{
125 struct mwifiex_adapter *adapter;
126 struct pcie_service_card *card;
127
128 if (pdev) {
129 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
130 if (!card || !card->adapter) {
131 pr_err("Card or adapter structure is not valid\n");
132 return 0;
133 }
134 } else {
135 pr_err("PCIE device is not specified\n");
136 return 0;
137 }
138
139 adapter = card->adapter;
140
141 if (!adapter->is_suspended) {
142 dev_warn(adapter->dev, "Device already resumed\n");
143 return 0;
144 }
145
146 adapter->is_suspended = false;
147
148 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
149 MWIFIEX_ASYNC_CMD);
150
151 return 0;
152}
153#endif
154
81/* 155/*
82 * This function probes an mwifiex device and registers it. It allocates 156 * This function probes an mwifiex device and registers it. It allocates
83 * the card structure, enables PCIE function number and initiates the 157 * the card structure, enables PCIE function number and initiates the
@@ -159,80 +233,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
159 kfree(card); 233 kfree(card);
160} 234}
161 235
162/*
163 * Kernel needs to suspend all functions separately. Therefore all
164 * registered functions must have drivers with suspend and resume
165 * methods. Failing that the kernel simply removes the whole card.
166 *
167 * If already not suspended, this function allocates and sends a host
168 * sleep activate request to the firmware and turns off the traffic.
169 */
170static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
171{
172 struct mwifiex_adapter *adapter;
173 struct pcie_service_card *card;
174 int hs_actived;
175
176 if (pdev) {
177 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
178 if (!card || !card->adapter) {
179 pr_err("Card or adapter structure is not valid\n");
180 return 0;
181 }
182 } else {
183 pr_err("PCIE device is not specified\n");
184 return 0;
185 }
186
187 adapter = card->adapter;
188
189 hs_actived = mwifiex_enable_hs(adapter);
190
191 /* Indicate device suspended */
192 adapter->is_suspended = true;
193
194 return 0;
195}
196
197/*
198 * Kernel needs to suspend all functions separately. Therefore all
199 * registered functions must have drivers with suspend and resume
200 * methods. Failing that the kernel simply removes the whole card.
201 *
202 * If already not resumed, this function turns on the traffic and
203 * sends a host sleep cancel request to the firmware.
204 */
205static int mwifiex_pcie_resume(struct pci_dev *pdev)
206{
207 struct mwifiex_adapter *adapter;
208 struct pcie_service_card *card;
209
210 if (pdev) {
211 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
212 if (!card || !card->adapter) {
213 pr_err("Card or adapter structure is not valid\n");
214 return 0;
215 }
216 } else {
217 pr_err("PCIE device is not specified\n");
218 return 0;
219 }
220
221 adapter = card->adapter;
222
223 if (!adapter->is_suspended) {
224 dev_warn(adapter->dev, "Device already resumed\n");
225 return 0;
226 }
227
228 adapter->is_suspended = false;
229
230 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
231 MWIFIEX_ASYNC_CMD);
232
233 return 0;
234}
235
236static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = { 236static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
237 { 237 {
238 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P, 238 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
@@ -1030,8 +1030,8 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1030 u32 wrindx, num_tx_buffs, rx_val; 1030 u32 wrindx, num_tx_buffs, rx_val;
1031 int ret; 1031 int ret;
1032 dma_addr_t buf_pa; 1032 dma_addr_t buf_pa;
1033 struct mwifiex_pcie_buf_desc *desc; 1033 struct mwifiex_pcie_buf_desc *desc = NULL;
1034 struct mwifiex_pfu_buf_desc *desc2; 1034 struct mwifiex_pfu_buf_desc *desc2 = NULL;
1035 __le16 *tmp; 1035 __le16 *tmp;
1036 1036
1037 if (!(skb->data && skb->len)) { 1037 if (!(skb->data && skb->len)) {
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index c55c5bb93134..a2ae690a0a67 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -334,7 +334,7 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv,
334 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); 334 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
335 335
336 if (!hs_activate && 336 if (!hs_activate &&
337 (hscfg_param->conditions != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) && 337 (hscfg_param->conditions != cpu_to_le32(HS_CFG_CANCEL)) &&
338 ((adapter->arp_filter_size > 0) && 338 ((adapter->arp_filter_size > 0) &&
339 (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { 339 (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
340 dev_dbg(adapter->dev, 340 dev_dbg(adapter->dev,
@@ -1059,6 +1059,80 @@ mwifiex_cmd_802_11_subsc_evt(struct mwifiex_private *priv,
1059 return 0; 1059 return 0;
1060} 1060}
1061 1061
1062static int
1063mwifiex_cmd_append_rpn_expression(struct mwifiex_private *priv,
1064 struct mwifiex_mef_entry *mef_entry,
1065 u8 **buffer)
1066{
1067 struct mwifiex_mef_filter *filter = mef_entry->filter;
1068 int i, byte_len;
1069 u8 *stack_ptr = *buffer;
1070
1071 for (i = 0; i < MWIFIEX_MAX_FILTERS; i++) {
1072 filter = &mef_entry->filter[i];
1073 if (!filter->filt_type)
1074 break;
1075 *(__le32 *)stack_ptr = cpu_to_le32((u32)filter->repeat);
1076 stack_ptr += 4;
1077 *stack_ptr = TYPE_DNUM;
1078 stack_ptr += 1;
1079
1080 byte_len = filter->byte_seq[MAX_BYTESEQ];
1081 memcpy(stack_ptr, filter->byte_seq, byte_len);
1082 stack_ptr += byte_len;
1083 *stack_ptr = byte_len;
1084 stack_ptr += 1;
1085 *stack_ptr = TYPE_BYTESEQ;
1086 stack_ptr += 1;
1087
1088 *(__le32 *)stack_ptr = cpu_to_le32((u32)filter->offset);
1089 stack_ptr += 4;
1090 *stack_ptr = TYPE_DNUM;
1091 stack_ptr += 1;
1092
1093 *stack_ptr = filter->filt_type;
1094 stack_ptr += 1;
1095
1096 if (filter->filt_action) {
1097 *stack_ptr = filter->filt_action;
1098 stack_ptr += 1;
1099 }
1100
1101 if (stack_ptr - *buffer > STACK_NBYTES)
1102 return -1;
1103 }
1104
1105 *buffer = stack_ptr;
1106 return 0;
1107}
1108
1109static int
1110mwifiex_cmd_mef_cfg(struct mwifiex_private *priv,
1111 struct host_cmd_ds_command *cmd,
1112 struct mwifiex_ds_mef_cfg *mef)
1113{
1114 struct host_cmd_ds_mef_cfg *mef_cfg = &cmd->params.mef_cfg;
1115 u8 *pos = (u8 *)mef_cfg;
1116
1117 cmd->command = cpu_to_le16(HostCmd_CMD_MEF_CFG);
1118
1119 mef_cfg->criteria = cpu_to_le32(mef->criteria);
1120 mef_cfg->num_entries = cpu_to_le16(mef->num_entries);
1121 pos += sizeof(*mef_cfg);
1122 mef_cfg->mef_entry->mode = mef->mef_entry->mode;
1123 mef_cfg->mef_entry->action = mef->mef_entry->action;
1124 pos += sizeof(*(mef_cfg->mef_entry));
1125
1126 if (mwifiex_cmd_append_rpn_expression(priv, mef->mef_entry, &pos))
1127 return -1;
1128
1129 mef_cfg->mef_entry->exprsize =
1130 cpu_to_le16(pos - mef_cfg->mef_entry->expr);
1131 cmd->size = cpu_to_le16((u16) (pos - (u8 *)mef_cfg) + S_DS_GEN);
1132
1133 return 0;
1134}
1135
1062/* 1136/*
1063 * This function prepares the commands before sending them to the firmware. 1137 * This function prepares the commands before sending them to the firmware.
1064 * 1138 *
@@ -1273,6 +1347,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1273 case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: 1347 case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
1274 ret = mwifiex_cmd_802_11_subsc_evt(priv, cmd_ptr, data_buf); 1348 ret = mwifiex_cmd_802_11_subsc_evt(priv, cmd_ptr, data_buf);
1275 break; 1349 break;
1350 case HostCmd_CMD_MEF_CFG:
1351 ret = mwifiex_cmd_mef_cfg(priv, cmd_ptr, data_buf);
1352 break;
1276 default: 1353 default:
1277 dev_err(priv->adapter->dev, 1354 dev_err(priv->adapter->dev,
1278 "PREP_CMD: unknown cmd- %#x\n", cmd_no); 1355 "PREP_CMD: unknown cmd- %#x\n", cmd_no);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 4669f8d9389f..80b9f2238001 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -976,6 +976,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
976 case HostCmd_CMD_UAP_BSS_STOP: 976 case HostCmd_CMD_UAP_BSS_STOP:
977 priv->bss_started = 0; 977 priv->bss_started = 0;
978 break; 978 break;
979 case HostCmd_CMD_MEF_CFG:
980 break;
979 default: 981 default:
980 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", 982 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
981 resp->command); 983 resp->command);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 9f33c92c90f5..76d31deb7b1b 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -388,7 +388,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
388 break; 388 break;
389 } 389 }
390 if (hs_cfg->is_invoke_hostcmd) { 390 if (hs_cfg->is_invoke_hostcmd) {
391 if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) { 391 if (hs_cfg->conditions == HS_CFG_CANCEL) {
392 if (!adapter->is_hs_configured) 392 if (!adapter->is_hs_configured)
393 /* Already cancelled */ 393 /* Already cancelled */
394 break; 394 break;
@@ -403,8 +403,8 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
403 adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; 403 adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
404 if (hs_cfg->gap) 404 if (hs_cfg->gap)
405 adapter->hs_cfg.gap = (u8)hs_cfg->gap; 405 adapter->hs_cfg.gap = (u8)hs_cfg->gap;
406 } else if (adapter->hs_cfg.conditions 406 } else if (adapter->hs_cfg.conditions ==
407 == cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) { 407 cpu_to_le32(HS_CFG_CANCEL)) {
408 /* Return failure if no parameters for HS 408 /* Return failure if no parameters for HS
409 enable */ 409 enable */
410 status = -1; 410 status = -1;
@@ -420,7 +420,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
420 HostCmd_CMD_802_11_HS_CFG_ENH, 420 HostCmd_CMD_802_11_HS_CFG_ENH,
421 HostCmd_ACT_GEN_SET, 0, 421 HostCmd_ACT_GEN_SET, 0,
422 &adapter->hs_cfg); 422 &adapter->hs_cfg);
423 if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) 423 if (hs_cfg->conditions == HS_CFG_CANCEL)
424 /* Restore previous condition */ 424 /* Restore previous condition */
425 adapter->hs_cfg.conditions = 425 adapter->hs_cfg.conditions =
426 cpu_to_le32(prev_cond); 426 cpu_to_le32(prev_cond);
@@ -454,7 +454,7 @@ int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type)
454{ 454{
455 struct mwifiex_ds_hs_cfg hscfg; 455 struct mwifiex_ds_hs_cfg hscfg;
456 456
457 hscfg.conditions = HOST_SLEEP_CFG_CANCEL; 457 hscfg.conditions = HS_CFG_CANCEL;
458 hscfg.is_invoke_hostcmd = true; 458 hscfg.is_invoke_hostcmd = true;
459 459
460 return mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, 460 return mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 296faec14365..8f923d0d2ba6 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -169,6 +169,8 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
169 if (!status) { 169 if (!status) {
170 priv->stats.tx_packets++; 170 priv->stats.tx_packets++;
171 priv->stats.tx_bytes += skb->len; 171 priv->stats.tx_bytes += skb->len;
172 if (priv->tx_timeout_cnt)
173 priv->tx_timeout_cnt = 0;
172 } else { 174 } else {
173 priv->stats.tx_errors++; 175 priv->stats.tx_errors++;
174 } 176 }
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 21553976b550..54667e65ca47 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -195,7 +195,7 @@ int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb)
195 skb->protocol = eth_type_trans(skb, priv->netdev); 195 skb->protocol = eth_type_trans(skb, priv->netdev);
196 skb->ip_summed = CHECKSUM_NONE; 196 skb->ip_summed = CHECKSUM_NONE;
197 197
198 /* This is required only in case of 11n and USB as we alloc 198 /* This is required only in case of 11n and USB/PCIE as we alloc
199 * a buffer of 4K only if its 11N (to be able to receive 4K 199 * a buffer of 4K only if its 11N (to be able to receive 4K
200 * AMSDU packets). In case of SD we allocate buffers based 200 * AMSDU packets). In case of SD we allocate buffers based
201 * on the size of packet and hence this is not needed. 201 * on the size of packet and hence this is not needed.
@@ -212,7 +212,8 @@ int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb)
212 * fragments. Currently we fail the Filesndl-ht.scr script 212 * fragments. Currently we fail the Filesndl-ht.scr script
213 * for UDP, hence this fix 213 * for UDP, hence this fix
214 */ 214 */
215 if ((priv->adapter->iface_type == MWIFIEX_USB) && 215 if ((priv->adapter->iface_type == MWIFIEX_USB ||
216 priv->adapter->iface_type == MWIFIEX_PCIE) &&
216 (skb->truesize > MWIFIEX_RX_DATA_BUF_SIZE)) 217 (skb->truesize > MWIFIEX_RX_DATA_BUF_SIZE))
217 skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE); 218 skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE);
218 219
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 091d9a64080a..0640e7d7f0c2 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -232,6 +232,7 @@ struct mwl8k_priv {
232 u16 num_mcaddrs; 232 u16 num_mcaddrs;
233 u8 hw_rev; 233 u8 hw_rev;
234 u32 fw_rev; 234 u32 fw_rev;
235 u32 caps;
235 236
236 /* 237 /*
237 * Running count of TX packets in flight, to avoid 238 * Running count of TX packets in flight, to avoid
@@ -284,6 +285,7 @@ struct mwl8k_priv {
284 unsigned fw_state; 285 unsigned fw_state;
285 char *fw_pref; 286 char *fw_pref;
286 char *fw_alt; 287 char *fw_alt;
288 bool is_8764;
287 struct completion firmware_loading_complete; 289 struct completion firmware_loading_complete;
288 290
289 /* bitmap of running BSSes */ 291 /* bitmap of running BSSes */
@@ -600,13 +602,18 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
600 loops = 1000; 602 loops = 1000;
601 do { 603 do {
602 u32 int_code; 604 u32 int_code;
603 605 if (priv->is_8764) {
604 int_code = ioread32(regs + MWL8K_HIU_INT_CODE); 606 int_code = ioread32(regs +
605 if (int_code == MWL8K_INT_CODE_CMD_FINISHED) { 607 MWL8K_HIU_H2A_INTERRUPT_STATUS);
606 iowrite32(0, regs + MWL8K_HIU_INT_CODE); 608 if (int_code == 0)
607 break; 609 break;
610 } else {
611 int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
612 if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
613 iowrite32(0, regs + MWL8K_HIU_INT_CODE);
614 break;
615 }
608 } 616 }
609
610 cond_resched(); 617 cond_resched();
611 udelay(1); 618 udelay(1);
612 } while (--loops); 619 } while (--loops);
@@ -724,7 +731,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw)
724 int rc; 731 int rc;
725 int loops; 732 int loops;
726 733
727 if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) { 734 if (!memcmp(fw->data, "\x01\x00\x00\x00", 4) && !priv->is_8764) {
728 const struct firmware *helper = priv->fw_helper; 735 const struct firmware *helper = priv->fw_helper;
729 736
730 if (helper == NULL) { 737 if (helper == NULL) {
@@ -743,7 +750,10 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw)
743 750
744 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); 751 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
745 } else { 752 } else {
746 rc = mwl8k_load_fw_image(priv, fw->data, fw->size); 753 if (priv->is_8764)
754 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
755 else
756 rc = mwl8k_load_fw_image(priv, fw->data, fw->size);
747 } 757 }
748 758
749 if (rc) { 759 if (rc) {
@@ -908,9 +918,9 @@ static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
908} 918}
909 919
910/* 920/*
911 * Packet reception for 88w8366 AP firmware. 921 * Packet reception for 88w8366/88w8764 AP firmware.
912 */ 922 */
913struct mwl8k_rxd_8366_ap { 923struct mwl8k_rxd_ap {
914 __le16 pkt_len; 924 __le16 pkt_len;
915 __u8 sq2; 925 __u8 sq2;
916 __u8 rate; 926 __u8 rate;
@@ -928,30 +938,30 @@ struct mwl8k_rxd_8366_ap {
928 __u8 rx_ctrl; 938 __u8 rx_ctrl;
929} __packed; 939} __packed;
930 940
931#define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT 0x80 941#define MWL8K_AP_RATE_INFO_MCS_FORMAT 0x80
932#define MWL8K_8366_AP_RATE_INFO_40MHZ 0x40 942#define MWL8K_AP_RATE_INFO_40MHZ 0x40
933#define MWL8K_8366_AP_RATE_INFO_RATEID(x) ((x) & 0x3f) 943#define MWL8K_AP_RATE_INFO_RATEID(x) ((x) & 0x3f)
934 944
935#define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST 0x80 945#define MWL8K_AP_RX_CTRL_OWNED_BY_HOST 0x80
936 946
937/* 8366 AP rx_status bits */ 947/* 8366/8764 AP rx_status bits */
938#define MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK 0x80 948#define MWL8K_AP_RXSTAT_DECRYPT_ERR_MASK 0x80
939#define MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR 0xFF 949#define MWL8K_AP_RXSTAT_GENERAL_DECRYPT_ERR 0xFF
940#define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR 0x02 950#define MWL8K_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR 0x02
941#define MWL8K_8366_AP_RXSTAT_WEP_DECRYPT_ICV_ERR 0x04 951#define MWL8K_AP_RXSTAT_WEP_DECRYPT_ICV_ERR 0x04
942#define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_ICV_ERR 0x08 952#define MWL8K_AP_RXSTAT_TKIP_DECRYPT_ICV_ERR 0x08
943 953
944static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr) 954static void mwl8k_rxd_ap_init(void *_rxd, dma_addr_t next_dma_addr)
945{ 955{
946 struct mwl8k_rxd_8366_ap *rxd = _rxd; 956 struct mwl8k_rxd_ap *rxd = _rxd;
947 957
948 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); 958 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
949 rxd->rx_ctrl = MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST; 959 rxd->rx_ctrl = MWL8K_AP_RX_CTRL_OWNED_BY_HOST;
950} 960}
951 961
952static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len) 962static void mwl8k_rxd_ap_refill(void *_rxd, dma_addr_t addr, int len)
953{ 963{
954 struct mwl8k_rxd_8366_ap *rxd = _rxd; 964 struct mwl8k_rxd_ap *rxd = _rxd;
955 965
956 rxd->pkt_len = cpu_to_le16(len); 966 rxd->pkt_len = cpu_to_le16(len);
957 rxd->pkt_phys_addr = cpu_to_le32(addr); 967 rxd->pkt_phys_addr = cpu_to_le32(addr);
@@ -960,12 +970,12 @@ static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len)
960} 970}
961 971
962static int 972static int
963mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, 973mwl8k_rxd_ap_process(void *_rxd, struct ieee80211_rx_status *status,
964 __le16 *qos, s8 *noise) 974 __le16 *qos, s8 *noise)
965{ 975{
966 struct mwl8k_rxd_8366_ap *rxd = _rxd; 976 struct mwl8k_rxd_ap *rxd = _rxd;
967 977
968 if (!(rxd->rx_ctrl & MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST)) 978 if (!(rxd->rx_ctrl & MWL8K_AP_RX_CTRL_OWNED_BY_HOST))
969 return -1; 979 return -1;
970 rmb(); 980 rmb();
971 981
@@ -974,11 +984,11 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
974 status->signal = -rxd->rssi; 984 status->signal = -rxd->rssi;
975 *noise = -rxd->noise_floor; 985 *noise = -rxd->noise_floor;
976 986
977 if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { 987 if (rxd->rate & MWL8K_AP_RATE_INFO_MCS_FORMAT) {
978 status->flag |= RX_FLAG_HT; 988 status->flag |= RX_FLAG_HT;
979 if (rxd->rate & MWL8K_8366_AP_RATE_INFO_40MHZ) 989 if (rxd->rate & MWL8K_AP_RATE_INFO_40MHZ)
980 status->flag |= RX_FLAG_40MHZ; 990 status->flag |= RX_FLAG_40MHZ;
981 status->rate_idx = MWL8K_8366_AP_RATE_INFO_RATEID(rxd->rate); 991 status->rate_idx = MWL8K_AP_RATE_INFO_RATEID(rxd->rate);
982 } else { 992 } else {
983 int i; 993 int i;
984 994
@@ -1002,19 +1012,19 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
1002 1012
1003 *qos = rxd->qos_control; 1013 *qos = rxd->qos_control;
1004 1014
1005 if ((rxd->rx_status != MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR) && 1015 if ((rxd->rx_status != MWL8K_AP_RXSTAT_GENERAL_DECRYPT_ERR) &&
1006 (rxd->rx_status & MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK) && 1016 (rxd->rx_status & MWL8K_AP_RXSTAT_DECRYPT_ERR_MASK) &&
1007 (rxd->rx_status & MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR)) 1017 (rxd->rx_status & MWL8K_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR))
1008 status->flag |= RX_FLAG_MMIC_ERROR; 1018 status->flag |= RX_FLAG_MMIC_ERROR;
1009 1019
1010 return le16_to_cpu(rxd->pkt_len); 1020 return le16_to_cpu(rxd->pkt_len);
1011} 1021}
1012 1022
1013static struct rxd_ops rxd_8366_ap_ops = { 1023static struct rxd_ops rxd_ap_ops = {
1014 .rxd_size = sizeof(struct mwl8k_rxd_8366_ap), 1024 .rxd_size = sizeof(struct mwl8k_rxd_ap),
1015 .rxd_init = mwl8k_rxd_8366_ap_init, 1025 .rxd_init = mwl8k_rxd_ap_init,
1016 .rxd_refill = mwl8k_rxd_8366_ap_refill, 1026 .rxd_refill = mwl8k_rxd_ap_refill,
1017 .rxd_process = mwl8k_rxd_8366_ap_process, 1027 .rxd_process = mwl8k_rxd_ap_process,
1018}; 1028};
1019 1029
1020/* 1030/*
@@ -2401,6 +2411,9 @@ mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps)
2401{ 2411{
2402 struct mwl8k_priv *priv = hw->priv; 2412 struct mwl8k_priv *priv = hw->priv;
2403 2413
2414 if (priv->caps)
2415 return;
2416
2404 if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) { 2417 if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) {
2405 mwl8k_setup_2ghz_band(hw); 2418 mwl8k_setup_2ghz_band(hw);
2406 if (caps & MWL8K_CAP_MIMO) 2419 if (caps & MWL8K_CAP_MIMO)
@@ -2412,6 +2425,8 @@ mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps)
2412 if (caps & MWL8K_CAP_MIMO) 2425 if (caps & MWL8K_CAP_MIMO)
2413 mwl8k_set_ht_caps(hw, &priv->band_50, caps); 2426 mwl8k_set_ht_caps(hw, &priv->band_50, caps);
2414 } 2427 }
2428
2429 priv->caps = caps;
2415} 2430}
2416 2431
2417static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw) 2432static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
@@ -5429,12 +5444,17 @@ enum {
5429 MWL8363 = 0, 5444 MWL8363 = 0,
5430 MWL8687, 5445 MWL8687,
5431 MWL8366, 5446 MWL8366,
5447 MWL8764,
5432}; 5448};
5433 5449
5434#define MWL8K_8366_AP_FW_API 3 5450#define MWL8K_8366_AP_FW_API 3
5435#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" 5451#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
5436#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) 5452#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
5437 5453
5454#define MWL8K_8764_AP_FW_API 1
5455#define _MWL8K_8764_AP_FW(api) "mwl8k/fmimage_8764_ap-" #api ".fw"
5456#define MWL8K_8764_AP_FW(api) _MWL8K_8764_AP_FW(api)
5457
5438static struct mwl8k_device_info mwl8k_info_tbl[] = { 5458static struct mwl8k_device_info mwl8k_info_tbl[] = {
5439 [MWL8363] = { 5459 [MWL8363] = {
5440 .part_name = "88w8363", 5460 .part_name = "88w8363",
@@ -5452,7 +5472,13 @@ static struct mwl8k_device_info mwl8k_info_tbl[] = {
5452 .fw_image_sta = "mwl8k/fmimage_8366.fw", 5472 .fw_image_sta = "mwl8k/fmimage_8366.fw",
5453 .fw_image_ap = MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API), 5473 .fw_image_ap = MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API),
5454 .fw_api_ap = MWL8K_8366_AP_FW_API, 5474 .fw_api_ap = MWL8K_8366_AP_FW_API,
5455 .ap_rxd_ops = &rxd_8366_ap_ops, 5475 .ap_rxd_ops = &rxd_ap_ops,
5476 },
5477 [MWL8764] = {
5478 .part_name = "88w8764",
5479 .fw_image_ap = MWL8K_8764_AP_FW(MWL8K_8764_AP_FW_API),
5480 .fw_api_ap = MWL8K_8764_AP_FW_API,
5481 .ap_rxd_ops = &rxd_ap_ops,
5456 }, 5482 },
5457}; 5483};
5458 5484
@@ -5474,6 +5500,7 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
5474 { PCI_VDEVICE(MARVELL, 0x2a41), .driver_data = MWL8366, }, 5500 { PCI_VDEVICE(MARVELL, 0x2a41), .driver_data = MWL8366, },
5475 { PCI_VDEVICE(MARVELL, 0x2a42), .driver_data = MWL8366, }, 5501 { PCI_VDEVICE(MARVELL, 0x2a42), .driver_data = MWL8366, },
5476 { PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, }, 5502 { PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, },
5503 { PCI_VDEVICE(MARVELL, 0x2b36), .driver_data = MWL8764, },
5477 { }, 5504 { },
5478}; 5505};
5479MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); 5506MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
@@ -5995,6 +6022,8 @@ static int mwl8k_probe(struct pci_dev *pdev,
5995 priv->pdev = pdev; 6022 priv->pdev = pdev;
5996 priv->device_info = &mwl8k_info_tbl[id->driver_data]; 6023 priv->device_info = &mwl8k_info_tbl[id->driver_data];
5997 6024
6025 if (id->driver_data == MWL8764)
6026 priv->is_8764 = true;
5998 6027
5999 priv->sram = pci_iomap(pdev, 0, 0x10000); 6028 priv->sram = pci_iomap(pdev, 0, 0x10000);
6000 if (priv->sram == NULL) { 6029 if (priv->sram == NULL) {
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index 7744f42de1ea..1f9cb55c3360 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -1584,7 +1584,7 @@ static int ezusb_probe(struct usb_interface *interface,
1584 struct ezusb_priv *upriv = NULL; 1584 struct ezusb_priv *upriv = NULL;
1585 struct usb_interface_descriptor *iface_desc; 1585 struct usb_interface_descriptor *iface_desc;
1586 struct usb_endpoint_descriptor *ep; 1586 struct usb_endpoint_descriptor *ep;
1587 const struct firmware *fw_entry; 1587 const struct firmware *fw_entry = NULL;
1588 int retval = 0; 1588 int retval = 0;
1589 int i; 1589 int i;
1590 1590
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 3109c0db66e1..4775b5d172d5 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -144,7 +144,7 @@ static int psm;
144static char *essid; 144static char *essid;
145 145
146/* Default to encapsulation unless translation requested */ 146/* Default to encapsulation unless translation requested */
147static int translate = 1; 147static bool translate = 1;
148 148
149static int country = USA; 149static int country = USA;
150 150
@@ -178,7 +178,7 @@ module_param(hop_dwell, int, 0);
178module_param(beacon_period, int, 0); 178module_param(beacon_period, int, 0);
179module_param(psm, int, 0); 179module_param(psm, int, 0);
180module_param(essid, charp, 0); 180module_param(essid, charp, 0);
181module_param(translate, int, 0); 181module_param(translate, bool, 0);
182module_param(country, int, 0); 182module_param(country, int, 0);
183module_param(sniffer, int, 0); 183module_param(sniffer, int, 0);
184module_param(bc, int, 0); 184module_param(bc, int, 0);
@@ -1353,7 +1353,7 @@ static int ray_get_range(struct net_device *dev, struct iw_request_info *info,
1353static int ray_set_framing(struct net_device *dev, struct iw_request_info *info, 1353static int ray_set_framing(struct net_device *dev, struct iw_request_info *info,
1354 union iwreq_data *wrqu, char *extra) 1354 union iwreq_data *wrqu, char *extra)
1355{ 1355{
1356 translate = *(extra); /* Set framing mode */ 1356 translate = !!*(extra); /* Set framing mode */
1357 1357
1358 return 0; 1358 return 0;
1359} 1359}
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 525fd7521dff..8169a85c4498 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2,7 +2,7 @@
2 * Driver for RNDIS based wireless USB devices. 2 * Driver for RNDIS based wireless USB devices.
3 * 3 *
4 * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net> 4 * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net>
5 * Copyright (C) 2008-2009 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi> 5 * Copyright (C) 2008-2009 by Jussi Kivilinna <jussi.kivilinna@iki.fi>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -2839,8 +2839,7 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2839 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) 2839 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
2840 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); 2840 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
2841 2841
2842 if (info != NULL) 2842 kfree(info);
2843 kfree(info);
2844 2843
2845 priv->connected = true; 2844 priv->connected = true;
2846 memcpy(priv->bssid, bssid, ETH_ALEN); 2845 memcpy(priv->bssid, bssid, ETH_ALEN);
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 2bf4efa33186..ffe61d53e3fe 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -169,6 +169,13 @@ config RT2800USB_RT53XX
169 rt2800usb driver. 169 rt2800usb driver.
170 Supported chips: RT5370 170 Supported chips: RT5370
171 171
172config RT2800USB_RT55XX
173 bool "rt2800usb - Include support for rt55xx devices (EXPERIMENTAL)"
174 ---help---
175 This adds support for rt55xx wireless chipset family to the
176 rt2800usb driver.
177 Supported chips: RT5572
178
172config RT2800USB_UNKNOWN 179config RT2800USB_UNKNOWN
173 bool "rt2800usb - Include support for unknown (USB) devices" 180 bool "rt2800usb - Include support for unknown (USB) devices"
174 default n 181 default n
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 4db1088a847f..a7630d5ec892 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -51,6 +51,7 @@
51 * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) 51 * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
52 * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) 52 * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
53 * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) 53 * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
54 * RF5592 2.4G/5G 2T2R
54 * RF5360 2.4G 1T1R 55 * RF5360 2.4G 1T1R
55 * RF5370 2.4G 1T1R 56 * RF5370 2.4G 1T1R
56 * RF5390 2.4G 1T1R 57 * RF5390 2.4G 1T1R
@@ -68,6 +69,7 @@
68#define RF3320 0x000b 69#define RF3320 0x000b
69#define RF3322 0x000c 70#define RF3322 0x000c
70#define RF3053 0x000d 71#define RF3053 0x000d
72#define RF5592 0x000f
71#define RF3290 0x3290 73#define RF3290 0x3290
72#define RF5360 0x5360 74#define RF5360 0x5360
73#define RF5370 0x5370 75#define RF5370 0x5370
@@ -88,11 +90,8 @@
88#define REV_RT3390E 0x0211 90#define REV_RT3390E 0x0211
89#define REV_RT5390F 0x0502 91#define REV_RT5390F 0x0502
90#define REV_RT5390R 0x1502 92#define REV_RT5390R 0x1502
93#define REV_RT5592C 0x0221
91 94
92/*
93 * Signal information.
94 * Default offset is required for RSSI <-> dBm conversion.
95 */
96#define DEFAULT_RSSI_OFFSET 120 95#define DEFAULT_RSSI_OFFSET 120
97 96
98/* 97/*
@@ -690,6 +689,12 @@
690#define GPIO_SWITCH_7 FIELD32(0x00000080) 689#define GPIO_SWITCH_7 FIELD32(0x00000080)
691 690
692/* 691/*
692 * FIXME: where the DEBUG_INDEX name come from?
693 */
694#define MAC_DEBUG_INDEX 0x05e8
695#define MAC_DEBUG_INDEX_XTAL FIELD32(0x80000000)
696
697/*
693 * MAC Control/Status Registers(CSR). 698 * MAC Control/Status Registers(CSR).
694 * Some values are set in TU, whereas 1 TU == 1024 us. 699 * Some values are set in TU, whereas 1 TU == 1024 us.
695 */ 700 */
@@ -1934,6 +1939,9 @@ struct mac_iveiv_entry {
1934#define BBP4_BANDWIDTH FIELD8(0x18) 1939#define BBP4_BANDWIDTH FIELD8(0x18)
1935#define BBP4_MAC_IF_CTRL FIELD8(0x40) 1940#define BBP4_MAC_IF_CTRL FIELD8(0x40)
1936 1941
1942/* BBP27 */
1943#define BBP27_RX_CHAIN_SEL FIELD8(0x60)
1944
1937/* 1945/*
1938 * BBP 47: Bandwidth 1946 * BBP 47: Bandwidth
1939 */ 1947 */
@@ -1948,6 +1956,20 @@ struct mac_iveiv_entry {
1948#define BBP49_UPDATE_FLAG FIELD8(0x01) 1956#define BBP49_UPDATE_FLAG FIELD8(0x01)
1949 1957
1950/* 1958/*
1959 * BBP 105:
1960 * - bit0: detect SIG on primary channel only (on 40MHz bandwidth)
1961 * - bit1: FEQ (Feed Forward Compensation) for independend streams
1962 * - bit2: MLD (Maximum Likehood Detection) for 2 streams (reserved on single
1963 * stream)
1964 * - bit4: channel estimation updates based on remodulation of
1965 * L-SIG and HT-SIG symbols
1966 */
1967#define BBP105_DETECT_SIG_ON_PRIMARY FIELD8(0x01)
1968#define BBP105_FEQ FIELD8(0x02)
1969#define BBP105_MLD FIELD8(0x04)
1970#define BBP105_SIG_REMODULATION FIELD8(0x08)
1971
1972/*
1951 * BBP 109 1973 * BBP 109
1952 */ 1974 */
1953#define BBP109_TX0_POWER FIELD8(0x0f) 1975#define BBP109_TX0_POWER FIELD8(0x0f)
@@ -1967,6 +1989,11 @@ struct mac_iveiv_entry {
1967#define BBP152_RX_DEFAULT_ANT FIELD8(0x80) 1989#define BBP152_RX_DEFAULT_ANT FIELD8(0x80)
1968 1990
1969/* 1991/*
1992 * BBP 254: unknown
1993 */
1994#define BBP254_BIT7 FIELD8(0x80)
1995
1996/*
1970 * RFCSR registers 1997 * RFCSR registers
1971 * The wordsize of the RFCSR is 8 bits. 1998 * The wordsize of the RFCSR is 8 bits.
1972 */ 1999 */
@@ -2022,9 +2049,18 @@ struct mac_iveiv_entry {
2022#define RFCSR7_BITS67 FIELD8(0xc0) 2049#define RFCSR7_BITS67 FIELD8(0xc0)
2023 2050
2024/* 2051/*
2052 * RFCSR 9:
2053 */
2054#define RFCSR9_K FIELD8(0x0f)
2055#define RFCSR9_N FIELD8(0x10)
2056#define RFCSR9_UNKNOWN FIELD8(0x60)
2057#define RFCSR9_MOD FIELD8(0x80)
2058
2059/*
2025 * RFCSR 11: 2060 * RFCSR 11:
2026 */ 2061 */
2027#define RFCSR11_R FIELD8(0x03) 2062#define RFCSR11_R FIELD8(0x03)
2063#define RFCSR11_MOD FIELD8(0xc0)
2028 2064
2029/* 2065/*
2030 * RFCSR 12: 2066 * RFCSR 12:
@@ -2130,11 +2166,13 @@ struct mac_iveiv_entry {
2130 * RFCSR 49: 2166 * RFCSR 49:
2131 */ 2167 */
2132#define RFCSR49_TX FIELD8(0x3f) 2168#define RFCSR49_TX FIELD8(0x3f)
2169#define RFCSR49_EP FIELD8(0xc0)
2133 2170
2134/* 2171/*
2135 * RFCSR 50: 2172 * RFCSR 50:
2136 */ 2173 */
2137#define RFCSR50_TX FIELD8(0x3f) 2174#define RFCSR50_TX FIELD8(0x3f)
2175#define RFCSR50_EP FIELD8(0xc0)
2138 2176
2139/* 2177/*
2140 * RF registers 2178 * RF registers
@@ -2497,6 +2535,61 @@ struct mac_iveiv_entry {
2497#define EEPROM_BBP_REG_ID FIELD16(0xff00) 2535#define EEPROM_BBP_REG_ID FIELD16(0xff00)
2498 2536
2499/* 2537/*
2538 * EEPROM IQ Calibration, unlike other entries those are byte addresses.
2539 */
2540
2541#define EEPROM_IQ_GAIN_CAL_TX0_2G 0x130
2542#define EEPROM_IQ_PHASE_CAL_TX0_2G 0x131
2543#define EEPROM_IQ_GROUPDELAY_CAL_TX0_2G 0x132
2544#define EEPROM_IQ_GAIN_CAL_TX1_2G 0x133
2545#define EEPROM_IQ_PHASE_CAL_TX1_2G 0x134
2546#define EEPROM_IQ_GROUPDELAY_CAL_TX1_2G 0x135
2547#define EEPROM_IQ_GAIN_CAL_RX0_2G 0x136
2548#define EEPROM_IQ_PHASE_CAL_RX0_2G 0x137
2549#define EEPROM_IQ_GROUPDELAY_CAL_RX0_2G 0x138
2550#define EEPROM_IQ_GAIN_CAL_RX1_2G 0x139
2551#define EEPROM_IQ_PHASE_CAL_RX1_2G 0x13A
2552#define EEPROM_IQ_GROUPDELAY_CAL_RX1_2G 0x13B
2553#define EEPROM_RF_IQ_COMPENSATION_CONTROL 0x13C
2554#define EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CONTROL 0x13D
2555#define EEPROM_IQ_GAIN_CAL_TX0_CH36_TO_CH64_5G 0x144
2556#define EEPROM_IQ_PHASE_CAL_TX0_CH36_TO_CH64_5G 0x145
2557#define EEPROM_IQ_GAIN_CAL_TX0_CH100_TO_CH138_5G 0X146
2558#define EEPROM_IQ_PHASE_CAL_TX0_CH100_TO_CH138_5G 0x147
2559#define EEPROM_IQ_GAIN_CAL_TX0_CH140_TO_CH165_5G 0x148
2560#define EEPROM_IQ_PHASE_CAL_TX0_CH140_TO_CH165_5G 0x149
2561#define EEPROM_IQ_GAIN_CAL_TX1_CH36_TO_CH64_5G 0x14A
2562#define EEPROM_IQ_PHASE_CAL_TX1_CH36_TO_CH64_5G 0x14B
2563#define EEPROM_IQ_GAIN_CAL_TX1_CH100_TO_CH138_5G 0X14C
2564#define EEPROM_IQ_PHASE_CAL_TX1_CH100_TO_CH138_5G 0x14D
2565#define EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5G 0x14E
2566#define EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5G 0x14F
2567#define EEPROM_IQ_GROUPDELAY_CAL_TX0_CH36_TO_CH64_5G 0x150
2568#define EEPROM_IQ_GROUPDELAY_CAL_TX1_CH36_TO_CH64_5G 0x151
2569#define EEPROM_IQ_GROUPDELAY_CAL_TX0_CH100_TO_CH138_5G 0x152
2570#define EEPROM_IQ_GROUPDELAY_CAL_TX1_CH100_TO_CH138_5G 0x153
2571#define EEPROM_IQ_GROUPDELAY_CAL_TX0_CH140_TO_CH165_5G 0x154
2572#define EEPROM_IQ_GROUPDELAY_CAL_TX1_CH140_TO_CH165_5G 0x155
2573#define EEPROM_IQ_GAIN_CAL_RX0_CH36_TO_CH64_5G 0x156
2574#define EEPROM_IQ_PHASE_CAL_RX0_CH36_TO_CH64_5G 0x157
2575#define EEPROM_IQ_GAIN_CAL_RX0_CH100_TO_CH138_5G 0X158
2576#define EEPROM_IQ_PHASE_CAL_RX0_CH100_TO_CH138_5G 0x159
2577#define EEPROM_IQ_GAIN_CAL_RX0_CH140_TO_CH165_5G 0x15A
2578#define EEPROM_IQ_PHASE_CAL_RX0_CH140_TO_CH165_5G 0x15B
2579#define EEPROM_IQ_GAIN_CAL_RX1_CH36_TO_CH64_5G 0x15C
2580#define EEPROM_IQ_PHASE_CAL_RX1_CH36_TO_CH64_5G 0x15D
2581#define EEPROM_IQ_GAIN_CAL_RX1_CH100_TO_CH138_5G 0X15E
2582#define EEPROM_IQ_PHASE_CAL_RX1_CH100_TO_CH138_5G 0x15F
2583#define EEPROM_IQ_GAIN_CAL_RX1_CH140_TO_CH165_5G 0x160
2584#define EEPROM_IQ_PHASE_CAL_RX1_CH140_TO_CH165_5G 0x161
2585#define EEPROM_IQ_GROUPDELAY_CAL_RX0_CH36_TO_CH64_5G 0x162
2586#define EEPROM_IQ_GROUPDELAY_CAL_RX1_CH36_TO_CH64_5G 0x163
2587#define EEPROM_IQ_GROUPDELAY_CAL_RX0_CH100_TO_CH138_5G 0x164
2588#define EEPROM_IQ_GROUPDELAY_CAL_RX1_CH100_TO_CH138_5G 0x165
2589#define EEPROM_IQ_GROUPDELAY_CAL_RX0_CH140_TO_CH165_5G 0x166
2590#define EEPROM_IQ_GROUPDELAY_CAL_RX1_CH140_TO_CH165_5G 0x167
2591
2592/*
2500 * MCU mailbox commands. 2593 * MCU mailbox commands.
2501 * MCU_SLEEP - go to power-save mode. 2594 * MCU_SLEEP - go to power-save mode.
2502 * arg1: 1: save as much power as possible, 0: save less power. 2595 * arg1: 1: save as much power as possible, 0: save less power.
@@ -2535,6 +2628,8 @@ struct mac_iveiv_entry {
2535#define TXWI_DESC_SIZE (4 * sizeof(__le32)) 2628#define TXWI_DESC_SIZE (4 * sizeof(__le32))
2536#define RXWI_DESC_SIZE (4 * sizeof(__le32)) 2629#define RXWI_DESC_SIZE (4 * sizeof(__le32))
2537 2630
2631#define TXWI_DESC_SIZE_5592 (5 * sizeof(__le32))
2632#define RXWI_DESC_SIZE_5592 (6 * sizeof(__le32))
2538/* 2633/*
2539 * TX WI structure 2634 * TX WI structure
2540 */ 2635 */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index a658b4bc7da2..f08a0424fe4d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -527,8 +527,10 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
527 */ 527 */
528 rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); 528 rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
529 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); 529 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
530 if (rt2x00_is_usb(rt2x00dev)) 530 if (rt2x00_is_usb(rt2x00dev)) {
531 rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); 531 rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
532 rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
533 }
532 msleep(1); 534 msleep(1);
533 535
534 return 0; 536 return 0;
@@ -674,11 +676,6 @@ void rt2800_process_rxwi(struct queue_entry *entry,
674 * Convert descriptor AGC value to RSSI value. 676 * Convert descriptor AGC value to RSSI value.
675 */ 677 */
676 rxdesc->rssi = rt2800_agc_to_rssi(entry->queue->rt2x00dev, word); 678 rxdesc->rssi = rt2800_agc_to_rssi(entry->queue->rt2x00dev, word);
677
678 /*
679 * Remove RXWI descriptor from start of buffer.
680 */
681 skb_pull(entry->skb, RXWI_DESC_SIZE);
682} 679}
683EXPORT_SYMBOL_GPL(rt2800_process_rxwi); 680EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
684 681
@@ -1988,8 +1985,21 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
1988} 1985}
1989 1986
1990#define POWER_BOUND 0x27 1987#define POWER_BOUND 0x27
1988#define POWER_BOUND_5G 0x2b
1991#define FREQ_OFFSET_BOUND 0x5f 1989#define FREQ_OFFSET_BOUND 0x5f
1992 1990
1991static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
1992{
1993 u8 rfcsr;
1994
1995 rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
1996 if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
1997 rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
1998 else
1999 rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
2000 rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
2001}
2002
1993static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev, 2003static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
1994 struct ieee80211_conf *conf, 2004 struct ieee80211_conf *conf,
1995 struct rf_channel *rf, 2005 struct rf_channel *rf,
@@ -2010,12 +2020,7 @@ static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
2010 rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); 2020 rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1);
2011 rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); 2021 rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
2012 2022
2013 rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); 2023 rt2800_adjust_freq_offset(rt2x00dev);
2014 if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
2015 rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
2016 else
2017 rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
2018 rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
2019 2024
2020 if (rf->channel <= 14) { 2025 if (rf->channel <= 14) {
2021 if (rf->channel == 6) 2026 if (rf->channel == 6)
@@ -2056,13 +2061,7 @@ static void rt2800_config_channel_rf3322(struct rt2x00_dev *rt2x00dev,
2056 else 2061 else
2057 rt2800_rfcsr_write(rt2x00dev, 48, info->default_power2); 2062 rt2800_rfcsr_write(rt2x00dev, 48, info->default_power2);
2058 2063
2059 rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); 2064 rt2800_adjust_freq_offset(rt2x00dev);
2060 if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
2061 rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
2062 else
2063 rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
2064
2065 rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
2066 2065
2067 rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); 2066 rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
2068 rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); 2067 rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
@@ -2127,12 +2126,7 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
2127 rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); 2126 rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
2128 rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); 2127 rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
2129 2128
2130 rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); 2129 rt2800_adjust_freq_offset(rt2x00dev);
2131 if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
2132 rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
2133 else
2134 rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
2135 rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
2136 2130
2137 if (rf->channel <= 14) { 2131 if (rf->channel <= 14) {
2138 int idx = rf->channel-1; 2132 int idx = rf->channel-1;
@@ -2184,6 +2178,382 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
2184 } 2178 }
2185} 2179}
2186 2180
2181static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev,
2182 struct ieee80211_conf *conf,
2183 struct rf_channel *rf,
2184 struct channel_info *info)
2185{
2186 u8 rfcsr, ep_reg;
2187 u32 reg;
2188 int power_bound;
2189
2190 /* TODO */
2191 const bool is_11b = false;
2192 const bool is_type_ep = false;
2193
2194 rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
2195 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL,
2196 (rf->channel > 14 || conf_is_ht40(conf)) ? 5 : 0);
2197 rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
2198
2199 /* Order of values on rf_channel entry: N, K, mod, R */
2200 rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1 & 0xff);
2201
2202 rt2800_rfcsr_read(rt2x00dev, 9, &rfcsr);
2203 rt2x00_set_field8(&rfcsr, RFCSR9_K, rf->rf2 & 0xf);
2204 rt2x00_set_field8(&rfcsr, RFCSR9_N, (rf->rf1 & 0x100) >> 8);
2205 rt2x00_set_field8(&rfcsr, RFCSR9_MOD, ((rf->rf3 - 8) & 0x4) >> 2);
2206 rt2800_rfcsr_write(rt2x00dev, 9, rfcsr);
2207
2208 rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr);
2209 rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf4 - 1);
2210 rt2x00_set_field8(&rfcsr, RFCSR11_MOD, (rf->rf3 - 8) & 0x3);
2211 rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
2212
2213 if (rf->channel <= 14) {
2214 rt2800_rfcsr_write(rt2x00dev, 10, 0x90);
2215 /* FIXME: RF11 owerwrite ? */
2216 rt2800_rfcsr_write(rt2x00dev, 11, 0x4A);
2217 rt2800_rfcsr_write(rt2x00dev, 12, 0x52);
2218 rt2800_rfcsr_write(rt2x00dev, 13, 0x42);
2219 rt2800_rfcsr_write(rt2x00dev, 22, 0x40);
2220 rt2800_rfcsr_write(rt2x00dev, 24, 0x4A);
2221 rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
2222 rt2800_rfcsr_write(rt2x00dev, 27, 0x42);
2223 rt2800_rfcsr_write(rt2x00dev, 36, 0x80);
2224 rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
2225 rt2800_rfcsr_write(rt2x00dev, 38, 0x89);
2226 rt2800_rfcsr_write(rt2x00dev, 39, 0x1B);
2227 rt2800_rfcsr_write(rt2x00dev, 40, 0x0D);
2228 rt2800_rfcsr_write(rt2x00dev, 41, 0x9B);
2229 rt2800_rfcsr_write(rt2x00dev, 42, 0xD5);
2230 rt2800_rfcsr_write(rt2x00dev, 43, 0x72);
2231 rt2800_rfcsr_write(rt2x00dev, 44, 0x0E);
2232 rt2800_rfcsr_write(rt2x00dev, 45, 0xA2);
2233 rt2800_rfcsr_write(rt2x00dev, 46, 0x6B);
2234 rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
2235 rt2800_rfcsr_write(rt2x00dev, 51, 0x3E);
2236 rt2800_rfcsr_write(rt2x00dev, 52, 0x48);
2237 rt2800_rfcsr_write(rt2x00dev, 54, 0x38);
2238 rt2800_rfcsr_write(rt2x00dev, 56, 0xA1);
2239 rt2800_rfcsr_write(rt2x00dev, 57, 0x00);
2240 rt2800_rfcsr_write(rt2x00dev, 58, 0x39);
2241 rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
2242 rt2800_rfcsr_write(rt2x00dev, 61, 0x91);
2243 rt2800_rfcsr_write(rt2x00dev, 62, 0x39);
2244
2245 /* TODO RF27 <- tssi */
2246
2247 rfcsr = rf->channel <= 10 ? 0x07 : 0x06;
2248 rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
2249 rt2800_rfcsr_write(rt2x00dev, 59, rfcsr);
2250
2251 if (is_11b) {
2252 /* CCK */
2253 rt2800_rfcsr_write(rt2x00dev, 31, 0xF8);
2254 rt2800_rfcsr_write(rt2x00dev, 32, 0xC0);
2255 if (is_type_ep)
2256 rt2800_rfcsr_write(rt2x00dev, 55, 0x06);
2257 else
2258 rt2800_rfcsr_write(rt2x00dev, 55, 0x47);
2259 } else {
2260 /* OFDM */
2261 if (is_type_ep)
2262 rt2800_rfcsr_write(rt2x00dev, 55, 0x03);
2263 else
2264 rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
2265 }
2266
2267 power_bound = POWER_BOUND;
2268 ep_reg = 0x2;
2269 } else {
2270 rt2800_rfcsr_write(rt2x00dev, 10, 0x97);
2271 /* FIMXE: RF11 overwrite */
2272 rt2800_rfcsr_write(rt2x00dev, 11, 0x40);
2273 rt2800_rfcsr_write(rt2x00dev, 25, 0xBF);
2274 rt2800_rfcsr_write(rt2x00dev, 27, 0x42);
2275 rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
2276 rt2800_rfcsr_write(rt2x00dev, 37, 0x04);
2277 rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
2278 rt2800_rfcsr_write(rt2x00dev, 40, 0x42);
2279 rt2800_rfcsr_write(rt2x00dev, 41, 0xBB);
2280 rt2800_rfcsr_write(rt2x00dev, 42, 0xD7);
2281 rt2800_rfcsr_write(rt2x00dev, 45, 0x41);
2282 rt2800_rfcsr_write(rt2x00dev, 48, 0x00);
2283 rt2800_rfcsr_write(rt2x00dev, 57, 0x77);
2284 rt2800_rfcsr_write(rt2x00dev, 60, 0x05);
2285 rt2800_rfcsr_write(rt2x00dev, 61, 0x01);
2286
2287 /* TODO RF27 <- tssi */
2288
2289 if (rf->channel >= 36 && rf->channel <= 64) {
2290
2291 rt2800_rfcsr_write(rt2x00dev, 12, 0x2E);
2292 rt2800_rfcsr_write(rt2x00dev, 13, 0x22);
2293 rt2800_rfcsr_write(rt2x00dev, 22, 0x60);
2294 rt2800_rfcsr_write(rt2x00dev, 23, 0x7F);
2295 if (rf->channel <= 50)
2296 rt2800_rfcsr_write(rt2x00dev, 24, 0x09);
2297 else if (rf->channel >= 52)
2298 rt2800_rfcsr_write(rt2x00dev, 24, 0x07);
2299 rt2800_rfcsr_write(rt2x00dev, 39, 0x1C);
2300 rt2800_rfcsr_write(rt2x00dev, 43, 0x5B);
2301 rt2800_rfcsr_write(rt2x00dev, 44, 0X40);
2302 rt2800_rfcsr_write(rt2x00dev, 46, 0X00);
2303 rt2800_rfcsr_write(rt2x00dev, 51, 0xFE);
2304 rt2800_rfcsr_write(rt2x00dev, 52, 0x0C);
2305 rt2800_rfcsr_write(rt2x00dev, 54, 0xF8);
2306 if (rf->channel <= 50) {
2307 rt2800_rfcsr_write(rt2x00dev, 55, 0x06),
2308 rt2800_rfcsr_write(rt2x00dev, 56, 0xD3);
2309 } else if (rf->channel >= 52) {
2310 rt2800_rfcsr_write(rt2x00dev, 55, 0x04);
2311 rt2800_rfcsr_write(rt2x00dev, 56, 0xBB);
2312 }
2313
2314 rt2800_rfcsr_write(rt2x00dev, 58, 0x15);
2315 rt2800_rfcsr_write(rt2x00dev, 59, 0x7F);
2316 rt2800_rfcsr_write(rt2x00dev, 62, 0x15);
2317
2318 } else if (rf->channel >= 100 && rf->channel <= 165) {
2319
2320 rt2800_rfcsr_write(rt2x00dev, 12, 0x0E);
2321 rt2800_rfcsr_write(rt2x00dev, 13, 0x42);
2322 rt2800_rfcsr_write(rt2x00dev, 22, 0x40);
2323 if (rf->channel <= 153) {
2324 rt2800_rfcsr_write(rt2x00dev, 23, 0x3C);
2325 rt2800_rfcsr_write(rt2x00dev, 24, 0x06);
2326 } else if (rf->channel >= 155) {
2327 rt2800_rfcsr_write(rt2x00dev, 23, 0x38);
2328 rt2800_rfcsr_write(rt2x00dev, 24, 0x05);
2329 }
2330 if (rf->channel <= 138) {
2331 rt2800_rfcsr_write(rt2x00dev, 39, 0x1A);
2332 rt2800_rfcsr_write(rt2x00dev, 43, 0x3B);
2333 rt2800_rfcsr_write(rt2x00dev, 44, 0x20);
2334 rt2800_rfcsr_write(rt2x00dev, 46, 0x18);
2335 } else if (rf->channel >= 140) {
2336 rt2800_rfcsr_write(rt2x00dev, 39, 0x18);
2337 rt2800_rfcsr_write(rt2x00dev, 43, 0x1B);
2338 rt2800_rfcsr_write(rt2x00dev, 44, 0x10);
2339 rt2800_rfcsr_write(rt2x00dev, 46, 0X08);
2340 }
2341 if (rf->channel <= 124)
2342 rt2800_rfcsr_write(rt2x00dev, 51, 0xFC);
2343 else if (rf->channel >= 126)
2344 rt2800_rfcsr_write(rt2x00dev, 51, 0xEC);
2345 if (rf->channel <= 138)
2346 rt2800_rfcsr_write(rt2x00dev, 52, 0x06);
2347 else if (rf->channel >= 140)
2348 rt2800_rfcsr_write(rt2x00dev, 52, 0x06);
2349 rt2800_rfcsr_write(rt2x00dev, 54, 0xEB);
2350 if (rf->channel <= 138)
2351 rt2800_rfcsr_write(rt2x00dev, 55, 0x01);
2352 else if (rf->channel >= 140)
2353 rt2800_rfcsr_write(rt2x00dev, 55, 0x00);
2354 if (rf->channel <= 128)
2355 rt2800_rfcsr_write(rt2x00dev, 56, 0xBB);
2356 else if (rf->channel >= 130)
2357 rt2800_rfcsr_write(rt2x00dev, 56, 0xAB);
2358 if (rf->channel <= 116)
2359 rt2800_rfcsr_write(rt2x00dev, 58, 0x1D);
2360 else if (rf->channel >= 118)
2361 rt2800_rfcsr_write(rt2x00dev, 58, 0x15);
2362 if (rf->channel <= 138)
2363 rt2800_rfcsr_write(rt2x00dev, 59, 0x3F);
2364 else if (rf->channel >= 140)
2365 rt2800_rfcsr_write(rt2x00dev, 59, 0x7C);
2366 if (rf->channel <= 116)
2367 rt2800_rfcsr_write(rt2x00dev, 62, 0x1D);
2368 else if (rf->channel >= 118)
2369 rt2800_rfcsr_write(rt2x00dev, 62, 0x15);
2370 }
2371
2372 power_bound = POWER_BOUND_5G;
2373 ep_reg = 0x3;
2374 }
2375
2376 rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr);
2377 if (info->default_power1 > power_bound)
2378 rt2x00_set_field8(&rfcsr, RFCSR49_TX, power_bound);
2379 else
2380 rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1);
2381 if (is_type_ep)
2382 rt2x00_set_field8(&rfcsr, RFCSR49_EP, ep_reg);
2383 rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
2384
2385 rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
2386 if (info->default_power1 > power_bound)
2387 rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound);
2388 else
2389 rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2);
2390 if (is_type_ep)
2391 rt2x00_set_field8(&rfcsr, RFCSR50_EP, ep_reg);
2392 rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
2393
2394 rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
2395 rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
2396 rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
2397
2398 rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD,
2399 rt2x00dev->default_ant.tx_chain_num >= 1);
2400 rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD,
2401 rt2x00dev->default_ant.tx_chain_num == 2);
2402 rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
2403
2404 rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD,
2405 rt2x00dev->default_ant.rx_chain_num >= 1);
2406 rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD,
2407 rt2x00dev->default_ant.rx_chain_num == 2);
2408 rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
2409
2410 rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
2411 rt2800_rfcsr_write(rt2x00dev, 6, 0xe4);
2412
2413 if (conf_is_ht40(conf))
2414 rt2800_rfcsr_write(rt2x00dev, 30, 0x16);
2415 else
2416 rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
2417
2418 if (!is_11b) {
2419 rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
2420 rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
2421 }
2422
2423 /* TODO proper frequency adjustment */
2424 rt2800_adjust_freq_offset(rt2x00dev);
2425
2426 /* TODO merge with others */
2427 rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
2428 rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
2429 rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
2430
2431 /* BBP settings */
2432 rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
2433 rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
2434 rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
2435
2436 rt2800_bbp_write(rt2x00dev, 79, (rf->channel <= 14) ? 0x1C : 0x18);
2437 rt2800_bbp_write(rt2x00dev, 80, (rf->channel <= 14) ? 0x0E : 0x08);
2438 rt2800_bbp_write(rt2x00dev, 81, (rf->channel <= 14) ? 0x3A : 0x38);
2439 rt2800_bbp_write(rt2x00dev, 82, (rf->channel <= 14) ? 0x62 : 0x92);
2440
2441 /* GLRT band configuration */
2442 rt2800_bbp_write(rt2x00dev, 195, 128);
2443 rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0xE0 : 0xF0);
2444 rt2800_bbp_write(rt2x00dev, 195, 129);
2445 rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x1F : 0x1E);
2446 rt2800_bbp_write(rt2x00dev, 195, 130);
2447 rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x38 : 0x28);
2448 rt2800_bbp_write(rt2x00dev, 195, 131);
2449 rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x32 : 0x20);
2450 rt2800_bbp_write(rt2x00dev, 195, 133);
2451 rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x28 : 0x7F);
2452 rt2800_bbp_write(rt2x00dev, 195, 124);
2453 rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F);
2454}
2455
2456static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev,
2457 const unsigned int word,
2458 const u8 value)
2459{
2460 u8 chain, reg;
2461
2462 for (chain = 0; chain < rt2x00dev->default_ant.rx_chain_num; chain++) {
2463 rt2800_bbp_read(rt2x00dev, 27, &reg);
2464 rt2x00_set_field8(&reg, BBP27_RX_CHAIN_SEL, chain);
2465 rt2800_bbp_write(rt2x00dev, 27, reg);
2466
2467 rt2800_bbp_write(rt2x00dev, word, value);
2468 }
2469}
2470
2471static void rt2800_iq_calibrate(struct rt2x00_dev *rt2x00dev, int channel)
2472{
2473 u8 cal;
2474
2475 /* TX0 IQ Gain */
2476 rt2800_bbp_write(rt2x00dev, 158, 0x2c);
2477 if (channel <= 14)
2478 cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_GAIN_CAL_TX0_2G);
2479 else if (channel >= 36 && channel <= 64)
2480 cal = rt2x00_eeprom_byte(rt2x00dev,
2481 EEPROM_IQ_GAIN_CAL_TX0_CH36_TO_CH64_5G);
2482 else if (channel >= 100 && channel <= 138)
2483 cal = rt2x00_eeprom_byte(rt2x00dev,
2484 EEPROM_IQ_GAIN_CAL_TX0_CH100_TO_CH138_5G);
2485 else if (channel >= 140 && channel <= 165)
2486 cal = rt2x00_eeprom_byte(rt2x00dev,
2487 EEPROM_IQ_GAIN_CAL_TX0_CH140_TO_CH165_5G);
2488 else
2489 cal = 0;
2490 rt2800_bbp_write(rt2x00dev, 159, cal);
2491
2492 /* TX0 IQ Phase */
2493 rt2800_bbp_write(rt2x00dev, 158, 0x2d);
2494 if (channel <= 14)
2495 cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_PHASE_CAL_TX0_2G);
2496 else if (channel >= 36 && channel <= 64)
2497 cal = rt2x00_eeprom_byte(rt2x00dev,
2498 EEPROM_IQ_PHASE_CAL_TX0_CH36_TO_CH64_5G);
2499 else if (channel >= 100 && channel <= 138)
2500 cal = rt2x00_eeprom_byte(rt2x00dev,
2501 EEPROM_IQ_PHASE_CAL_TX0_CH100_TO_CH138_5G);
2502 else if (channel >= 140 && channel <= 165)
2503 cal = rt2x00_eeprom_byte(rt2x00dev,
2504 EEPROM_IQ_PHASE_CAL_TX0_CH140_TO_CH165_5G);
2505 else
2506 cal = 0;
2507 rt2800_bbp_write(rt2x00dev, 159, cal);
2508
2509 /* TX1 IQ Gain */
2510 rt2800_bbp_write(rt2x00dev, 158, 0x4a);
2511 if (channel <= 14)
2512 cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_GAIN_CAL_TX1_2G);
2513 else if (channel >= 36 && channel <= 64)
2514 cal = rt2x00_eeprom_byte(rt2x00dev,
2515 EEPROM_IQ_GAIN_CAL_TX1_CH36_TO_CH64_5G);
2516 else if (channel >= 100 && channel <= 138)
2517 cal = rt2x00_eeprom_byte(rt2x00dev,
2518 EEPROM_IQ_GAIN_CAL_TX1_CH100_TO_CH138_5G);
2519 else if (channel >= 140 && channel <= 165)
2520 cal = rt2x00_eeprom_byte(rt2x00dev,
2521 EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5G);
2522 else
2523 cal = 0;
2524 rt2800_bbp_write(rt2x00dev, 159, cal);
2525
2526 /* TX1 IQ Phase */
2527 rt2800_bbp_write(rt2x00dev, 158, 0x4b);
2528 if (channel <= 14)
2529 cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_PHASE_CAL_TX1_2G);
2530 else if (channel >= 36 && channel <= 64)
2531 cal = rt2x00_eeprom_byte(rt2x00dev,
2532 EEPROM_IQ_PHASE_CAL_TX1_CH36_TO_CH64_5G);
2533 else if (channel >= 100 && channel <= 138)
2534 cal = rt2x00_eeprom_byte(rt2x00dev,
2535 EEPROM_IQ_PHASE_CAL_TX1_CH100_TO_CH138_5G);
2536 else if (channel >= 140 && channel <= 165)
2537 cal = rt2x00_eeprom_byte(rt2x00dev,
2538 EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5G);
2539 else
2540 cal = 0;
2541 rt2800_bbp_write(rt2x00dev, 159, cal);
2542
2543 /* FIXME: possible RX0, RX1 callibration ? */
2544
2545 /* RF IQ compensation control */
2546 rt2800_bbp_write(rt2x00dev, 158, 0x04);
2547 cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_RF_IQ_COMPENSATION_CONTROL);
2548 rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0);
2549
2550 /* RF IQ imbalance compensation control */
2551 rt2800_bbp_write(rt2x00dev, 158, 0x03);
2552 cal = rt2x00_eeprom_byte(rt2x00dev,
2553 EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CONTROL);
2554 rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0);
2555}
2556
2187static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, 2557static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2188 struct ieee80211_conf *conf, 2558 struct ieee80211_conf *conf,
2189 struct rf_channel *rf, 2559 struct rf_channel *rf,
@@ -2225,6 +2595,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2225 case RF5392: 2595 case RF5392:
2226 rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); 2596 rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info);
2227 break; 2597 break;
2598 case RF5592:
2599 rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info);
2600 break;
2228 default: 2601 default:
2229 rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); 2602 rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
2230 } 2603 }
@@ -2326,6 +2699,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2326 if (rt2x00_rt(rt2x00dev, RT3572)) 2699 if (rt2x00_rt(rt2x00dev, RT3572))
2327 rt2800_rfcsr_write(rt2x00dev, 8, 0x80); 2700 rt2800_rfcsr_write(rt2x00dev, 8, 0x80);
2328 2701
2702 if (rt2x00_rt(rt2x00dev, RT5592)) {
2703 rt2800_bbp_write(rt2x00dev, 195, 141);
2704 rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a);
2705
2706 /* AGC init */
2707 reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2 * rt2x00dev->lna_gain;
2708 rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
2709
2710 rt2800_iq_calibrate(rt2x00dev, rf->channel);
2711 }
2712
2329 rt2800_bbp_read(rt2x00dev, 4, &bbp); 2713 rt2800_bbp_read(rt2x00dev, 4, &bbp);
2330 rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); 2714 rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
2331 rt2800_bbp_write(rt2x00dev, 4, bbp); 2715 rt2800_bbp_write(rt2x00dev, 4, bbp);
@@ -2938,13 +3322,16 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
2938 rt2x00_rt(rt2x00dev, RT3390) || 3322 rt2x00_rt(rt2x00dev, RT3390) ||
2939 rt2x00_rt(rt2x00dev, RT3572) || 3323 rt2x00_rt(rt2x00dev, RT3572) ||
2940 rt2x00_rt(rt2x00dev, RT5390) || 3324 rt2x00_rt(rt2x00dev, RT5390) ||
2941 rt2x00_rt(rt2x00dev, RT5392)) 3325 rt2x00_rt(rt2x00dev, RT5392) ||
3326 rt2x00_rt(rt2x00dev, RT5592))
2942 vgc = 0x1c + (2 * rt2x00dev->lna_gain); 3327 vgc = 0x1c + (2 * rt2x00dev->lna_gain);
2943 else 3328 else
2944 vgc = 0x2e + rt2x00dev->lna_gain; 3329 vgc = 0x2e + rt2x00dev->lna_gain;
2945 } else { /* 5GHZ band */ 3330 } else { /* 5GHZ band */
2946 if (rt2x00_rt(rt2x00dev, RT3572)) 3331 if (rt2x00_rt(rt2x00dev, RT3572))
2947 vgc = 0x22 + (rt2x00dev->lna_gain * 5) / 3; 3332 vgc = 0x22 + (rt2x00dev->lna_gain * 5) / 3;
3333 else if (rt2x00_rt(rt2x00dev, RT5592))
3334 vgc = 0x24 + (2 * rt2x00dev->lna_gain);
2948 else { 3335 else {
2949 if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) 3336 if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
2950 vgc = 0x32 + (rt2x00dev->lna_gain * 5) / 3; 3337 vgc = 0x32 + (rt2x00dev->lna_gain * 5) / 3;
@@ -2960,7 +3347,11 @@ static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev,
2960 struct link_qual *qual, u8 vgc_level) 3347 struct link_qual *qual, u8 vgc_level)
2961{ 3348{
2962 if (qual->vgc_level != vgc_level) { 3349 if (qual->vgc_level != vgc_level) {
2963 rt2800_bbp_write(rt2x00dev, 66, vgc_level); 3350 if (rt2x00_rt(rt2x00dev, RT5592)) {
3351 rt2800_bbp_write(rt2x00dev, 83, qual->rssi > -65 ? 0x4a : 0x7a);
3352 rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, vgc_level);
3353 } else
3354 rt2800_bbp_write(rt2x00dev, 66, vgc_level);
2964 qual->vgc_level = vgc_level; 3355 qual->vgc_level = vgc_level;
2965 qual->vgc_level_reg = vgc_level; 3356 qual->vgc_level_reg = vgc_level;
2966 } 3357 }
@@ -2975,15 +3366,23 @@ EXPORT_SYMBOL_GPL(rt2800_reset_tuner);
2975void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, 3366void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
2976 const u32 count) 3367 const u32 count)
2977{ 3368{
3369 u8 vgc;
3370
2978 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) 3371 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C))
2979 return; 3372 return;
2980
2981 /* 3373 /*
2982 * When RSSI is better then -80 increase VGC level with 0x10 3374 * When RSSI is better then -80 increase VGC level with 0x10, except
3375 * for rt5592 chip.
2983 */ 3376 */
2984 rt2800_set_vgc(rt2x00dev, qual, 3377
2985 rt2800_get_default_vgc(rt2x00dev) + 3378 vgc = rt2800_get_default_vgc(rt2x00dev);
2986 ((qual->rssi > -80) * 0x10)); 3379
3380 if (rt2x00_rt(rt2x00dev, RT5592) && qual->rssi > -65)
3381 vgc += 0x20;
3382 else if (qual->rssi > -80)
3383 vgc += 0x10;
3384
3385 rt2800_set_vgc(rt2x00dev, qual, vgc);
2987} 3386}
2988EXPORT_SYMBOL_GPL(rt2800_link_tuner); 3387EXPORT_SYMBOL_GPL(rt2800_link_tuner);
2989 3388
@@ -3122,7 +3521,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
3122 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); 3521 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
3123 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); 3522 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
3124 } else if (rt2x00_rt(rt2x00dev, RT5390) || 3523 } else if (rt2x00_rt(rt2x00dev, RT5390) ||
3125 rt2x00_rt(rt2x00dev, RT5392)) { 3524 rt2x00_rt(rt2x00dev, RT5392) ||
3525 rt2x00_rt(rt2x00dev, RT5592)) {
3126 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); 3526 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
3127 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); 3527 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
3128 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); 3528 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
@@ -3302,7 +3702,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
3302 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CWMIN, 0); 3702 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CWMIN, 0);
3303 rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg); 3703 rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg);
3304 3704
3305 rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002); 3705 reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
3706 rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
3306 3707
3307 rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg); 3708 rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
3308 rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32); 3709 rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
@@ -3487,6 +3888,136 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
3487 return -EACCES; 3888 return -EACCES;
3488} 3889}
3489 3890
3891static void rt2800_bbp4_mac_if_ctrl(struct rt2x00_dev *rt2x00dev)
3892{
3893 u8 value;
3894
3895 rt2800_bbp_read(rt2x00dev, 4, &value);
3896 rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1);
3897 rt2800_bbp_write(rt2x00dev, 4, value);
3898}
3899
3900static void rt2800_init_freq_calibration(struct rt2x00_dev *rt2x00dev)
3901{
3902 rt2800_bbp_write(rt2x00dev, 142, 1);
3903 rt2800_bbp_write(rt2x00dev, 143, 57);
3904}
3905
3906static void rt2800_init_bbp_5592_glrt(struct rt2x00_dev *rt2x00dev)
3907{
3908 const u8 glrt_table[] = {
3909 0xE0, 0x1F, 0X38, 0x32, 0x08, 0x28, 0x19, 0x0A, 0xFF, 0x00, /* 128 ~ 137 */
3910 0x16, 0x10, 0x10, 0x0B, 0x36, 0x2C, 0x26, 0x24, 0x42, 0x36, /* 138 ~ 147 */
3911 0x30, 0x2D, 0x4C, 0x46, 0x3D, 0x40, 0x3E, 0x42, 0x3D, 0x40, /* 148 ~ 157 */
3912 0X3C, 0x34, 0x2C, 0x2F, 0x3C, 0x35, 0x2E, 0x2A, 0x49, 0x41, /* 158 ~ 167 */
3913 0x36, 0x31, 0x30, 0x30, 0x0E, 0x0D, 0x28, 0x21, 0x1C, 0x16, /* 168 ~ 177 */
3914 0x50, 0x4A, 0x43, 0x40, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, /* 178 ~ 187 */
3915 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 188 ~ 197 */
3916 0x00, 0x00, 0x7D, 0x14, 0x32, 0x2C, 0x36, 0x4C, 0x43, 0x2C, /* 198 ~ 207 */
3917 0x2E, 0x36, 0x30, 0x6E, /* 208 ~ 211 */
3918 };
3919 int i;
3920
3921 for (i = 0; i < ARRAY_SIZE(glrt_table); i++) {
3922 rt2800_bbp_write(rt2x00dev, 195, 128 + i);
3923 rt2800_bbp_write(rt2x00dev, 196, glrt_table[i]);
3924 }
3925};
3926
3927static void rt2800_init_bbb_early(struct rt2x00_dev *rt2x00dev)
3928{
3929 rt2800_bbp_write(rt2x00dev, 65, 0x2C);
3930 rt2800_bbp_write(rt2x00dev, 66, 0x38);
3931 rt2800_bbp_write(rt2x00dev, 68, 0x0B);
3932 rt2800_bbp_write(rt2x00dev, 69, 0x12);
3933 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
3934 rt2800_bbp_write(rt2x00dev, 73, 0x10);
3935 rt2800_bbp_write(rt2x00dev, 81, 0x37);
3936 rt2800_bbp_write(rt2x00dev, 82, 0x62);
3937 rt2800_bbp_write(rt2x00dev, 83, 0x6A);
3938 rt2800_bbp_write(rt2x00dev, 84, 0x99);
3939 rt2800_bbp_write(rt2x00dev, 86, 0x00);
3940 rt2800_bbp_write(rt2x00dev, 91, 0x04);
3941 rt2800_bbp_write(rt2x00dev, 92, 0x00);
3942 rt2800_bbp_write(rt2x00dev, 103, 0x00);
3943 rt2800_bbp_write(rt2x00dev, 105, 0x05);
3944 rt2800_bbp_write(rt2x00dev, 106, 0x35);
3945}
3946
3947static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev)
3948{
3949 int ant, div_mode;
3950 u16 eeprom;
3951 u8 value;
3952
3953 rt2800_init_bbb_early(rt2x00dev);
3954
3955 rt2800_bbp_read(rt2x00dev, 105, &value);
3956 rt2x00_set_field8(&value, BBP105_MLD,
3957 rt2x00dev->default_ant.rx_chain_num == 2);
3958 rt2800_bbp_write(rt2x00dev, 105, value);
3959
3960 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
3961
3962 rt2800_bbp_write(rt2x00dev, 20, 0x06);
3963 rt2800_bbp_write(rt2x00dev, 31, 0x08);
3964 rt2800_bbp_write(rt2x00dev, 65, 0x2C);
3965 rt2800_bbp_write(rt2x00dev, 68, 0xDD);
3966 rt2800_bbp_write(rt2x00dev, 69, 0x1A);
3967 rt2800_bbp_write(rt2x00dev, 70, 0x05);
3968 rt2800_bbp_write(rt2x00dev, 73, 0x13);
3969 rt2800_bbp_write(rt2x00dev, 74, 0x0F);
3970 rt2800_bbp_write(rt2x00dev, 75, 0x4F);
3971 rt2800_bbp_write(rt2x00dev, 76, 0x28);
3972 rt2800_bbp_write(rt2x00dev, 77, 0x59);
3973 rt2800_bbp_write(rt2x00dev, 84, 0x9A);
3974 rt2800_bbp_write(rt2x00dev, 86, 0x38);
3975 rt2800_bbp_write(rt2x00dev, 88, 0x90);
3976 rt2800_bbp_write(rt2x00dev, 91, 0x04);
3977 rt2800_bbp_write(rt2x00dev, 92, 0x02);
3978 rt2800_bbp_write(rt2x00dev, 95, 0x9a);
3979 rt2800_bbp_write(rt2x00dev, 98, 0x12);
3980 rt2800_bbp_write(rt2x00dev, 103, 0xC0);
3981 rt2800_bbp_write(rt2x00dev, 104, 0x92);
3982 /* FIXME BBP105 owerwrite */
3983 rt2800_bbp_write(rt2x00dev, 105, 0x3C);
3984 rt2800_bbp_write(rt2x00dev, 106, 0x35);
3985 rt2800_bbp_write(rt2x00dev, 128, 0x12);
3986 rt2800_bbp_write(rt2x00dev, 134, 0xD0);
3987 rt2800_bbp_write(rt2x00dev, 135, 0xF6);
3988 rt2800_bbp_write(rt2x00dev, 137, 0x0F);
3989
3990 /* Initialize GLRT (Generalized Likehood Radio Test) */
3991 rt2800_init_bbp_5592_glrt(rt2x00dev);
3992
3993 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
3994
3995 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
3996 div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY);
3997 ant = (div_mode == 3) ? 1 : 0;
3998 rt2800_bbp_read(rt2x00dev, 152, &value);
3999 if (ant == 0) {
4000 /* Main antenna */
4001 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
4002 } else {
4003 /* Auxiliary antenna */
4004 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
4005 }
4006 rt2800_bbp_write(rt2x00dev, 152, value);
4007
4008 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) {
4009 rt2800_bbp_read(rt2x00dev, 254, &value);
4010 rt2x00_set_field8(&value, BBP254_BIT7, 1);
4011 rt2800_bbp_write(rt2x00dev, 254, value);
4012 }
4013
4014 rt2800_init_freq_calibration(rt2x00dev);
4015
4016 rt2800_bbp_write(rt2x00dev, 84, 0x19);
4017 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C))
4018 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4019}
4020
3490static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) 4021static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
3491{ 4022{
3492 unsigned int i; 4023 unsigned int i;
@@ -3498,6 +4029,11 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
3498 rt2800_wait_bbp_ready(rt2x00dev))) 4029 rt2800_wait_bbp_ready(rt2x00dev)))
3499 return -EACCES; 4030 return -EACCES;
3500 4031
4032 if (rt2x00_rt(rt2x00dev, RT5592)) {
4033 rt2800_init_bbp_5592(rt2x00dev);
4034 return 0;
4035 }
4036
3501 if (rt2x00_rt(rt2x00dev, RT3352)) { 4037 if (rt2x00_rt(rt2x00dev, RT3352)) {
3502 rt2800_bbp_write(rt2x00dev, 3, 0x00); 4038 rt2800_bbp_write(rt2x00dev, 3, 0x00);
3503 rt2800_bbp_write(rt2x00dev, 4, 0x50); 4039 rt2800_bbp_write(rt2x00dev, 4, 0x50);
@@ -3505,11 +4041,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
3505 4041
3506 if (rt2x00_rt(rt2x00dev, RT3290) || 4042 if (rt2x00_rt(rt2x00dev, RT3290) ||
3507 rt2x00_rt(rt2x00dev, RT5390) || 4043 rt2x00_rt(rt2x00dev, RT5390) ||
3508 rt2x00_rt(rt2x00dev, RT5392)) { 4044 rt2x00_rt(rt2x00dev, RT5392))
3509 rt2800_bbp_read(rt2x00dev, 4, &value); 4045 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
3510 rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1);
3511 rt2800_bbp_write(rt2x00dev, 4, value);
3512 }
3513 4046
3514 if (rt2800_is_305x_soc(rt2x00dev) || 4047 if (rt2800_is_305x_soc(rt2x00dev) ||
3515 rt2x00_rt(rt2x00dev, RT3290) || 4048 rt2x00_rt(rt2x00dev, RT3290) ||
@@ -3783,9 +4316,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
3783 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); 4316 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
3784 rt2800_bbp_write(rt2x00dev, 152, value); 4317 rt2800_bbp_write(rt2x00dev, 152, value);
3785 4318
3786 /* Init frequency calibration */ 4319 rt2800_init_freq_calibration(rt2x00dev);
3787 rt2800_bbp_write(rt2x00dev, 142, 1);
3788 rt2800_bbp_write(rt2x00dev, 143, 57);
3789 } 4320 }
3790 4321
3791 for (i = 0; i < EEPROM_BBP_SIZE; i++) { 4322 for (i = 0; i < EEPROM_BBP_SIZE; i++) {
@@ -4259,6 +4790,69 @@ static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev)
4259 rt2800_rfcsr_write(rt2x00dev, 63, 0x07); 4790 rt2800_rfcsr_write(rt2x00dev, 63, 0x07);
4260} 4791}
4261 4792
4793static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev)
4794{
4795 u8 reg;
4796 u16 eeprom;
4797
4798 rt2800_rfcsr_write(rt2x00dev, 1, 0x3F);
4799 rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
4800 rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
4801 rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
4802 rt2800_rfcsr_write(rt2x00dev, 6, 0xE4);
4803 rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
4804 rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
4805 rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
4806 rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
4807 rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
4808 rt2800_rfcsr_write(rt2x00dev, 19, 0x4D);
4809 rt2800_rfcsr_write(rt2x00dev, 20, 0x10);
4810 rt2800_rfcsr_write(rt2x00dev, 21, 0x8D);
4811 rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
4812 rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
4813 rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
4814 rt2800_rfcsr_write(rt2x00dev, 33, 0xC0);
4815 rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
4816 rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
4817 rt2800_rfcsr_write(rt2x00dev, 47, 0x0C);
4818 rt2800_rfcsr_write(rt2x00dev, 53, 0x22);
4819 rt2800_rfcsr_write(rt2x00dev, 63, 0x07);
4820
4821 rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
4822 msleep(1);
4823
4824 rt2800_adjust_freq_offset(rt2x00dev);
4825
4826 rt2800_bbp_read(rt2x00dev, 138, &reg);
4827
4828 /* Turn off unused DAC1 and ADC1 to reduce power consumption */
4829 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
4830 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
4831 rt2x00_set_field8(&reg, BBP138_RX_ADC1, 0);
4832 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
4833 rt2x00_set_field8(&reg, BBP138_TX_DAC1, 1);
4834
4835 rt2800_bbp_write(rt2x00dev, 138, reg);
4836
4837 /* Enable DC filter */
4838 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C))
4839 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4840
4841 rt2800_rfcsr_read(rt2x00dev, 38, &reg);
4842 rt2x00_set_field8(&reg, RFCSR38_RX_LO1_EN, 0);
4843 rt2800_rfcsr_write(rt2x00dev, 38, reg);
4844
4845 rt2800_rfcsr_read(rt2x00dev, 39, &reg);
4846 rt2x00_set_field8(&reg, RFCSR39_RX_LO2_EN, 0);
4847 rt2800_rfcsr_write(rt2x00dev, 39, reg);
4848
4849 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
4850
4851 rt2800_rfcsr_read(rt2x00dev, 30, &reg);
4852 rt2x00_set_field8(&reg, RFCSR30_RX_VCM, 2);
4853 rt2800_rfcsr_write(rt2x00dev, 30, reg);
4854}
4855
4262static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) 4856static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
4263{ 4857{
4264 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; 4858 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
@@ -4276,6 +4870,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
4276 !rt2x00_rt(rt2x00dev, RT3572) && 4870 !rt2x00_rt(rt2x00dev, RT3572) &&
4277 !rt2x00_rt(rt2x00dev, RT5390) && 4871 !rt2x00_rt(rt2x00dev, RT5390) &&
4278 !rt2x00_rt(rt2x00dev, RT5392) && 4872 !rt2x00_rt(rt2x00dev, RT5392) &&
4873 !rt2x00_rt(rt2x00dev, RT5392) &&
4874 !rt2x00_rt(rt2x00dev, RT5592) &&
4279 !rt2800_is_305x_soc(rt2x00dev)) 4875 !rt2800_is_305x_soc(rt2x00dev))
4280 return 0; 4876 return 0;
4281 4877
@@ -4330,6 +4926,9 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
4330 case RT5392: 4926 case RT5392:
4331 rt2800_init_rfcsr_5392(rt2x00dev); 4927 rt2800_init_rfcsr_5392(rt2x00dev);
4332 break; 4928 break;
4929 case RT5592:
4930 rt2800_init_rfcsr_5592(rt2x00dev);
4931 return 0;
4333 } 4932 }
4334 4933
4335 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { 4934 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
@@ -4427,7 +5026,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
4427 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || 5026 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) ||
4428 rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || 5027 rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
4429 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || 5028 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
4430 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) 5029 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E) ||
5030 rt2x00_rt_rev_lt(rt2x00dev, RT5592, REV_RT5592C))
4431 rt2800_rfcsr_write(rt2x00dev, 27, 0x03); 5031 rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
4432 5032
4433 rt2800_register_read(rt2x00dev, OPT_14_CSR, &reg); 5033 rt2800_register_read(rt2x00dev, OPT_14_CSR, &reg);
@@ -4451,7 +5051,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
4451 rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); 5051 rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
4452 } 5052 }
4453 5053
4454 if (rt2x00_rt(rt2x00dev, RT3090)) { 5054 if (rt2x00_rt(rt2x00dev, RT3090) ||
5055 rt2x00_rt(rt2x00dev, RT5592)) {
4455 rt2800_bbp_read(rt2x00dev, 138, &bbp); 5056 rt2800_bbp_read(rt2x00dev, 138, &bbp);
4456 5057
4457 /* Turn off unused DAC1 and ADC1 to reduce power consumption */ 5058 /* Turn off unused DAC1 and ADC1 to reduce power consumption */
@@ -4507,7 +5108,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
4507 } 5108 }
4508 5109
4509 if (rt2x00_rt(rt2x00dev, RT5390) || 5110 if (rt2x00_rt(rt2x00dev, RT5390) ||
4510 rt2x00_rt(rt2x00dev, RT5392)) { 5111 rt2x00_rt(rt2x00dev, RT5392) ||
5112 rt2x00_rt(rt2x00dev, RT5592)) {
4511 rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); 5113 rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
4512 rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); 5114 rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0);
4513 rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); 5115 rt2800_rfcsr_write(rt2x00dev, 38, rfcsr);
@@ -4533,15 +5135,23 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
4533 * Initialize all registers. 5135 * Initialize all registers.
4534 */ 5136 */
4535 if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || 5137 if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
4536 rt2800_init_registers(rt2x00dev) || 5138 rt2800_init_registers(rt2x00dev)))
4537 rt2800_init_bbp(rt2x00dev) ||
4538 rt2800_init_rfcsr(rt2x00dev)))
4539 return -EIO; 5139 return -EIO;
4540 5140
4541 /* 5141 /*
4542 * Send signal to firmware during boot time. 5142 * Send signal to firmware during boot time.
4543 */ 5143 */
4544 rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); 5144 rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
5145 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
5146 if (rt2x00_is_usb(rt2x00dev)) {
5147 rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
5148 rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
5149 }
5150 msleep(1);
5151
5152 if (unlikely(rt2800_init_bbp(rt2x00dev) ||
5153 rt2800_init_rfcsr(rt2x00dev)))
5154 return -EIO;
4545 5155
4546 if (rt2x00_is_usb(rt2x00dev) && 5156 if (rt2x00_is_usb(rt2x00dev) &&
4547 (rt2x00_rt(rt2x00dev, RT3070) || 5157 (rt2x00_rt(rt2x00dev, RT3070) ||
@@ -4863,6 +5473,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
4863 case RT3572: 5473 case RT3572:
4864 case RT5390: 5474 case RT5390:
4865 case RT5392: 5475 case RT5392:
5476 case RT5592:
4866 break; 5477 break;
4867 default: 5478 default:
4868 ERROR(rt2x00dev, "Invalid RT chipset 0x%04x detected.\n", rt2x00dev->chip.rt); 5479 ERROR(rt2x00dev, "Invalid RT chipset 0x%04x detected.\n", rt2x00dev->chip.rt);
@@ -4887,6 +5498,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
4887 case RF5372: 5498 case RF5372:
4888 case RF5390: 5499 case RF5390:
4889 case RF5392: 5500 case RF5392:
5501 case RF5592:
4890 break; 5502 break;
4891 default: 5503 default:
4892 ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", 5504 ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n",
@@ -5122,6 +5734,138 @@ static const struct rf_channel rf_vals_3x[] = {
5122 {173, 0x61, 0, 9}, 5734 {173, 0x61, 0, 9},
5123}; 5735};
5124 5736
5737static const struct rf_channel rf_vals_5592_xtal20[] = {
5738 /* Channel, N, K, mod, R */
5739 {1, 482, 4, 10, 3},
5740 {2, 483, 4, 10, 3},
5741 {3, 484, 4, 10, 3},
5742 {4, 485, 4, 10, 3},
5743 {5, 486, 4, 10, 3},
5744 {6, 487, 4, 10, 3},
5745 {7, 488, 4, 10, 3},
5746 {8, 489, 4, 10, 3},
5747 {9, 490, 4, 10, 3},
5748 {10, 491, 4, 10, 3},
5749 {11, 492, 4, 10, 3},
5750 {12, 493, 4, 10, 3},
5751 {13, 494, 4, 10, 3},
5752 {14, 496, 8, 10, 3},
5753 {36, 172, 8, 12, 1},
5754 {38, 173, 0, 12, 1},
5755 {40, 173, 4, 12, 1},
5756 {42, 173, 8, 12, 1},
5757 {44, 174, 0, 12, 1},
5758 {46, 174, 4, 12, 1},
5759 {48, 174, 8, 12, 1},
5760 {50, 175, 0, 12, 1},
5761 {52, 175, 4, 12, 1},
5762 {54, 175, 8, 12, 1},
5763 {56, 176, 0, 12, 1},
5764 {58, 176, 4, 12, 1},
5765 {60, 176, 8, 12, 1},
5766 {62, 177, 0, 12, 1},
5767 {64, 177, 4, 12, 1},
5768 {100, 183, 4, 12, 1},
5769 {102, 183, 8, 12, 1},
5770 {104, 184, 0, 12, 1},
5771 {106, 184, 4, 12, 1},
5772 {108, 184, 8, 12, 1},
5773 {110, 185, 0, 12, 1},
5774 {112, 185, 4, 12, 1},
5775 {114, 185, 8, 12, 1},
5776 {116, 186, 0, 12, 1},
5777 {118, 186, 4, 12, 1},
5778 {120, 186, 8, 12, 1},
5779 {122, 187, 0, 12, 1},
5780 {124, 187, 4, 12, 1},
5781 {126, 187, 8, 12, 1},
5782 {128, 188, 0, 12, 1},
5783 {130, 188, 4, 12, 1},
5784 {132, 188, 8, 12, 1},
5785 {134, 189, 0, 12, 1},
5786 {136, 189, 4, 12, 1},
5787 {138, 189, 8, 12, 1},
5788 {140, 190, 0, 12, 1},
5789 {149, 191, 6, 12, 1},
5790 {151, 191, 10, 12, 1},
5791 {153, 192, 2, 12, 1},
5792 {155, 192, 6, 12, 1},
5793 {157, 192, 10, 12, 1},
5794 {159, 193, 2, 12, 1},
5795 {161, 193, 6, 12, 1},
5796 {165, 194, 2, 12, 1},
5797 {184, 164, 0, 12, 1},
5798 {188, 164, 4, 12, 1},
5799 {192, 165, 8, 12, 1},
5800 {196, 166, 0, 12, 1},
5801};
5802
5803static const struct rf_channel rf_vals_5592_xtal40[] = {
5804 /* Channel, N, K, mod, R */
5805 {1, 241, 2, 10, 3},
5806 {2, 241, 7, 10, 3},
5807 {3, 242, 2, 10, 3},
5808 {4, 242, 7, 10, 3},
5809 {5, 243, 2, 10, 3},
5810 {6, 243, 7, 10, 3},
5811 {7, 244, 2, 10, 3},
5812 {8, 244, 7, 10, 3},
5813 {9, 245, 2, 10, 3},
5814 {10, 245, 7, 10, 3},
5815 {11, 246, 2, 10, 3},
5816 {12, 246, 7, 10, 3},
5817 {13, 247, 2, 10, 3},
5818 {14, 248, 4, 10, 3},
5819 {36, 86, 4, 12, 1},
5820 {38, 86, 6, 12, 1},
5821 {40, 86, 8, 12, 1},
5822 {42, 86, 10, 12, 1},
5823 {44, 87, 0, 12, 1},
5824 {46, 87, 2, 12, 1},
5825 {48, 87, 4, 12, 1},
5826 {50, 87, 6, 12, 1},
5827 {52, 87, 8, 12, 1},
5828 {54, 87, 10, 12, 1},
5829 {56, 88, 0, 12, 1},
5830 {58, 88, 2, 12, 1},
5831 {60, 88, 4, 12, 1},
5832 {62, 88, 6, 12, 1},
5833 {64, 88, 8, 12, 1},
5834 {100, 91, 8, 12, 1},
5835 {102, 91, 10, 12, 1},
5836 {104, 92, 0, 12, 1},
5837 {106, 92, 2, 12, 1},
5838 {108, 92, 4, 12, 1},
5839 {110, 92, 6, 12, 1},
5840 {112, 92, 8, 12, 1},
5841 {114, 92, 10, 12, 1},
5842 {116, 93, 0, 12, 1},
5843 {118, 93, 2, 12, 1},
5844 {120, 93, 4, 12, 1},
5845 {122, 93, 6, 12, 1},
5846 {124, 93, 8, 12, 1},
5847 {126, 93, 10, 12, 1},
5848 {128, 94, 0, 12, 1},
5849 {130, 94, 2, 12, 1},
5850 {132, 94, 4, 12, 1},
5851 {134, 94, 6, 12, 1},
5852 {136, 94, 8, 12, 1},
5853 {138, 94, 10, 12, 1},
5854 {140, 95, 0, 12, 1},
5855 {149, 95, 9, 12, 1},
5856 {151, 95, 11, 12, 1},
5857 {153, 96, 1, 12, 1},
5858 {155, 96, 3, 12, 1},
5859 {157, 96, 5, 12, 1},
5860 {159, 96, 7, 12, 1},
5861 {161, 96, 9, 12, 1},
5862 {165, 97, 1, 12, 1},
5863 {184, 82, 0, 12, 1},
5864 {188, 82, 4, 12, 1},
5865 {192, 82, 8, 12, 1},
5866 {196, 83, 0, 12, 1},
5867};
5868
5125static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) 5869static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
5126{ 5870{
5127 struct hw_mode_spec *spec = &rt2x00dev->spec; 5871 struct hw_mode_spec *spec = &rt2x00dev->spec;
@@ -5130,6 +5874,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
5130 char *default_power2; 5874 char *default_power2;
5131 unsigned int i; 5875 unsigned int i;
5132 u16 eeprom; 5876 u16 eeprom;
5877 u32 reg;
5133 5878
5134 /* 5879 /*
5135 * Disable powersaving as default on PCI devices. 5880 * Disable powersaving as default on PCI devices.
@@ -5211,8 +5956,22 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
5211 spec->supported_bands |= SUPPORT_BAND_5GHZ; 5956 spec->supported_bands |= SUPPORT_BAND_5GHZ;
5212 spec->num_channels = ARRAY_SIZE(rf_vals_3x); 5957 spec->num_channels = ARRAY_SIZE(rf_vals_3x);
5213 spec->channels = rf_vals_3x; 5958 spec->channels = rf_vals_3x;
5959 } else if (rt2x00_rf(rt2x00dev, RF5592)) {
5960 spec->supported_bands |= SUPPORT_BAND_5GHZ;
5961
5962 rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX, &reg);
5963 if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) {
5964 spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal40);
5965 spec->channels = rf_vals_5592_xtal40;
5966 } else {
5967 spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal20);
5968 spec->channels = rf_vals_5592_xtal20;
5969 }
5214 } 5970 }
5215 5971
5972 if (WARN_ON_ONCE(!spec->channels))
5973 return -ENODEV;
5974
5216 /* 5975 /*
5217 * Initialize HT information. 5976 * Initialize HT information.
5218 */ 5977 */
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index ded73da4de0b..f732ded8f1ba 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -729,6 +729,11 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
729 * Process the RXWI structure that is at the start of the buffer. 729 * Process the RXWI structure that is at the start of the buffer.
730 */ 730 */
731 rt2800_process_rxwi(entry, rxdesc); 731 rt2800_process_rxwi(entry, rxdesc);
732
733 /*
734 * Remove RXWI descriptor from start of buffer.
735 */
736 skb_pull(entry->skb, RXWI_DESC_SIZE);
732} 737}
733 738
734/* 739/*
@@ -742,10 +747,90 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
742 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); 747 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
743} 748}
744 749
750static bool rt2800pci_txdone_entry_check(struct queue_entry *entry, u32 status)
751{
752 __le32 *txwi;
753 u32 word;
754 int wcid, tx_wcid;
755
756 wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID);
757
758 txwi = rt2800_drv_get_txwi(entry);
759 rt2x00_desc_read(txwi, 1, &word);
760 tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
761
762 return (tx_wcid == wcid);
763}
764
765static bool rt2800pci_txdone_find_entry(struct queue_entry *entry, void *data)
766{
767 u32 status = *(u32 *)data;
768
769 /*
770 * rt2800pci hardware might reorder frames when exchanging traffic
771 * with multiple BA enabled STAs.
772 *
773 * For example, a tx queue
774 * [ STA1 | STA2 | STA1 | STA2 ]
775 * can result in tx status reports
776 * [ STA1 | STA1 | STA2 | STA2 ]
777 * when the hw decides to aggregate the frames for STA1 into one AMPDU.
778 *
779 * To mitigate this effect, associate the tx status to the first frame
780 * in the tx queue with a matching wcid.
781 */
782 if (rt2800pci_txdone_entry_check(entry, status) &&
783 !test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
784 /*
785 * Got a matching frame, associate the tx status with
786 * the frame
787 */
788 entry->status = status;
789 set_bit(ENTRY_DATA_STATUS_SET, &entry->flags);
790 return true;
791 }
792
793 /* Check the next frame */
794 return false;
795}
796
797static bool rt2800pci_txdone_match_first(struct queue_entry *entry, void *data)
798{
799 u32 status = *(u32 *)data;
800
801 /*
802 * Find the first frame without tx status and assign this status to it
803 * regardless if it matches or not.
804 */
805 if (!test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
806 /*
807 * Got a matching frame, associate the tx status with
808 * the frame
809 */
810 entry->status = status;
811 set_bit(ENTRY_DATA_STATUS_SET, &entry->flags);
812 return true;
813 }
814
815 /* Check the next frame */
816 return false;
817}
818static bool rt2800pci_txdone_release_entries(struct queue_entry *entry,
819 void *data)
820{
821 if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
822 rt2800_txdone_entry(entry, entry->status,
823 rt2800pci_get_txwi(entry));
824 return false;
825 }
826
827 /* No more frames to release */
828 return true;
829}
830
745static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) 831static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
746{ 832{
747 struct data_queue *queue; 833 struct data_queue *queue;
748 struct queue_entry *entry;
749 u32 status; 834 u32 status;
750 u8 qid; 835 u8 qid;
751 int max_tx_done = 16; 836 int max_tx_done = 16;
@@ -783,8 +868,33 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
783 break; 868 break;
784 } 869 }
785 870
786 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); 871 /*
787 rt2800_txdone_entry(entry, status, rt2800pci_get_txwi(entry)); 872 * Let's associate this tx status with the first
873 * matching frame.
874 */
875 if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE,
876 Q_INDEX, &status,
877 rt2800pci_txdone_find_entry)) {
878 /*
879 * We cannot match the tx status to any frame, so just
880 * use the first one.
881 */
882 if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE,
883 Q_INDEX, &status,
884 rt2800pci_txdone_match_first)) {
885 WARNING(rt2x00dev, "No frame found for TX "
886 "status on queue %u, dropping\n",
887 qid);
888 break;
889 }
890 }
891
892 /*
893 * Release all frames with a valid tx status.
894 */
895 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE,
896 Q_INDEX, NULL,
897 rt2800pci_txdone_release_entries);
788 898
789 if (--max_tx_done == 0) 899 if (--max_tx_done == 0)
790 break; 900 break;
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 098613ed93fb..f32282009146 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -485,7 +485,7 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry,
485 */ 485 */
486 skbdesc->flags |= SKBDESC_DESC_IN_SKB; 486 skbdesc->flags |= SKBDESC_DESC_IN_SKB;
487 skbdesc->desc = txi; 487 skbdesc->desc = txi;
488 skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; 488 skbdesc->desc_len = entry->queue->desc_size;
489} 489}
490 490
491/* 491/*
@@ -730,6 +730,11 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
730 * Process the RXWI structure. 730 * Process the RXWI structure.
731 */ 731 */
732 rt2800_process_rxwi(entry, rxdesc); 732 rt2800_process_rxwi(entry, rxdesc);
733
734 /*
735 * Remove RXWI descriptor from start of buffer.
736 */
737 skb_pull(entry->skb, entry->queue->desc_size - RXINFO_DESC_SIZE);
733} 738}
734 739
735/* 740/*
@@ -890,6 +895,47 @@ static const struct rt2x00_ops rt2800usb_ops = {
890#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 895#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
891}; 896};
892 897
898static const struct data_queue_desc rt2800usb_queue_rx_5592 = {
899 .entry_num = 128,
900 .data_size = AGGREGATION_SIZE,
901 .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE_5592,
902 .priv_size = sizeof(struct queue_entry_priv_usb),
903};
904
905static const struct data_queue_desc rt2800usb_queue_tx_5592 = {
906 .entry_num = 16,
907 .data_size = AGGREGATION_SIZE,
908 .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592,
909 .priv_size = sizeof(struct queue_entry_priv_usb),
910};
911
912static const struct data_queue_desc rt2800usb_queue_bcn_5592 = {
913 .entry_num = 8,
914 .data_size = MGMT_FRAME_SIZE,
915 .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592,
916 .priv_size = sizeof(struct queue_entry_priv_usb),
917};
918
919
920static const struct rt2x00_ops rt2800usb_ops_5592 = {
921 .name = KBUILD_MODNAME,
922 .drv_data_size = sizeof(struct rt2800_drv_data),
923 .max_ap_intf = 8,
924 .eeprom_size = EEPROM_SIZE,
925 .rf_size = RF_SIZE,
926 .tx_queues = NUM_TX_QUEUES,
927 .extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592,
928 .rx = &rt2800usb_queue_rx_5592,
929 .tx = &rt2800usb_queue_tx_5592,
930 .bcn = &rt2800usb_queue_bcn_5592,
931 .lib = &rt2800usb_rt2x00_ops,
932 .drv = &rt2800usb_rt2800_ops,
933 .hw = &rt2800usb_mac80211_ops,
934#ifdef CONFIG_RT2X00_LIB_DEBUGFS
935 .debugfs = &rt2800_rt2x00debug,
936#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
937};
938
893/* 939/*
894 * rt2800usb module information. 940 * rt2800usb module information.
895 */ 941 */
@@ -1200,6 +1246,18 @@ static struct usb_device_id rt2800usb_device_table[] = {
1200 { USB_DEVICE(0x148f, 0x5370) }, 1246 { USB_DEVICE(0x148f, 0x5370) },
1201 { USB_DEVICE(0x148f, 0x5372) }, 1247 { USB_DEVICE(0x148f, 0x5372) },
1202#endif 1248#endif
1249#ifdef CONFIG_RT2800USB_RT55XX
1250 /* Arcadyan */
1251 { USB_DEVICE(0x043e, 0x7a32), .driver_info = 5592 },
1252 /* AVM GmbH */
1253 { USB_DEVICE(0x057c, 0x8501), .driver_info = 5592 },
1254 /* D-Link DWA-160-B2 */
1255 { USB_DEVICE(0x2001, 0x3c1a), .driver_info = 5592 },
1256 /* Proware */
1257 { USB_DEVICE(0x043e, 0x7a13), .driver_info = 5592 },
1258 /* Ralink */
1259 { USB_DEVICE(0x148f, 0x5572), .driver_info = 5592 },
1260#endif
1203#ifdef CONFIG_RT2800USB_UNKNOWN 1261#ifdef CONFIG_RT2800USB_UNKNOWN
1204 /* 1262 /*
1205 * Unclear what kind of devices these are (they aren't supported by the 1263 * Unclear what kind of devices these are (they aren't supported by the
@@ -1303,6 +1361,9 @@ MODULE_LICENSE("GPL");
1303static int rt2800usb_probe(struct usb_interface *usb_intf, 1361static int rt2800usb_probe(struct usb_interface *usb_intf,
1304 const struct usb_device_id *id) 1362 const struct usb_device_id *id)
1305{ 1363{
1364 if (id->driver_info == 5592)
1365 return rt2x00usb_probe(usb_intf, &rt2800usb_ops_5592);
1366
1306 return rt2x00usb_probe(usb_intf, &rt2800usb_ops); 1367 return rt2x00usb_probe(usb_intf, &rt2800usb_ops);
1307} 1368}
1308 1369
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 086abb403a4f..51922cc179de 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -193,6 +193,7 @@ struct rt2x00_chip {
193#define RT3883 0x3883 /* WSOC */ 193#define RT3883 0x3883 /* WSOC */
194#define RT5390 0x5390 /* 2.4GHz */ 194#define RT5390 0x5390 /* 2.4GHz */
195#define RT5392 0x5392 /* 2.4GHz */ 195#define RT5392 0x5392 /* 2.4GHz */
196#define RT5592 0x5592
196 197
197 u16 rf; 198 u16 rf;
198 u16 rev; 199 u16 rev;
@@ -1064,8 +1065,7 @@ static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev,
1064} 1065}
1065 1066
1066/* 1067/*
1067 * Generic EEPROM access. 1068 * Generic EEPROM access. The EEPROM is being accessed by word or byte index.
1068 * The EEPROM is being accessed by word index.
1069 */ 1069 */
1070static inline void *rt2x00_eeprom_addr(struct rt2x00_dev *rt2x00dev, 1070static inline void *rt2x00_eeprom_addr(struct rt2x00_dev *rt2x00dev,
1071 const unsigned int word) 1071 const unsigned int word)
@@ -1085,6 +1085,12 @@ static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev,
1085 rt2x00dev->eeprom[word] = cpu_to_le16(data); 1085 rt2x00dev->eeprom[word] = cpu_to_le16(data);
1086} 1086}
1087 1087
1088static inline u8 rt2x00_eeprom_byte(struct rt2x00_dev *rt2x00dev,
1089 const unsigned int byte)
1090{
1091 return *(((u8 *)rt2x00dev->eeprom) + byte);
1092}
1093
1088/* 1094/*
1089 * Chipset handlers 1095 * Chipset handlers
1090 */ 1096 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 696abed3e74b..c4009eaeb697 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -52,8 +52,8 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
52 udelay(REGISTER_BUSY_DELAY); 52 udelay(REGISTER_BUSY_DELAY);
53 } 53 }
54 54
55 ERROR(rt2x00dev, "Indirect register access failed: " 55 printk_once(KERN_ERR "%s() Indirect register access failed: "
56 "offset=0x%.08x, value=0x%.08x\n", offset, *reg); 56 "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg);
57 *reg = ~0; 57 *reg = ~0;
58 58
59 return 0; 59 return 0;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 4d91795dc6a2..952a0490eb17 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -832,7 +832,9 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
832bool rt2x00queue_for_each_entry(struct data_queue *queue, 832bool rt2x00queue_for_each_entry(struct data_queue *queue,
833 enum queue_index start, 833 enum queue_index start,
834 enum queue_index end, 834 enum queue_index end,
835 bool (*fn)(struct queue_entry *entry)) 835 void *data,
836 bool (*fn)(struct queue_entry *entry,
837 void *data))
836{ 838{
837 unsigned long irqflags; 839 unsigned long irqflags;
838 unsigned int index_start; 840 unsigned int index_start;
@@ -863,17 +865,17 @@ bool rt2x00queue_for_each_entry(struct data_queue *queue,
863 */ 865 */
864 if (index_start < index_end) { 866 if (index_start < index_end) {
865 for (i = index_start; i < index_end; i++) { 867 for (i = index_start; i < index_end; i++) {
866 if (fn(&queue->entries[i])) 868 if (fn(&queue->entries[i], data))
867 return true; 869 return true;
868 } 870 }
869 } else { 871 } else {
870 for (i = index_start; i < queue->limit; i++) { 872 for (i = index_start; i < queue->limit; i++) {
871 if (fn(&queue->entries[i])) 873 if (fn(&queue->entries[i], data))
872 return true; 874 return true;
873 } 875 }
874 876
875 for (i = 0; i < index_end; i++) { 877 for (i = 0; i < index_end; i++) {
876 if (fn(&queue->entries[i])) 878 if (fn(&queue->entries[i], data))
877 return true; 879 return true;
878 } 880 }
879 } 881 }
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 9b8c10a86dee..3d0137193da0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -359,6 +359,7 @@ enum queue_entry_flags {
359 ENTRY_DATA_PENDING, 359 ENTRY_DATA_PENDING,
360 ENTRY_DATA_IO_FAILED, 360 ENTRY_DATA_IO_FAILED,
361 ENTRY_DATA_STATUS_PENDING, 361 ENTRY_DATA_STATUS_PENDING,
362 ENTRY_DATA_STATUS_SET,
362}; 363};
363 364
364/** 365/**
@@ -372,6 +373,7 @@ enum queue_entry_flags {
372 * @entry_idx: The entry index number. 373 * @entry_idx: The entry index number.
373 * @priv_data: Private data belonging to this queue entry. The pointer 374 * @priv_data: Private data belonging to this queue entry. The pointer
374 * points to data specific to a particular driver and queue type. 375 * points to data specific to a particular driver and queue type.
376 * @status: Device specific status
375 */ 377 */
376struct queue_entry { 378struct queue_entry {
377 unsigned long flags; 379 unsigned long flags;
@@ -383,6 +385,8 @@ struct queue_entry {
383 385
384 unsigned int entry_idx; 386 unsigned int entry_idx;
385 387
388 u32 status;
389
386 void *priv_data; 390 void *priv_data;
387}; 391};
388 392
@@ -584,6 +588,7 @@ struct data_queue_desc {
584 * @queue: Pointer to @data_queue 588 * @queue: Pointer to @data_queue
585 * @start: &enum queue_index Pointer to start index 589 * @start: &enum queue_index Pointer to start index
586 * @end: &enum queue_index Pointer to end index 590 * @end: &enum queue_index Pointer to end index
591 * @data: Data to pass to the callback function
587 * @fn: The function to call for each &struct queue_entry 592 * @fn: The function to call for each &struct queue_entry
588 * 593 *
589 * This will walk through all entries in the queue, in chronological 594 * This will walk through all entries in the queue, in chronological
@@ -596,7 +601,9 @@ struct data_queue_desc {
596bool rt2x00queue_for_each_entry(struct data_queue *queue, 601bool rt2x00queue_for_each_entry(struct data_queue *queue,
597 enum queue_index start, 602 enum queue_index start,
598 enum queue_index end, 603 enum queue_index end,
599 bool (*fn)(struct queue_entry *entry)); 604 void *data,
605 bool (*fn)(struct queue_entry *entry,
606 void *data));
600 607
601/** 608/**
602 * rt2x00queue_empty - Check if the queue is empty. 609 * rt2x00queue_empty - Check if the queue is empty.
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 40ea80725a96..5e50d4ff9d21 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -285,7 +285,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
285 queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); 285 queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
286} 286}
287 287
288static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry) 288static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data)
289{ 289{
290 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 290 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
291 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 291 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
@@ -390,7 +390,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
390 queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); 390 queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work);
391} 391}
392 392
393static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry) 393static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data)
394{ 394{
395 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 395 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
396 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 396 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
@@ -427,12 +427,18 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
427 case QID_AC_BE: 427 case QID_AC_BE:
428 case QID_AC_BK: 428 case QID_AC_BK:
429 if (!rt2x00queue_empty(queue)) 429 if (!rt2x00queue_empty(queue))
430 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, 430 rt2x00queue_for_each_entry(queue,
431 Q_INDEX_DONE,
432 Q_INDEX,
433 NULL,
431 rt2x00usb_kick_tx_entry); 434 rt2x00usb_kick_tx_entry);
432 break; 435 break;
433 case QID_RX: 436 case QID_RX:
434 if (!rt2x00queue_full(queue)) 437 if (!rt2x00queue_full(queue))
435 rt2x00queue_for_each_entry(queue, Q_INDEX, Q_INDEX_DONE, 438 rt2x00queue_for_each_entry(queue,
439 Q_INDEX,
440 Q_INDEX_DONE,
441 NULL,
436 rt2x00usb_kick_rx_entry); 442 rt2x00usb_kick_rx_entry);
437 break; 443 break;
438 default: 444 default:
@@ -441,7 +447,7 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
441} 447}
442EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); 448EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue);
443 449
444static bool rt2x00usb_flush_entry(struct queue_entry *entry) 450static bool rt2x00usb_flush_entry(struct queue_entry *entry, void *data)
445{ 451{
446 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 452 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
447 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 453 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
@@ -468,7 +474,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue, bool drop)
468 unsigned int i; 474 unsigned int i;
469 475
470 if (drop) 476 if (drop)
471 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, 477 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL,
472 rt2x00usb_flush_entry); 478 rt2x00usb_flush_entry);
473 479
474 /* 480 /*
@@ -559,7 +565,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
559 entry->flags = 0; 565 entry->flags = 0;
560 566
561 if (entry->queue->qid == QID_RX) 567 if (entry->queue->qid == QID_RX)
562 rt2x00usb_kick_rx_entry(entry); 568 rt2x00usb_kick_rx_entry(entry, NULL);
563} 569}
564EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); 570EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
565 571
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 156b52732f3d..b5c80b5d57ef 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -224,10 +224,9 @@ static void _usb_writeN_sync(struct rtl_priv *rtlpriv, u32 addr, void *data,
224 u8 *buffer; 224 u8 *buffer;
225 225
226 wvalue = (u16)(addr & 0x0000ffff); 226 wvalue = (u16)(addr & 0x0000ffff);
227 buffer = kmalloc(len, GFP_ATOMIC); 227 buffer = kmemdup(data, len, GFP_ATOMIC);
228 if (!buffer) 228 if (!buffer)
229 return; 229 return;
230 memcpy(buffer, data, len);
231 usb_control_msg(udev, pipe, request, reqtype, wvalue, 230 usb_control_msg(udev, pipe, request, reqtype, wvalue,
232 index, buffer, len, 50); 231 index, buffer, len, 50);
233 232
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index f13258a8d995..c3eff32acf6c 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -2127,9 +2127,6 @@ value to host byte ordering.*/
2127#define WLAN_FC_GET_TYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) 2127#define WLAN_FC_GET_TYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE)
2128#define WLAN_FC_GET_STYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) 2128#define WLAN_FC_GET_STYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE)
2129#define WLAN_FC_MORE_DATA(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_MOREDATA) 2129#define WLAN_FC_MORE_DATA(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_MOREDATA)
2130#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
2131#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
2132#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
2133 2130
2134#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */ 2131#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */
2135#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */ 2132#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 2c2ff3e1f849..d7e306333f6c 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -4956,7 +4956,8 @@ static void wlcore_op_flush(struct ieee80211_hw *hw, bool drop)
4956static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw, 4956static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw,
4957 struct ieee80211_vif *vif, 4957 struct ieee80211_vif *vif,
4958 struct ieee80211_channel *chan, 4958 struct ieee80211_channel *chan,
4959 int duration) 4959 int duration,
4960 enum ieee80211_roc_type type)
4960{ 4961{
4961 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 4962 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4962 struct wl1271 *wl = hw->priv; 4963 struct wl1271 *wl = hw->priv;
diff --git a/drivers/nfc/microread/mei.c b/drivers/nfc/microread/mei.c
index eef38cfd812e..13bde92b1e29 100644
--- a/drivers/nfc/microread/mei.c
+++ b/drivers/nfc/microread/mei.c
@@ -48,7 +48,7 @@ struct mei_nfc_hdr {
48#define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) 48#define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD)
49 49
50struct microread_mei_phy { 50struct microread_mei_phy {
51 struct mei_device *mei_device; 51 struct mei_device *device;
52 struct nfc_hci_dev *hdev; 52 struct nfc_hci_dev *hdev;
53 53
54 int powered; 54 int powered;
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 71098a7b5fed..7cb7d2c8fd86 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -354,7 +354,7 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
354 354
355 if (cc->dev->id.revision >= 11) 355 if (cc->dev->id.revision >= 11)
356 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); 356 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
357 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); 357 ssb_dbg("chipcommon status is 0x%x\n", cc->status);
358 358
359 if (cc->dev->id.revision >= 20) { 359 if (cc->dev->id.revision >= 20) {
360 chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0); 360 chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0);
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index 4c0f6d883dd3..791da2c0d8f6 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -110,8 +110,8 @@ static void ssb_pmu0_pllinit_r0(struct ssb_chipcommon *cc,
110 return; 110 return;
111 } 111 }
112 112
113 ssb_printk(KERN_INFO PFX "Programming PLL to %u.%03u MHz\n", 113 ssb_info("Programming PLL to %u.%03u MHz\n",
114 (crystalfreq / 1000), (crystalfreq % 1000)); 114 crystalfreq / 1000, crystalfreq % 1000);
115 115
116 /* First turn the PLL off. */ 116 /* First turn the PLL off. */
117 switch (bus->chip_id) { 117 switch (bus->chip_id) {
@@ -138,7 +138,7 @@ static void ssb_pmu0_pllinit_r0(struct ssb_chipcommon *cc,
138 } 138 }
139 tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST); 139 tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST);
140 if (tmp & SSB_CHIPCO_CLKCTLST_HAVEHT) 140 if (tmp & SSB_CHIPCO_CLKCTLST_HAVEHT)
141 ssb_printk(KERN_EMERG PFX "Failed to turn the PLL off!\n"); 141 ssb_emerg("Failed to turn the PLL off!\n");
142 142
143 /* Set PDIV in PLL control 0. */ 143 /* Set PDIV in PLL control 0. */
144 pllctl = ssb_chipco_pll_read(cc, SSB_PMU0_PLLCTL0); 144 pllctl = ssb_chipco_pll_read(cc, SSB_PMU0_PLLCTL0);
@@ -249,8 +249,8 @@ static void ssb_pmu1_pllinit_r0(struct ssb_chipcommon *cc,
249 return; 249 return;
250 } 250 }
251 251
252 ssb_printk(KERN_INFO PFX "Programming PLL to %u.%03u MHz\n", 252 ssb_info("Programming PLL to %u.%03u MHz\n",
253 (crystalfreq / 1000), (crystalfreq % 1000)); 253 crystalfreq / 1000, crystalfreq % 1000);
254 254
255 /* First turn the PLL off. */ 255 /* First turn the PLL off. */
256 switch (bus->chip_id) { 256 switch (bus->chip_id) {
@@ -275,7 +275,7 @@ static void ssb_pmu1_pllinit_r0(struct ssb_chipcommon *cc,
275 } 275 }
276 tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST); 276 tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST);
277 if (tmp & SSB_CHIPCO_CLKCTLST_HAVEHT) 277 if (tmp & SSB_CHIPCO_CLKCTLST_HAVEHT)
278 ssb_printk(KERN_EMERG PFX "Failed to turn the PLL off!\n"); 278 ssb_emerg("Failed to turn the PLL off!\n");
279 279
280 /* Set p1div and p2div. */ 280 /* Set p1div and p2div. */
281 pllctl = ssb_chipco_pll_read(cc, SSB_PMU1_PLLCTL0); 281 pllctl = ssb_chipco_pll_read(cc, SSB_PMU1_PLLCTL0);
@@ -349,9 +349,8 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc)
349 case 43222: 349 case 43222:
350 break; 350 break;
351 default: 351 default:
352 ssb_printk(KERN_ERR PFX 352 ssb_err("ERROR: PLL init unknown for device %04X\n",
353 "ERROR: PLL init unknown for device %04X\n", 353 bus->chip_id);
354 bus->chip_id);
355 } 354 }
356} 355}
357 356
@@ -472,9 +471,8 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc)
472 max_msk = 0xFFFFF; 471 max_msk = 0xFFFFF;
473 break; 472 break;
474 default: 473 default:
475 ssb_printk(KERN_ERR PFX 474 ssb_err("ERROR: PMU resource config unknown for device %04X\n",
476 "ERROR: PMU resource config unknown for device %04X\n", 475 bus->chip_id);
477 bus->chip_id);
478 } 476 }
479 477
480 if (updown_tab) { 478 if (updown_tab) {
@@ -526,8 +524,8 @@ void ssb_pmu_init(struct ssb_chipcommon *cc)
526 pmucap = chipco_read32(cc, SSB_CHIPCO_PMU_CAP); 524 pmucap = chipco_read32(cc, SSB_CHIPCO_PMU_CAP);
527 cc->pmu.rev = (pmucap & SSB_CHIPCO_PMU_CAP_REVISION); 525 cc->pmu.rev = (pmucap & SSB_CHIPCO_PMU_CAP_REVISION);
528 526
529 ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n", 527 ssb_dbg("Found rev %u PMU (capabilities 0x%08X)\n",
530 cc->pmu.rev, pmucap); 528 cc->pmu.rev, pmucap);
531 529
532 if (cc->pmu.rev == 1) 530 if (cc->pmu.rev == 1)
533 chipco_mask32(cc, SSB_CHIPCO_PMU_CTL, 531 chipco_mask32(cc, SSB_CHIPCO_PMU_CTL,
@@ -638,9 +636,8 @@ u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc)
638 case 0x5354: 636 case 0x5354:
639 ssb_pmu_get_alp_clock_clk0(cc); 637 ssb_pmu_get_alp_clock_clk0(cc);
640 default: 638 default:
641 ssb_printk(KERN_ERR PFX 639 ssb_err("ERROR: PMU alp clock unknown for device %04X\n",
642 "ERROR: PMU alp clock unknown for device %04X\n", 640 bus->chip_id);
643 bus->chip_id);
644 return 0; 641 return 0;
645 } 642 }
646} 643}
@@ -654,9 +651,8 @@ u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc)
654 /* 5354 chip uses a non programmable PLL of frequency 240MHz */ 651 /* 5354 chip uses a non programmable PLL of frequency 240MHz */
655 return 240000000; 652 return 240000000;
656 default: 653 default:
657 ssb_printk(KERN_ERR PFX 654 ssb_err("ERROR: PMU cpu clock unknown for device %04X\n",
658 "ERROR: PMU cpu clock unknown for device %04X\n", 655 bus->chip_id);
659 bus->chip_id);
660 return 0; 656 return 0;
661 } 657 }
662} 658}
@@ -669,9 +665,8 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
669 case 0x5354: 665 case 0x5354:
670 return 120000000; 666 return 120000000;
671 default: 667 default:
672 ssb_printk(KERN_ERR PFX 668 ssb_err("ERROR: PMU controlclock unknown for device %04X\n",
673 "ERROR: PMU controlclock unknown for device %04X\n", 669 bus->chip_id);
674 bus->chip_id);
675 return 0; 670 return 0;
676 } 671 }
677} 672}
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index 33b37dac40bd..fa385a368a56 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -167,21 +167,22 @@ static void set_irq(struct ssb_device *dev, unsigned int irq)
167 irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]); 167 irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]);
168 ssb_write32(mdev, SSB_IPSFLAG, irqflag); 168 ssb_write32(mdev, SSB_IPSFLAG, irqflag);
169 } 169 }
170 ssb_dprintk(KERN_INFO PFX 170 ssb_dbg("set_irq: core 0x%04x, irq %d => %d\n",
171 "set_irq: core 0x%04x, irq %d => %d\n", 171 dev->id.coreid, oldirq+2, irq+2);
172 dev->id.coreid, oldirq+2, irq+2);
173} 172}
174 173
175static void print_irq(struct ssb_device *dev, unsigned int irq) 174static void print_irq(struct ssb_device *dev, unsigned int irq)
176{ 175{
177 int i;
178 static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; 176 static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
179 ssb_dprintk(KERN_INFO PFX 177 ssb_dbg("core 0x%04x, irq : %s%s %s%s %s%s %s%s %s%s %s%s %s%s\n",
180 "core 0x%04x, irq :", dev->id.coreid); 178 dev->id.coreid,
181 for (i = 0; i <= 6; i++) { 179 irq_name[0], irq == 0 ? "*" : " ",
182 ssb_dprintk(" %s%s", irq_name[i], i==irq?"*":" "); 180 irq_name[1], irq == 1 ? "*" : " ",
183 } 181 irq_name[2], irq == 2 ? "*" : " ",
184 ssb_dprintk("\n"); 182 irq_name[3], irq == 3 ? "*" : " ",
183 irq_name[4], irq == 4 ? "*" : " ",
184 irq_name[5], irq == 5 ? "*" : " ",
185 irq_name[6], irq == 6 ? "*" : " ");
185} 186}
186 187
187static void dump_irq(struct ssb_bus *bus) 188static void dump_irq(struct ssb_bus *bus)
@@ -286,7 +287,7 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore)
286 if (!mcore->dev) 287 if (!mcore->dev)
287 return; /* We don't have a MIPS core */ 288 return; /* We don't have a MIPS core */
288 289
289 ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n"); 290 ssb_dbg("Initializing MIPS core...\n");
290 291
291 bus = mcore->dev->bus; 292 bus = mcore->dev->bus;
292 hz = ssb_clockspeed(bus); 293 hz = ssb_clockspeed(bus);
@@ -334,7 +335,7 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore)
334 break; 335 break;
335 } 336 }
336 } 337 }
337 ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n"); 338 ssb_dbg("after irq reconfiguration\n");
338 dump_irq(bus); 339 dump_irq(bus);
339 340
340 ssb_mips_serial_init(mcore); 341 ssb_mips_serial_init(mcore);
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index 59801d23d7ec..d75b72ba2672 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -263,8 +263,7 @@ int ssb_pcicore_plat_dev_init(struct pci_dev *d)
263 return -ENODEV; 263 return -ENODEV;
264 } 264 }
265 265
266 ssb_printk(KERN_INFO "PCI: Fixing up device %s\n", 266 ssb_info("PCI: Fixing up device %s\n", pci_name(d));
267 pci_name(d));
268 267
269 /* Fix up interrupt lines */ 268 /* Fix up interrupt lines */
270 d->irq = ssb_mips_irq(extpci_core->dev) + 2; 269 d->irq = ssb_mips_irq(extpci_core->dev) + 2;
@@ -285,12 +284,12 @@ static void ssb_pcicore_fixup_pcibridge(struct pci_dev *dev)
285 if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0) 284 if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0)
286 return; 285 return;
287 286
288 ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev)); 287 ssb_info("PCI: Fixing up bridge %s\n", pci_name(dev));
289 288
290 /* Enable PCI bridge bus mastering and memory space */ 289 /* Enable PCI bridge bus mastering and memory space */
291 pci_set_master(dev); 290 pci_set_master(dev);
292 if (pcibios_enable_device(dev, ~0) < 0) { 291 if (pcibios_enable_device(dev, ~0) < 0) {
293 ssb_printk(KERN_ERR "PCI: SSB bridge enable failed\n"); 292 ssb_err("PCI: SSB bridge enable failed\n");
294 return; 293 return;
295 } 294 }
296 295
@@ -299,8 +298,8 @@ static void ssb_pcicore_fixup_pcibridge(struct pci_dev *dev)
299 298
300 /* Make sure our latency is high enough to handle the devices behind us */ 299 /* Make sure our latency is high enough to handle the devices behind us */
301 lat = 168; 300 lat = 168;
302 ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n", 301 ssb_info("PCI: Fixing latency timer of device %s to %u\n",
303 pci_name(dev), lat); 302 pci_name(dev), lat);
304 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); 303 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
305} 304}
306DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_pcicore_fixup_pcibridge); 305DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_pcicore_fixup_pcibridge);
@@ -323,7 +322,7 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
323 return; 322 return;
324 extpci_core = pc; 323 extpci_core = pc;
325 324
326 ssb_dprintk(KERN_INFO PFX "PCIcore in host mode found\n"); 325 ssb_dbg("PCIcore in host mode found\n");
327 /* Reset devices on the external PCI bus */ 326 /* Reset devices on the external PCI bus */
328 val = SSB_PCICORE_CTL_RST_OE; 327 val = SSB_PCICORE_CTL_RST_OE;
329 val |= SSB_PCICORE_CTL_CLK_OE; 328 val |= SSB_PCICORE_CTL_CLK_OE;
@@ -338,7 +337,7 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
338 udelay(1); /* Assertion time demanded by the PCI standard */ 337 udelay(1); /* Assertion time demanded by the PCI standard */
339 338
340 if (pc->dev->bus->has_cardbus_slot) { 339 if (pc->dev->bus->has_cardbus_slot) {
341 ssb_dprintk(KERN_INFO PFX "CardBus slot detected\n"); 340 ssb_dbg("CardBus slot detected\n");
342 pc->cardbusmode = 1; 341 pc->cardbusmode = 1;
343 /* GPIO 1 resets the bridge */ 342 /* GPIO 1 resets the bridge */
344 ssb_gpio_out(pc->dev->bus, 1, 1); 343 ssb_gpio_out(pc->dev->bus, 1, 1);
diff --git a/drivers/ssb/embedded.c b/drivers/ssb/embedded.c
index bb18d76f9f2c..55e101115038 100644
--- a/drivers/ssb/embedded.c
+++ b/drivers/ssb/embedded.c
@@ -57,9 +57,8 @@ int ssb_watchdog_register(struct ssb_bus *bus)
57 bus->busnumber, &wdt, 57 bus->busnumber, &wdt,
58 sizeof(wdt)); 58 sizeof(wdt));
59 if (IS_ERR(pdev)) { 59 if (IS_ERR(pdev)) {
60 ssb_dprintk(KERN_INFO PFX 60 ssb_dbg("can not register watchdog device, err: %li\n",
61 "can not register watchdog device, err: %li\n", 61 PTR_ERR(pdev));
62 PTR_ERR(pdev));
63 return PTR_ERR(pdev); 62 return PTR_ERR(pdev);
64 } 63 }
65 64
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 3b645b8a261f..812775a4bfb6 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -275,8 +275,8 @@ int ssb_devices_thaw(struct ssb_freeze_context *ctx)
275 275
276 err = sdrv->probe(sdev, &sdev->id); 276 err = sdrv->probe(sdev, &sdev->id);
277 if (err) { 277 if (err) {
278 ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n", 278 ssb_err("Failed to thaw device %s\n",
279 dev_name(sdev->dev)); 279 dev_name(sdev->dev));
280 result = err; 280 result = err;
281 } 281 }
282 ssb_device_put(sdev); 282 ssb_device_put(sdev);
@@ -447,10 +447,9 @@ void ssb_bus_unregister(struct ssb_bus *bus)
447 447
448 err = ssb_gpio_unregister(bus); 448 err = ssb_gpio_unregister(bus);
449 if (err == -EBUSY) 449 if (err == -EBUSY)
450 ssb_dprintk(KERN_ERR PFX "Some GPIOs are still in use.\n"); 450 ssb_dbg("Some GPIOs are still in use\n");
451 else if (err) 451 else if (err)
452 ssb_dprintk(KERN_ERR PFX 452 ssb_dbg("Can not unregister GPIO driver: %i\n", err);
453 "Can not unregister GPIO driver: %i\n", err);
454 453
455 ssb_buses_lock(); 454 ssb_buses_lock();
456 ssb_devices_unregister(bus); 455 ssb_devices_unregister(bus);
@@ -497,8 +496,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
497 496
498 devwrap = kzalloc(sizeof(*devwrap), GFP_KERNEL); 497 devwrap = kzalloc(sizeof(*devwrap), GFP_KERNEL);
499 if (!devwrap) { 498 if (!devwrap) {
500 ssb_printk(KERN_ERR PFX 499 ssb_err("Could not allocate device\n");
501 "Could not allocate device\n");
502 err = -ENOMEM; 500 err = -ENOMEM;
503 goto error; 501 goto error;
504 } 502 }
@@ -537,9 +535,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
537 sdev->dev = dev; 535 sdev->dev = dev;
538 err = device_register(dev); 536 err = device_register(dev);
539 if (err) { 537 if (err) {
540 ssb_printk(KERN_ERR PFX 538 ssb_err("Could not register %s\n", dev_name(dev));
541 "Could not register %s\n",
542 dev_name(dev));
543 /* Set dev to NULL to not unregister 539 /* Set dev to NULL to not unregister
544 * dev on error unwinding. */ 540 * dev on error unwinding. */
545 sdev->dev = NULL; 541 sdev->dev = NULL;
@@ -825,10 +821,9 @@ static int ssb_bus_register(struct ssb_bus *bus,
825 ssb_mipscore_init(&bus->mipscore); 821 ssb_mipscore_init(&bus->mipscore);
826 err = ssb_gpio_init(bus); 822 err = ssb_gpio_init(bus);
827 if (err == -ENOTSUPP) 823 if (err == -ENOTSUPP)
828 ssb_dprintk(KERN_DEBUG PFX "GPIO driver not activated\n"); 824 ssb_dbg("GPIO driver not activated\n");
829 else if (err) 825 else if (err)
830 ssb_dprintk(KERN_ERR PFX 826 ssb_dbg("Error registering GPIO driver: %i\n", err);
831 "Error registering GPIO driver: %i\n", err);
832 err = ssb_fetch_invariants(bus, get_invariants); 827 err = ssb_fetch_invariants(bus, get_invariants);
833 if (err) { 828 if (err) {
834 ssb_bus_may_powerdown(bus); 829 ssb_bus_may_powerdown(bus);
@@ -878,11 +873,11 @@ int ssb_bus_pcibus_register(struct ssb_bus *bus, struct pci_dev *host_pci)
878 873
879 err = ssb_bus_register(bus, ssb_pci_get_invariants, 0); 874 err = ssb_bus_register(bus, ssb_pci_get_invariants, 0);
880 if (!err) { 875 if (!err) {
881 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " 876 ssb_info("Sonics Silicon Backplane found on PCI device %s\n",
882 "PCI device %s\n", dev_name(&host_pci->dev)); 877 dev_name(&host_pci->dev));
883 } else { 878 } else {
884 ssb_printk(KERN_ERR PFX "Failed to register PCI version" 879 ssb_err("Failed to register PCI version of SSB with error %d\n",
885 " of SSB with error %d\n", err); 880 err);
886 } 881 }
887 882
888 return err; 883 return err;
@@ -903,8 +898,8 @@ int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
903 898
904 err = ssb_bus_register(bus, ssb_pcmcia_get_invariants, baseaddr); 899 err = ssb_bus_register(bus, ssb_pcmcia_get_invariants, baseaddr);
905 if (!err) { 900 if (!err) {
906 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " 901 ssb_info("Sonics Silicon Backplane found on PCMCIA device %s\n",
907 "PCMCIA device %s\n", pcmcia_dev->devname); 902 pcmcia_dev->devname);
908 } 903 }
909 904
910 return err; 905 return err;
@@ -925,8 +920,8 @@ int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func,
925 920
926 err = ssb_bus_register(bus, ssb_sdio_get_invariants, ~0); 921 err = ssb_bus_register(bus, ssb_sdio_get_invariants, ~0);
927 if (!err) { 922 if (!err) {
928 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " 923 ssb_info("Sonics Silicon Backplane found on SDIO device %s\n",
929 "SDIO device %s\n", sdio_func_id(func)); 924 sdio_func_id(func));
930 } 925 }
931 926
932 return err; 927 return err;
@@ -944,8 +939,8 @@ int ssb_bus_ssbbus_register(struct ssb_bus *bus, unsigned long baseaddr,
944 939
945 err = ssb_bus_register(bus, get_invariants, baseaddr); 940 err = ssb_bus_register(bus, get_invariants, baseaddr);
946 if (!err) { 941 if (!err) {
947 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found at " 942 ssb_info("Sonics Silicon Backplane found at address 0x%08lX\n",
948 "address 0x%08lX\n", baseaddr); 943 baseaddr);
949 } 944 }
950 945
951 return err; 946 return err;
@@ -1339,7 +1334,7 @@ out:
1339#endif 1334#endif
1340 return err; 1335 return err;
1341error: 1336error:
1342 ssb_printk(KERN_ERR PFX "Bus powerdown failed\n"); 1337 ssb_err("Bus powerdown failed\n");
1343 goto out; 1338 goto out;
1344} 1339}
1345EXPORT_SYMBOL(ssb_bus_may_powerdown); 1340EXPORT_SYMBOL(ssb_bus_may_powerdown);
@@ -1362,7 +1357,7 @@ int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
1362 1357
1363 return 0; 1358 return 0;
1364error: 1359error:
1365 ssb_printk(KERN_ERR PFX "Bus powerup failed\n"); 1360 ssb_err("Bus powerup failed\n");
1366 return err; 1361 return err;
1367} 1362}
1368EXPORT_SYMBOL(ssb_bus_powerup); 1363EXPORT_SYMBOL(ssb_bus_powerup);
@@ -1470,15 +1465,13 @@ static int __init ssb_modinit(void)
1470 1465
1471 err = b43_pci_ssb_bridge_init(); 1466 err = b43_pci_ssb_bridge_init();
1472 if (err) { 1467 if (err) {
1473 ssb_printk(KERN_ERR "Broadcom 43xx PCI-SSB-bridge " 1468 ssb_err("Broadcom 43xx PCI-SSB-bridge initialization failed\n");
1474 "initialization failed\n");
1475 /* don't fail SSB init because of this */ 1469 /* don't fail SSB init because of this */
1476 err = 0; 1470 err = 0;
1477 } 1471 }
1478 err = ssb_gige_init(); 1472 err = ssb_gige_init();
1479 if (err) { 1473 if (err) {
1480 ssb_printk(KERN_ERR "SSB Broadcom Gigabit Ethernet " 1474 ssb_err("SSB Broadcom Gigabit Ethernet driver initialization failed\n");
1481 "driver initialization failed\n");
1482 /* don't fail SSB init because of this */ 1475 /* don't fail SSB init because of this */
1483 err = 0; 1476 err = 0;
1484 } 1477 }
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index e9d94968f394..63ff69f9d3eb 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -56,7 +56,7 @@ int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
56 } 56 }
57 return 0; 57 return 0;
58error: 58error:
59 ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx); 59 ssb_err("Failed to switch to core %u\n", coreidx);
60 return -ENODEV; 60 return -ENODEV;
61} 61}
62 62
@@ -67,10 +67,9 @@ int ssb_pci_switch_core(struct ssb_bus *bus,
67 unsigned long flags; 67 unsigned long flags;
68 68
69#if SSB_VERBOSE_PCICORESWITCH_DEBUG 69#if SSB_VERBOSE_PCICORESWITCH_DEBUG
70 ssb_printk(KERN_INFO PFX 70 ssb_info("Switching to %s core, index %d\n",
71 "Switching to %s core, index %d\n", 71 ssb_core_name(dev->id.coreid),
72 ssb_core_name(dev->id.coreid), 72 dev->core_index);
73 dev->core_index);
74#endif 73#endif
75 74
76 spin_lock_irqsave(&bus->bar_lock, flags); 75 spin_lock_irqsave(&bus->bar_lock, flags);
@@ -231,6 +230,15 @@ static inline u8 ssb_crc8(u8 crc, u8 data)
231 return t[crc ^ data]; 230 return t[crc ^ data];
232} 231}
233 232
233static void sprom_get_mac(char *mac, const u16 *in)
234{
235 int i;
236 for (i = 0; i < 3; i++) {
237 *mac++ = in[i] >> 8;
238 *mac++ = in[i];
239 }
240}
241
234static u8 ssb_sprom_crc(const u16 *sprom, u16 size) 242static u8 ssb_sprom_crc(const u16 *sprom, u16 size)
235{ 243{
236 int word; 244 int word;
@@ -278,7 +286,7 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
278 u32 spromctl; 286 u32 spromctl;
279 u16 size = bus->sprom_size; 287 u16 size = bus->sprom_size;
280 288
281 ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); 289 ssb_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n");
282 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); 290 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
283 if (err) 291 if (err)
284 goto err_ctlreg; 292 goto err_ctlreg;
@@ -286,17 +294,17 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
286 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl); 294 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
287 if (err) 295 if (err)
288 goto err_ctlreg; 296 goto err_ctlreg;
289 ssb_printk(KERN_NOTICE PFX "[ 0%%"); 297 ssb_notice("[ 0%%");
290 msleep(500); 298 msleep(500);
291 for (i = 0; i < size; i++) { 299 for (i = 0; i < size; i++) {
292 if (i == size / 4) 300 if (i == size / 4)
293 ssb_printk("25%%"); 301 ssb_cont("25%%");
294 else if (i == size / 2) 302 else if (i == size / 2)
295 ssb_printk("50%%"); 303 ssb_cont("50%%");
296 else if (i == (size * 3) / 4) 304 else if (i == (size * 3) / 4)
297 ssb_printk("75%%"); 305 ssb_cont("75%%");
298 else if (i % 2) 306 else if (i % 2)
299 ssb_printk("."); 307 ssb_cont(".");
300 writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2)); 308 writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
301 mmiowb(); 309 mmiowb();
302 msleep(20); 310 msleep(20);
@@ -309,12 +317,12 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
309 if (err) 317 if (err)
310 goto err_ctlreg; 318 goto err_ctlreg;
311 msleep(500); 319 msleep(500);
312 ssb_printk("100%% ]\n"); 320 ssb_cont("100%% ]\n");
313 ssb_printk(KERN_NOTICE PFX "SPROM written.\n"); 321 ssb_notice("SPROM written\n");
314 322
315 return 0; 323 return 0;
316err_ctlreg: 324err_ctlreg:
317 ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n"); 325 ssb_err("Could not access SPROM control register.\n");
318 return err; 326 return err;
319} 327}
320 328
@@ -341,8 +349,6 @@ static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
341 349
342static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) 350static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
343{ 351{
344 int i;
345 u16 v;
346 u16 loc[3]; 352 u16 loc[3];
347 353
348 if (out->revision == 3) /* rev 3 moved MAC */ 354 if (out->revision == 3) /* rev 3 moved MAC */
@@ -352,19 +358,10 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
352 loc[1] = SSB_SPROM1_ET0MAC; 358 loc[1] = SSB_SPROM1_ET0MAC;
353 loc[2] = SSB_SPROM1_ET1MAC; 359 loc[2] = SSB_SPROM1_ET1MAC;
354 } 360 }
355 for (i = 0; i < 3; i++) { 361 sprom_get_mac(out->il0mac, &in[SPOFF(loc[0])]);
356 v = in[SPOFF(loc[0]) + i];
357 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
358 }
359 if (out->revision < 3) { /* only rev 1-2 have et0, et1 */ 362 if (out->revision < 3) { /* only rev 1-2 have et0, et1 */
360 for (i = 0; i < 3; i++) { 363 sprom_get_mac(out->et0mac, &in[SPOFF(loc[1])]);
361 v = in[SPOFF(loc[1]) + i]; 364 sprom_get_mac(out->et1mac, &in[SPOFF(loc[2])]);
362 *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
363 }
364 for (i = 0; i < 3; i++) {
365 v = in[SPOFF(loc[2]) + i];
366 *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
367 }
368 } 365 }
369 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); 366 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
370 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, 367 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
@@ -454,19 +451,15 @@ static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
454 451
455static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) 452static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
456{ 453{
457 int i;
458 u16 v;
459 u16 il0mac_offset; 454 u16 il0mac_offset;
460 455
461 if (out->revision == 4) 456 if (out->revision == 4)
462 il0mac_offset = SSB_SPROM4_IL0MAC; 457 il0mac_offset = SSB_SPROM4_IL0MAC;
463 else 458 else
464 il0mac_offset = SSB_SPROM5_IL0MAC; 459 il0mac_offset = SSB_SPROM5_IL0MAC;
465 /* extract the MAC address */ 460
466 for (i = 0; i < 3; i++) { 461 sprom_get_mac(out->il0mac, &in[SPOFF(il0mac_offset)]);
467 v = in[SPOFF(il0mac_offset) + i]; 462
468 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
469 }
470 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); 463 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
471 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, 464 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
472 SSB_SPROM4_ETHPHY_ET1A_SHIFT); 465 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
@@ -530,7 +523,7 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
530static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) 523static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
531{ 524{
532 int i; 525 int i;
533 u16 v, o; 526 u16 o;
534 u16 pwr_info_offset[] = { 527 u16 pwr_info_offset[] = {
535 SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, 528 SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
536 SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 529 SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
@@ -539,10 +532,8 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
539 ARRAY_SIZE(out->core_pwr_info)); 532 ARRAY_SIZE(out->core_pwr_info));
540 533
541 /* extract the MAC address */ 534 /* extract the MAC address */
542 for (i = 0; i < 3; i++) { 535 sprom_get_mac(out->il0mac, &in[SPOFF(SSB_SPROM8_IL0MAC)]);
543 v = in[SPOFF(SSB_SPROM8_IL0MAC) + i]; 536
544 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
545 }
546 SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0); 537 SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
547 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); 538 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
548 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); 539 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
@@ -743,7 +734,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
743 memset(out, 0, sizeof(*out)); 734 memset(out, 0, sizeof(*out));
744 735
745 out->revision = in[size - 1] & 0x00FF; 736 out->revision = in[size - 1] & 0x00FF;
746 ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); 737 ssb_dbg("SPROM revision %d detected\n", out->revision);
747 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ 738 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
748 memset(out->et1mac, 0xFF, 6); 739 memset(out->et1mac, 0xFF, 6);
749 740
@@ -752,7 +743,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
752 * number stored in the SPROM. 743 * number stored in the SPROM.
753 * Always extract r1. */ 744 * Always extract r1. */
754 out->revision = 1; 745 out->revision = 1;
755 ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision); 746 ssb_dbg("SPROM treated as revision %d\n", out->revision);
756 } 747 }
757 748
758 switch (out->revision) { 749 switch (out->revision) {
@@ -769,9 +760,8 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
769 sprom_extract_r8(out, in); 760 sprom_extract_r8(out, in);
770 break; 761 break;
771 default: 762 default:
772 ssb_printk(KERN_WARNING PFX "Unsupported SPROM" 763 ssb_warn("Unsupported SPROM revision %d detected. Will extract v1\n",
773 " revision %d detected. Will extract" 764 out->revision);
774 " v1\n", out->revision);
775 out->revision = 1; 765 out->revision = 1;
776 sprom_extract_r123(out, in); 766 sprom_extract_r123(out, in);
777 } 767 }
@@ -791,7 +781,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
791 u16 *buf; 781 u16 *buf;
792 782
793 if (!ssb_is_sprom_available(bus)) { 783 if (!ssb_is_sprom_available(bus)) {
794 ssb_printk(KERN_ERR PFX "No SPROM available!\n"); 784 ssb_err("No SPROM available!\n");
795 return -ENODEV; 785 return -ENODEV;
796 } 786 }
797 if (bus->chipco.dev) { /* can be unavailable! */ 787 if (bus->chipco.dev) { /* can be unavailable! */
@@ -810,7 +800,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
810 } else { 800 } else {
811 bus->sprom_offset = SSB_SPROM_BASE1; 801 bus->sprom_offset = SSB_SPROM_BASE1;
812 } 802 }
813 ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset); 803 ssb_dbg("SPROM offset is 0x%x\n", bus->sprom_offset);
814 804
815 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); 805 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
816 if (!buf) 806 if (!buf)
@@ -835,18 +825,15 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
835 * available for this device in some other storage */ 825 * available for this device in some other storage */
836 err = ssb_fill_sprom_with_fallback(bus, sprom); 826 err = ssb_fill_sprom_with_fallback(bus, sprom);
837 if (err) { 827 if (err) {
838 ssb_printk(KERN_WARNING PFX "WARNING: Using" 828 ssb_warn("WARNING: Using fallback SPROM failed (err %d)\n",
839 " fallback SPROM failed (err %d)\n", 829 err);
840 err);
841 } else { 830 } else {
842 ssb_dprintk(KERN_DEBUG PFX "Using SPROM" 831 ssb_dbg("Using SPROM revision %d provided by platform\n",
843 " revision %d provided by" 832 sprom->revision);
844 " platform.\n", sprom->revision);
845 err = 0; 833 err = 0;
846 goto out_free; 834 goto out_free;
847 } 835 }
848 ssb_printk(KERN_WARNING PFX "WARNING: Invalid" 836 ssb_warn("WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
849 " SPROM CRC (corrupt SPROM)\n");
850 } 837 }
851 } 838 }
852 err = sprom_extract(bus, sprom, buf, bus->sprom_size); 839 err = sprom_extract(bus, sprom, buf, bus->sprom_size);
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index fbafed5b729b..b413e0187087 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -143,7 +143,7 @@ int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
143 143
144 return 0; 144 return 0;
145error: 145error:
146 ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx); 146 ssb_err("Failed to switch to core %u\n", coreidx);
147 return err; 147 return err;
148} 148}
149 149
@@ -153,10 +153,9 @@ int ssb_pcmcia_switch_core(struct ssb_bus *bus,
153 int err; 153 int err;
154 154
155#if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG 155#if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
156 ssb_printk(KERN_INFO PFX 156 ssb_info("Switching to %s core, index %d\n",
157 "Switching to %s core, index %d\n", 157 ssb_core_name(dev->id.coreid),
158 ssb_core_name(dev->id.coreid), 158 dev->core_index);
159 dev->core_index);
160#endif 159#endif
161 160
162 err = ssb_pcmcia_switch_coreidx(bus, dev->core_index); 161 err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
@@ -192,7 +191,7 @@ int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
192 191
193 return 0; 192 return 0;
194error: 193error:
195 ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n"); 194 ssb_err("Failed to switch pcmcia segment\n");
196 return err; 195 return err;
197} 196}
198 197
@@ -549,44 +548,39 @@ static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom)
549 bool failed = 0; 548 bool failed = 0;
550 size_t size = SSB_PCMCIA_SPROM_SIZE; 549 size_t size = SSB_PCMCIA_SPROM_SIZE;
551 550
552 ssb_printk(KERN_NOTICE PFX 551 ssb_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n");
553 "Writing SPROM. Do NOT turn off the power! "
554 "Please stand by...\n");
555 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN); 552 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN);
556 if (err) { 553 if (err) {
557 ssb_printk(KERN_NOTICE PFX 554 ssb_notice("Could not enable SPROM write access\n");
558 "Could not enable SPROM write access.\n");
559 return -EBUSY; 555 return -EBUSY;
560 } 556 }
561 ssb_printk(KERN_NOTICE PFX "[ 0%%"); 557 ssb_notice("[ 0%%");
562 msleep(500); 558 msleep(500);
563 for (i = 0; i < size; i++) { 559 for (i = 0; i < size; i++) {
564 if (i == size / 4) 560 if (i == size / 4)
565 ssb_printk("25%%"); 561 ssb_cont("25%%");
566 else if (i == size / 2) 562 else if (i == size / 2)
567 ssb_printk("50%%"); 563 ssb_cont("50%%");
568 else if (i == (size * 3) / 4) 564 else if (i == (size * 3) / 4)
569 ssb_printk("75%%"); 565 ssb_cont("75%%");
570 else if (i % 2) 566 else if (i % 2)
571 ssb_printk("."); 567 ssb_cont(".");
572 err = ssb_pcmcia_sprom_write(bus, i, sprom[i]); 568 err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
573 if (err) { 569 if (err) {
574 ssb_printk(KERN_NOTICE PFX 570 ssb_notice("Failed to write to SPROM\n");
575 "Failed to write to SPROM.\n");
576 failed = 1; 571 failed = 1;
577 break; 572 break;
578 } 573 }
579 } 574 }
580 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS); 575 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
581 if (err) { 576 if (err) {
582 ssb_printk(KERN_NOTICE PFX 577 ssb_notice("Could not disable SPROM write access\n");
583 "Could not disable SPROM write access.\n");
584 failed = 1; 578 failed = 1;
585 } 579 }
586 msleep(500); 580 msleep(500);
587 if (!failed) { 581 if (!failed) {
588 ssb_printk("100%% ]\n"); 582 ssb_cont("100%% ]\n");
589 ssb_printk(KERN_NOTICE PFX "SPROM written.\n"); 583 ssb_notice("SPROM written\n");
590 } 584 }
591 585
592 return failed ? -EBUSY : 0; 586 return failed ? -EBUSY : 0;
@@ -700,7 +694,7 @@ static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
700 return -ENOSPC; /* continue with next entry */ 694 return -ENOSPC; /* continue with next entry */
701 695
702error: 696error:
703 ssb_printk(KERN_ERR PFX 697 ssb_err(
704 "PCMCIA: Failed to fetch device invariants: %s\n", 698 "PCMCIA: Failed to fetch device invariants: %s\n",
705 error_description); 699 error_description);
706 return -ENODEV; 700 return -ENODEV;
@@ -722,7 +716,7 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
722 res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE, 716 res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
723 ssb_pcmcia_get_mac, sprom); 717 ssb_pcmcia_get_mac, sprom);
724 if (res != 0) { 718 if (res != 0) {
725 ssb_printk(KERN_ERR PFX 719 ssb_err(
726 "PCMCIA: Failed to fetch MAC address\n"); 720 "PCMCIA: Failed to fetch MAC address\n");
727 return -ENODEV; 721 return -ENODEV;
728 } 722 }
@@ -733,7 +727,7 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
733 if ((res == 0) || (res == -ENOSPC)) 727 if ((res == 0) || (res == -ENOSPC))
734 return 0; 728 return 0;
735 729
736 ssb_printk(KERN_ERR PFX 730 ssb_err(
737 "PCMCIA: Failed to fetch device invariants\n"); 731 "PCMCIA: Failed to fetch device invariants\n");
738 return -ENODEV; 732 return -ENODEV;
739} 733}
@@ -843,6 +837,6 @@ int ssb_pcmcia_init(struct ssb_bus *bus)
843 837
844 return 0; 838 return 0;
845error: 839error:
846 ssb_printk(KERN_ERR PFX "Failed to initialize PCMCIA host device\n"); 840 ssb_err("Failed to initialize PCMCIA host device\n");
847 return err; 841 return err;
848} 842}
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index ab4627cf1114..b9429df583eb 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -125,8 +125,7 @@ static u16 pcidev_to_chipid(struct pci_dev *pci_dev)
125 chipid_fallback = 0x4401; 125 chipid_fallback = 0x4401;
126 break; 126 break;
127 default: 127 default:
128 ssb_printk(KERN_ERR PFX 128 ssb_err("PCI-ID not in fallback list\n");
129 "PCI-ID not in fallback list\n");
130 } 129 }
131 130
132 return chipid_fallback; 131 return chipid_fallback;
@@ -152,8 +151,7 @@ static u8 chipid_to_nrcores(u16 chipid)
152 case 0x4704: 151 case 0x4704:
153 return 9; 152 return 9;
154 default: 153 default:
155 ssb_printk(KERN_ERR PFX 154 ssb_err("CHIPID not in nrcores fallback list\n");
156 "CHIPID not in nrcores fallback list\n");
157 } 155 }
158 156
159 return 1; 157 return 1;
@@ -320,15 +318,13 @@ int ssb_bus_scan(struct ssb_bus *bus,
320 bus->chip_package = 0; 318 bus->chip_package = 0;
321 } 319 }
322 } 320 }
323 ssb_printk(KERN_INFO PFX "Found chip with id 0x%04X, rev 0x%02X and " 321 ssb_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
324 "package 0x%02X\n", bus->chip_id, bus->chip_rev, 322 bus->chip_id, bus->chip_rev, bus->chip_package);
325 bus->chip_package);
326 if (!bus->nr_devices) 323 if (!bus->nr_devices)
327 bus->nr_devices = chipid_to_nrcores(bus->chip_id); 324 bus->nr_devices = chipid_to_nrcores(bus->chip_id);
328 if (bus->nr_devices > ARRAY_SIZE(bus->devices)) { 325 if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
329 ssb_printk(KERN_ERR PFX 326 ssb_err("More than %d ssb cores found (%d)\n",
330 "More than %d ssb cores found (%d)\n", 327 SSB_MAX_NR_CORES, bus->nr_devices);
331 SSB_MAX_NR_CORES, bus->nr_devices);
332 goto err_unmap; 328 goto err_unmap;
333 } 329 }
334 if (bus->bustype == SSB_BUSTYPE_SSB) { 330 if (bus->bustype == SSB_BUSTYPE_SSB) {
@@ -370,8 +366,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
370 nr_80211_cores++; 366 nr_80211_cores++;
371 if (nr_80211_cores > 1) { 367 if (nr_80211_cores > 1) {
372 if (!we_support_multiple_80211_cores(bus)) { 368 if (!we_support_multiple_80211_cores(bus)) {
373 ssb_dprintk(KERN_INFO PFX "Ignoring additional " 369 ssb_dbg("Ignoring additional 802.11 core\n");
374 "802.11 core\n");
375 continue; 370 continue;
376 } 371 }
377 } 372 }
@@ -379,8 +374,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
379 case SSB_DEV_EXTIF: 374 case SSB_DEV_EXTIF:
380#ifdef CONFIG_SSB_DRIVER_EXTIF 375#ifdef CONFIG_SSB_DRIVER_EXTIF
381 if (bus->extif.dev) { 376 if (bus->extif.dev) {
382 ssb_printk(KERN_WARNING PFX 377 ssb_warn("WARNING: Multiple EXTIFs found\n");
383 "WARNING: Multiple EXTIFs found\n");
384 break; 378 break;
385 } 379 }
386 bus->extif.dev = dev; 380 bus->extif.dev = dev;
@@ -388,8 +382,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
388 break; 382 break;
389 case SSB_DEV_CHIPCOMMON: 383 case SSB_DEV_CHIPCOMMON:
390 if (bus->chipco.dev) { 384 if (bus->chipco.dev) {
391 ssb_printk(KERN_WARNING PFX 385 ssb_warn("WARNING: Multiple ChipCommon found\n");
392 "WARNING: Multiple ChipCommon found\n");
393 break; 386 break;
394 } 387 }
395 bus->chipco.dev = dev; 388 bus->chipco.dev = dev;
@@ -398,8 +391,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
398 case SSB_DEV_MIPS_3302: 391 case SSB_DEV_MIPS_3302:
399#ifdef CONFIG_SSB_DRIVER_MIPS 392#ifdef CONFIG_SSB_DRIVER_MIPS
400 if (bus->mipscore.dev) { 393 if (bus->mipscore.dev) {
401 ssb_printk(KERN_WARNING PFX 394 ssb_warn("WARNING: Multiple MIPS cores found\n");
402 "WARNING: Multiple MIPS cores found\n");
403 break; 395 break;
404 } 396 }
405 bus->mipscore.dev = dev; 397 bus->mipscore.dev = dev;
@@ -420,8 +412,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
420 } 412 }
421 } 413 }
422 if (bus->pcicore.dev) { 414 if (bus->pcicore.dev) {
423 ssb_printk(KERN_WARNING PFX 415 ssb_warn("WARNING: Multiple PCI(E) cores found\n");
424 "WARNING: Multiple PCI(E) cores found\n");
425 break; 416 break;
426 } 417 }
427 bus->pcicore.dev = dev; 418 bus->pcicore.dev = dev;
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
index 80d366fcf8d3..a3b23644b0fb 100644
--- a/drivers/ssb/sprom.c
+++ b/drivers/ssb/sprom.c
@@ -127,13 +127,13 @@ ssize_t ssb_attr_sprom_store(struct ssb_bus *bus,
127 goto out_kfree; 127 goto out_kfree;
128 err = ssb_devices_freeze(bus, &freeze); 128 err = ssb_devices_freeze(bus, &freeze);
129 if (err) { 129 if (err) {
130 ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n"); 130 ssb_err("SPROM write: Could not freeze all devices\n");
131 goto out_unlock; 131 goto out_unlock;
132 } 132 }
133 res = sprom_write(bus, sprom); 133 res = sprom_write(bus, sprom);
134 err = ssb_devices_thaw(&freeze); 134 err = ssb_devices_thaw(&freeze);
135 if (err) 135 if (err)
136 ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n"); 136 ssb_err("SPROM write: Could not thaw all devices\n");
137out_unlock: 137out_unlock:
138 mutex_unlock(&bus->sprom_mutex); 138 mutex_unlock(&bus->sprom_mutex);
139out_kfree: 139out_kfree:
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index 466171b77f68..4671f17f09af 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -9,16 +9,27 @@
9#define PFX "ssb: " 9#define PFX "ssb: "
10 10
11#ifdef CONFIG_SSB_SILENT 11#ifdef CONFIG_SSB_SILENT
12# define ssb_printk(fmt, x...) do { /* nothing */ } while (0) 12# define ssb_printk(fmt, ...) \
13 do { if (0) printk(fmt, ##__VA_ARGS__); } while (0)
13#else 14#else
14# define ssb_printk printk 15# define ssb_printk(fmt, ...) \
16 printk(fmt, ##__VA_ARGS__)
15#endif /* CONFIG_SSB_SILENT */ 17#endif /* CONFIG_SSB_SILENT */
16 18
19#define ssb_emerg(fmt, ...) ssb_printk(KERN_EMERG PFX fmt, ##__VA_ARGS__)
20#define ssb_err(fmt, ...) ssb_printk(KERN_ERR PFX fmt, ##__VA_ARGS__)
21#define ssb_warn(fmt, ...) ssb_printk(KERN_WARNING PFX fmt, ##__VA_ARGS__)
22#define ssb_notice(fmt, ...) ssb_printk(KERN_NOTICE PFX fmt, ##__VA_ARGS__)
23#define ssb_info(fmt, ...) ssb_printk(KERN_INFO PFX fmt, ##__VA_ARGS__)
24#define ssb_cont(fmt, ...) ssb_printk(KERN_CONT fmt, ##__VA_ARGS__)
25
17/* dprintk: Debugging printk; vanishes for non-debug compilation */ 26/* dprintk: Debugging printk; vanishes for non-debug compilation */
18#ifdef CONFIG_SSB_DEBUG 27#ifdef CONFIG_SSB_DEBUG
19# define ssb_dprintk(fmt, x...) ssb_printk(fmt , ##x) 28# define ssb_dbg(fmt, ...) \
29 ssb_printk(KERN_DEBUG PFX fmt, ##__VA_ARGS__)
20#else 30#else
21# define ssb_dprintk(fmt, x...) do { /* nothing */ } while (0) 31# define ssb_dbg(fmt, ...) \
32 do { if (0) printk(KERN_DEBUG PFX fmt, ##__VA_ARGS__); } while (0)
22#endif 33#endif
23 34
24#ifdef CONFIG_SSB_DEBUG 35#ifdef CONFIG_SSB_DEBUG
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 7e24fe0cfbcd..4cf0c9e4dd99 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -113,6 +113,34 @@
113#define IEEE80211_CTL_EXT_SSW_FBACK 0x9000 113#define IEEE80211_CTL_EXT_SSW_FBACK 0x9000
114#define IEEE80211_CTL_EXT_SSW_ACK 0xa000 114#define IEEE80211_CTL_EXT_SSW_ACK 0xa000
115 115
116
117#define IEEE80211_SN_MASK ((IEEE80211_SCTL_SEQ) >> 4)
118#define IEEE80211_MAX_SN IEEE80211_SN_MASK
119#define IEEE80211_SN_MODULO (IEEE80211_MAX_SN + 1)
120
121static inline int ieee80211_sn_less(u16 sn1, u16 sn2)
122{
123 return ((sn1 - sn2) & IEEE80211_SN_MASK) > (IEEE80211_SN_MODULO >> 1);
124}
125
126static inline u16 ieee80211_sn_add(u16 sn1, u16 sn2)
127{
128 return (sn1 + sn2) & IEEE80211_SN_MASK;
129}
130
131static inline u16 ieee80211_sn_inc(u16 sn)
132{
133 return ieee80211_sn_add(sn, 1);
134}
135
136static inline u16 ieee80211_sn_sub(u16 sn1, u16 sn2)
137{
138 return (sn1 - sn2) & IEEE80211_SN_MASK;
139}
140
141#define IEEE80211_SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
142#define IEEE80211_SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
143
116/* miscellaneous IEEE 802.11 constants */ 144/* miscellaneous IEEE 802.11 constants */
117#define IEEE80211_MAX_FRAG_THRESHOLD 2352 145#define IEEE80211_MAX_FRAG_THRESHOLD 2352
118#define IEEE80211_MAX_RTS_THRESHOLD 2353 146#define IEEE80211_MAX_RTS_THRESHOLD 2353
@@ -185,7 +213,7 @@ struct ieee80211_hdr {
185 u8 addr3[6]; 213 u8 addr3[6];
186 __le16 seq_ctrl; 214 __le16 seq_ctrl;
187 u8 addr4[6]; 215 u8 addr4[6];
188} __packed; 216} __packed __aligned(2);
189 217
190struct ieee80211_hdr_3addr { 218struct ieee80211_hdr_3addr {
191 __le16 frame_control; 219 __le16 frame_control;
@@ -194,7 +222,7 @@ struct ieee80211_hdr_3addr {
194 u8 addr2[6]; 222 u8 addr2[6];
195 u8 addr3[6]; 223 u8 addr3[6];
196 __le16 seq_ctrl; 224 __le16 seq_ctrl;
197} __packed; 225} __packed __aligned(2);
198 226
199struct ieee80211_qos_hdr { 227struct ieee80211_qos_hdr {
200 __le16 frame_control; 228 __le16 frame_control;
@@ -204,7 +232,7 @@ struct ieee80211_qos_hdr {
204 u8 addr3[6]; 232 u8 addr3[6];
205 __le16 seq_ctrl; 233 __le16 seq_ctrl;
206 __le16 qos_ctrl; 234 __le16 qos_ctrl;
207} __packed; 235} __packed __aligned(2);
208 236
209/** 237/**
210 * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set 238 * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set
@@ -581,7 +609,7 @@ struct ieee80211s_hdr {
581 __le32 seqnum; 609 __le32 seqnum;
582 u8 eaddr1[6]; 610 u8 eaddr1[6];
583 u8 eaddr2[6]; 611 u8 eaddr2[6];
584} __packed; 612} __packed __aligned(2);
585 613
586/* Mesh flags */ 614/* Mesh flags */
587#define MESH_FLAGS_AE_A4 0x1 615#define MESH_FLAGS_AE_A4 0x1
@@ -875,7 +903,7 @@ struct ieee80211_mgmt {
875 } u; 903 } u;
876 } __packed action; 904 } __packed action;
877 } u; 905 } u;
878} __packed; 906} __packed __aligned(2);
879 907
880/* Supported Rates value encodings in 802.11n-2009 7.3.2.2 */ 908/* Supported Rates value encodings in 802.11n-2009 7.3.2.2 */
881#define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 909#define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127
@@ -906,20 +934,20 @@ struct ieee80211_rts {
906 __le16 duration; 934 __le16 duration;
907 u8 ra[6]; 935 u8 ra[6];
908 u8 ta[6]; 936 u8 ta[6];
909} __packed; 937} __packed __aligned(2);
910 938
911struct ieee80211_cts { 939struct ieee80211_cts {
912 __le16 frame_control; 940 __le16 frame_control;
913 __le16 duration; 941 __le16 duration;
914 u8 ra[6]; 942 u8 ra[6];
915} __packed; 943} __packed __aligned(2);
916 944
917struct ieee80211_pspoll { 945struct ieee80211_pspoll {
918 __le16 frame_control; 946 __le16 frame_control;
919 __le16 aid; 947 __le16 aid;
920 u8 bssid[6]; 948 u8 bssid[6];
921 u8 ta[6]; 949 u8 ta[6];
922} __packed; 950} __packed __aligned(2);
923 951
924/* TDLS */ 952/* TDLS */
925 953
@@ -1290,11 +1318,6 @@ struct ieee80211_vht_operation {
1290} __packed; 1318} __packed;
1291 1319
1292 1320
1293#define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0
1294#define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1
1295#define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT 2
1296#define IEEE80211_VHT_MCS_NOT_SUPPORTED 3
1297
1298/* 802.11ac VHT Capabilities */ 1321/* 802.11ac VHT Capabilities */
1299#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000 1322#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000
1300#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x00000001 1323#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x00000001
@@ -1310,10 +1333,11 @@ struct ieee80211_vht_operation {
1310#define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200 1333#define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200
1311#define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 1334#define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300
1312#define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 1335#define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400
1336#define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700
1313#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 1337#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800
1314#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 1338#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000
1315#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000 1339#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000
1316#define IEEE80211_VHT_CAP_SOUNDING_DIMENTION_MAX 0x00030000 1340#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX 0x00030000
1317#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000 1341#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000
1318#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000 1342#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000
1319#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000 1343#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 2b9f74b0ffea..428c37a1f95c 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -298,6 +298,7 @@ struct ucred {
298#define SOL_IUCV 277 298#define SOL_IUCV 277
299#define SOL_CAIF 278 299#define SOL_CAIF 278
300#define SOL_ALG 279 300#define SOL_ALG 279
301#define SOL_NFC 280
301 302
302/* IPX options */ 303/* IPX options */
303#define IPX_TYPE 1 304#define IPX_TYPE 1
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 22958d68ecfe..8b1322296fed 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -26,9 +26,9 @@ struct ssb_sprom_core_pwr_info {
26 26
27struct ssb_sprom { 27struct ssb_sprom {
28 u8 revision; 28 u8 revision;
29 u8 il0mac[6]; /* MAC address for 802.11b/g */ 29 u8 il0mac[6] __aligned(sizeof(u16)); /* MAC address for 802.11b/g */
30 u8 et0mac[6]; /* MAC address for Ethernet */ 30 u8 et0mac[6] __aligned(sizeof(u16)); /* MAC address for Ethernet */
31 u8 et1mac[6]; /* MAC address for 802.11a */ 31 u8 et1mac[6] __aligned(sizeof(u16)); /* MAC address for 802.11a */
32 u8 et0phyaddr; /* MII address for enet0 */ 32 u8 et0phyaddr; /* MII address for enet0 */
33 u8 et1phyaddr; /* MII address for enet1 */ 33 u8 et1phyaddr; /* MII address for enet1 */
34 u8 et0mdcport; /* MDIO for enet0 */ 34 u8 et0mdcport; /* MDIO for enet0 */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d581c6de5d64..bdba9b619064 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -611,22 +611,10 @@ struct cfg80211_ap_settings {
611}; 611};
612 612
613/** 613/**
614 * enum plink_action - actions to perform in mesh peers
615 *
616 * @PLINK_ACTION_INVALID: action 0 is reserved
617 * @PLINK_ACTION_OPEN: start mesh peer link establishment
618 * @PLINK_ACTION_BLOCK: block traffic from this mesh peer
619 */
620enum plink_actions {
621 PLINK_ACTION_INVALID,
622 PLINK_ACTION_OPEN,
623 PLINK_ACTION_BLOCK,
624};
625
626/**
627 * enum station_parameters_apply_mask - station parameter values to apply 614 * enum station_parameters_apply_mask - station parameter values to apply
628 * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) 615 * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
629 * @STATION_PARAM_APPLY_CAPABILITY: apply new capability 616 * @STATION_PARAM_APPLY_CAPABILITY: apply new capability
617 * @STATION_PARAM_APPLY_PLINK_STATE: apply new plink state
630 * 618 *
631 * Not all station parameters have in-band "no change" signalling, 619 * Not all station parameters have in-band "no change" signalling,
632 * for those that don't these flags will are used. 620 * for those that don't these flags will are used.
@@ -634,6 +622,7 @@ enum plink_actions {
634enum station_parameters_apply_mask { 622enum station_parameters_apply_mask {
635 STATION_PARAM_APPLY_UAPSD = BIT(0), 623 STATION_PARAM_APPLY_UAPSD = BIT(0),
636 STATION_PARAM_APPLY_CAPABILITY = BIT(1), 624 STATION_PARAM_APPLY_CAPABILITY = BIT(1),
625 STATION_PARAM_APPLY_PLINK_STATE = BIT(2),
637}; 626};
638 627
639/** 628/**
@@ -669,7 +658,7 @@ enum station_parameters_apply_mask {
669 * @ext_capab_len: number of extended capabilities 658 * @ext_capab_len: number of extended capabilities
670 */ 659 */
671struct station_parameters { 660struct station_parameters {
672 u8 *supported_rates; 661 const u8 *supported_rates;
673 struct net_device *vlan; 662 struct net_device *vlan;
674 u32 sta_flags_mask, sta_flags_set; 663 u32 sta_flags_mask, sta_flags_set;
675 u32 sta_modify_mask; 664 u32 sta_modify_mask;
@@ -678,17 +667,60 @@ struct station_parameters {
678 u8 supported_rates_len; 667 u8 supported_rates_len;
679 u8 plink_action; 668 u8 plink_action;
680 u8 plink_state; 669 u8 plink_state;
681 struct ieee80211_ht_cap *ht_capa; 670 const struct ieee80211_ht_cap *ht_capa;
682 struct ieee80211_vht_cap *vht_capa; 671 const struct ieee80211_vht_cap *vht_capa;
683 u8 uapsd_queues; 672 u8 uapsd_queues;
684 u8 max_sp; 673 u8 max_sp;
685 enum nl80211_mesh_power_mode local_pm; 674 enum nl80211_mesh_power_mode local_pm;
686 u16 capability; 675 u16 capability;
687 u8 *ext_capab; 676 const u8 *ext_capab;
688 u8 ext_capab_len; 677 u8 ext_capab_len;
689}; 678};
690 679
691/** 680/**
681 * enum cfg80211_station_type - the type of station being modified
682 * @CFG80211_STA_AP_CLIENT: client of an AP interface
683 * @CFG80211_STA_AP_MLME_CLIENT: client of an AP interface that has
684 * the AP MLME in the device
685 * @CFG80211_STA_AP_STA: AP station on managed interface
686 * @CFG80211_STA_IBSS: IBSS station
687 * @CFG80211_STA_TDLS_PEER_SETUP: TDLS peer on managed interface (dummy entry
688 * while TDLS setup is in progress, it moves out of this state when
689 * being marked authorized; use this only if TDLS with external setup is
690 * supported/used)
691 * @CFG80211_STA_TDLS_PEER_ACTIVE: TDLS peer on managed interface (active
692 * entry that is operating, has been marked authorized by userspace)
693 * @CFG80211_STA_MESH_PEER_KERNEL: peer on mesh interface (kernel managed)
694 * @CFG80211_STA_MESH_PEER_USER: peer on mesh interface (user managed)
695 */
696enum cfg80211_station_type {
697 CFG80211_STA_AP_CLIENT,
698 CFG80211_STA_AP_MLME_CLIENT,
699 CFG80211_STA_AP_STA,
700 CFG80211_STA_IBSS,
701 CFG80211_STA_TDLS_PEER_SETUP,
702 CFG80211_STA_TDLS_PEER_ACTIVE,
703 CFG80211_STA_MESH_PEER_KERNEL,
704 CFG80211_STA_MESH_PEER_USER,
705};
706
707/**
708 * cfg80211_check_station_change - validate parameter changes
709 * @wiphy: the wiphy this operates on
710 * @params: the new parameters for a station
711 * @statype: the type of station being modified
712 *
713 * Utility function for the @change_station driver method. Call this function
714 * with the appropriate station type looking up the station (and checking that
715 * it exists). It will verify whether the station change is acceptable, and if
716 * not will return an error code. Note that it may modify the parameters for
717 * backward compatibility reasons, so don't use them before calling this.
718 */
719int cfg80211_check_station_change(struct wiphy *wiphy,
720 struct station_parameters *params,
721 enum cfg80211_station_type statype);
722
723/**
692 * enum station_info_flags - station information flags 724 * enum station_info_flags - station information flags
693 * 725 *
694 * Used by the driver to indicate which info in &struct station_info 726 * Used by the driver to indicate which info in &struct station_info
@@ -1119,6 +1151,7 @@ struct mesh_config {
1119 * @ie_len: length of vendor information elements 1151 * @ie_len: length of vendor information elements
1120 * @is_authenticated: this mesh requires authentication 1152 * @is_authenticated: this mesh requires authentication
1121 * @is_secure: this mesh uses security 1153 * @is_secure: this mesh uses security
1154 * @user_mpm: userspace handles all MPM functions
1122 * @dtim_period: DTIM period to use 1155 * @dtim_period: DTIM period to use
1123 * @beacon_interval: beacon interval to use 1156 * @beacon_interval: beacon interval to use
1124 * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a] 1157 * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a]
@@ -1136,6 +1169,7 @@ struct mesh_setup {
1136 u8 ie_len; 1169 u8 ie_len;
1137 bool is_authenticated; 1170 bool is_authenticated;
1138 bool is_secure; 1171 bool is_secure;
1172 bool user_mpm;
1139 u8 dtim_period; 1173 u8 dtim_period;
1140 u16 beacon_interval; 1174 u16 beacon_interval;
1141 int mcast_rate[IEEE80211_NUM_BANDS]; 1175 int mcast_rate[IEEE80211_NUM_BANDS];
@@ -1398,9 +1432,11 @@ struct cfg80211_auth_request {
1398 * enum cfg80211_assoc_req_flags - Over-ride default behaviour in association. 1432 * enum cfg80211_assoc_req_flags - Over-ride default behaviour in association.
1399 * 1433 *
1400 * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n) 1434 * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n)
1435 * @ASSOC_REQ_DISABLE_VHT: Disable VHT
1401 */ 1436 */
1402enum cfg80211_assoc_req_flags { 1437enum cfg80211_assoc_req_flags {
1403 ASSOC_REQ_DISABLE_HT = BIT(0), 1438 ASSOC_REQ_DISABLE_HT = BIT(0),
1439 ASSOC_REQ_DISABLE_VHT = BIT(1),
1404}; 1440};
1405 1441
1406/** 1442/**
@@ -1422,6 +1458,8 @@ enum cfg80211_assoc_req_flags {
1422 * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask 1458 * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask
1423 * will be used in ht_capa. Un-supported values will be ignored. 1459 * will be used in ht_capa. Un-supported values will be ignored.
1424 * @ht_capa_mask: The bits of ht_capa which are to be used. 1460 * @ht_capa_mask: The bits of ht_capa which are to be used.
1461 * @vht_capa: VHT capability override
1462 * @vht_capa_mask: VHT capability mask indicating which fields to use
1425 */ 1463 */
1426struct cfg80211_assoc_request { 1464struct cfg80211_assoc_request {
1427 struct cfg80211_bss *bss; 1465 struct cfg80211_bss *bss;
@@ -1432,6 +1470,7 @@ struct cfg80211_assoc_request {
1432 u32 flags; 1470 u32 flags;
1433 struct ieee80211_ht_cap ht_capa; 1471 struct ieee80211_ht_cap ht_capa;
1434 struct ieee80211_ht_cap ht_capa_mask; 1472 struct ieee80211_ht_cap ht_capa_mask;
1473 struct ieee80211_vht_cap vht_capa, vht_capa_mask;
1435}; 1474};
1436 1475
1437/** 1476/**
@@ -1542,6 +1581,8 @@ struct cfg80211_ibss_params {
1542 * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask 1581 * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask
1543 * will be used in ht_capa. Un-supported values will be ignored. 1582 * will be used in ht_capa. Un-supported values will be ignored.
1544 * @ht_capa_mask: The bits of ht_capa which are to be used. 1583 * @ht_capa_mask: The bits of ht_capa which are to be used.
1584 * @vht_capa: VHT Capability overrides
1585 * @vht_capa_mask: The bits of vht_capa which are to be used.
1545 */ 1586 */
1546struct cfg80211_connect_params { 1587struct cfg80211_connect_params {
1547 struct ieee80211_channel *channel; 1588 struct ieee80211_channel *channel;
@@ -1560,6 +1601,8 @@ struct cfg80211_connect_params {
1560 int bg_scan_period; 1601 int bg_scan_period;
1561 struct ieee80211_ht_cap ht_capa; 1602 struct ieee80211_ht_cap ht_capa;
1562 struct ieee80211_ht_cap ht_capa_mask; 1603 struct ieee80211_ht_cap ht_capa_mask;
1604 struct ieee80211_vht_cap vht_capa;
1605 struct ieee80211_vht_cap vht_capa_mask;
1563}; 1606};
1564 1607
1565/** 1608/**
@@ -1722,6 +1765,21 @@ struct cfg80211_gtk_rekey_data {
1722}; 1765};
1723 1766
1724/** 1767/**
1768 * struct cfg80211_update_ft_ies_params - FT IE Information
1769 *
1770 * This structure provides information needed to update the fast transition IE
1771 *
1772 * @md: The Mobility Domain ID, 2 Octet value
1773 * @ie: Fast Transition IEs
1774 * @ie_len: Length of ft_ie in octets
1775 */
1776struct cfg80211_update_ft_ies_params {
1777 u16 md;
1778 const u8 *ie;
1779 size_t ie_len;
1780};
1781
1782/**
1725 * struct cfg80211_ops - backend description for wireless configuration 1783 * struct cfg80211_ops - backend description for wireless configuration
1726 * 1784 *
1727 * This struct is registered by fullmac card drivers and/or wireless stacks 1785 * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -1781,9 +1839,8 @@ struct cfg80211_gtk_rekey_data {
1781 * @change_station: Modify a given station. Note that flags changes are not much 1839 * @change_station: Modify a given station. Note that flags changes are not much
1782 * validated in cfg80211, in particular the auth/assoc/authorized flags 1840 * validated in cfg80211, in particular the auth/assoc/authorized flags
1783 * might come to the driver in invalid combinations -- make sure to check 1841 * might come to the driver in invalid combinations -- make sure to check
1784 * them, also against the existing state! Also, supported_rates changes are 1842 * them, also against the existing state! Drivers must call
1785 * not checked in station mode -- drivers need to reject (or ignore) them 1843 * cfg80211_check_station_change() to validate the information.
1786 * for anything but TDLS peers.
1787 * @get_station: get station information for the station identified by @mac 1844 * @get_station: get station information for the station identified by @mac
1788 * @dump_station: dump station callback -- resume dump at index @idx 1845 * @dump_station: dump station callback -- resume dump at index @idx
1789 * 1846 *
@@ -2168,6 +2225,8 @@ struct cfg80211_ops {
2168 int (*start_radar_detection)(struct wiphy *wiphy, 2225 int (*start_radar_detection)(struct wiphy *wiphy,
2169 struct net_device *dev, 2226 struct net_device *dev,
2170 struct cfg80211_chan_def *chandef); 2227 struct cfg80211_chan_def *chandef);
2228 int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
2229 struct cfg80211_update_ft_ies_params *ftie);
2171}; 2230};
2172 2231
2173/* 2232/*
@@ -2485,6 +2544,8 @@ struct wiphy_wowlan_support {
2485 * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features. 2544 * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features.
2486 * @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden. 2545 * @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden.
2487 * If null, then none can be over-ridden. 2546 * If null, then none can be over-ridden.
2547 * @vht_capa_mod_mask: Specify what VHT capabilities can be over-ridden.
2548 * If null, then none can be over-ridden.
2488 * 2549 *
2489 * @max_acl_mac_addrs: Maximum number of MAC addresses that the device 2550 * @max_acl_mac_addrs: Maximum number of MAC addresses that the device
2490 * supports for ACL. 2551 * supports for ACL.
@@ -2593,6 +2654,7 @@ struct wiphy {
2593 struct dentry *debugfsdir; 2654 struct dentry *debugfsdir;
2594 2655
2595 const struct ieee80211_ht_cap *ht_capa_mod_mask; 2656 const struct ieee80211_ht_cap *ht_capa_mod_mask;
2657 const struct ieee80211_vht_cap *vht_capa_mod_mask;
2596 2658
2597#ifdef CONFIG_NET_NS 2659#ifdef CONFIG_NET_NS
2598 /* the network namespace this phy lives in currently */ 2660 /* the network namespace this phy lives in currently */
@@ -4002,6 +4064,30 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate);
4002void cfg80211_unregister_wdev(struct wireless_dev *wdev); 4064void cfg80211_unregister_wdev(struct wireless_dev *wdev);
4003 4065
4004/** 4066/**
4067 * struct cfg80211_ft_event - FT Information Elements
4068 * @ies: FT IEs
4069 * @ies_len: length of the FT IE in bytes
4070 * @target_ap: target AP's MAC address
4071 * @ric_ies: RIC IE
4072 * @ric_ies_len: length of the RIC IE in bytes
4073 */
4074struct cfg80211_ft_event_params {
4075 const u8 *ies;
4076 size_t ies_len;
4077 const u8 *target_ap;
4078 const u8 *ric_ies;
4079 size_t ric_ies_len;
4080};
4081
4082/**
4083 * cfg80211_ft_event - notify userspace about FT IE and RIC IE
4084 * @netdev: network device
4085 * @ft_event: IE information
4086 */
4087void cfg80211_ft_event(struct net_device *netdev,
4088 struct cfg80211_ft_event_params *ft_event);
4089
4090/**
4005 * cfg80211_get_p2p_attr - find and copy a P2P attribute from IE buffer 4091 * cfg80211_get_p2p_attr - find and copy a P2P attribute from IE buffer
4006 * @ies: the input IE buffer 4092 * @ies: the input IE buffer
4007 * @len: the input length 4093 * @len: the input length
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f7eba1300d82..cdd7cea1fd4c 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1101,8 +1101,6 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
1101 * These flags are used for communication about keys between the driver 1101 * These flags are used for communication about keys between the driver
1102 * and mac80211, with the @flags parameter of &struct ieee80211_key_conf. 1102 * and mac80211, with the @flags parameter of &struct ieee80211_key_conf.
1103 * 1103 *
1104 * @IEEE80211_KEY_FLAG_WMM_STA: Set by mac80211, this flag indicates
1105 * that the STA this key will be used with could be using QoS.
1106 * @IEEE80211_KEY_FLAG_GENERATE_IV: This flag should be set by the 1104 * @IEEE80211_KEY_FLAG_GENERATE_IV: This flag should be set by the
1107 * driver to indicate that it requires IV generation for this 1105 * driver to indicate that it requires IV generation for this
1108 * particular key. 1106 * particular key.
@@ -1127,7 +1125,6 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
1127 * %IEEE80211_KEY_FLAG_SW_MGMT_TX flag to encrypt such frames in SW. 1125 * %IEEE80211_KEY_FLAG_SW_MGMT_TX flag to encrypt such frames in SW.
1128 */ 1126 */
1129enum ieee80211_key_flags { 1127enum ieee80211_key_flags {
1130 IEEE80211_KEY_FLAG_WMM_STA = 1<<0,
1131 IEEE80211_KEY_FLAG_GENERATE_IV = 1<<1, 1128 IEEE80211_KEY_FLAG_GENERATE_IV = 1<<1,
1132 IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2, 1129 IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2,
1133 IEEE80211_KEY_FLAG_PAIRWISE = 1<<3, 1130 IEEE80211_KEY_FLAG_PAIRWISE = 1<<3,
@@ -1231,9 +1228,8 @@ enum ieee80211_sta_rx_bandwidth {
1231 * @addr: MAC address 1228 * @addr: MAC address
1232 * @aid: AID we assigned to the station if we're an AP 1229 * @aid: AID we assigned to the station if we're an AP
1233 * @supp_rates: Bitmap of supported rates (per band) 1230 * @supp_rates: Bitmap of supported rates (per band)
1234 * @ht_cap: HT capabilities of this STA; restricted to our own TX capabilities 1231 * @ht_cap: HT capabilities of this STA; restricted to our own capabilities
1235 * @vht_cap: VHT capabilities of this STA; Not restricting any capabilities 1232 * @vht_cap: VHT capabilities of this STA; restricted to our own capabilities
1236 * of remote STA. Taking as is.
1237 * @wme: indicates whether the STA supports WME. Only valid during AP-mode. 1233 * @wme: indicates whether the STA supports WME. Only valid during AP-mode.
1238 * @drv_priv: data area for driver use, will always be aligned to 1234 * @drv_priv: data area for driver use, will always be aligned to
1239 * sizeof(void *), size is determined in hw information. 1235 * sizeof(void *), size is determined in hw information.
@@ -2135,6 +2131,24 @@ enum ieee80211_rate_control_changed {
2135}; 2131};
2136 2132
2137/** 2133/**
2134 * enum ieee80211_roc_type - remain on channel type
2135 *
2136 * With the support for multi channel contexts and multi channel operations,
2137 * remain on channel operations might be limited/deferred/aborted by other
2138 * flows/operations which have higher priority (and vise versa).
2139 * Specifying the ROC type can be used by devices to prioritize the ROC
2140 * operations compared to other operations/flows.
2141 *
2142 * @IEEE80211_ROC_TYPE_NORMAL: There are no special requirements for this ROC.
2143 * @IEEE80211_ROC_TYPE_MGMT_TX: The remain on channel request is required
2144 * for sending managment frames offchannel.
2145 */
2146enum ieee80211_roc_type {
2147 IEEE80211_ROC_TYPE_NORMAL = 0,
2148 IEEE80211_ROC_TYPE_MGMT_TX,
2149};
2150
2151/**
2138 * struct ieee80211_ops - callbacks from mac80211 to the driver 2152 * struct ieee80211_ops - callbacks from mac80211 to the driver
2139 * 2153 *
2140 * This structure contains various callbacks that the driver may 2154 * This structure contains various callbacks that the driver may
@@ -2687,7 +2701,8 @@ struct ieee80211_ops {
2687 int (*remain_on_channel)(struct ieee80211_hw *hw, 2701 int (*remain_on_channel)(struct ieee80211_hw *hw,
2688 struct ieee80211_vif *vif, 2702 struct ieee80211_vif *vif,
2689 struct ieee80211_channel *chan, 2703 struct ieee80211_channel *chan,
2690 int duration); 2704 int duration,
2705 enum ieee80211_roc_type type);
2691 int (*cancel_remain_on_channel)(struct ieee80211_hw *hw); 2706 int (*cancel_remain_on_channel)(struct ieee80211_hw *hw);
2692 int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); 2707 int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx);
2693 void (*get_ringparam)(struct ieee80211_hw *hw, 2708 void (*get_ringparam)(struct ieee80211_hw *hw,
diff --git a/include/uapi/linux/nfc.h b/include/uapi/linux/nfc.h
index 7969f46f1bb3..7440bc81a04b 100644
--- a/include/uapi/linux/nfc.h
+++ b/include/uapi/linux/nfc.h
@@ -90,6 +90,8 @@ enum nfc_commands {
90 NFC_CMD_LLC_SET_PARAMS, 90 NFC_CMD_LLC_SET_PARAMS,
91 NFC_CMD_ENABLE_SE, 91 NFC_CMD_ENABLE_SE,
92 NFC_CMD_DISABLE_SE, 92 NFC_CMD_DISABLE_SE,
93 NFC_CMD_LLC_SDREQ,
94 NFC_EVENT_LLC_SDRES,
93/* private: internal use only */ 95/* private: internal use only */
94 __NFC_CMD_AFTER_LAST 96 __NFC_CMD_AFTER_LAST
95}; 97};
@@ -140,11 +142,21 @@ enum nfc_attrs {
140 NFC_ATTR_LLC_PARAM_RW, 142 NFC_ATTR_LLC_PARAM_RW,
141 NFC_ATTR_LLC_PARAM_MIUX, 143 NFC_ATTR_LLC_PARAM_MIUX,
142 NFC_ATTR_SE, 144 NFC_ATTR_SE,
145 NFC_ATTR_LLC_SDP,
143/* private: internal use only */ 146/* private: internal use only */
144 __NFC_ATTR_AFTER_LAST 147 __NFC_ATTR_AFTER_LAST
145}; 148};
146#define NFC_ATTR_MAX (__NFC_ATTR_AFTER_LAST - 1) 149#define NFC_ATTR_MAX (__NFC_ATTR_AFTER_LAST - 1)
147 150
151enum nfc_sdp_attr {
152 NFC_SDP_ATTR_UNSPEC,
153 NFC_SDP_ATTR_URI,
154 NFC_SDP_ATTR_SAP,
155/* private: internal use only */
156 __NFC_SDP_ATTR_AFTER_LAST
157};
158#define NFC_SDP_ATTR_MAX (__NFC_SDP_ATTR_AFTER_LAST - 1)
159
148#define NFC_DEVICE_NAME_MAXSIZE 8 160#define NFC_DEVICE_NAME_MAXSIZE 8
149#define NFC_NFCID1_MAXSIZE 10 161#define NFC_NFCID1_MAXSIZE 10
150#define NFC_SENSB_RES_MAXSIZE 12 162#define NFC_SENSB_RES_MAXSIZE 12
@@ -220,4 +232,8 @@ struct sockaddr_nfc_llcp {
220#define NFC_LLCP_DIRECTION_RX 0x00 232#define NFC_LLCP_DIRECTION_RX 0x00
221#define NFC_LLCP_DIRECTION_TX 0x01 233#define NFC_LLCP_DIRECTION_TX 0x01
222 234
235/* socket option names */
236#define NFC_LLCP_RW 0
237#define NFC_LLCP_MIUX 1
238
223#endif /*__LINUX_NFC_H */ 239#endif /*__LINUX_NFC_H */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index c46bb016f4e4..79da8710448e 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -36,7 +36,21 @@
36 * The station is still assumed to belong to the AP interface it was added 36 * The station is still assumed to belong to the AP interface it was added
37 * to. 37 * to.
38 * 38 *
39 * TODO: need more info? 39 * Station handling varies per interface type and depending on the driver's
40 * capabilities.
41 *
42 * For drivers supporting TDLS with external setup (WIPHY_FLAG_SUPPORTS_TDLS
43 * and WIPHY_FLAG_TDLS_EXTERNAL_SETUP), the station lifetime is as follows:
44 * - a setup station entry is added, not yet authorized, without any rate
45 * or capability information, this just exists to avoid race conditions
46 * - when the TDLS setup is done, a single NL80211_CMD_SET_STATION is valid
47 * to add rate and capability information to the station and at the same
48 * time mark it authorized.
49 * - %NL80211_TDLS_ENABLE_LINK is then used
50 * - after this, the only valid operation is to remove it by tearing down
51 * the TDLS link (%NL80211_TDLS_DISABLE_LINK)
52 *
53 * TODO: need more info for other interface types
40 */ 54 */
41 55
42/** 56/**
@@ -499,9 +513,11 @@
499 * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a 513 * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a
500 * beacon or probe response from a compatible mesh peer. This is only 514 * beacon or probe response from a compatible mesh peer. This is only
501 * sent while no station information (sta_info) exists for the new peer 515 * sent while no station information (sta_info) exists for the new peer
502 * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On 516 * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH,
503 * reception of this notification, userspace may decide to create a new 517 * @NL80211_MESH_SETUP_USERSPACE_AMPE, or
504 * station (@NL80211_CMD_NEW_STATION). To stop this notification from 518 * @NL80211_MESH_SETUP_USERSPACE_MPM is set. On reception of this
519 * notification, userspace may decide to create a new station
520 * (@NL80211_CMD_NEW_STATION). To stop this notification from
505 * reoccurring, the userspace authentication daemon may want to create the 521 * reoccurring, the userspace authentication daemon may want to create the
506 * new station with the AUTHENTICATED flag unset and maybe change it later 522 * new station with the AUTHENTICATED flag unset and maybe change it later
507 * depending on the authentication result. 523 * depending on the authentication result.
@@ -611,6 +627,18 @@
611 * %NL80211_ATTR_RADAR_EVENT is used to inform about the type of the 627 * %NL80211_ATTR_RADAR_EVENT is used to inform about the type of the
612 * event. 628 * event.
613 * 629 *
630 * @NL80211_CMD_GET_PROTOCOL_FEATURES: Get global nl80211 protocol features,
631 * i.e. features for the nl80211 protocol rather than device features.
632 * Returns the features in the %NL80211_ATTR_PROTOCOL_FEATURES bitmap.
633 *
634 * @NL80211_CMD_UPDATE_FT_IES: Pass down the most up-to-date Fast Transition
635 * Information Element to the WLAN driver
636 *
637 * @NL80211_CMD_FT_EVENT: Send a Fast transition event from the WLAN driver
638 * to the supplicant. This will carry the target AP's MAC address along
639 * with the relevant Information Elements. This event is used to report
640 * received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE).
641 *
614 * @NL80211_CMD_MAX: highest used command number 642 * @NL80211_CMD_MAX: highest used command number
615 * @__NL80211_CMD_AFTER_LAST: internal use 643 * @__NL80211_CMD_AFTER_LAST: internal use
616 */ 644 */
@@ -765,6 +793,11 @@ enum nl80211_commands {
765 793
766 NL80211_CMD_RADAR_DETECT, 794 NL80211_CMD_RADAR_DETECT,
767 795
796 NL80211_CMD_GET_PROTOCOL_FEATURES,
797
798 NL80211_CMD_UPDATE_FT_IES,
799 NL80211_CMD_FT_EVENT,
800
768 /* add new commands above here */ 801 /* add new commands above here */
769 802
770 /* used to define NL80211_CMD_MAX below */ 803 /* used to define NL80211_CMD_MAX below */
@@ -884,7 +917,8 @@ enum nl80211_commands {
884 * consisting of a nested array. 917 * consisting of a nested array.
885 * 918 *
886 * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes). 919 * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes).
887 * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link. 920 * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link
921 * (see &enum nl80211_plink_action).
888 * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. 922 * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path.
889 * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path 923 * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path
890 * info given for %NL80211_CMD_GET_MPATH, nested attribute described at 924 * info given for %NL80211_CMD_GET_MPATH, nested attribute described at
@@ -1167,10 +1201,10 @@ enum nl80211_commands {
1167 * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver 1201 * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver
1168 * allows auth frames in a mesh to be passed to userspace for processing via 1202 * allows auth frames in a mesh to be passed to userspace for processing via
1169 * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. 1203 * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag.
1170 * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link as 1204 * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link as defined in
1171 * defined in &enum nl80211_plink_state. Used when userspace is 1205 * &enum nl80211_plink_state. Used when userspace is driving the peer link
1172 * driving the peer link management state machine. 1206 * management state machine. @NL80211_MESH_SETUP_USERSPACE_AMPE or
1173 * @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled. 1207 * @NL80211_MESH_SETUP_USERSPACE_MPM must be enabled.
1174 * 1208 *
1175 * @NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: indicates, as part of the wiphy 1209 * @NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: indicates, as part of the wiphy
1176 * capabilities, the supported WoWLAN triggers 1210 * capabilities, the supported WoWLAN triggers
@@ -1368,6 +1402,18 @@ enum nl80211_commands {
1368 * advertised to the driver, e.g., to enable TDLS off channel operations 1402 * advertised to the driver, e.g., to enable TDLS off channel operations
1369 * and PU-APSD. 1403 * and PU-APSD.
1370 * 1404 *
1405 * @NL80211_ATTR_PROTOCOL_FEATURES: global nl80211 feature flags, see
1406 * &enum nl80211_protocol_features, the attribute is a u32.
1407 *
1408 * @NL80211_ATTR_SPLIT_WIPHY_DUMP: flag attribute, userspace supports
1409 * receiving the data for a single wiphy split across multiple
1410 * messages, given with wiphy dump message
1411 *
1412 * @NL80211_ATTR_MDID: Mobility Domain Identifier
1413 *
1414 * @NL80211_ATTR_IE_RIC: Resource Information Container Information
1415 * Element
1416 *
1371 * @NL80211_ATTR_MAX: highest attribute number currently defined 1417 * @NL80211_ATTR_MAX: highest attribute number currently defined
1372 * @__NL80211_ATTR_AFTER_LAST: internal use 1418 * @__NL80211_ATTR_AFTER_LAST: internal use
1373 */ 1419 */
@@ -1654,6 +1700,15 @@ enum nl80211_attrs {
1654 NL80211_ATTR_STA_CAPABILITY, 1700 NL80211_ATTR_STA_CAPABILITY,
1655 NL80211_ATTR_STA_EXT_CAPABILITY, 1701 NL80211_ATTR_STA_EXT_CAPABILITY,
1656 1702
1703 NL80211_ATTR_PROTOCOL_FEATURES,
1704 NL80211_ATTR_SPLIT_WIPHY_DUMP,
1705
1706 NL80211_ATTR_DISABLE_VHT,
1707 NL80211_ATTR_VHT_CAPABILITY_MASK,
1708
1709 NL80211_ATTR_MDID,
1710 NL80211_ATTR_IE_RIC,
1711
1657 /* add attributes here, update the policy in nl80211.c */ 1712 /* add attributes here, update the policy in nl80211.c */
1658 1713
1659 __NL80211_ATTR_AFTER_LAST, 1714 __NL80211_ATTR_AFTER_LAST,
@@ -2412,8 +2467,10 @@ enum nl80211_mesh_power_mode {
2412 * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh 2467 * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh
2413 * point. 2468 * point.
2414 * 2469 *
2415 * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically 2470 * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically open
2416 * open peer links when we detect compatible mesh peers. 2471 * peer links when we detect compatible mesh peers. Disabled if
2472 * @NL80211_MESH_SETUP_USERSPACE_MPM or @NL80211_MESH_SETUP_USERSPACE_AMPE are
2473 * set.
2417 * 2474 *
2418 * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames 2475 * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames
2419 * containing a PREQ that an MP can send to a particular destination (path 2476 * containing a PREQ that an MP can send to a particular destination (path
@@ -2559,6 +2616,9 @@ enum nl80211_meshconf_params {
2559 * vendor specific synchronization method or disable it to use the default 2616 * vendor specific synchronization method or disable it to use the default
2560 * neighbor offset synchronization 2617 * neighbor offset synchronization
2561 * 2618 *
2619 * @NL80211_MESH_SETUP_USERSPACE_MPM: Enable this option if userspace will
2620 * implement an MPM which handles peer allocation and state.
2621 *
2562 * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number 2622 * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
2563 * 2623 *
2564 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use 2624 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
@@ -2571,6 +2631,7 @@ enum nl80211_mesh_setup_params {
2571 NL80211_MESH_SETUP_USERSPACE_AUTH, 2631 NL80211_MESH_SETUP_USERSPACE_AUTH,
2572 NL80211_MESH_SETUP_USERSPACE_AMPE, 2632 NL80211_MESH_SETUP_USERSPACE_AMPE,
2573 NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC, 2633 NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC,
2634 NL80211_MESH_SETUP_USERSPACE_MPM,
2574 2635
2575 /* keep last */ 2636 /* keep last */
2576 __NL80211_MESH_SETUP_ATTR_AFTER_LAST, 2637 __NL80211_MESH_SETUP_ATTR_AFTER_LAST,
@@ -3307,6 +3368,23 @@ enum nl80211_plink_state {
3307 MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1 3368 MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1
3308}; 3369};
3309 3370
3371/**
3372 * enum nl80211_plink_action - actions to perform in mesh peers
3373 *
3374 * @NL80211_PLINK_ACTION_NO_ACTION: perform no action
3375 * @NL80211_PLINK_ACTION_OPEN: start mesh peer link establishment
3376 * @NL80211_PLINK_ACTION_BLOCK: block traffic from this mesh peer
3377 * @NUM_NL80211_PLINK_ACTIONS: number of possible actions
3378 */
3379enum plink_actions {
3380 NL80211_PLINK_ACTION_NO_ACTION,
3381 NL80211_PLINK_ACTION_OPEN,
3382 NL80211_PLINK_ACTION_BLOCK,
3383
3384 NUM_NL80211_PLINK_ACTIONS,
3385};
3386
3387
3310#define NL80211_KCK_LEN 16 3388#define NL80211_KCK_LEN 16
3311#define NL80211_KEK_LEN 16 3389#define NL80211_KEK_LEN 16
3312#define NL80211_REPLAY_CTR_LEN 8 3390#define NL80211_REPLAY_CTR_LEN 8
@@ -3456,6 +3534,10 @@ enum nl80211_ap_sme_features {
3456 * stations the authenticated/associated bits have to be set in the mask. 3534 * stations the authenticated/associated bits have to be set in the mask.
3457 * @NL80211_FEATURE_ADVERTISE_CHAN_LIMITS: cfg80211 advertises channel limits 3535 * @NL80211_FEATURE_ADVERTISE_CHAN_LIMITS: cfg80211 advertises channel limits
3458 * (HT40, VHT 80/160 MHz) if this flag is set 3536 * (HT40, VHT 80/160 MHz) if this flag is set
3537 * @NL80211_FEATURE_USERSPACE_MPM: This driver supports a userspace Mesh
3538 * Peering Management entity which may be implemented by registering for
3539 * beacons or NL80211_CMD_NEW_PEER_CANDIDATE events. The mesh beacon is
3540 * still generated by the driver.
3459 */ 3541 */
3460enum nl80211_feature_flags { 3542enum nl80211_feature_flags {
3461 NL80211_FEATURE_SK_TX_STATUS = 1 << 0, 3543 NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
@@ -3474,6 +3556,7 @@ enum nl80211_feature_flags {
3474 /* bit 13 is reserved */ 3556 /* bit 13 is reserved */
3475 NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14, 3557 NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14,
3476 NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15, 3558 NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15,
3559 NL80211_FEATURE_USERSPACE_MPM = 1 << 16,
3477}; 3560};
3478 3561
3479/** 3562/**
@@ -3587,4 +3670,16 @@ enum nl80211_dfs_state {
3587 NL80211_DFS_AVAILABLE, 3670 NL80211_DFS_AVAILABLE,
3588}; 3671};
3589 3672
3673/**
3674 * enum enum nl80211_protocol_features - nl80211 protocol features
3675 * @NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP: nl80211 supports splitting
3676 * wiphy dumps (if requested by the application with the attribute
3677 * %NL80211_ATTR_SPLIT_WIPHY_DUMP. Also supported is filtering the
3678 * wiphy dump by %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFINDEX or
3679 * %NL80211_ATTR_WDEV.
3680 */
3681enum nl80211_protocol_features {
3682 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP = 1 << 0,
3683};
3684
3590#endif /* __LINUX_NL80211_H */ 3685#endif /* __LINUX_NL80211_H */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index fb306814576a..1d1ddabd89ca 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -254,7 +254,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
254 goto out_unlock; 254 goto out_unlock;
255 } 255 }
256 256
257 __ieee80211_key_free(key); 257 __ieee80211_key_free(key, true);
258 258
259 ret = 0; 259 ret = 0;
260 out_unlock: 260 out_unlock:
@@ -1035,9 +1035,12 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1035 sta_info_flush_defer(vlan); 1035 sta_info_flush_defer(vlan);
1036 sta_info_flush_defer(sdata); 1036 sta_info_flush_defer(sdata);
1037 rcu_barrier(); 1037 rcu_barrier();
1038 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 1038 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
1039 sta_info_flush_cleanup(vlan); 1039 sta_info_flush_cleanup(vlan);
1040 ieee80211_free_keys(vlan);
1041 }
1040 sta_info_flush_cleanup(sdata); 1042 sta_info_flush_cleanup(sdata);
1043 ieee80211_free_keys(sdata);
1041 1044
1042 sdata->vif.bss_conf.enable_beacon = false; 1045 sdata->vif.bss_conf.enable_beacon = false;
1043 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); 1046 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
@@ -1177,6 +1180,18 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1177 mask |= BIT(NL80211_STA_FLAG_ASSOCIATED); 1180 mask |= BIT(NL80211_STA_FLAG_ASSOCIATED);
1178 if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) 1181 if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED))
1179 set |= BIT(NL80211_STA_FLAG_ASSOCIATED); 1182 set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
1183 } else if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
1184 /*
1185 * TDLS -- everything follows authorized, but
1186 * only becoming authorized is possible, not
1187 * going back
1188 */
1189 if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
1190 set |= BIT(NL80211_STA_FLAG_AUTHENTICATED) |
1191 BIT(NL80211_STA_FLAG_ASSOCIATED);
1192 mask |= BIT(NL80211_STA_FLAG_AUTHENTICATED) |
1193 BIT(NL80211_STA_FLAG_ASSOCIATED);
1194 }
1180 } 1195 }
1181 1196
1182 ret = sta_apply_auth_flags(local, sta, mask, set); 1197 ret = sta_apply_auth_flags(local, sta, mask, set);
@@ -1261,7 +1276,8 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1261 if (ieee80211_vif_is_mesh(&sdata->vif)) { 1276 if (ieee80211_vif_is_mesh(&sdata->vif)) {
1262#ifdef CONFIG_MAC80211_MESH 1277#ifdef CONFIG_MAC80211_MESH
1263 u32 changed = 0; 1278 u32 changed = 0;
1264 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) { 1279
1280 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) {
1265 switch (params->plink_state) { 1281 switch (params->plink_state) {
1266 case NL80211_PLINK_ESTAB: 1282 case NL80211_PLINK_ESTAB:
1267 if (sta->plink_state != NL80211_PLINK_ESTAB) 1283 if (sta->plink_state != NL80211_PLINK_ESTAB)
@@ -1292,15 +1308,18 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1292 /* nothing */ 1308 /* nothing */
1293 break; 1309 break;
1294 } 1310 }
1295 } else { 1311 }
1296 switch (params->plink_action) { 1312
1297 case PLINK_ACTION_OPEN: 1313 switch (params->plink_action) {
1298 changed |= mesh_plink_open(sta); 1314 case NL80211_PLINK_ACTION_NO_ACTION:
1299 break; 1315 /* nothing */
1300 case PLINK_ACTION_BLOCK: 1316 break;
1301 changed |= mesh_plink_block(sta); 1317 case NL80211_PLINK_ACTION_OPEN:
1302 break; 1318 changed |= mesh_plink_open(sta);
1303 } 1319 break;
1320 case NL80211_PLINK_ACTION_BLOCK:
1321 changed |= mesh_plink_block(sta);
1322 break;
1304 } 1323 }
1305 1324
1306 if (params->local_pm) 1325 if (params->local_pm)
@@ -1346,8 +1365,10 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
1346 * defaults -- if userspace wants something else we'll 1365 * defaults -- if userspace wants something else we'll
1347 * change it accordingly in sta_apply_parameters() 1366 * change it accordingly in sta_apply_parameters()
1348 */ 1367 */
1349 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); 1368 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) {
1350 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); 1369 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
1370 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
1371 }
1351 1372
1352 err = sta_apply_parameters(local, sta, params); 1373 err = sta_apply_parameters(local, sta, params);
1353 if (err) { 1374 if (err) {
@@ -1356,8 +1377,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
1356 } 1377 }
1357 1378
1358 /* 1379 /*
1359 * for TDLS, rate control should be initialized only when supported 1380 * for TDLS, rate control should be initialized only when
1360 * rates are known. 1381 * rates are known and station is marked authorized
1361 */ 1382 */
1362 if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) 1383 if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER))
1363 rate_control_rate_init(sta); 1384 rate_control_rate_init(sta);
@@ -1394,50 +1415,67 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1394} 1415}
1395 1416
1396static int ieee80211_change_station(struct wiphy *wiphy, 1417static int ieee80211_change_station(struct wiphy *wiphy,
1397 struct net_device *dev, 1418 struct net_device *dev, u8 *mac,
1398 u8 *mac,
1399 struct station_parameters *params) 1419 struct station_parameters *params)
1400{ 1420{
1401 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1421 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1402 struct ieee80211_local *local = wiphy_priv(wiphy); 1422 struct ieee80211_local *local = wiphy_priv(wiphy);
1403 struct sta_info *sta; 1423 struct sta_info *sta;
1404 struct ieee80211_sub_if_data *vlansdata; 1424 struct ieee80211_sub_if_data *vlansdata;
1425 enum cfg80211_station_type statype;
1405 int err; 1426 int err;
1406 1427
1407 mutex_lock(&local->sta_mtx); 1428 mutex_lock(&local->sta_mtx);
1408 1429
1409 sta = sta_info_get_bss(sdata, mac); 1430 sta = sta_info_get_bss(sdata, mac);
1410 if (!sta) { 1431 if (!sta) {
1411 mutex_unlock(&local->sta_mtx); 1432 err = -ENOENT;
1412 return -ENOENT; 1433 goto out_err;
1413 } 1434 }
1414 1435
1415 /* in station mode, some updates are only valid with TDLS */ 1436 switch (sdata->vif.type) {
1416 if (sdata->vif.type == NL80211_IFTYPE_STATION && 1437 case NL80211_IFTYPE_MESH_POINT:
1417 (params->supported_rates || params->ht_capa || params->vht_capa || 1438 if (sdata->u.mesh.user_mpm)
1418 params->sta_modify_mask || 1439 statype = CFG80211_STA_MESH_PEER_USER;
1419 (params->sta_flags_mask & BIT(NL80211_STA_FLAG_WME))) && 1440 else
1420 !test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { 1441 statype = CFG80211_STA_MESH_PEER_KERNEL;
1421 mutex_unlock(&local->sta_mtx); 1442 break;
1422 return -EINVAL; 1443 case NL80211_IFTYPE_ADHOC:
1444 statype = CFG80211_STA_IBSS;
1445 break;
1446 case NL80211_IFTYPE_STATION:
1447 if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
1448 statype = CFG80211_STA_AP_STA;
1449 break;
1450 }
1451 if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
1452 statype = CFG80211_STA_TDLS_PEER_ACTIVE;
1453 else
1454 statype = CFG80211_STA_TDLS_PEER_SETUP;
1455 break;
1456 case NL80211_IFTYPE_AP:
1457 case NL80211_IFTYPE_AP_VLAN:
1458 statype = CFG80211_STA_AP_CLIENT;
1459 break;
1460 default:
1461 err = -EOPNOTSUPP;
1462 goto out_err;
1423 } 1463 }
1424 1464
1465 err = cfg80211_check_station_change(wiphy, params, statype);
1466 if (err)
1467 goto out_err;
1468
1425 if (params->vlan && params->vlan != sta->sdata->dev) { 1469 if (params->vlan && params->vlan != sta->sdata->dev) {
1426 bool prev_4addr = false; 1470 bool prev_4addr = false;
1427 bool new_4addr = false; 1471 bool new_4addr = false;
1428 1472
1429 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 1473 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
1430 1474
1431 if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
1432 vlansdata->vif.type != NL80211_IFTYPE_AP) {
1433 mutex_unlock(&local->sta_mtx);
1434 return -EINVAL;
1435 }
1436
1437 if (params->vlan->ieee80211_ptr->use_4addr) { 1475 if (params->vlan->ieee80211_ptr->use_4addr) {
1438 if (vlansdata->u.vlan.sta) { 1476 if (vlansdata->u.vlan.sta) {
1439 mutex_unlock(&local->sta_mtx); 1477 err = -EBUSY;
1440 return -EBUSY; 1478 goto out_err;
1441 } 1479 }
1442 1480
1443 rcu_assign_pointer(vlansdata->u.vlan.sta, sta); 1481 rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
@@ -1464,12 +1502,12 @@ static int ieee80211_change_station(struct wiphy *wiphy,
1464 } 1502 }
1465 1503
1466 err = sta_apply_parameters(local, sta, params); 1504 err = sta_apply_parameters(local, sta, params);
1467 if (err) { 1505 if (err)
1468 mutex_unlock(&local->sta_mtx); 1506 goto out_err;
1469 return err;
1470 }
1471 1507
1472 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && params->supported_rates) 1508 /* When peer becomes authorized, init rate control as well */
1509 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
1510 test_sta_flag(sta, WLAN_STA_AUTHORIZED))
1473 rate_control_rate_init(sta); 1511 rate_control_rate_init(sta);
1474 1512
1475 mutex_unlock(&local->sta_mtx); 1513 mutex_unlock(&local->sta_mtx);
@@ -1479,7 +1517,11 @@ static int ieee80211_change_station(struct wiphy *wiphy,
1479 ieee80211_recalc_ps(local, -1); 1517 ieee80211_recalc_ps(local, -1);
1480 ieee80211_recalc_ps_vif(sdata); 1518 ieee80211_recalc_ps_vif(sdata);
1481 } 1519 }
1520
1482 return 0; 1521 return 0;
1522out_err:
1523 mutex_unlock(&local->sta_mtx);
1524 return err;
1483} 1525}
1484 1526
1485#ifdef CONFIG_MAC80211_MESH 1527#ifdef CONFIG_MAC80211_MESH
@@ -1687,6 +1729,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1687 ifmsh->mesh_sp_id = setup->sync_method; 1729 ifmsh->mesh_sp_id = setup->sync_method;
1688 ifmsh->mesh_pp_id = setup->path_sel_proto; 1730 ifmsh->mesh_pp_id = setup->path_sel_proto;
1689 ifmsh->mesh_pm_id = setup->path_metric; 1731 ifmsh->mesh_pm_id = setup->path_metric;
1732 ifmsh->user_mpm = setup->user_mpm;
1690 ifmsh->security = IEEE80211_MESH_SEC_NONE; 1733 ifmsh->security = IEEE80211_MESH_SEC_NONE;
1691 if (setup->is_authenticated) 1734 if (setup->is_authenticated)
1692 ifmsh->security |= IEEE80211_MESH_SEC_AUTHED; 1735 ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
@@ -1730,8 +1773,11 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1730 conf->dot11MeshTTL = nconf->dot11MeshTTL; 1773 conf->dot11MeshTTL = nconf->dot11MeshTTL;
1731 if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask)) 1774 if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
1732 conf->element_ttl = nconf->element_ttl; 1775 conf->element_ttl = nconf->element_ttl;
1733 if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) 1776 if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) {
1777 if (ifmsh->user_mpm)
1778 return -EBUSY;
1734 conf->auto_open_plinks = nconf->auto_open_plinks; 1779 conf->auto_open_plinks = nconf->auto_open_plinks;
1780 }
1735 if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask)) 1781 if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask))
1736 conf->dot11MeshNbrOffsetMaxNeighbor = 1782 conf->dot11MeshNbrOffsetMaxNeighbor =
1737 nconf->dot11MeshNbrOffsetMaxNeighbor; 1783 nconf->dot11MeshNbrOffsetMaxNeighbor;
@@ -2371,7 +2417,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2371 struct ieee80211_sub_if_data *sdata, 2417 struct ieee80211_sub_if_data *sdata,
2372 struct ieee80211_channel *channel, 2418 struct ieee80211_channel *channel,
2373 unsigned int duration, u64 *cookie, 2419 unsigned int duration, u64 *cookie,
2374 struct sk_buff *txskb) 2420 struct sk_buff *txskb,
2421 enum ieee80211_roc_type type)
2375{ 2422{
2376 struct ieee80211_roc_work *roc, *tmp; 2423 struct ieee80211_roc_work *roc, *tmp;
2377 bool queued = false; 2424 bool queued = false;
@@ -2390,6 +2437,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2390 roc->duration = duration; 2437 roc->duration = duration;
2391 roc->req_duration = duration; 2438 roc->req_duration = duration;
2392 roc->frame = txskb; 2439 roc->frame = txskb;
2440 roc->type = type;
2393 roc->mgmt_tx_cookie = (unsigned long)txskb; 2441 roc->mgmt_tx_cookie = (unsigned long)txskb;
2394 roc->sdata = sdata; 2442 roc->sdata = sdata;
2395 INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); 2443 INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work);
@@ -2420,7 +2468,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2420 if (!duration) 2468 if (!duration)
2421 duration = 10; 2469 duration = 10;
2422 2470
2423 ret = drv_remain_on_channel(local, sdata, channel, duration); 2471 ret = drv_remain_on_channel(local, sdata, channel, duration, type);
2424 if (ret) { 2472 if (ret) {
2425 kfree(roc); 2473 kfree(roc);
2426 return ret; 2474 return ret;
@@ -2439,10 +2487,13 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2439 * 2487 *
2440 * If it hasn't started yet, just increase the duration 2488 * If it hasn't started yet, just increase the duration
2441 * and add the new one to the list of dependents. 2489 * and add the new one to the list of dependents.
2490 * If the type of the new ROC has higher priority, modify the
2491 * type of the previous one to match that of the new one.
2442 */ 2492 */
2443 if (!tmp->started) { 2493 if (!tmp->started) {
2444 list_add_tail(&roc->list, &tmp->dependents); 2494 list_add_tail(&roc->list, &tmp->dependents);
2445 tmp->duration = max(tmp->duration, roc->duration); 2495 tmp->duration = max(tmp->duration, roc->duration);
2496 tmp->type = max(tmp->type, roc->type);
2446 queued = true; 2497 queued = true;
2447 break; 2498 break;
2448 } 2499 }
@@ -2454,16 +2505,18 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2454 /* 2505 /*
2455 * In the offloaded ROC case, if it hasn't begun, add 2506 * In the offloaded ROC case, if it hasn't begun, add
2456 * this new one to the dependent list to be handled 2507 * this new one to the dependent list to be handled
2457 * when the the master one begins. If it has begun, 2508 * when the master one begins. If it has begun,
2458 * check that there's still a minimum time left and 2509 * check that there's still a minimum time left and
2459 * if so, start this one, transmitting the frame, but 2510 * if so, start this one, transmitting the frame, but
2460 * add it to the list directly after this one with a 2511 * add it to the list directly after this one with
2461 * a reduced time so we'll ask the driver to execute 2512 * a reduced time so we'll ask the driver to execute
2462 * it right after finishing the previous one, in the 2513 * it right after finishing the previous one, in the
2463 * hope that it'll also be executed right afterwards, 2514 * hope that it'll also be executed right afterwards,
2464 * effectively extending the old one. 2515 * effectively extending the old one.
2465 * If there's no minimum time left, just add it to the 2516 * If there's no minimum time left, just add it to the
2466 * normal list. 2517 * normal list.
2518 * TODO: the ROC type is ignored here, assuming that it
2519 * is better to immediately use the current ROC.
2467 */ 2520 */
2468 if (!tmp->hw_begun) { 2521 if (!tmp->hw_begun) {
2469 list_add_tail(&roc->list, &tmp->dependents); 2522 list_add_tail(&roc->list, &tmp->dependents);
@@ -2557,7 +2610,8 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy,
2557 2610
2558 mutex_lock(&local->mtx); 2611 mutex_lock(&local->mtx);
2559 ret = ieee80211_start_roc_work(local, sdata, chan, 2612 ret = ieee80211_start_roc_work(local, sdata, chan,
2560 duration, cookie, NULL); 2613 duration, cookie, NULL,
2614 IEEE80211_ROC_TYPE_NORMAL);
2561 mutex_unlock(&local->mtx); 2615 mutex_unlock(&local->mtx);
2562 2616
2563 return ret; 2617 return ret;
@@ -2790,7 +2844,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2790 2844
2791 /* This will handle all kinds of coalescing and immediate TX */ 2845 /* This will handle all kinds of coalescing and immediate TX */
2792 ret = ieee80211_start_roc_work(local, sdata, chan, 2846 ret = ieee80211_start_roc_work(local, sdata, chan,
2793 wait, cookie, skb); 2847 wait, cookie, skb,
2848 IEEE80211_ROC_TYPE_MGMT_TX);
2794 if (ret) 2849 if (ret)
2795 kfree_skb(skb); 2850 kfree_skb(skb);
2796 out_unlock: 2851 out_unlock:
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index c7591f73dbc3..4f841fe559df 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -325,6 +325,36 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
325} 325}
326STA_OPS(ht_capa); 326STA_OPS(ht_capa);
327 327
328static ssize_t sta_vht_capa_read(struct file *file, char __user *userbuf,
329 size_t count, loff_t *ppos)
330{
331 char buf[128], *p = buf;
332 struct sta_info *sta = file->private_data;
333 struct ieee80211_sta_vht_cap *vhtc = &sta->sta.vht_cap;
334
335 p += scnprintf(p, sizeof(buf) + buf - p, "VHT %ssupported\n",
336 vhtc->vht_supported ? "" : "not ");
337 if (vhtc->vht_supported) {
338 p += scnprintf(p, sizeof(buf)+buf-p, "cap: %#.8x\n", vhtc->cap);
339
340 p += scnprintf(p, sizeof(buf)+buf-p, "RX MCS: %.4x\n",
341 le16_to_cpu(vhtc->vht_mcs.rx_mcs_map));
342 if (vhtc->vht_mcs.rx_highest)
343 p += scnprintf(p, sizeof(buf)+buf-p,
344 "MCS RX highest: %d Mbps\n",
345 le16_to_cpu(vhtc->vht_mcs.rx_highest));
346 p += scnprintf(p, sizeof(buf)+buf-p, "TX MCS: %.4x\n",
347 le16_to_cpu(vhtc->vht_mcs.tx_mcs_map));
348 if (vhtc->vht_mcs.tx_highest)
349 p += scnprintf(p, sizeof(buf)+buf-p,
350 "MCS TX highest: %d Mbps\n",
351 le16_to_cpu(vhtc->vht_mcs.tx_highest));
352 }
353
354 return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
355}
356STA_OPS(vht_capa);
357
328static ssize_t sta_current_tx_rate_read(struct file *file, char __user *userbuf, 358static ssize_t sta_current_tx_rate_read(struct file *file, char __user *userbuf,
329 size_t count, loff_t *ppos) 359 size_t count, loff_t *ppos)
330{ 360{
@@ -405,6 +435,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
405 DEBUGFS_ADD(dev); 435 DEBUGFS_ADD(dev);
406 DEBUGFS_ADD(last_signal); 436 DEBUGFS_ADD(last_signal);
407 DEBUGFS_ADD(ht_capa); 437 DEBUGFS_ADD(ht_capa);
438 DEBUGFS_ADD(vht_capa);
408 DEBUGFS_ADD(last_ack_signal); 439 DEBUGFS_ADD(last_ack_signal);
409 DEBUGFS_ADD(current_tx_rate); 440 DEBUGFS_ADD(current_tx_rate);
410 DEBUGFS_ADD(last_rx_rate); 441 DEBUGFS_ADD(last_rx_rate);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index ee56d0779d8b..832acea4a5cb 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -787,15 +787,16 @@ static inline int drv_get_antenna(struct ieee80211_local *local,
787static inline int drv_remain_on_channel(struct ieee80211_local *local, 787static inline int drv_remain_on_channel(struct ieee80211_local *local,
788 struct ieee80211_sub_if_data *sdata, 788 struct ieee80211_sub_if_data *sdata,
789 struct ieee80211_channel *chan, 789 struct ieee80211_channel *chan,
790 unsigned int duration) 790 unsigned int duration,
791 enum ieee80211_roc_type type)
791{ 792{
792 int ret; 793 int ret;
793 794
794 might_sleep(); 795 might_sleep();
795 796
796 trace_drv_remain_on_channel(local, sdata, chan, duration); 797 trace_drv_remain_on_channel(local, sdata, chan, duration, type);
797 ret = local->ops->remain_on_channel(&local->hw, &sdata->vif, 798 ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
798 chan, duration); 799 chan, duration, type);
799 trace_drv_return_int(local, ret); 800 trace_drv_return_int(local, ret);
800 801
801 return ret; 802 return ret;
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 0db25d4bb223..af8cee06e4f3 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -40,13 +40,6 @@ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
40 if (!ht_cap->ht_supported) 40 if (!ht_cap->ht_supported)
41 return; 41 return;
42 42
43 if (sdata->vif.type != NL80211_IFTYPE_STATION) {
44 /* AP interfaces call this code when adding new stations,
45 * so just silently ignore non station interfaces.
46 */
47 return;
48 }
49
50 /* NOTE: If you add more over-rides here, update register_hw 43 /* NOTE: If you add more over-rides here, update register_hw
51 * ht_capa_mod_msk logic in main.c as well. 44 * ht_capa_mod_msk logic in main.c as well.
52 * And, if this method can ever change ht_cap.ht_supported, fix 45 * And, if this method can ever change ht_cap.ht_supported, fix
@@ -97,7 +90,7 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
97 const struct ieee80211_ht_cap *ht_cap_ie, 90 const struct ieee80211_ht_cap *ht_cap_ie,
98 struct sta_info *sta) 91 struct sta_info *sta)
99{ 92{
100 struct ieee80211_sta_ht_cap ht_cap; 93 struct ieee80211_sta_ht_cap ht_cap, own_cap;
101 u8 ampdu_info, tx_mcs_set_cap; 94 u8 ampdu_info, tx_mcs_set_cap;
102 int i, max_tx_streams; 95 int i, max_tx_streams;
103 bool changed; 96 bool changed;
@@ -111,6 +104,18 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
111 104
112 ht_cap.ht_supported = true; 105 ht_cap.ht_supported = true;
113 106
107 own_cap = sband->ht_cap;
108
109 /*
110 * If user has specified capability over-rides, take care
111 * of that if the station we're setting up is the AP that
112 * we advertised a restricted capability set to. Override
113 * our own capabilities and then use those below.
114 */
115 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
116 !test_sta_flag(sta, WLAN_STA_TDLS_PEER))
117 ieee80211_apply_htcap_overrides(sdata, &own_cap);
118
114 /* 119 /*
115 * The bits listed in this expression should be 120 * The bits listed in this expression should be
116 * the same for the peer and us, if the station 121 * the same for the peer and us, if the station
@@ -118,21 +123,20 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
118 * we mask them out. 123 * we mask them out.
119 */ 124 */
120 ht_cap.cap = le16_to_cpu(ht_cap_ie->cap_info) & 125 ht_cap.cap = le16_to_cpu(ht_cap_ie->cap_info) &
121 (sband->ht_cap.cap | 126 (own_cap.cap | ~(IEEE80211_HT_CAP_LDPC_CODING |
122 ~(IEEE80211_HT_CAP_LDPC_CODING | 127 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
123 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 128 IEEE80211_HT_CAP_GRN_FLD |
124 IEEE80211_HT_CAP_GRN_FLD | 129 IEEE80211_HT_CAP_SGI_20 |
125 IEEE80211_HT_CAP_SGI_20 | 130 IEEE80211_HT_CAP_SGI_40 |
126 IEEE80211_HT_CAP_SGI_40 | 131 IEEE80211_HT_CAP_DSSSCCK40));
127 IEEE80211_HT_CAP_DSSSCCK40));
128 132
129 /* 133 /*
130 * The STBC bits are asymmetric -- if we don't have 134 * The STBC bits are asymmetric -- if we don't have
131 * TX then mask out the peer's RX and vice versa. 135 * TX then mask out the peer's RX and vice versa.
132 */ 136 */
133 if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC)) 137 if (!(own_cap.cap & IEEE80211_HT_CAP_TX_STBC))
134 ht_cap.cap &= ~IEEE80211_HT_CAP_RX_STBC; 138 ht_cap.cap &= ~IEEE80211_HT_CAP_RX_STBC;
135 if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)) 139 if (!(own_cap.cap & IEEE80211_HT_CAP_RX_STBC))
136 ht_cap.cap &= ~IEEE80211_HT_CAP_TX_STBC; 140 ht_cap.cap &= ~IEEE80211_HT_CAP_TX_STBC;
137 141
138 ampdu_info = ht_cap_ie->ampdu_params_info; 142 ampdu_info = ht_cap_ie->ampdu_params_info;
@@ -142,7 +146,7 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
142 (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2; 146 (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
143 147
144 /* own MCS TX capabilities */ 148 /* own MCS TX capabilities */
145 tx_mcs_set_cap = sband->ht_cap.mcs.tx_params; 149 tx_mcs_set_cap = own_cap.mcs.tx_params;
146 150
147 /* Copy peer MCS TX capabilities, the driver might need them. */ 151 /* Copy peer MCS TX capabilities, the driver might need them. */
148 ht_cap.mcs.tx_params = ht_cap_ie->mcs.tx_params; 152 ht_cap.mcs.tx_params = ht_cap_ie->mcs.tx_params;
@@ -168,26 +172,20 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
168 */ 172 */
169 for (i = 0; i < max_tx_streams; i++) 173 for (i = 0; i < max_tx_streams; i++)
170 ht_cap.mcs.rx_mask[i] = 174 ht_cap.mcs.rx_mask[i] =
171 sband->ht_cap.mcs.rx_mask[i] & ht_cap_ie->mcs.rx_mask[i]; 175 own_cap.mcs.rx_mask[i] & ht_cap_ie->mcs.rx_mask[i];
172 176
173 if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION) 177 if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION)
174 for (i = IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE; 178 for (i = IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE;
175 i < IEEE80211_HT_MCS_MASK_LEN; i++) 179 i < IEEE80211_HT_MCS_MASK_LEN; i++)
176 ht_cap.mcs.rx_mask[i] = 180 ht_cap.mcs.rx_mask[i] =
177 sband->ht_cap.mcs.rx_mask[i] & 181 own_cap.mcs.rx_mask[i] &
178 ht_cap_ie->mcs.rx_mask[i]; 182 ht_cap_ie->mcs.rx_mask[i];
179 183
180 /* handle MCS rate 32 too */ 184 /* handle MCS rate 32 too */
181 if (sband->ht_cap.mcs.rx_mask[32/8] & ht_cap_ie->mcs.rx_mask[32/8] & 1) 185 if (own_cap.mcs.rx_mask[32/8] & ht_cap_ie->mcs.rx_mask[32/8] & 1)
182 ht_cap.mcs.rx_mask[32/8] |= 1; 186 ht_cap.mcs.rx_mask[32/8] |= 1;
183 187
184 apply: 188 apply:
185 /*
186 * If user has specified capability over-rides, take care
187 * of that here.
188 */
189 ieee80211_apply_htcap_overrides(sdata, &ht_cap);
190
191 changed = memcmp(&sta->sta.ht_cap, &ht_cap, sizeof(ht_cap)); 189 changed = memcmp(&sta->sta.ht_cap, &ht_cap, sizeof(ht_cap));
192 190
193 memcpy(&sta->sta.ht_cap, &ht_cap, sizeof(ht_cap)); 191 memcpy(&sta->sta.ht_cap, &ht_cap, sizeof(ht_cap));
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 40b71dfcc79d..539d4a11b47b 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -985,36 +985,9 @@ static void ieee80211_ibss_timer(unsigned long data)
985{ 985{
986 struct ieee80211_sub_if_data *sdata = 986 struct ieee80211_sub_if_data *sdata =
987 (struct ieee80211_sub_if_data *) data; 987 (struct ieee80211_sub_if_data *) data;
988 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
989 struct ieee80211_local *local = sdata->local;
990
991 if (local->quiescing) {
992 ifibss->timer_running = true;
993 return;
994 }
995
996 ieee80211_queue_work(&local->hw, &sdata->work);
997}
998
999#ifdef CONFIG_PM
1000void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata)
1001{
1002 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
1003 988
1004 if (del_timer_sync(&ifibss->timer)) 989 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
1005 ifibss->timer_running = true;
1006}
1007
1008void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata)
1009{
1010 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
1011
1012 if (ifibss->timer_running) {
1013 add_timer(&ifibss->timer);
1014 ifibss->timer_running = false;
1015 }
1016} 990}
1017#endif
1018 991
1019void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata) 992void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
1020{ 993{
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 388580a1bada..f4433f081e77 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -315,6 +315,7 @@ struct ieee80211_roc_work {
315 u32 duration, req_duration; 315 u32 duration, req_duration;
316 struct sk_buff *frame; 316 struct sk_buff *frame;
317 u64 cookie, mgmt_tx_cookie; 317 u64 cookie, mgmt_tx_cookie;
318 enum ieee80211_roc_type type;
318}; 319};
319 320
320/* flags used in struct ieee80211_if_managed.flags */ 321/* flags used in struct ieee80211_if_managed.flags */
@@ -400,7 +401,6 @@ struct ieee80211_if_managed {
400 401
401 u16 aid; 402 u16 aid;
402 403
403 unsigned long timers_running; /* used for quiesce/restart */
404 bool powersave; /* powersave requested for this iface */ 404 bool powersave; /* powersave requested for this iface */
405 bool broken_ap; /* AP is broken -- turn off powersave */ 405 bool broken_ap; /* AP is broken -- turn off powersave */
406 u8 dtim_period; 406 u8 dtim_period;
@@ -479,6 +479,8 @@ struct ieee80211_if_managed {
479 479
480 struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */ 480 struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */
481 struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */ 481 struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */
482 struct ieee80211_vht_cap vht_capa; /* configured VHT overrides */
483 struct ieee80211_vht_cap vht_capa_mask; /* Valid parts of vht_capa */
482}; 484};
483 485
484struct ieee80211_if_ibss { 486struct ieee80211_if_ibss {
@@ -490,8 +492,6 @@ struct ieee80211_if_ibss {
490 492
491 u32 basic_rates; 493 u32 basic_rates;
492 494
493 bool timer_running;
494
495 bool fixed_bssid; 495 bool fixed_bssid;
496 bool fixed_channel; 496 bool fixed_channel;
497 bool privacy; 497 bool privacy;
@@ -543,8 +543,6 @@ struct ieee80211_if_mesh {
543 struct timer_list mesh_path_timer; 543 struct timer_list mesh_path_timer;
544 struct timer_list mesh_path_root_timer; 544 struct timer_list mesh_path_root_timer;
545 545
546 unsigned long timers_running;
547
548 unsigned long wrkq_flags; 546 unsigned long wrkq_flags;
549 547
550 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; 548 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
@@ -590,6 +588,7 @@ struct ieee80211_if_mesh {
590 IEEE80211_MESH_SEC_AUTHED = 0x1, 588 IEEE80211_MESH_SEC_AUTHED = 0x1,
591 IEEE80211_MESH_SEC_SECURED = 0x2, 589 IEEE80211_MESH_SEC_SECURED = 0x2,
592 } security; 590 } security;
591 bool user_mpm;
593 /* Extensible Synchronization Framework */ 592 /* Extensible Synchronization Framework */
594 const struct ieee80211_mesh_sync_ops *sync_ops; 593 const struct ieee80211_mesh_sync_ops *sync_ops;
595 s64 sync_offset_clockdrift_max; 594 s64 sync_offset_clockdrift_max;
@@ -682,6 +681,8 @@ struct ieee80211_sub_if_data {
682 681
683 /* count for keys needing tailroom space allocation */ 682 /* count for keys needing tailroom space allocation */
684 int crypto_tx_tailroom_needed_cnt; 683 int crypto_tx_tailroom_needed_cnt;
684 int crypto_tx_tailroom_pending_dec;
685 struct delayed_work dec_tailroom_needed_wk;
685 686
686 struct net_device *dev; 687 struct net_device *dev;
687 struct ieee80211_local *local; 688 struct ieee80211_local *local;
@@ -765,10 +766,6 @@ struct ieee80211_sub_if_data {
765 } debugfs; 766 } debugfs;
766#endif 767#endif
767 768
768#ifdef CONFIG_PM
769 struct ieee80211_bss_conf suspend_bss_conf;
770#endif
771
772 /* must be last, dynamically sized area in this! */ 769 /* must be last, dynamically sized area in this! */
773 struct ieee80211_vif vif; 770 struct ieee80211_vif vif;
774}; 771};
@@ -1136,11 +1133,6 @@ struct ieee80211_local {
1136 1133
1137 struct ieee80211_sub_if_data __rcu *p2p_sdata; 1134 struct ieee80211_sub_if_data __rcu *p2p_sdata;
1138 1135
1139 /* dummy netdev for use w/ NAPI */
1140 struct net_device napi_dev;
1141
1142 struct napi_struct napi;
1143
1144 /* virtual monitor interface */ 1136 /* virtual monitor interface */
1145 struct ieee80211_sub_if_data __rcu *monitor_sdata; 1137 struct ieee80211_sub_if_data __rcu *monitor_sdata;
1146 struct cfg80211_chan_def monitor_chandef; 1138 struct cfg80211_chan_def monitor_chandef;
@@ -1283,8 +1275,6 @@ void
1283ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, 1275ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1284 const struct ieee80211_channel_sw_ie *sw_elem, 1276 const struct ieee80211_channel_sw_ie *sw_elem,
1285 struct ieee80211_bss *bss, u64 timestamp); 1277 struct ieee80211_bss *bss, u64 timestamp);
1286void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata);
1287void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
1288void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); 1278void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata);
1289void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 1279void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1290 struct sk_buff *skb); 1280 struct sk_buff *skb);
@@ -1302,8 +1292,6 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
1302int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, 1292int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1303 struct cfg80211_ibss_params *params); 1293 struct cfg80211_ibss_params *params);
1304int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata); 1294int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
1305void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata);
1306void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata);
1307void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata); 1295void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata);
1308void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 1296void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1309 struct sk_buff *skb); 1297 struct sk_buff *skb);
@@ -1441,6 +1429,8 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta);
1441void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, 1429void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
1442 struct sta_info *sta, u8 opmode, 1430 struct sta_info *sta, u8 opmode,
1443 enum ieee80211_band band, bool nss_only); 1431 enum ieee80211_band band, bool nss_only);
1432void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
1433 struct ieee80211_sta_vht_cap *vht_cap);
1444 1434
1445/* Spectrum management */ 1435/* Spectrum management */
1446void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, 1436void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index baaa8608e52d..d85282f64405 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -485,8 +485,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
485 res = drv_start(local); 485 res = drv_start(local);
486 if (res) 486 if (res)
487 goto err_del_bss; 487 goto err_del_bss;
488 if (local->ops->napi_poll)
489 napi_enable(&local->napi);
490 /* we're brought up, everything changes */ 488 /* we're brought up, everything changes */
491 hw_reconf_flags = ~0; 489 hw_reconf_flags = ~0;
492 ieee80211_led_radio(local, true); 490 ieee80211_led_radio(local, true);
@@ -838,14 +836,16 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
838 rcu_barrier(); 836 rcu_barrier();
839 sta_info_flush_cleanup(sdata); 837 sta_info_flush_cleanup(sdata);
840 838
841 skb_queue_purge(&sdata->skb_queue);
842
843 /* 839 /*
844 * Free all remaining keys, there shouldn't be any, 840 * Free all remaining keys, there shouldn't be any,
845 * except maybe group keys in AP more or WDS? 841 * except maybe in WDS mode?
846 */ 842 */
847 ieee80211_free_keys(sdata); 843 ieee80211_free_keys(sdata);
848 844
845 /* fall through */
846 case NL80211_IFTYPE_AP:
847 skb_queue_purge(&sdata->skb_queue);
848
849 drv_remove_interface_debugfs(local, sdata); 849 drv_remove_interface_debugfs(local, sdata);
850 850
851 if (going_down) 851 if (going_down)
@@ -857,8 +857,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
857 ieee80211_recalc_ps(local, -1); 857 ieee80211_recalc_ps(local, -1);
858 858
859 if (local->open_count == 0) { 859 if (local->open_count == 0) {
860 if (local->ops->napi_poll)
861 napi_disable(&local->napi);
862 ieee80211_clear_tx_pending(local); 860 ieee80211_clear_tx_pending(local);
863 ieee80211_stop_device(local); 861 ieee80211_stop_device(local);
864 862
@@ -1547,6 +1545,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1547 INIT_WORK(&sdata->cleanup_stations_wk, ieee80211_cleanup_sdata_stas_wk); 1545 INIT_WORK(&sdata->cleanup_stations_wk, ieee80211_cleanup_sdata_stas_wk);
1548 INIT_DELAYED_WORK(&sdata->dfs_cac_timer_work, 1546 INIT_DELAYED_WORK(&sdata->dfs_cac_timer_work,
1549 ieee80211_dfs_cac_timer_work); 1547 ieee80211_dfs_cac_timer_work);
1548 INIT_DELAYED_WORK(&sdata->dec_tailroom_needed_wk,
1549 ieee80211_delayed_tailroom_dec);
1550 1550
1551 for (i = 0; i < IEEE80211_NUM_BANDS; i++) { 1551 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
1552 struct ieee80211_supported_band *sband; 1552 struct ieee80211_supported_band *sband;
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index ef252eb58c36..99e9f6ae6a54 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -397,7 +397,8 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
397 return key; 397 return key;
398} 398}
399 399
400static void __ieee80211_key_destroy(struct ieee80211_key *key) 400static void __ieee80211_key_destroy(struct ieee80211_key *key,
401 bool delay_tailroom)
401{ 402{
402 if (!key) 403 if (!key)
403 return; 404 return;
@@ -416,8 +417,18 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
416 if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) 417 if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
417 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); 418 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
418 if (key->local) { 419 if (key->local) {
420 struct ieee80211_sub_if_data *sdata = key->sdata;
421
419 ieee80211_debugfs_key_remove(key); 422 ieee80211_debugfs_key_remove(key);
420 key->sdata->crypto_tx_tailroom_needed_cnt--; 423
424 if (delay_tailroom) {
425 /* see ieee80211_delayed_tailroom_dec */
426 sdata->crypto_tx_tailroom_pending_dec++;
427 schedule_delayed_work(&sdata->dec_tailroom_needed_wk,
428 HZ/2);
429 } else {
430 sdata->crypto_tx_tailroom_needed_cnt--;
431 }
421 } 432 }
422 433
423 kfree(key); 434 kfree(key);
@@ -440,32 +451,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
440 key->sdata = sdata; 451 key->sdata = sdata;
441 key->sta = sta; 452 key->sta = sta;
442 453
443 if (sta) {
444 /*
445 * some hardware cannot handle TKIP with QoS, so
446 * we indicate whether QoS could be in use.
447 */
448 if (test_sta_flag(sta, WLAN_STA_WME))
449 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
450 } else {
451 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
452 struct sta_info *ap;
453
454 /*
455 * We're getting a sta pointer in, so must be under
456 * appropriate locking for sta_info_get().
457 */
458
459 /* same here, the AP could be using QoS */
460 ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid);
461 if (ap) {
462 if (test_sta_flag(ap, WLAN_STA_WME))
463 key->conf.flags |=
464 IEEE80211_KEY_FLAG_WMM_STA;
465 }
466 }
467 }
468
469 mutex_lock(&sdata->local->key_mtx); 454 mutex_lock(&sdata->local->key_mtx);
470 455
471 if (sta && pairwise) 456 if (sta && pairwise)
@@ -478,7 +463,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
478 increment_tailroom_need_count(sdata); 463 increment_tailroom_need_count(sdata);
479 464
480 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key); 465 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
481 __ieee80211_key_destroy(old_key); 466 __ieee80211_key_destroy(old_key, true);
482 467
483 ieee80211_debugfs_key_add(key); 468 ieee80211_debugfs_key_add(key);
484 469
@@ -489,7 +474,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
489 return ret; 474 return ret;
490} 475}
491 476
492void __ieee80211_key_free(struct ieee80211_key *key) 477void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
493{ 478{
494 if (!key) 479 if (!key)
495 return; 480 return;
@@ -501,14 +486,14 @@ void __ieee80211_key_free(struct ieee80211_key *key)
501 __ieee80211_key_replace(key->sdata, key->sta, 486 __ieee80211_key_replace(key->sdata, key->sta,
502 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, 487 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
503 key, NULL); 488 key, NULL);
504 __ieee80211_key_destroy(key); 489 __ieee80211_key_destroy(key, delay_tailroom);
505} 490}
506 491
507void ieee80211_key_free(struct ieee80211_local *local, 492void ieee80211_key_free(struct ieee80211_local *local,
508 struct ieee80211_key *key) 493 struct ieee80211_key *key)
509{ 494{
510 mutex_lock(&local->key_mtx); 495 mutex_lock(&local->key_mtx);
511 __ieee80211_key_free(key); 496 __ieee80211_key_free(key, true);
512 mutex_unlock(&local->key_mtx); 497 mutex_unlock(&local->key_mtx);
513} 498}
514 499
@@ -566,36 +551,60 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw,
566} 551}
567EXPORT_SYMBOL(ieee80211_iter_keys); 552EXPORT_SYMBOL(ieee80211_iter_keys);
568 553
569void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata)
570{
571 struct ieee80211_key *key;
572
573 ASSERT_RTNL();
574
575 mutex_lock(&sdata->local->key_mtx);
576
577 list_for_each_entry(key, &sdata->key_list, list)
578 ieee80211_key_disable_hw_accel(key);
579
580 mutex_unlock(&sdata->local->key_mtx);
581}
582
583void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) 554void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
584{ 555{
585 struct ieee80211_key *key, *tmp; 556 struct ieee80211_key *key, *tmp;
586 557
558 cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk);
559
587 mutex_lock(&sdata->local->key_mtx); 560 mutex_lock(&sdata->local->key_mtx);
588 561
562 sdata->crypto_tx_tailroom_needed_cnt -=
563 sdata->crypto_tx_tailroom_pending_dec;
564 sdata->crypto_tx_tailroom_pending_dec = 0;
565
589 ieee80211_debugfs_key_remove_mgmt_default(sdata); 566 ieee80211_debugfs_key_remove_mgmt_default(sdata);
590 567
591 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) 568 list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
592 __ieee80211_key_free(key); 569 __ieee80211_key_free(key, false);
593 570
594 ieee80211_debugfs_key_update_default(sdata); 571 ieee80211_debugfs_key_update_default(sdata);
595 572
573 WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
574 sdata->crypto_tx_tailroom_pending_dec);
575
596 mutex_unlock(&sdata->local->key_mtx); 576 mutex_unlock(&sdata->local->key_mtx);
597} 577}
598 578
579void ieee80211_delayed_tailroom_dec(struct work_struct *wk)
580{
581 struct ieee80211_sub_if_data *sdata;
582
583 sdata = container_of(wk, struct ieee80211_sub_if_data,
584 dec_tailroom_needed_wk.work);
585
586 /*
587 * The reason for the delayed tailroom needed decrementing is to
588 * make roaming faster: during roaming, all keys are first deleted
589 * and then new keys are installed. The first new key causes the
590 * crypto_tx_tailroom_needed_cnt to go from 0 to 1, which invokes
591 * the cost of synchronize_net() (which can be slow). Avoid this
592 * by deferring the crypto_tx_tailroom_needed_cnt decrementing on
593 * key removal for a while, so if we roam the value is larger than
594 * zero and no 0->1 transition happens.
595 *
596 * The cost is that if the AP switching was from an AP with keys
597 * to one without, we still allocate tailroom while it would no
598 * longer be needed. However, in the typical (fast) roaming case
599 * within an ESS this usually won't happen.
600 */
601
602 mutex_lock(&sdata->local->key_mtx);
603 sdata->crypto_tx_tailroom_needed_cnt -=
604 sdata->crypto_tx_tailroom_pending_dec;
605 sdata->crypto_tx_tailroom_pending_dec = 0;
606 mutex_unlock(&sdata->local->key_mtx);
607}
599 608
600void ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const u8 *bssid, 609void ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const u8 *bssid,
601 const u8 *replay_ctr, gfp_t gfp) 610 const u8 *replay_ctr, gfp_t gfp)
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 382dc44ed330..2a682d81cee9 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -134,7 +134,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
134int __must_check ieee80211_key_link(struct ieee80211_key *key, 134int __must_check ieee80211_key_link(struct ieee80211_key *key,
135 struct ieee80211_sub_if_data *sdata, 135 struct ieee80211_sub_if_data *sdata,
136 struct sta_info *sta); 136 struct sta_info *sta);
137void __ieee80211_key_free(struct ieee80211_key *key); 137void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom);
138void ieee80211_key_free(struct ieee80211_local *local, 138void ieee80211_key_free(struct ieee80211_local *local,
139 struct ieee80211_key *key); 139 struct ieee80211_key *key);
140void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, 140void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
@@ -143,9 +143,10 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
143 int idx); 143 int idx);
144void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); 144void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
145void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); 145void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
146void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata);
147 146
148#define key_mtx_dereference(local, ref) \ 147#define key_mtx_dereference(local, ref) \
149 rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx))) 148 rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx)))
150 149
150void ieee80211_delayed_tailroom_dec(struct work_struct *wk);
151
151#endif /* IEEE80211_KEY_H */ 152#endif /* IEEE80211_KEY_H */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 1a8591b77a13..5a53aa5ede80 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -399,30 +399,6 @@ static int ieee80211_ifa6_changed(struct notifier_block *nb,
399} 399}
400#endif 400#endif
401 401
402static int ieee80211_napi_poll(struct napi_struct *napi, int budget)
403{
404 struct ieee80211_local *local =
405 container_of(napi, struct ieee80211_local, napi);
406
407 return local->ops->napi_poll(&local->hw, budget);
408}
409
410void ieee80211_napi_schedule(struct ieee80211_hw *hw)
411{
412 struct ieee80211_local *local = hw_to_local(hw);
413
414 napi_schedule(&local->napi);
415}
416EXPORT_SYMBOL(ieee80211_napi_schedule);
417
418void ieee80211_napi_complete(struct ieee80211_hw *hw)
419{
420 struct ieee80211_local *local = hw_to_local(hw);
421
422 napi_complete(&local->napi);
423}
424EXPORT_SYMBOL(ieee80211_napi_complete);
425
426/* There isn't a lot of sense in it, but you can transmit anything you like */ 402/* There isn't a lot of sense in it, but you can transmit anything you like */
427static const struct ieee80211_txrx_stypes 403static const struct ieee80211_txrx_stypes
428ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { 404ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
@@ -501,6 +477,27 @@ static const struct ieee80211_ht_cap mac80211_ht_capa_mod_mask = {
501 }, 477 },
502}; 478};
503 479
480static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = {
481 .vht_cap_info =
482 cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC |
483 IEEE80211_VHT_CAP_SHORT_GI_80 |
484 IEEE80211_VHT_CAP_SHORT_GI_160 |
485 IEEE80211_VHT_CAP_RXSTBC_1 |
486 IEEE80211_VHT_CAP_RXSTBC_2 |
487 IEEE80211_VHT_CAP_RXSTBC_3 |
488 IEEE80211_VHT_CAP_RXSTBC_4 |
489 IEEE80211_VHT_CAP_TXSTBC |
490 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
491 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
492 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN |
493 IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
494 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK),
495 .supp_mcs = {
496 .rx_mcs_map = cpu_to_le16(~0),
497 .tx_mcs_map = cpu_to_le16(~0),
498 },
499};
500
504static const u8 extended_capabilities[] = { 501static const u8 extended_capabilities[] = {
505 0, 0, 0, 0, 0, 0, 0, 502 0, 0, 0, 0, 0, 0, 0,
506 WLAN_EXT_CAPA8_OPMODE_NOTIF, 503 WLAN_EXT_CAPA8_OPMODE_NOTIF,
@@ -572,7 +569,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
572 wiphy->features |= NL80211_FEATURE_SK_TX_STATUS | 569 wiphy->features |= NL80211_FEATURE_SK_TX_STATUS |
573 NL80211_FEATURE_SAE | 570 NL80211_FEATURE_SAE |
574 NL80211_FEATURE_HT_IBSS | 571 NL80211_FEATURE_HT_IBSS |
575 NL80211_FEATURE_VIF_TXPOWER; 572 NL80211_FEATURE_VIF_TXPOWER |
573 NL80211_FEATURE_USERSPACE_MPM;
576 574
577 if (!ops->hw_scan) 575 if (!ops->hw_scan)
578 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | 576 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
@@ -609,6 +607,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
609 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; 607 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
610 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; 608 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
611 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; 609 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
610 wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask;
612 611
613 INIT_LIST_HEAD(&local->interfaces); 612 INIT_LIST_HEAD(&local->interfaces);
614 613
@@ -664,9 +663,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
664 skb_queue_head_init(&local->skb_queue); 663 skb_queue_head_init(&local->skb_queue);
665 skb_queue_head_init(&local->skb_queue_unreliable); 664 skb_queue_head_init(&local->skb_queue_unreliable);
666 665
667 /* init dummy netdev for use w/ NAPI */
668 init_dummy_netdev(&local->napi_dev);
669
670 ieee80211_led_names(local); 666 ieee80211_led_names(local);
671 667
672 ieee80211_roc_setup(local); 668 ieee80211_roc_setup(local);
@@ -1021,9 +1017,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1021 goto fail_ifa6; 1017 goto fail_ifa6;
1022#endif 1018#endif
1023 1019
1024 netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll,
1025 local->hw.napi_weight);
1026
1027 return 0; 1020 return 0;
1028 1021
1029#if IS_ENABLED(CONFIG_IPV6) 1022#if IS_ENABLED(CONFIG_IPV6)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 29ce2aa87e7b..5ac017f3fcd2 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -13,10 +13,6 @@
13#include "ieee80211_i.h" 13#include "ieee80211_i.h"
14#include "mesh.h" 14#include "mesh.h"
15 15
16#define TMR_RUNNING_HK 0
17#define TMR_RUNNING_MP 1
18#define TMR_RUNNING_MPR 2
19
20static int mesh_allocated; 16static int mesh_allocated;
21static struct kmem_cache *rm_cache; 17static struct kmem_cache *rm_cache;
22 18
@@ -50,11 +46,6 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data)
50 46
51 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); 47 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
52 48
53 if (local->quiescing) {
54 set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
55 return;
56 }
57
58 ieee80211_queue_work(&local->hw, &sdata->work); 49 ieee80211_queue_work(&local->hw, &sdata->work);
59} 50}
60 51
@@ -165,7 +156,7 @@ void mesh_sta_cleanup(struct sta_info *sta)
165 * an update. 156 * an update.
166 */ 157 */
167 changed = mesh_accept_plinks_update(sdata); 158 changed = mesh_accept_plinks_update(sdata);
168 if (sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { 159 if (!sdata->u.mesh.user_mpm) {
169 changed |= mesh_plink_deactivate(sta); 160 changed |= mesh_plink_deactivate(sta);
170 del_timer_sync(&sta->plink_timer); 161 del_timer_sync(&sta->plink_timer);
171 } 162 }
@@ -479,15 +470,8 @@ static void ieee80211_mesh_path_timer(unsigned long data)
479{ 470{
480 struct ieee80211_sub_if_data *sdata = 471 struct ieee80211_sub_if_data *sdata =
481 (struct ieee80211_sub_if_data *) data; 472 (struct ieee80211_sub_if_data *) data;
482 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
483 struct ieee80211_local *local = sdata->local;
484
485 if (local->quiescing) {
486 set_bit(TMR_RUNNING_MP, &ifmsh->timers_running);
487 return;
488 }
489 473
490 ieee80211_queue_work(&local->hw, &sdata->work); 474 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
491} 475}
492 476
493static void ieee80211_mesh_path_root_timer(unsigned long data) 477static void ieee80211_mesh_path_root_timer(unsigned long data)
@@ -495,16 +479,10 @@ static void ieee80211_mesh_path_root_timer(unsigned long data)
495 struct ieee80211_sub_if_data *sdata = 479 struct ieee80211_sub_if_data *sdata =
496 (struct ieee80211_sub_if_data *) data; 480 (struct ieee80211_sub_if_data *) data;
497 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 481 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
498 struct ieee80211_local *local = sdata->local;
499 482
500 set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); 483 set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
501 484
502 if (local->quiescing) { 485 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
503 set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running);
504 return;
505 }
506
507 ieee80211_queue_work(&local->hw, &sdata->work);
508} 486}
509 487
510void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) 488void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
@@ -622,35 +600,6 @@ static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
622 round_jiffies(TU_TO_EXP_TIME(interval))); 600 round_jiffies(TU_TO_EXP_TIME(interval)));
623} 601}
624 602
625#ifdef CONFIG_PM
626void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
627{
628 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
629
630 /* use atomic bitops in case all timers fire at the same time */
631
632 if (del_timer_sync(&ifmsh->housekeeping_timer))
633 set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
634 if (del_timer_sync(&ifmsh->mesh_path_timer))
635 set_bit(TMR_RUNNING_MP, &ifmsh->timers_running);
636 if (del_timer_sync(&ifmsh->mesh_path_root_timer))
637 set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running);
638}
639
640void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
641{
642 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
643
644 if (test_and_clear_bit(TMR_RUNNING_HK, &ifmsh->timers_running))
645 add_timer(&ifmsh->housekeeping_timer);
646 if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running))
647 add_timer(&ifmsh->mesh_path_timer);
648 if (test_and_clear_bit(TMR_RUNNING_MPR, &ifmsh->timers_running))
649 add_timer(&ifmsh->mesh_path_root_timer);
650 ieee80211_mesh_root_setup(ifmsh);
651}
652#endif
653
654static int 603static int
655ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) 604ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
656{ 605{
@@ -871,8 +820,6 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
871 local->fif_other_bss--; 820 local->fif_other_bss--;
872 atomic_dec(&local->iff_allmultis); 821 atomic_dec(&local->iff_allmultis);
873 ieee80211_configure_filter(local); 822 ieee80211_configure_filter(local);
874
875 sdata->u.mesh.timers_running = 0;
876} 823}
877 824
878static void 825static void
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 336c88a16687..6ffabbe99c46 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -313,8 +313,6 @@ void mesh_path_timer(unsigned long data);
313void mesh_path_flush_by_nexthop(struct sta_info *sta); 313void mesh_path_flush_by_nexthop(struct sta_info *sta);
314void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata, 314void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
315 struct sk_buff *skb); 315 struct sk_buff *skb);
316void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
317void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
318void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); 316void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
319 317
320bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); 318bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
@@ -359,22 +357,12 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
359 357
360void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local); 358void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
361 359
362void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata);
363void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata);
364void mesh_plink_quiesce(struct sta_info *sta);
365void mesh_plink_restart(struct sta_info *sta);
366void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata); 360void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
367void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata); 361void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
368void ieee80211s_stop(void); 362void ieee80211s_stop(void);
369#else 363#else
370static inline void 364static inline void
371ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {} 365ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
372static inline void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
373{}
374static inline void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
375{}
376static inline void mesh_plink_quiesce(struct sta_info *sta) {}
377static inline void mesh_plink_restart(struct sta_info *sta) {}
378static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) 366static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
379{ return false; } 367{ return false; }
380static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) 368static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 07d396d57079..937e06fe8f2a 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -420,7 +420,6 @@ __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr)
420 return NULL; 420 return NULL;
421 421
422 sta->plink_state = NL80211_PLINK_LISTEN; 422 sta->plink_state = NL80211_PLINK_LISTEN;
423 init_timer(&sta->plink_timer);
424 423
425 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); 424 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
426 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); 425 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
@@ -437,8 +436,9 @@ mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
437{ 436{
438 struct sta_info *sta = NULL; 437 struct sta_info *sta = NULL;
439 438
440 /* Userspace handles peer allocation when security is enabled */ 439 /* Userspace handles station allocation */
441 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) 440 if (sdata->u.mesh.user_mpm ||
441 sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
442 cfg80211_notify_new_peer_candidate(sdata->dev, addr, 442 cfg80211_notify_new_peer_candidate(sdata->dev, addr,
443 elems->ie_start, 443 elems->ie_start,
444 elems->total_len, 444 elems->total_len,
@@ -534,10 +534,8 @@ static void mesh_plink_timer(unsigned long data)
534 */ 534 */
535 sta = (struct sta_info *) data; 535 sta = (struct sta_info *) data;
536 536
537 if (sta->sdata->local->quiescing) { 537 if (sta->sdata->local->quiescing)
538 sta->plink_timer_was_running = true;
539 return; 538 return;
540 }
541 539
542 spin_lock_bh(&sta->lock); 540 spin_lock_bh(&sta->lock);
543 if (sta->ignore_plink_timer) { 541 if (sta->ignore_plink_timer) {
@@ -598,29 +596,6 @@ static void mesh_plink_timer(unsigned long data)
598 } 596 }
599} 597}
600 598
601#ifdef CONFIG_PM
602void mesh_plink_quiesce(struct sta_info *sta)
603{
604 if (!ieee80211_vif_is_mesh(&sta->sdata->vif))
605 return;
606
607 /* no kernel mesh sta timers have been initialized */
608 if (sta->sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
609 return;
610
611 if (del_timer_sync(&sta->plink_timer))
612 sta->plink_timer_was_running = true;
613}
614
615void mesh_plink_restart(struct sta_info *sta)
616{
617 if (sta->plink_timer_was_running) {
618 add_timer(&sta->plink_timer);
619 sta->plink_timer_was_running = false;
620 }
621}
622#endif
623
624static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) 599static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
625{ 600{
626 sta->plink_timer.expires = jiffies + (HZ * timeout / 1000); 601 sta->plink_timer.expires = jiffies + (HZ * timeout / 1000);
@@ -695,6 +670,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
695 if (len < IEEE80211_MIN_ACTION_SIZE + 3) 670 if (len < IEEE80211_MIN_ACTION_SIZE + 3)
696 return; 671 return;
697 672
673 if (sdata->u.mesh.user_mpm)
674 /* userspace must register for these */
675 return;
676
698 if (is_multicast_ether_addr(mgmt->da)) { 677 if (is_multicast_ether_addr(mgmt->da)) {
699 mpl_dbg(sdata, 678 mpl_dbg(sdata,
700 "Mesh plink: ignore frame from multicast address\n"); 679 "Mesh plink: ignore frame from multicast address\n");
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 141577412d84..fdc06e381c10 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -87,9 +87,6 @@ MODULE_PARM_DESC(probe_wait_ms,
87 */ 87 */
88#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 88#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
89 89
90#define TMR_RUNNING_TIMER 0
91#define TMR_RUNNING_CHANSW 1
92
93/* 90/*
94 * All cfg80211 functions have to be called outside a locked 91 * All cfg80211 functions have to be called outside a locked
95 * section so that they can acquire a lock themselves... This 92 * section so that they can acquire a lock themselves... This
@@ -609,6 +606,7 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
609 BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap)); 606 BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap));
610 607
611 memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap)); 608 memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
609 ieee80211_apply_vhtcap_overrides(sdata, &vht_cap);
612 610
613 /* determine capability flags */ 611 /* determine capability flags */
614 cap = vht_cap.cap; 612 cap = vht_cap.cap;
@@ -1038,14 +1036,8 @@ static void ieee80211_chswitch_timer(unsigned long data)
1038{ 1036{
1039 struct ieee80211_sub_if_data *sdata = 1037 struct ieee80211_sub_if_data *sdata =
1040 (struct ieee80211_sub_if_data *) data; 1038 (struct ieee80211_sub_if_data *) data;
1041 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1042 1039
1043 if (sdata->local->quiescing) { 1040 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.chswitch_work);
1044 set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
1045 return;
1046 }
1047
1048 ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
1049} 1041}
1050 1042
1051void 1043void
@@ -1802,9 +1794,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1802 sdata->vif.bss_conf.p2p_ctwindow = 0; 1794 sdata->vif.bss_conf.p2p_ctwindow = 0;
1803 sdata->vif.bss_conf.p2p_oppps = false; 1795 sdata->vif.bss_conf.p2p_oppps = false;
1804 1796
1805 /* on the next assoc, re-program HT parameters */ 1797 /* on the next assoc, re-program HT/VHT parameters */
1806 memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); 1798 memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
1807 memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask)); 1799 memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));
1800 memset(&ifmgd->vht_capa, 0, sizeof(ifmgd->vht_capa));
1801 memset(&ifmgd->vht_capa_mask, 0, sizeof(ifmgd->vht_capa_mask));
1808 1802
1809 sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; 1803 sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
1810 1804
@@ -1830,8 +1824,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1830 del_timer_sync(&sdata->u.mgd.timer); 1824 del_timer_sync(&sdata->u.mgd.timer);
1831 del_timer_sync(&sdata->u.mgd.chswitch_timer); 1825 del_timer_sync(&sdata->u.mgd.chswitch_timer);
1832 1826
1833 sdata->u.mgd.timers_running = 0;
1834
1835 sdata->vif.bss_conf.dtim_period = 0; 1827 sdata->vif.bss_conf.dtim_period = 0;
1836 1828
1837 ifmgd->flags = 0; 1829 ifmgd->flags = 0;
@@ -3140,15 +3132,8 @@ static void ieee80211_sta_timer(unsigned long data)
3140{ 3132{
3141 struct ieee80211_sub_if_data *sdata = 3133 struct ieee80211_sub_if_data *sdata =
3142 (struct ieee80211_sub_if_data *) data; 3134 (struct ieee80211_sub_if_data *) data;
3143 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3144 struct ieee80211_local *local = sdata->local;
3145
3146 if (local->quiescing) {
3147 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
3148 return;
3149 }
3150 3135
3151 ieee80211_queue_work(&local->hw, &sdata->work); 3136 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
3152} 3137}
3153 3138
3154static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, 3139static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
@@ -3500,72 +3485,6 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
3500 } 3485 }
3501} 3486}
3502 3487
3503#ifdef CONFIG_PM
3504void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
3505{
3506 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3507
3508 /*
3509 * Stop timers before deleting work items, as timers
3510 * could race and re-add the work-items. They will be
3511 * re-established on connection.
3512 */
3513 del_timer_sync(&ifmgd->conn_mon_timer);
3514 del_timer_sync(&ifmgd->bcn_mon_timer);
3515
3516 /*
3517 * we need to use atomic bitops for the running bits
3518 * only because both timers might fire at the same
3519 * time -- the code here is properly synchronised.
3520 */
3521
3522 cancel_work_sync(&ifmgd->request_smps_work);
3523
3524 cancel_work_sync(&ifmgd->monitor_work);
3525 cancel_work_sync(&ifmgd->beacon_connection_loss_work);
3526 cancel_work_sync(&ifmgd->csa_connection_drop_work);
3527 if (del_timer_sync(&ifmgd->timer))
3528 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
3529
3530 if (del_timer_sync(&ifmgd->chswitch_timer))
3531 set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
3532 cancel_work_sync(&ifmgd->chswitch_work);
3533}
3534
3535void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
3536{
3537 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3538
3539 mutex_lock(&ifmgd->mtx);
3540 if (!ifmgd->associated) {
3541 mutex_unlock(&ifmgd->mtx);
3542 return;
3543 }
3544
3545 if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) {
3546 sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME;
3547 mlme_dbg(sdata, "driver requested disconnect after resume\n");
3548 ieee80211_sta_connection_lost(sdata,
3549 ifmgd->associated->bssid,
3550 WLAN_REASON_UNSPECIFIED,
3551 true);
3552 mutex_unlock(&ifmgd->mtx);
3553 return;
3554 }
3555 mutex_unlock(&ifmgd->mtx);
3556
3557 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running))
3558 add_timer(&ifmgd->timer);
3559 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
3560 add_timer(&ifmgd->chswitch_timer);
3561 ieee80211_sta_reset_beacon_monitor(sdata);
3562
3563 mutex_lock(&sdata->local->mtx);
3564 ieee80211_restart_sta_timer(sdata);
3565 mutex_unlock(&sdata->local->mtx);
3566}
3567#endif
3568
3569/* interface setup */ 3488/* interface setup */
3570void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) 3489void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
3571{ 3490{
@@ -4071,6 +3990,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4071 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 3990 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
4072 } 3991 }
4073 3992
3993 if (req->flags & ASSOC_REQ_DISABLE_VHT)
3994 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
3995
4074 /* Also disable HT if we don't support it or the AP doesn't use WMM */ 3996 /* Also disable HT if we don't support it or the AP doesn't use WMM */
4075 sband = local->hw.wiphy->bands[req->bss->channel->band]; 3997 sband = local->hw.wiphy->bands[req->bss->channel->band];
4076 if (!sband->ht_cap.ht_supported || 3998 if (!sband->ht_cap.ht_supported ||
@@ -4094,6 +4016,10 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4094 memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, 4016 memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask,
4095 sizeof(ifmgd->ht_capa_mask)); 4017 sizeof(ifmgd->ht_capa_mask));
4096 4018
4019 memcpy(&ifmgd->vht_capa, &req->vht_capa, sizeof(ifmgd->vht_capa));
4020 memcpy(&ifmgd->vht_capa_mask, &req->vht_capa_mask,
4021 sizeof(ifmgd->vht_capa_mask));
4022
4097 if (req->ie && req->ie_len) { 4023 if (req->ie && req->ie_len) {
4098 memcpy(assoc_data->ie, req->ie, req->ie_len); 4024 memcpy(assoc_data->ie, req->ie, req->ie_len);
4099 assoc_data->ie_len = req->ie_len; 4025 assoc_data->ie_len = req->ie_len;
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index cc79b4a2e821..db547fceaeb9 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -277,7 +277,7 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
277 duration = 10; 277 duration = 10;
278 278
279 ret = drv_remain_on_channel(local, roc->sdata, roc->chan, 279 ret = drv_remain_on_channel(local, roc->sdata, roc->chan,
280 duration); 280 duration, roc->type);
281 281
282 roc->started = true; 282 roc->started = true;
283 283
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index d0275f34bf70..b471a67f224d 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -6,32 +6,11 @@
6#include "driver-ops.h" 6#include "driver-ops.h"
7#include "led.h" 7#include "led.h"
8 8
9/* return value indicates whether the driver should be further notified */
10static void ieee80211_quiesce(struct ieee80211_sub_if_data *sdata)
11{
12 switch (sdata->vif.type) {
13 case NL80211_IFTYPE_STATION:
14 ieee80211_sta_quiesce(sdata);
15 break;
16 case NL80211_IFTYPE_ADHOC:
17 ieee80211_ibss_quiesce(sdata);
18 break;
19 case NL80211_IFTYPE_MESH_POINT:
20 ieee80211_mesh_quiesce(sdata);
21 break;
22 default:
23 break;
24 }
25
26 cancel_work_sync(&sdata->work);
27}
28
29int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) 9int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
30{ 10{
31 struct ieee80211_local *local = hw_to_local(hw); 11 struct ieee80211_local *local = hw_to_local(hw);
32 struct ieee80211_sub_if_data *sdata; 12 struct ieee80211_sub_if_data *sdata;
33 struct sta_info *sta; 13 struct sta_info *sta;
34 struct ieee80211_chanctx *ctx;
35 14
36 if (!local->open_count) 15 if (!local->open_count)
37 goto suspend; 16 goto suspend;
@@ -93,19 +72,12 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
93 return err; 72 return err;
94 } else if (err > 0) { 73 } else if (err > 0) {
95 WARN_ON(err != 1); 74 WARN_ON(err != 1);
96 local->wowlan = false; 75 return err;
97 } else { 76 } else {
98 list_for_each_entry(sdata, &local->interfaces, list)
99 if (ieee80211_sdata_running(sdata))
100 ieee80211_quiesce(sdata);
101 goto suspend; 77 goto suspend;
102 } 78 }
103 } 79 }
104 80
105 /* disable keys */
106 list_for_each_entry(sdata, &local->interfaces, list)
107 ieee80211_disable_keys(sdata);
108
109 /* tear down aggregation sessions and remove STAs */ 81 /* tear down aggregation sessions and remove STAs */
110 mutex_lock(&local->sta_mtx); 82 mutex_lock(&local->sta_mtx);
111 list_for_each_entry(sta, &local->sta_list, list) { 83 list_for_each_entry(sta, &local->sta_list, list) {
@@ -117,100 +89,25 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
117 WARN_ON(drv_sta_state(local, sta->sdata, sta, 89 WARN_ON(drv_sta_state(local, sta->sdata, sta,
118 state, state - 1)); 90 state, state - 1));
119 } 91 }
120
121 mesh_plink_quiesce(sta);
122 } 92 }
123 mutex_unlock(&local->sta_mtx); 93 mutex_unlock(&local->sta_mtx);
124 94
125 /* remove all interfaces */ 95 /* remove all interfaces */
126 list_for_each_entry(sdata, &local->interfaces, list) { 96 list_for_each_entry(sdata, &local->interfaces, list) {
127 static u8 zero_addr[ETH_ALEN] = {};
128 u32 changed = 0;
129
130 if (!ieee80211_sdata_running(sdata)) 97 if (!ieee80211_sdata_running(sdata))
131 continue; 98 continue;
132
133 switch (sdata->vif.type) {
134 case NL80211_IFTYPE_AP_VLAN:
135 case NL80211_IFTYPE_MONITOR:
136 /* skip these */
137 continue;
138 case NL80211_IFTYPE_STATION:
139 if (sdata->vif.bss_conf.assoc)
140 changed = BSS_CHANGED_ASSOC |
141 BSS_CHANGED_BSSID |
142 BSS_CHANGED_IDLE;
143 break;
144 case NL80211_IFTYPE_AP:
145 case NL80211_IFTYPE_ADHOC:
146 case NL80211_IFTYPE_MESH_POINT:
147 if (sdata->vif.bss_conf.enable_beacon)
148 changed = BSS_CHANGED_BEACON_ENABLED;
149 break;
150 default:
151 break;
152 }
153
154 ieee80211_quiesce(sdata);
155
156 sdata->suspend_bss_conf = sdata->vif.bss_conf;
157 memset(&sdata->vif.bss_conf, 0, sizeof(sdata->vif.bss_conf));
158 sdata->vif.bss_conf.idle = true;
159 if (sdata->suspend_bss_conf.bssid)
160 sdata->vif.bss_conf.bssid = zero_addr;
161
162 /* disable beaconing or remove association */
163 ieee80211_bss_info_change_notify(sdata, changed);
164
165 if (sdata->vif.type == NL80211_IFTYPE_AP &&
166 rcu_access_pointer(sdata->u.ap.beacon))
167 drv_stop_ap(local, sdata);
168
169 if (local->use_chanctx) {
170 struct ieee80211_chanctx_conf *conf;
171
172 mutex_lock(&local->chanctx_mtx);
173 conf = rcu_dereference_protected(
174 sdata->vif.chanctx_conf,
175 lockdep_is_held(&local->chanctx_mtx));
176 if (conf) {
177 ctx = container_of(conf,
178 struct ieee80211_chanctx,
179 conf);
180 drv_unassign_vif_chanctx(local, sdata, ctx);
181 }
182
183 mutex_unlock(&local->chanctx_mtx);
184 }
185 drv_remove_interface(local, sdata); 99 drv_remove_interface(local, sdata);
186 } 100 }
187 101
188 sdata = rtnl_dereference(local->monitor_sdata); 102 sdata = rtnl_dereference(local->monitor_sdata);
189 if (sdata) { 103 if (sdata)
190 if (local->use_chanctx) {
191 struct ieee80211_chanctx_conf *conf;
192
193 mutex_lock(&local->chanctx_mtx);
194 conf = rcu_dereference_protected(
195 sdata->vif.chanctx_conf,
196 lockdep_is_held(&local->chanctx_mtx));
197 if (conf) {
198 ctx = container_of(conf,
199 struct ieee80211_chanctx,
200 conf);
201 drv_unassign_vif_chanctx(local, sdata, ctx);
202 }
203
204 mutex_unlock(&local->chanctx_mtx);
205 }
206
207 drv_remove_interface(local, sdata); 104 drv_remove_interface(local, sdata);
208 }
209 105
210 mutex_lock(&local->chanctx_mtx); 106 /*
211 list_for_each_entry(ctx, &local->chanctx_list, list) 107 * We disconnected on all interfaces before suspend, all channel
212 drv_remove_chanctx(local, ctx); 108 * contexts should be released.
213 mutex_unlock(&local->chanctx_mtx); 109 */
110 WARN_ON(!list_empty(&local->chanctx_list));
214 111
215 /* stop hardware - this must stop RX */ 112 /* stop hardware - this must stop RX */
216 if (local->open_count) 113 if (local->open_count)
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index eea45a2c7c35..1c36c9b4fa4a 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -55,7 +55,6 @@
55#include "rate.h" 55#include "rate.h"
56#include "rc80211_minstrel.h" 56#include "rc80211_minstrel.h"
57 57
58#define SAMPLE_COLUMNS 10
59#define SAMPLE_TBL(_mi, _idx, _col) \ 58#define SAMPLE_TBL(_mi, _idx, _col) \
60 _mi->sample_table[(_idx * SAMPLE_COLUMNS) + _col] 59 _mi->sample_table[(_idx * SAMPLE_COLUMNS) + _col]
61 60
@@ -70,16 +69,31 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
70 return i; 69 return i;
71} 70}
72 71
72/* find & sort topmost throughput rates */
73static inline void
74minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list)
75{
76 int j = MAX_THR_RATES;
77
78 while (j > 0 && mi->r[i].cur_tp > mi->r[tp_list[j - 1]].cur_tp)
79 j--;
80 if (j < MAX_THR_RATES - 1)
81 memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1));
82 if (j < MAX_THR_RATES)
83 tp_list[j] = i;
84}
85
73static void 86static void
74minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) 87minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
75{ 88{
76 u32 max_tp = 0, index_max_tp = 0, index_max_tp2 = 0; 89 u8 tmp_tp_rate[MAX_THR_RATES];
77 u32 max_prob = 0, index_max_prob = 0; 90 u8 tmp_prob_rate = 0;
78 u32 usecs; 91 u32 usecs;
79 u32 p;
80 int i; 92 int i;
81 93
82 mi->stats_update = jiffies; 94 for (i=0; i < MAX_THR_RATES; i++)
95 tmp_tp_rate[i] = 0;
96
83 for (i = 0; i < mi->n_rates; i++) { 97 for (i = 0; i < mi->n_rates; i++) {
84 struct minstrel_rate *mr = &mi->r[i]; 98 struct minstrel_rate *mr = &mi->r[i];
85 99
@@ -87,27 +101,32 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
87 if (!usecs) 101 if (!usecs)
88 usecs = 1000000; 102 usecs = 1000000;
89 103
90 /* To avoid rounding issues, probabilities scale from 0 (0%) 104 if (unlikely(mr->attempts > 0)) {
91 * to 18000 (100%) */ 105 mr->sample_skipped = 0;
92 if (mr->attempts) { 106 mr->cur_prob = MINSTREL_FRAC(mr->success, mr->attempts);
93 p = (mr->success * 18000) / mr->attempts;
94 mr->succ_hist += mr->success; 107 mr->succ_hist += mr->success;
95 mr->att_hist += mr->attempts; 108 mr->att_hist += mr->attempts;
96 mr->cur_prob = p; 109 mr->probability = minstrel_ewma(mr->probability,
97 p = ((p * (100 - mp->ewma_level)) + (mr->probability * 110 mr->cur_prob,
98 mp->ewma_level)) / 100; 111 EWMA_LEVEL);
99 mr->probability = p; 112 } else
100 mr->cur_tp = p * (1000000 / usecs); 113 mr->sample_skipped++;
101 }
102 114
103 mr->last_success = mr->success; 115 mr->last_success = mr->success;
104 mr->last_attempts = mr->attempts; 116 mr->last_attempts = mr->attempts;
105 mr->success = 0; 117 mr->success = 0;
106 mr->attempts = 0; 118 mr->attempts = 0;
107 119
120 /* Update throughput per rate, reset thr. below 10% success */
121 if (mr->probability < MINSTREL_FRAC(10, 100))
122 mr->cur_tp = 0;
123 else
124 mr->cur_tp = mr->probability * (1000000 / usecs);
125
108 /* Sample less often below the 10% chance of success. 126 /* Sample less often below the 10% chance of success.
109 * Sample less often above the 95% chance of success. */ 127 * Sample less often above the 95% chance of success. */
110 if ((mr->probability > 17100) || (mr->probability < 1800)) { 128 if (mr->probability > MINSTREL_FRAC(95, 100) ||
129 mr->probability < MINSTREL_FRAC(10, 100)) {
111 mr->adjusted_retry_count = mr->retry_count >> 1; 130 mr->adjusted_retry_count = mr->retry_count >> 1;
112 if (mr->adjusted_retry_count > 2) 131 if (mr->adjusted_retry_count > 2)
113 mr->adjusted_retry_count = 2; 132 mr->adjusted_retry_count = 2;
@@ -118,35 +137,30 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
118 } 137 }
119 if (!mr->adjusted_retry_count) 138 if (!mr->adjusted_retry_count)
120 mr->adjusted_retry_count = 2; 139 mr->adjusted_retry_count = 2;
121 }
122 140
123 for (i = 0; i < mi->n_rates; i++) { 141 minstrel_sort_best_tp_rates(mi, i, tmp_tp_rate);
124 struct minstrel_rate *mr = &mi->r[i]; 142
125 if (max_tp < mr->cur_tp) { 143 /* To determine the most robust rate (max_prob_rate) used at
126 index_max_tp = i; 144 * 3rd mmr stage we distinct between two cases:
127 max_tp = mr->cur_tp; 145 * (1) if any success probabilitiy >= 95%, out of those rates
128 } 146 * choose the maximum throughput rate as max_prob_rate
129 if (max_prob < mr->probability) { 147 * (2) if all success probabilities < 95%, the rate with
130 index_max_prob = i; 148 * highest success probability is choosen as max_prob_rate */
131 max_prob = mr->probability; 149 if (mr->probability >= MINSTREL_FRAC(95,100)) {
150 if (mr->cur_tp >= mi->r[tmp_prob_rate].cur_tp)
151 tmp_prob_rate = i;
152 } else {
153 if (mr->probability >= mi->r[tmp_prob_rate].probability)
154 tmp_prob_rate = i;
132 } 155 }
133 } 156 }
134 157
135 max_tp = 0; 158 /* Assign the new rate set */
136 for (i = 0; i < mi->n_rates; i++) { 159 memcpy(mi->max_tp_rate, tmp_tp_rate, sizeof(mi->max_tp_rate));
137 struct minstrel_rate *mr = &mi->r[i]; 160 mi->max_prob_rate = tmp_prob_rate;
138
139 if (i == index_max_tp)
140 continue;
141 161
142 if (max_tp < mr->cur_tp) { 162 /* Reset update timer */
143 index_max_tp2 = i; 163 mi->stats_update = jiffies;
144 max_tp = mr->cur_tp;
145 }
146 }
147 mi->max_tp_rate = index_max_tp;
148 mi->max_tp_rate2 = index_max_tp2;
149 mi->max_prob_rate = index_max_prob;
150} 164}
151 165
152static void 166static void
@@ -207,10 +221,10 @@ static int
207minstrel_get_next_sample(struct minstrel_sta_info *mi) 221minstrel_get_next_sample(struct minstrel_sta_info *mi)
208{ 222{
209 unsigned int sample_ndx; 223 unsigned int sample_ndx;
210 sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column); 224 sample_ndx = SAMPLE_TBL(mi, mi->sample_row, mi->sample_column);
211 mi->sample_idx++; 225 mi->sample_row++;
212 if ((int) mi->sample_idx > (mi->n_rates - 2)) { 226 if ((int) mi->sample_row >= mi->n_rates) {
213 mi->sample_idx = 0; 227 mi->sample_row = 0;
214 mi->sample_column++; 228 mi->sample_column++;
215 if (mi->sample_column >= SAMPLE_COLUMNS) 229 if (mi->sample_column >= SAMPLE_COLUMNS)
216 mi->sample_column = 0; 230 mi->sample_column = 0;
@@ -228,31 +242,37 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
228 struct minstrel_priv *mp = priv; 242 struct minstrel_priv *mp = priv;
229 struct ieee80211_tx_rate *ar = info->control.rates; 243 struct ieee80211_tx_rate *ar = info->control.rates;
230 unsigned int ndx, sample_ndx = 0; 244 unsigned int ndx, sample_ndx = 0;
231 bool mrr; 245 bool mrr_capable;
232 bool sample_slower = false; 246 bool indirect_rate_sampling = false;
233 bool sample = false; 247 bool rate_sampling = false;
234 int i, delta; 248 int i, delta;
235 int mrr_ndx[3]; 249 int mrr_ndx[3];
236 int sample_rate; 250 int sampling_ratio;
237 251
252 /* management/no-ack frames do not use rate control */
238 if (rate_control_send_low(sta, priv_sta, txrc)) 253 if (rate_control_send_low(sta, priv_sta, txrc))
239 return; 254 return;
240 255
241 mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot; 256 /* check multi-rate-retry capabilities & adjust lookaround_rate */
242 257 mrr_capable = mp->has_mrr &&
243 ndx = mi->max_tp_rate; 258 !txrc->rts &&
244 259 !txrc->bss_conf->use_cts_prot;
245 if (mrr) 260 if (mrr_capable)
246 sample_rate = mp->lookaround_rate_mrr; 261 sampling_ratio = mp->lookaround_rate_mrr;
247 else 262 else
248 sample_rate = mp->lookaround_rate; 263 sampling_ratio = mp->lookaround_rate;
264
265 /* init rateindex [ndx] with max throughput rate */
266 ndx = mi->max_tp_rate[0];
249 267
268 /* increase sum packet counter */
250 mi->packet_count++; 269 mi->packet_count++;
251 delta = (mi->packet_count * sample_rate / 100) - 270
271 delta = (mi->packet_count * sampling_ratio / 100) -
252 (mi->sample_count + mi->sample_deferred / 2); 272 (mi->sample_count + mi->sample_deferred / 2);
253 273
254 /* delta > 0: sampling required */ 274 /* delta > 0: sampling required */
255 if ((delta > 0) && (mrr || !mi->prev_sample)) { 275 if ((delta > 0) && (mrr_capable || !mi->prev_sample)) {
256 struct minstrel_rate *msr; 276 struct minstrel_rate *msr;
257 if (mi->packet_count >= 10000) { 277 if (mi->packet_count >= 10000) {
258 mi->sample_deferred = 0; 278 mi->sample_deferred = 0;
@@ -271,21 +291,28 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
271 mi->sample_count += (delta - mi->n_rates * 2); 291 mi->sample_count += (delta - mi->n_rates * 2);
272 } 292 }
273 293
294 /* get next random rate sample */
274 sample_ndx = minstrel_get_next_sample(mi); 295 sample_ndx = minstrel_get_next_sample(mi);
275 msr = &mi->r[sample_ndx]; 296 msr = &mi->r[sample_ndx];
276 sample = true; 297 rate_sampling = true;
277 sample_slower = mrr && (msr->perfect_tx_time > 298
278 mi->r[ndx].perfect_tx_time); 299 /* Decide if direct ( 1st mrr stage) or indirect (2nd mrr stage)
279 300 * rate sampling method should be used.
280 if (!sample_slower) { 301 * Respect such rates that are not sampled for 20 interations.
302 */
303 if (mrr_capable &&
304 msr->perfect_tx_time > mi->r[ndx].perfect_tx_time &&
305 msr->sample_skipped < 20)
306 indirect_rate_sampling = true;
307
308 if (!indirect_rate_sampling) {
281 if (msr->sample_limit != 0) { 309 if (msr->sample_limit != 0) {
282 ndx = sample_ndx; 310 ndx = sample_ndx;
283 mi->sample_count++; 311 mi->sample_count++;
284 if (msr->sample_limit > 0) 312 if (msr->sample_limit > 0)
285 msr->sample_limit--; 313 msr->sample_limit--;
286 } else { 314 } else
287 sample = false; 315 rate_sampling = false;
288 }
289 } else { 316 } else {
290 /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark 317 /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
291 * packets that have the sampling rate deferred to the 318 * packets that have the sampling rate deferred to the
@@ -297,34 +324,39 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
297 mi->sample_deferred++; 324 mi->sample_deferred++;
298 } 325 }
299 } 326 }
300 mi->prev_sample = sample; 327 mi->prev_sample = rate_sampling;
301 328
302 /* If we're not using MRR and the sampling rate already 329 /* If we're not using MRR and the sampling rate already
303 * has a probability of >95%, we shouldn't be attempting 330 * has a probability of >95%, we shouldn't be attempting
304 * to use it, as this only wastes precious airtime */ 331 * to use it, as this only wastes precious airtime */
305 if (!mrr && sample && (mi->r[ndx].probability > 17100)) 332 if (!mrr_capable && rate_sampling &&
306 ndx = mi->max_tp_rate; 333 (mi->r[ndx].probability > MINSTREL_FRAC(95, 100)))
334 ndx = mi->max_tp_rate[0];
307 335
336 /* mrr setup for 1st stage */
308 ar[0].idx = mi->r[ndx].rix; 337 ar[0].idx = mi->r[ndx].rix;
309 ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info); 338 ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info);
310 339
311 if (!mrr) { 340 /* non mrr setup for 2nd stage */
312 if (!sample) 341 if (!mrr_capable) {
342 if (!rate_sampling)
313 ar[0].count = mp->max_retry; 343 ar[0].count = mp->max_retry;
314 ar[1].idx = mi->lowest_rix; 344 ar[1].idx = mi->lowest_rix;
315 ar[1].count = mp->max_retry; 345 ar[1].count = mp->max_retry;
316 return; 346 return;
317 } 347 }
318 348
319 /* MRR setup */ 349 /* mrr setup for 2nd stage */
320 if (sample) { 350 if (rate_sampling) {
321 if (sample_slower) 351 if (indirect_rate_sampling)
322 mrr_ndx[0] = sample_ndx; 352 mrr_ndx[0] = sample_ndx;
323 else 353 else
324 mrr_ndx[0] = mi->max_tp_rate; 354 mrr_ndx[0] = mi->max_tp_rate[0];
325 } else { 355 } else {
326 mrr_ndx[0] = mi->max_tp_rate2; 356 mrr_ndx[0] = mi->max_tp_rate[1];
327 } 357 }
358
359 /* mrr setup for 3rd & 4th stage */
328 mrr_ndx[1] = mi->max_prob_rate; 360 mrr_ndx[1] = mi->max_prob_rate;
329 mrr_ndx[2] = 0; 361 mrr_ndx[2] = 0;
330 for (i = 1; i < 4; i++) { 362 for (i = 1; i < 4; i++) {
@@ -351,26 +383,21 @@ static void
351init_sample_table(struct minstrel_sta_info *mi) 383init_sample_table(struct minstrel_sta_info *mi)
352{ 384{
353 unsigned int i, col, new_idx; 385 unsigned int i, col, new_idx;
354 unsigned int n_srates = mi->n_rates - 1;
355 u8 rnd[8]; 386 u8 rnd[8];
356 387
357 mi->sample_column = 0; 388 mi->sample_column = 0;
358 mi->sample_idx = 0; 389 mi->sample_row = 0;
359 memset(mi->sample_table, 0, SAMPLE_COLUMNS * mi->n_rates); 390 memset(mi->sample_table, 0xff, SAMPLE_COLUMNS * mi->n_rates);
360 391
361 for (col = 0; col < SAMPLE_COLUMNS; col++) { 392 for (col = 0; col < SAMPLE_COLUMNS; col++) {
362 for (i = 0; i < n_srates; i++) { 393 for (i = 0; i < mi->n_rates; i++) {
363 get_random_bytes(rnd, sizeof(rnd)); 394 get_random_bytes(rnd, sizeof(rnd));
364 new_idx = (i + rnd[i & 7]) % n_srates; 395 new_idx = (i + rnd[i & 7]) % mi->n_rates;
365 396
366 while (SAMPLE_TBL(mi, new_idx, col) != 0) 397 while (SAMPLE_TBL(mi, new_idx, col) != 0xff)
367 new_idx = (new_idx + 1) % n_srates; 398 new_idx = (new_idx + 1) % mi->n_rates;
368 399
369 /* Don't sample the slowest rate (i.e. slowest base 400 SAMPLE_TBL(mi, new_idx, col) = i;
370 * rate). We must presume that the slowest rate works
371 * fine, or else other management frames will also be
372 * failing and the link will break */
373 SAMPLE_TBL(mi, new_idx, col) = i + 1;
374 } 401 }
375 } 402 }
376} 403}
@@ -542,9 +569,6 @@ minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
542 mp->lookaround_rate = 5; 569 mp->lookaround_rate = 5;
543 mp->lookaround_rate_mrr = 10; 570 mp->lookaround_rate_mrr = 10;
544 571
545 /* moving average weight for EWMA */
546 mp->ewma_level = 75;
547
548 /* maximum time that the hw is allowed to stay in one MRR segment */ 572 /* maximum time that the hw is allowed to stay in one MRR segment */
549 mp->segment_size = 6000; 573 mp->segment_size = 6000;
550 574
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 5ecf757817f2..85ebf42cb46d 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -9,6 +9,28 @@
9#ifndef __RC_MINSTREL_H 9#ifndef __RC_MINSTREL_H
10#define __RC_MINSTREL_H 10#define __RC_MINSTREL_H
11 11
12#define EWMA_LEVEL 75 /* ewma weighting factor [%] */
13#define SAMPLE_COLUMNS 10 /* number of columns in sample table */
14
15
16/* scaled fraction values */
17#define MINSTREL_SCALE 16
18#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
19#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
20
21/* number of highest throughput rates to consider*/
22#define MAX_THR_RATES 4
23
24/*
25 * Perform EWMA (Exponentially Weighted Moving Average) calculation
26 */
27static inline int
28minstrel_ewma(int old, int new, int weight)
29{
30 return (new * (100 - weight) + old * weight) / 100;
31}
32
33
12struct minstrel_rate { 34struct minstrel_rate {
13 int bitrate; 35 int bitrate;
14 int rix; 36 int rix;
@@ -26,6 +48,7 @@ struct minstrel_rate {
26 u32 attempts; 48 u32 attempts;
27 u32 last_attempts; 49 u32 last_attempts;
28 u32 last_success; 50 u32 last_success;
51 u8 sample_skipped;
29 52
30 /* parts per thousand */ 53 /* parts per thousand */
31 u32 cur_prob; 54 u32 cur_prob;
@@ -45,14 +68,13 @@ struct minstrel_sta_info {
45 68
46 unsigned int lowest_rix; 69 unsigned int lowest_rix;
47 70
48 unsigned int max_tp_rate; 71 u8 max_tp_rate[MAX_THR_RATES];
49 unsigned int max_tp_rate2; 72 u8 max_prob_rate;
50 unsigned int max_prob_rate;
51 unsigned int packet_count; 73 unsigned int packet_count;
52 unsigned int sample_count; 74 unsigned int sample_count;
53 int sample_deferred; 75 int sample_deferred;
54 76
55 unsigned int sample_idx; 77 unsigned int sample_row;
56 unsigned int sample_column; 78 unsigned int sample_column;
57 79
58 int n_rates; 80 int n_rates;
@@ -73,7 +95,6 @@ struct minstrel_priv {
73 unsigned int cw_min; 95 unsigned int cw_min;
74 unsigned int cw_max; 96 unsigned int cw_max;
75 unsigned int max_retry; 97 unsigned int max_retry;
76 unsigned int ewma_level;
77 unsigned int segment_size; 98 unsigned int segment_size;
78 unsigned int update_interval; 99 unsigned int update_interval;
79 unsigned int lookaround_rate; 100 unsigned int lookaround_rate;
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
index d5a56226e675..d1048348d399 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -73,15 +73,17 @@ minstrel_stats_open(struct inode *inode, struct file *file)
73 for (i = 0; i < mi->n_rates; i++) { 73 for (i = 0; i < mi->n_rates; i++) {
74 struct minstrel_rate *mr = &mi->r[i]; 74 struct minstrel_rate *mr = &mi->r[i];
75 75
76 *(p++) = (i == mi->max_tp_rate) ? 'T' : ' '; 76 *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' ';
77 *(p++) = (i == mi->max_tp_rate2) ? 't' : ' '; 77 *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' ';
78 *(p++) = (i == mi->max_tp_rate[2]) ? 'C' : ' ';
79 *(p++) = (i == mi->max_tp_rate[3]) ? 'D' : ' ';
78 *(p++) = (i == mi->max_prob_rate) ? 'P' : ' '; 80 *(p++) = (i == mi->max_prob_rate) ? 'P' : ' ';
79 p += sprintf(p, "%3u%s", mr->bitrate / 2, 81 p += sprintf(p, "%3u%s", mr->bitrate / 2,
80 (mr->bitrate & 1 ? ".5" : " ")); 82 (mr->bitrate & 1 ? ".5" : " "));
81 83
82 tp = mr->cur_tp / ((18000 << 10) / 96); 84 tp = MINSTREL_TRUNC(mr->cur_tp / 10);
83 prob = mr->cur_prob / 18; 85 prob = MINSTREL_TRUNC(mr->cur_prob * 1000);
84 eprob = mr->probability / 18; 86 eprob = MINSTREL_TRUNC(mr->probability * 1000);
85 87
86 p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u " 88 p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u "
87 "%3u(%3u) %8llu %8llu\n", 89 "%3u(%3u) %8llu %8llu\n",
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 3af141c69712..749552bdcfe1 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -17,8 +17,6 @@
17#include "rc80211_minstrel_ht.h" 17#include "rc80211_minstrel_ht.h"
18 18
19#define AVG_PKT_SIZE 1200 19#define AVG_PKT_SIZE 1200
20#define SAMPLE_COLUMNS 10
21#define EWMA_LEVEL 75
22 20
23/* Number of bits for an average sized packet */ 21/* Number of bits for an average sized packet */
24#define MCS_NBITS (AVG_PKT_SIZE << 3) 22#define MCS_NBITS (AVG_PKT_SIZE << 3)
@@ -26,11 +24,11 @@
26/* Number of symbols for a packet with (bps) bits per symbol */ 24/* Number of symbols for a packet with (bps) bits per symbol */
27#define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps)) 25#define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps))
28 26
29/* Transmission time for a packet containing (syms) symbols */ 27/* Transmission time (nanoseconds) for a packet containing (syms) symbols */
30#define MCS_SYMBOL_TIME(sgi, syms) \ 28#define MCS_SYMBOL_TIME(sgi, syms) \
31 (sgi ? \ 29 (sgi ? \
32 ((syms) * 18 + 4) / 5 : /* syms * 3.6 us */ \ 30 ((syms) * 18000 + 4000) / 5 : /* syms * 3.6 us */ \
33 (syms) << 2 /* syms * 4 us */ \ 31 ((syms) * 1000) << 2 /* syms * 4 us */ \
34 ) 32 )
35 33
36/* Transmit duration for the raw data part of an average sized packet */ 34/* Transmit duration for the raw data part of an average sized packet */
@@ -64,9 +62,9 @@
64} 62}
65 63
66#define CCK_DURATION(_bitrate, _short, _len) \ 64#define CCK_DURATION(_bitrate, _short, _len) \
67 (10 /* SIFS */ + \ 65 (1000 * (10 /* SIFS */ + \
68 (_short ? 72 + 24 : 144 + 48 ) + \ 66 (_short ? 72 + 24 : 144 + 48 ) + \
69 (8 * (_len + 4) * 10) / (_bitrate)) 67 (8 * (_len + 4) * 10) / (_bitrate)))
70 68
71#define CCK_ACK_DURATION(_bitrate, _short) \ 69#define CCK_ACK_DURATION(_bitrate, _short) \
72 (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \ 70 (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \
@@ -129,15 +127,6 @@ const struct mcs_group minstrel_mcs_groups[] = {
129static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES]; 127static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES];
130 128
131/* 129/*
132 * Perform EWMA (Exponentially Weighted Moving Average) calculation
133 */
134static int
135minstrel_ewma(int old, int new, int weight)
136{
137 return (new * (100 - weight) + old * weight) / 100;
138}
139
140/*
141 * Look up an MCS group index based on mac80211 rate information 130 * Look up an MCS group index based on mac80211 rate information
142 */ 131 */
143static int 132static int
@@ -211,7 +200,8 @@ static void
211minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) 200minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
212{ 201{
213 struct minstrel_rate_stats *mr; 202 struct minstrel_rate_stats *mr;
214 unsigned int usecs = 0; 203 unsigned int nsecs = 0;
204 unsigned int tp;
215 205
216 mr = &mi->groups[group].rates[rate]; 206 mr = &mi->groups[group].rates[rate];
217 207
@@ -221,10 +211,12 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
221 } 211 }
222 212
223 if (group != MINSTREL_CCK_GROUP) 213 if (group != MINSTREL_CCK_GROUP)
224 usecs = mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); 214 nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
225 215
226 usecs += minstrel_mcs_groups[group].duration[rate]; 216 nsecs += minstrel_mcs_groups[group].duration[rate];
227 mr->cur_tp = MINSTREL_TRUNC((1000000 / usecs) * mr->probability); 217 tp = 1000000 * ((mr->probability * 1000) / nsecs);
218
219 mr->cur_tp = MINSTREL_TRUNC(tp);
228} 220}
229 221
230/* 222/*
@@ -308,8 +300,8 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
308 } 300 }
309 } 301 }
310 302
311 /* try to sample up to half of the available rates during each interval */ 303 /* try to sample all available rates during each interval */
312 mi->sample_count *= 4; 304 mi->sample_count *= 8;
313 305
314 cur_prob = 0; 306 cur_prob = 0;
315 cur_prob_tp = 0; 307 cur_prob_tp = 0;
@@ -320,20 +312,13 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
320 if (!mg->supported) 312 if (!mg->supported)
321 continue; 313 continue;
322 314
323 mr = minstrel_get_ratestats(mi, mg->max_prob_rate);
324 if (cur_prob_tp < mr->cur_tp &&
325 minstrel_mcs_groups[group].streams == 1) {
326 mi->max_prob_rate = mg->max_prob_rate;
327 cur_prob = mr->cur_prob;
328 cur_prob_tp = mr->cur_tp;
329 }
330
331 mr = minstrel_get_ratestats(mi, mg->max_tp_rate); 315 mr = minstrel_get_ratestats(mi, mg->max_tp_rate);
332 if (cur_tp < mr->cur_tp) { 316 if (cur_tp < mr->cur_tp) {
333 mi->max_tp_rate2 = mi->max_tp_rate; 317 mi->max_tp_rate2 = mi->max_tp_rate;
334 cur_tp2 = cur_tp; 318 cur_tp2 = cur_tp;
335 mi->max_tp_rate = mg->max_tp_rate; 319 mi->max_tp_rate = mg->max_tp_rate;
336 cur_tp = mr->cur_tp; 320 cur_tp = mr->cur_tp;
321 mi->max_prob_streams = minstrel_mcs_groups[group].streams - 1;
337 } 322 }
338 323
339 mr = minstrel_get_ratestats(mi, mg->max_tp_rate2); 324 mr = minstrel_get_ratestats(mi, mg->max_tp_rate2);
@@ -343,6 +328,23 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
343 } 328 }
344 } 329 }
345 330
331 if (mi->max_prob_streams < 1)
332 mi->max_prob_streams = 1;
333
334 for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
335 mg = &mi->groups[group];
336 if (!mg->supported)
337 continue;
338 mr = minstrel_get_ratestats(mi, mg->max_prob_rate);
339 if (cur_prob_tp < mr->cur_tp &&
340 minstrel_mcs_groups[group].streams <= mi->max_prob_streams) {
341 mi->max_prob_rate = mg->max_prob_rate;
342 cur_prob = mr->cur_prob;
343 cur_prob_tp = mr->cur_tp;
344 }
345 }
346
347
346 mi->stats_update = jiffies; 348 mi->stats_update = jiffies;
347} 349}
348 350
@@ -467,7 +469,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
467 469
468 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { 470 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
469 mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len); 471 mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
470 mi->sample_tries = 2; 472 mi->sample_tries = 1;
471 mi->sample_count--; 473 mi->sample_count--;
472 } 474 }
473 475
@@ -536,7 +538,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
536 mr->retry_updated = true; 538 mr->retry_updated = true;
537 539
538 group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; 540 group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
539 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len; 541 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000;
540 542
541 /* Contention time for first 2 tries */ 543 /* Contention time for first 2 tries */
542 ctime = (t_slot * cw) >> 1; 544 ctime = (t_slot * cw) >> 1;
@@ -616,6 +618,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
616{ 618{
617 struct minstrel_rate_stats *mr; 619 struct minstrel_rate_stats *mr;
618 struct minstrel_mcs_group_data *mg; 620 struct minstrel_mcs_group_data *mg;
621 unsigned int sample_dur, sample_group;
619 int sample_idx = 0; 622 int sample_idx = 0;
620 623
621 if (mi->sample_wait > 0) { 624 if (mi->sample_wait > 0) {
@@ -626,11 +629,11 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
626 if (!mi->sample_tries) 629 if (!mi->sample_tries)
627 return -1; 630 return -1;
628 631
629 mi->sample_tries--;
630 mg = &mi->groups[mi->sample_group]; 632 mg = &mi->groups[mi->sample_group];
631 sample_idx = sample_table[mg->column][mg->index]; 633 sample_idx = sample_table[mg->column][mg->index];
632 mr = &mg->rates[sample_idx]; 634 mr = &mg->rates[sample_idx];
633 sample_idx += mi->sample_group * MCS_GROUP_RATES; 635 sample_group = mi->sample_group;
636 sample_idx += sample_group * MCS_GROUP_RATES;
634 minstrel_next_sample_idx(mi); 637 minstrel_next_sample_idx(mi);
635 638
636 /* 639 /*
@@ -651,14 +654,18 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
651 * Make sure that lower rates get sampled only occasionally, 654 * Make sure that lower rates get sampled only occasionally,
652 * if the link is working perfectly. 655 * if the link is working perfectly.
653 */ 656 */
654 if (minstrel_get_duration(sample_idx) > 657 sample_dur = minstrel_get_duration(sample_idx);
655 minstrel_get_duration(mi->max_tp_rate)) { 658 if (sample_dur >= minstrel_get_duration(mi->max_tp_rate2) &&
659 (mi->max_prob_streams <
660 minstrel_mcs_groups[sample_group].streams ||
661 sample_dur >= minstrel_get_duration(mi->max_prob_rate))) {
656 if (mr->sample_skipped < 20) 662 if (mr->sample_skipped < 20)
657 return -1; 663 return -1;
658 664
659 if (mi->sample_slow++ > 2) 665 if (mi->sample_slow++ > 2)
660 return -1; 666 return -1;
661 } 667 }
668 mi->sample_tries--;
662 669
663 return sample_idx; 670 return sample_idx;
664} 671}
diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h
index 302dbd52180d..9b16e9de9923 100644
--- a/net/mac80211/rc80211_minstrel_ht.h
+++ b/net/mac80211/rc80211_minstrel_ht.h
@@ -16,11 +16,6 @@
16#define MINSTREL_MAX_STREAMS 3 16#define MINSTREL_MAX_STREAMS 3
17#define MINSTREL_STREAM_GROUPS 4 17#define MINSTREL_STREAM_GROUPS 4
18 18
19/* scaled fraction values */
20#define MINSTREL_SCALE 16
21#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
22#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
23
24#define MCS_GROUP_RATES 8 19#define MCS_GROUP_RATES 8
25 20
26struct mcs_group { 21struct mcs_group {
@@ -85,6 +80,7 @@ struct minstrel_ht_sta {
85 80
86 /* best probability rate */ 81 /* best probability rate */
87 unsigned int max_prob_rate; 82 unsigned int max_prob_rate;
83 unsigned int max_prob_streams;
88 84
89 /* time of last status update */ 85 /* time of last status update */
90 unsigned long stats_update; 86 unsigned long stats_update;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index bb73ed2d20b9..5b4492af4e85 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -648,24 +648,6 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
648 return RX_CONTINUE; 648 return RX_CONTINUE;
649} 649}
650 650
651#define SEQ_MODULO 0x1000
652#define SEQ_MASK 0xfff
653
654static inline int seq_less(u16 sq1, u16 sq2)
655{
656 return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1);
657}
658
659static inline u16 seq_inc(u16 sq)
660{
661 return (sq + 1) & SEQ_MASK;
662}
663
664static inline u16 seq_sub(u16 sq1, u16 sq2)
665{
666 return (sq1 - sq2) & SEQ_MASK;
667}
668
669static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, 651static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
670 struct tid_ampdu_rx *tid_agg_rx, 652 struct tid_ampdu_rx *tid_agg_rx,
671 int index, 653 int index,
@@ -687,7 +669,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
687 __skb_queue_tail(frames, skb); 669 __skb_queue_tail(frames, skb);
688 670
689no_frame: 671no_frame:
690 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); 672 tid_agg_rx->head_seq_num = ieee80211_sn_inc(tid_agg_rx->head_seq_num);
691} 673}
692 674
693static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata, 675static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata,
@@ -699,8 +681,9 @@ static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata
699 681
700 lockdep_assert_held(&tid_agg_rx->reorder_lock); 682 lockdep_assert_held(&tid_agg_rx->reorder_lock);
701 683
702 while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { 684 while (ieee80211_sn_less(tid_agg_rx->head_seq_num, head_seq_num)) {
703 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % 685 index = ieee80211_sn_sub(tid_agg_rx->head_seq_num,
686 tid_agg_rx->ssn) %
704 tid_agg_rx->buf_size; 687 tid_agg_rx->buf_size;
705 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, 688 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
706 frames); 689 frames);
@@ -727,8 +710,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
727 lockdep_assert_held(&tid_agg_rx->reorder_lock); 710 lockdep_assert_held(&tid_agg_rx->reorder_lock);
728 711
729 /* release the buffer until next missing frame */ 712 /* release the buffer until next missing frame */
730 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % 713 index = ieee80211_sn_sub(tid_agg_rx->head_seq_num,
731 tid_agg_rx->buf_size; 714 tid_agg_rx->ssn) % tid_agg_rx->buf_size;
732 if (!tid_agg_rx->reorder_buf[index] && 715 if (!tid_agg_rx->reorder_buf[index] &&
733 tid_agg_rx->stored_mpdu_num) { 716 tid_agg_rx->stored_mpdu_num) {
734 /* 717 /*
@@ -756,19 +739,22 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
756 * Increment the head seq# also for the skipped slots. 739 * Increment the head seq# also for the skipped slots.
757 */ 740 */
758 tid_agg_rx->head_seq_num = 741 tid_agg_rx->head_seq_num =
759 (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; 742 (tid_agg_rx->head_seq_num +
743 skipped) & IEEE80211_SN_MASK;
760 skipped = 0; 744 skipped = 0;
761 } 745 }
762 } else while (tid_agg_rx->reorder_buf[index]) { 746 } else while (tid_agg_rx->reorder_buf[index]) {
763 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, 747 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
764 frames); 748 frames);
765 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % 749 index = ieee80211_sn_sub(tid_agg_rx->head_seq_num,
750 tid_agg_rx->ssn) %
766 tid_agg_rx->buf_size; 751 tid_agg_rx->buf_size;
767 } 752 }
768 753
769 if (tid_agg_rx->stored_mpdu_num) { 754 if (tid_agg_rx->stored_mpdu_num) {
770 j = index = seq_sub(tid_agg_rx->head_seq_num, 755 j = index = ieee80211_sn_sub(tid_agg_rx->head_seq_num,
771 tid_agg_rx->ssn) % tid_agg_rx->buf_size; 756 tid_agg_rx->ssn) %
757 tid_agg_rx->buf_size;
772 758
773 for (; j != (index - 1) % tid_agg_rx->buf_size; 759 for (; j != (index - 1) % tid_agg_rx->buf_size;
774 j = (j + 1) % tid_agg_rx->buf_size) { 760 j = (j + 1) % tid_agg_rx->buf_size) {
@@ -809,7 +795,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
809 head_seq_num = tid_agg_rx->head_seq_num; 795 head_seq_num = tid_agg_rx->head_seq_num;
810 796
811 /* frame with out of date sequence number */ 797 /* frame with out of date sequence number */
812 if (seq_less(mpdu_seq_num, head_seq_num)) { 798 if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) {
813 dev_kfree_skb(skb); 799 dev_kfree_skb(skb);
814 goto out; 800 goto out;
815 } 801 }
@@ -818,8 +804,9 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
818 * If frame the sequence number exceeds our buffering window 804 * If frame the sequence number exceeds our buffering window
819 * size release some previous frames to make room for this one. 805 * size release some previous frames to make room for this one.
820 */ 806 */
821 if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { 807 if (!ieee80211_sn_less(mpdu_seq_num, head_seq_num + buf_size)) {
822 head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); 808 head_seq_num = ieee80211_sn_inc(
809 ieee80211_sn_sub(mpdu_seq_num, buf_size));
823 /* release stored frames up to new head to stack */ 810 /* release stored frames up to new head to stack */
824 ieee80211_release_reorder_frames(sdata, tid_agg_rx, 811 ieee80211_release_reorder_frames(sdata, tid_agg_rx,
825 head_seq_num, frames); 812 head_seq_num, frames);
@@ -827,7 +814,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
827 814
828 /* Now the new frame is always in the range of the reordering buffer */ 815 /* Now the new frame is always in the range of the reordering buffer */
829 816
830 index = seq_sub(mpdu_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; 817 index = ieee80211_sn_sub(mpdu_seq_num,
818 tid_agg_rx->ssn) % tid_agg_rx->buf_size;
831 819
832 /* check if we already stored this frame */ 820 /* check if we already stored this frame */
833 if (tid_agg_rx->reorder_buf[index]) { 821 if (tid_agg_rx->reorder_buf[index]) {
@@ -843,7 +831,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
843 */ 831 */
844 if (mpdu_seq_num == tid_agg_rx->head_seq_num && 832 if (mpdu_seq_num == tid_agg_rx->head_seq_num &&
845 tid_agg_rx->stored_mpdu_num == 0) { 833 tid_agg_rx->stored_mpdu_num == 0) {
846 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); 834 tid_agg_rx->head_seq_num =
835 ieee80211_sn_inc(tid_agg_rx->head_seq_num);
847 ret = false; 836 ret = false;
848 goto out; 837 goto out;
849 } 838 }
@@ -1894,8 +1883,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1894 * 'align' will only take the values 0 or 2 here 1883 * 'align' will only take the values 0 or 2 here
1895 * since all frames are required to be aligned 1884 * since all frames are required to be aligned
1896 * to 2-byte boundaries when being passed to 1885 * to 2-byte boundaries when being passed to
1897 * mac80211. That also explains the __skb_push() 1886 * mac80211; the code here works just as well if
1898 * below. 1887 * that isn't true, but mac80211 assumes it can
1888 * access fields as 2-byte aligned (e.g. for
1889 * compare_ether_addr)
1899 */ 1890 */
1900 align = ((unsigned long)(skb->data + sizeof(struct ethhdr))) & 3; 1891 align = ((unsigned long)(skb->data + sizeof(struct ethhdr))) & 3;
1901 if (align) { 1892 if (align) {
@@ -2552,7 +2543,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2552 case WLAN_SP_MESH_PEERING_CONFIRM: 2543 case WLAN_SP_MESH_PEERING_CONFIRM:
2553 if (!ieee80211_vif_is_mesh(&sdata->vif)) 2544 if (!ieee80211_vif_is_mesh(&sdata->vif))
2554 goto invalid; 2545 goto invalid;
2555 if (sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE) 2546 if (sdata->u.mesh.user_mpm)
2556 /* userspace handles this frame */ 2547 /* userspace handles this frame */
2557 break; 2548 break;
2558 goto queue; 2549 goto queue;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index a79ce820cb50..3644ad79688a 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -342,6 +342,11 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
342 INIT_WORK(&sta->drv_unblock_wk, sta_unblock); 342 INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
343 INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); 343 INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
344 mutex_init(&sta->ampdu_mlme.mtx); 344 mutex_init(&sta->ampdu_mlme.mtx);
345#ifdef CONFIG_MAC80211_MESH
346 if (ieee80211_vif_is_mesh(&sdata->vif) &&
347 !sdata->u.mesh.user_mpm)
348 init_timer(&sta->plink_timer);
349#endif
345 350
346 memcpy(sta->sta.addr, addr, ETH_ALEN); 351 memcpy(sta->sta.addr, addr, ETH_ALEN);
347 sta->local = local; 352 sta->local = local;
@@ -794,9 +799,11 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
794 799
795 mutex_lock(&local->key_mtx); 800 mutex_lock(&local->key_mtx);
796 for (i = 0; i < NUM_DEFAULT_KEYS; i++) 801 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
797 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i])); 802 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]),
803 true);
798 if (sta->ptk) 804 if (sta->ptk)
799 __ieee80211_key_free(key_mtx_dereference(local, sta->ptk)); 805 __ieee80211_key_free(key_mtx_dereference(local, sta->ptk),
806 true);
800 mutex_unlock(&local->key_mtx); 807 mutex_unlock(&local->key_mtx);
801 808
802 sta->dead = true; 809 sta->dead = true;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 4947341a2a82..e5868c32d1a3 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -281,7 +281,6 @@ struct sta_ampdu_mlme {
281 * @plink_state: peer link state 281 * @plink_state: peer link state
282 * @plink_timeout: timeout of peer link 282 * @plink_timeout: timeout of peer link
283 * @plink_timer: peer link watch timer 283 * @plink_timer: peer link watch timer
284 * @plink_timer_was_running: used by suspend/resume to restore timers
285 * @t_offset: timing offset relative to this host 284 * @t_offset: timing offset relative to this host
286 * @t_offset_setpoint: reference timing offset of this sta to be used when 285 * @t_offset_setpoint: reference timing offset of this sta to be used when
287 * calculating clockdrift 286 * calculating clockdrift
@@ -379,7 +378,6 @@ struct sta_info {
379 __le16 reason; 378 __le16 reason;
380 u8 plink_retries; 379 u8 plink_retries;
381 bool ignore_plink_timer; 380 bool ignore_plink_timer;
382 bool plink_timer_was_running;
383 enum nl80211_plink_state plink_state; 381 enum nl80211_plink_state plink_state;
384 u32 plink_timeout; 382 u32 plink_timeout;
385 struct timer_list plink_timer; 383 struct timer_list plink_timer;
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 3d7cd2a0582f..e7db2b804e0c 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1042,15 +1042,17 @@ TRACE_EVENT(drv_remain_on_channel,
1042 TP_PROTO(struct ieee80211_local *local, 1042 TP_PROTO(struct ieee80211_local *local,
1043 struct ieee80211_sub_if_data *sdata, 1043 struct ieee80211_sub_if_data *sdata,
1044 struct ieee80211_channel *chan, 1044 struct ieee80211_channel *chan,
1045 unsigned int duration), 1045 unsigned int duration,
1046 enum ieee80211_roc_type type),
1046 1047
1047 TP_ARGS(local, sdata, chan, duration), 1048 TP_ARGS(local, sdata, chan, duration, type),
1048 1049
1049 TP_STRUCT__entry( 1050 TP_STRUCT__entry(
1050 LOCAL_ENTRY 1051 LOCAL_ENTRY
1051 VIF_ENTRY 1052 VIF_ENTRY
1052 __field(int, center_freq) 1053 __field(int, center_freq)
1053 __field(unsigned int, duration) 1054 __field(unsigned int, duration)
1055 __field(u32, type)
1054 ), 1056 ),
1055 1057
1056 TP_fast_assign( 1058 TP_fast_assign(
@@ -1058,12 +1060,13 @@ TRACE_EVENT(drv_remain_on_channel,
1058 VIF_ASSIGN; 1060 VIF_ASSIGN;
1059 __entry->center_freq = chan->center_freq; 1061 __entry->center_freq = chan->center_freq;
1060 __entry->duration = duration; 1062 __entry->duration = duration;
1063 __entry->type = type;
1061 ), 1064 ),
1062 1065
1063 TP_printk( 1066 TP_printk(
1064 LOCAL_PR_FMT VIF_PR_FMT " freq:%dMHz duration:%dms", 1067 LOCAL_PR_FMT VIF_PR_FMT " freq:%dMHz duration:%dms type=%d",
1065 LOCAL_PR_ARG, VIF_PR_ARG, 1068 LOCAL_PR_ARG, VIF_PR_ARG,
1066 __entry->center_freq, __entry->duration 1069 __entry->center_freq, __entry->duration, __entry->type
1067 ) 1070 )
1068); 1071);
1069 1072
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 0f38f43ac62e..b7a856e3281b 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1357,6 +1357,25 @@ void ieee80211_stop_device(struct ieee80211_local *local)
1357 drv_stop(local); 1357 drv_stop(local);
1358} 1358}
1359 1359
1360static void ieee80211_assign_chanctx(struct ieee80211_local *local,
1361 struct ieee80211_sub_if_data *sdata)
1362{
1363 struct ieee80211_chanctx_conf *conf;
1364 struct ieee80211_chanctx *ctx;
1365
1366 if (!local->use_chanctx)
1367 return;
1368
1369 mutex_lock(&local->chanctx_mtx);
1370 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1371 lockdep_is_held(&local->chanctx_mtx));
1372 if (conf) {
1373 ctx = container_of(conf, struct ieee80211_chanctx, conf);
1374 drv_assign_vif_chanctx(local, sdata, ctx);
1375 }
1376 mutex_unlock(&local->chanctx_mtx);
1377}
1378
1360int ieee80211_reconfig(struct ieee80211_local *local) 1379int ieee80211_reconfig(struct ieee80211_local *local)
1361{ 1380{
1362 struct ieee80211_hw *hw = &local->hw; 1381 struct ieee80211_hw *hw = &local->hw;
@@ -1445,36 +1464,14 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1445 } 1464 }
1446 1465
1447 list_for_each_entry(sdata, &local->interfaces, list) { 1466 list_for_each_entry(sdata, &local->interfaces, list) {
1448 struct ieee80211_chanctx_conf *ctx_conf;
1449
1450 if (!ieee80211_sdata_running(sdata)) 1467 if (!ieee80211_sdata_running(sdata))
1451 continue; 1468 continue;
1452 1469 ieee80211_assign_chanctx(local, sdata);
1453 mutex_lock(&local->chanctx_mtx);
1454 ctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1455 lockdep_is_held(&local->chanctx_mtx));
1456 if (ctx_conf) {
1457 ctx = container_of(ctx_conf, struct ieee80211_chanctx,
1458 conf);
1459 drv_assign_vif_chanctx(local, sdata, ctx);
1460 }
1461 mutex_unlock(&local->chanctx_mtx);
1462 } 1470 }
1463 1471
1464 sdata = rtnl_dereference(local->monitor_sdata); 1472 sdata = rtnl_dereference(local->monitor_sdata);
1465 if (sdata && local->use_chanctx && ieee80211_sdata_running(sdata)) { 1473 if (sdata && ieee80211_sdata_running(sdata))
1466 struct ieee80211_chanctx_conf *ctx_conf; 1474 ieee80211_assign_chanctx(local, sdata);
1467
1468 mutex_lock(&local->chanctx_mtx);
1469 ctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1470 lockdep_is_held(&local->chanctx_mtx));
1471 if (ctx_conf) {
1472 ctx = container_of(ctx_conf, struct ieee80211_chanctx,
1473 conf);
1474 drv_assign_vif_chanctx(local, sdata, ctx);
1475 }
1476 mutex_unlock(&local->chanctx_mtx);
1477 }
1478 1475
1479 /* add STAs back */ 1476 /* add STAs back */
1480 mutex_lock(&local->sta_mtx); 1477 mutex_lock(&local->sta_mtx);
@@ -1534,11 +1531,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1534 BSS_CHANGED_IDLE | 1531 BSS_CHANGED_IDLE |
1535 BSS_CHANGED_TXPOWER; 1532 BSS_CHANGED_TXPOWER;
1536 1533
1537#ifdef CONFIG_PM
1538 if (local->resuming && !reconfig_due_to_wowlan)
1539 sdata->vif.bss_conf = sdata->suspend_bss_conf;
1540#endif
1541
1542 switch (sdata->vif.type) { 1534 switch (sdata->vif.type) {
1543 case NL80211_IFTYPE_STATION: 1535 case NL80211_IFTYPE_STATION:
1544 changed |= BSS_CHANGED_ASSOC | 1536 changed |= BSS_CHANGED_ASSOC |
@@ -1678,28 +1670,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1678 mb(); 1670 mb();
1679 local->resuming = false; 1671 local->resuming = false;
1680 1672
1681 list_for_each_entry(sdata, &local->interfaces, list) {
1682 switch(sdata->vif.type) {
1683 case NL80211_IFTYPE_STATION:
1684 ieee80211_sta_restart(sdata);
1685 break;
1686 case NL80211_IFTYPE_ADHOC:
1687 ieee80211_ibss_restart(sdata);
1688 break;
1689 case NL80211_IFTYPE_MESH_POINT:
1690 ieee80211_mesh_restart(sdata);
1691 break;
1692 default:
1693 break;
1694 }
1695 }
1696
1697 mod_timer(&local->sta_cleanup, jiffies + 1); 1673 mod_timer(&local->sta_cleanup, jiffies + 1);
1698
1699 mutex_lock(&local->sta_mtx);
1700 list_for_each_entry(sta, &local->sta_list, list)
1701 mesh_plink_restart(sta);
1702 mutex_unlock(&local->sta_mtx);
1703#else 1674#else
1704 WARN_ON(1); 1675 WARN_ON(1);
1705#endif 1676#endif
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index a2c2258bc84e..171344d4eb7c 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -13,6 +13,104 @@
13#include "rate.h" 13#include "rate.h"
14 14
15 15
16static void __check_vhtcap_disable(struct ieee80211_sub_if_data *sdata,
17 struct ieee80211_sta_vht_cap *vht_cap,
18 u32 flag)
19{
20 __le32 le_flag = cpu_to_le32(flag);
21
22 if (sdata->u.mgd.vht_capa_mask.vht_cap_info & le_flag &&
23 !(sdata->u.mgd.vht_capa.vht_cap_info & le_flag))
24 vht_cap->cap &= ~flag;
25}
26
27void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
28 struct ieee80211_sta_vht_cap *vht_cap)
29{
30 int i;
31 u16 rxmcs_mask, rxmcs_cap, rxmcs_n, txmcs_mask, txmcs_cap, txmcs_n;
32
33 if (!vht_cap->vht_supported)
34 return;
35
36 if (sdata->vif.type != NL80211_IFTYPE_STATION)
37 return;
38
39 __check_vhtcap_disable(sdata, vht_cap,
40 IEEE80211_VHT_CAP_RXLDPC);
41 __check_vhtcap_disable(sdata, vht_cap,
42 IEEE80211_VHT_CAP_SHORT_GI_80);
43 __check_vhtcap_disable(sdata, vht_cap,
44 IEEE80211_VHT_CAP_SHORT_GI_160);
45 __check_vhtcap_disable(sdata, vht_cap,
46 IEEE80211_VHT_CAP_TXSTBC);
47 __check_vhtcap_disable(sdata, vht_cap,
48 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
49 __check_vhtcap_disable(sdata, vht_cap,
50 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);
51 __check_vhtcap_disable(sdata, vht_cap,
52 IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN);
53 __check_vhtcap_disable(sdata, vht_cap,
54 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN);
55
56 /* Allow user to decrease AMPDU length exponent */
57 if (sdata->u.mgd.vht_capa_mask.vht_cap_info &
58 cpu_to_le32(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK)) {
59 u32 cap, n;
60
61 n = le32_to_cpu(sdata->u.mgd.vht_capa.vht_cap_info) &
62 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
63 n >>= IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
64 cap = vht_cap->cap & IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
65 cap >>= IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
66
67 if (n < cap) {
68 vht_cap->cap &=
69 ~IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
70 vht_cap->cap |=
71 n << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
72 }
73 }
74
75 /* Allow the user to decrease MCSes */
76 rxmcs_mask =
77 le16_to_cpu(sdata->u.mgd.vht_capa_mask.supp_mcs.rx_mcs_map);
78 rxmcs_n = le16_to_cpu(sdata->u.mgd.vht_capa.supp_mcs.rx_mcs_map);
79 rxmcs_n &= rxmcs_mask;
80 rxmcs_cap = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
81
82 txmcs_mask =
83 le16_to_cpu(sdata->u.mgd.vht_capa_mask.supp_mcs.tx_mcs_map);
84 txmcs_n = le16_to_cpu(sdata->u.mgd.vht_capa.supp_mcs.tx_mcs_map);
85 txmcs_n &= txmcs_mask;
86 txmcs_cap = le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
87 for (i = 0; i < 8; i++) {
88 u8 m, n, c;
89
90 m = (rxmcs_mask >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
91 n = (rxmcs_n >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
92 c = (rxmcs_cap >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
93
94 if (m && ((c != IEEE80211_VHT_MCS_NOT_SUPPORTED && n < c) ||
95 n == IEEE80211_VHT_MCS_NOT_SUPPORTED)) {
96 rxmcs_cap &= ~(3 << 2*i);
97 rxmcs_cap |= (rxmcs_n & (3 << 2*i));
98 }
99
100 m = (txmcs_mask >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
101 n = (txmcs_n >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
102 c = (txmcs_cap >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
103
104 if (m && ((c != IEEE80211_VHT_MCS_NOT_SUPPORTED && n < c) ||
105 n == IEEE80211_VHT_MCS_NOT_SUPPORTED)) {
106 txmcs_cap &= ~(3 << 2*i);
107 txmcs_cap |= (txmcs_n & (3 << 2*i));
108 }
109 }
110 vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(rxmcs_cap);
111 vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(txmcs_cap);
112}
113
16void 114void
17ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, 115ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
18 struct ieee80211_supported_band *sband, 116 struct ieee80211_supported_band *sband,
@@ -20,6 +118,8 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
20 struct sta_info *sta) 118 struct sta_info *sta)
21{ 119{
22 struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap; 120 struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
121 struct ieee80211_sta_vht_cap own_cap;
122 u32 cap_info, i;
23 123
24 memset(vht_cap, 0, sizeof(*vht_cap)); 124 memset(vht_cap, 0, sizeof(*vht_cap));
25 125
@@ -35,12 +135,122 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
35 135
36 vht_cap->vht_supported = true; 136 vht_cap->vht_supported = true;
37 137
38 vht_cap->cap = le32_to_cpu(vht_cap_ie->vht_cap_info); 138 own_cap = sband->vht_cap;
139 /*
140 * If user has specified capability overrides, take care
141 * of that if the station we're setting up is the AP that
142 * we advertised a restricted capability set to. Override
143 * our own capabilities and then use those below.
144 */
145 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
146 !test_sta_flag(sta, WLAN_STA_TDLS_PEER))
147 ieee80211_apply_vhtcap_overrides(sdata, &own_cap);
148
149 /* take some capabilities as-is */
150 cap_info = le32_to_cpu(vht_cap_ie->vht_cap_info);
151 vht_cap->cap = cap_info;
152 vht_cap->cap &= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 |
153 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
154 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
155 IEEE80211_VHT_CAP_RXLDPC |
156 IEEE80211_VHT_CAP_VHT_TXOP_PS |
157 IEEE80211_VHT_CAP_HTC_VHT |
158 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
159 IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB |
160 IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB |
161 IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
162 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
163
164 /* and some based on our own capabilities */
165 switch (own_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
166 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
167 vht_cap->cap |= cap_info &
168 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
169 break;
170 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
171 vht_cap->cap |= cap_info &
172 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
173 break;
174 default:
175 /* nothing */
176 break;
177 }
178
179 /* symmetric capabilities */
180 vht_cap->cap |= cap_info & own_cap.cap &
181 (IEEE80211_VHT_CAP_SHORT_GI_80 |
182 IEEE80211_VHT_CAP_SHORT_GI_160);
183
184 /* remaining ones */
185 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) {
186 vht_cap->cap |= cap_info &
187 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
188 IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX |
189 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX);
190 }
191
192 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
193 vht_cap->cap |= cap_info &
194 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
195
196 if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
197 vht_cap->cap |= cap_info &
198 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
199
200 if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
201 vht_cap->cap |= cap_info &
202 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
203
204 if (own_cap.cap & IEEE80211_VHT_CAP_TXSTBC)
205 vht_cap->cap |= cap_info & IEEE80211_VHT_CAP_RXSTBC_MASK;
206
207 if (own_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
208 vht_cap->cap |= cap_info & IEEE80211_VHT_CAP_TXSTBC;
39 209
40 /* Copy peer MCS info, the driver might need them. */ 210 /* Copy peer MCS info, the driver might need them. */
41 memcpy(&vht_cap->vht_mcs, &vht_cap_ie->supp_mcs, 211 memcpy(&vht_cap->vht_mcs, &vht_cap_ie->supp_mcs,
42 sizeof(struct ieee80211_vht_mcs_info)); 212 sizeof(struct ieee80211_vht_mcs_info));
43 213
214 /* but also restrict MCSes */
215 for (i = 0; i < 8; i++) {
216 u16 own_rx, own_tx, peer_rx, peer_tx;
217
218 own_rx = le16_to_cpu(own_cap.vht_mcs.rx_mcs_map);
219 own_rx = (own_rx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
220
221 own_tx = le16_to_cpu(own_cap.vht_mcs.tx_mcs_map);
222 own_tx = (own_tx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
223
224 peer_rx = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
225 peer_rx = (peer_rx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
226
227 peer_tx = le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
228 peer_tx = (peer_tx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
229
230 if (peer_tx != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
231 if (own_rx == IEEE80211_VHT_MCS_NOT_SUPPORTED)
232 peer_tx = IEEE80211_VHT_MCS_NOT_SUPPORTED;
233 else if (own_rx < peer_tx)
234 peer_tx = own_rx;
235 }
236
237 if (peer_rx != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
238 if (own_tx == IEEE80211_VHT_MCS_NOT_SUPPORTED)
239 peer_rx = IEEE80211_VHT_MCS_NOT_SUPPORTED;
240 else if (own_tx < peer_rx)
241 peer_rx = own_tx;
242 }
243
244 vht_cap->vht_mcs.rx_mcs_map &=
245 ~cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << i * 2);
246 vht_cap->vht_mcs.rx_mcs_map |= cpu_to_le16(peer_rx << i * 2);
247
248 vht_cap->vht_mcs.tx_mcs_map &=
249 ~cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << i * 2);
250 vht_cap->vht_mcs.tx_mcs_map |= cpu_to_le16(peer_tx << i * 2);
251 }
252
253 /* finally set up the bandwidth */
44 switch (vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) { 254 switch (vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
45 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ: 255 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
46 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ: 256 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c
index c6bc3bd95052..b75a9b3f9e89 100644
--- a/net/nfc/llcp/commands.c
+++ b/net/nfc/llcp/commands.c
@@ -117,6 +117,88 @@ u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length)
117 return tlv; 117 return tlv;
118} 118}
119 119
120struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap)
121{
122 struct nfc_llcp_sdp_tlv *sdres;
123 u8 value[2];
124
125 sdres = kzalloc(sizeof(struct nfc_llcp_sdp_tlv), GFP_KERNEL);
126 if (sdres == NULL)
127 return NULL;
128
129 value[0] = tid;
130 value[1] = sap;
131
132 sdres->tlv = nfc_llcp_build_tlv(LLCP_TLV_SDRES, value, 2,
133 &sdres->tlv_len);
134 if (sdres->tlv == NULL) {
135 kfree(sdres);
136 return NULL;
137 }
138
139 sdres->tid = tid;
140 sdres->sap = sap;
141
142 INIT_HLIST_NODE(&sdres->node);
143
144 return sdres;
145}
146
147struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
148 size_t uri_len)
149{
150 struct nfc_llcp_sdp_tlv *sdreq;
151
152 pr_debug("uri: %s, len: %zu\n", uri, uri_len);
153
154 sdreq = kzalloc(sizeof(struct nfc_llcp_sdp_tlv), GFP_KERNEL);
155 if (sdreq == NULL)
156 return NULL;
157
158 sdreq->tlv_len = uri_len + 3;
159
160 if (uri[uri_len - 1] == 0)
161 sdreq->tlv_len--;
162
163 sdreq->tlv = kzalloc(sdreq->tlv_len + 1, GFP_KERNEL);
164 if (sdreq->tlv == NULL) {
165 kfree(sdreq);
166 return NULL;
167 }
168
169 sdreq->tlv[0] = LLCP_TLV_SDREQ;
170 sdreq->tlv[1] = sdreq->tlv_len - 2;
171 sdreq->tlv[2] = tid;
172
173 sdreq->tid = tid;
174 sdreq->uri = sdreq->tlv + 3;
175 memcpy(sdreq->uri, uri, uri_len);
176
177 sdreq->time = jiffies;
178
179 INIT_HLIST_NODE(&sdreq->node);
180
181 return sdreq;
182}
183
184void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp)
185{
186 kfree(sdp->tlv);
187 kfree(sdp);
188}
189
190void nfc_llcp_free_sdp_tlv_list(struct hlist_head *head)
191{
192 struct nfc_llcp_sdp_tlv *sdp;
193 struct hlist_node *n;
194
195 hlist_for_each_entry_safe(sdp, n, head, node) {
196 hlist_del(&sdp->node);
197
198 nfc_llcp_free_sdp_tlv(sdp);
199 }
200}
201
120int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local, 202int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
121 u8 *tlv_array, u16 tlv_array_len) 203 u8 *tlv_array, u16 tlv_array_len)
122{ 204{
@@ -184,10 +266,10 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
184 266
185 switch (type) { 267 switch (type) {
186 case LLCP_TLV_MIUX: 268 case LLCP_TLV_MIUX:
187 sock->miu = llcp_tlv_miux(tlv) + 128; 269 sock->remote_miu = llcp_tlv_miux(tlv) + 128;
188 break; 270 break;
189 case LLCP_TLV_RW: 271 case LLCP_TLV_RW:
190 sock->rw = llcp_tlv_rw(tlv); 272 sock->remote_rw = llcp_tlv_rw(tlv);
191 break; 273 break;
192 case LLCP_TLV_SN: 274 case LLCP_TLV_SN:
193 break; 275 break;
@@ -200,7 +282,8 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
200 tlv += length + 2; 282 tlv += length + 2;
201 } 283 }
202 284
203 pr_debug("sock %p rw %d miu %d\n", sock, sock->rw, sock->miu); 285 pr_debug("sock %p rw %d miu %d\n", sock,
286 sock->remote_rw, sock->remote_miu);
204 287
205 return 0; 288 return 0;
206} 289}
@@ -318,9 +401,9 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
318 struct sk_buff *skb; 401 struct sk_buff *skb;
319 u8 *service_name_tlv = NULL, service_name_tlv_length; 402 u8 *service_name_tlv = NULL, service_name_tlv_length;
320 u8 *miux_tlv = NULL, miux_tlv_length; 403 u8 *miux_tlv = NULL, miux_tlv_length;
321 u8 *rw_tlv = NULL, rw_tlv_length; 404 u8 *rw_tlv = NULL, rw_tlv_length, rw;
322 int err; 405 int err;
323 u16 size = 0; 406 u16 size = 0, miux;
324 407
325 pr_debug("Sending CONNECT\n"); 408 pr_debug("Sending CONNECT\n");
326 409
@@ -336,11 +419,15 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
336 size += service_name_tlv_length; 419 size += service_name_tlv_length;
337 } 420 }
338 421
339 miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, 422 /* If the socket parameters are not set, use the local ones */
423 miux = sock->miux > LLCP_MAX_MIUX ? local->miux : sock->miux;
424 rw = sock->rw > LLCP_MAX_RW ? local->rw : sock->rw;
425
426 miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
340 &miux_tlv_length); 427 &miux_tlv_length);
341 size += miux_tlv_length; 428 size += miux_tlv_length;
342 429
343 rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &local->rw, 0, &rw_tlv_length); 430 rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length);
344 size += rw_tlv_length; 431 size += rw_tlv_length;
345 432
346 pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); 433 pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len);
@@ -377,9 +464,9 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
377 struct nfc_llcp_local *local; 464 struct nfc_llcp_local *local;
378 struct sk_buff *skb; 465 struct sk_buff *skb;
379 u8 *miux_tlv = NULL, miux_tlv_length; 466 u8 *miux_tlv = NULL, miux_tlv_length;
380 u8 *rw_tlv = NULL, rw_tlv_length; 467 u8 *rw_tlv = NULL, rw_tlv_length, rw;
381 int err; 468 int err;
382 u16 size = 0; 469 u16 size = 0, miux;
383 470
384 pr_debug("Sending CC\n"); 471 pr_debug("Sending CC\n");
385 472
@@ -387,11 +474,15 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
387 if (local == NULL) 474 if (local == NULL)
388 return -ENODEV; 475 return -ENODEV;
389 476
390 miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, 477 /* If the socket parameters are not set, use the local ones */
478 miux = sock->miux > LLCP_MAX_MIUX ? local->miux : sock->miux;
479 rw = sock->rw > LLCP_MAX_RW ? local->rw : sock->rw;
480
481 miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
391 &miux_tlv_length); 482 &miux_tlv_length);
392 size += miux_tlv_length; 483 size += miux_tlv_length;
393 484
394 rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &local->rw, 0, &rw_tlv_length); 485 rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length);
395 size += rw_tlv_length; 486 size += rw_tlv_length;
396 487
397 skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size); 488 skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size);
@@ -416,48 +507,90 @@ error_tlv:
416 return err; 507 return err;
417} 508}
418 509
419int nfc_llcp_send_snl(struct nfc_llcp_local *local, u8 tid, u8 sap) 510static struct sk_buff *nfc_llcp_allocate_snl(struct nfc_llcp_local *local,
511 size_t tlv_length)
420{ 512{
421 struct sk_buff *skb; 513 struct sk_buff *skb;
422 struct nfc_dev *dev; 514 struct nfc_dev *dev;
423 u8 *sdres_tlv = NULL, sdres_tlv_length, sdres[2];
424 u16 size = 0; 515 u16 size = 0;
425 516
426 pr_debug("Sending SNL tid 0x%x sap 0x%x\n", tid, sap);
427
428 if (local == NULL) 517 if (local == NULL)
429 return -ENODEV; 518 return ERR_PTR(-ENODEV);
430 519
431 dev = local->dev; 520 dev = local->dev;
432 if (dev == NULL) 521 if (dev == NULL)
433 return -ENODEV; 522 return ERR_PTR(-ENODEV);
434
435 sdres[0] = tid;
436 sdres[1] = sap;
437 sdres_tlv = nfc_llcp_build_tlv(LLCP_TLV_SDRES, sdres, 0,
438 &sdres_tlv_length);
439 if (sdres_tlv == NULL)
440 return -ENOMEM;
441 523
442 size += LLCP_HEADER_SIZE; 524 size += LLCP_HEADER_SIZE;
443 size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE; 525 size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
444 size += sdres_tlv_length; 526 size += tlv_length;
445 527
446 skb = alloc_skb(size, GFP_KERNEL); 528 skb = alloc_skb(size, GFP_KERNEL);
447 if (skb == NULL) { 529 if (skb == NULL)
448 kfree(sdres_tlv); 530 return ERR_PTR(-ENOMEM);
449 return -ENOMEM;
450 }
451 531
452 skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE); 532 skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
453 533
454 skb = llcp_add_header(skb, LLCP_SAP_SDP, LLCP_SAP_SDP, LLCP_PDU_SNL); 534 skb = llcp_add_header(skb, LLCP_SAP_SDP, LLCP_SAP_SDP, LLCP_PDU_SNL);
455 535
456 memcpy(skb_put(skb, sdres_tlv_length), sdres_tlv, sdres_tlv_length); 536 return skb;
537}
538
539int nfc_llcp_send_snl_sdres(struct nfc_llcp_local *local,
540 struct hlist_head *tlv_list, size_t tlvs_len)
541{
542 struct nfc_llcp_sdp_tlv *sdp;
543 struct hlist_node *n;
544 struct sk_buff *skb;
545
546 skb = nfc_llcp_allocate_snl(local, tlvs_len);
547 if (IS_ERR(skb))
548 return PTR_ERR(skb);
549
550 hlist_for_each_entry_safe(sdp, n, tlv_list, node) {
551 memcpy(skb_put(skb, sdp->tlv_len), sdp->tlv, sdp->tlv_len);
552
553 hlist_del(&sdp->node);
554
555 nfc_llcp_free_sdp_tlv(sdp);
556 }
457 557
458 skb_queue_tail(&local->tx_queue, skb); 558 skb_queue_tail(&local->tx_queue, skb);
459 559
460 kfree(sdres_tlv); 560 return 0;
561}
562
563int nfc_llcp_send_snl_sdreq(struct nfc_llcp_local *local,
564 struct hlist_head *tlv_list, size_t tlvs_len)
565{
566 struct nfc_llcp_sdp_tlv *sdreq;
567 struct hlist_node *n;
568 struct sk_buff *skb;
569
570 skb = nfc_llcp_allocate_snl(local, tlvs_len);
571 if (IS_ERR(skb))
572 return PTR_ERR(skb);
573
574 mutex_lock(&local->sdreq_lock);
575
576 if (hlist_empty(&local->pending_sdreqs))
577 mod_timer(&local->sdreq_timer,
578 jiffies + msecs_to_jiffies(3 * local->remote_lto));
579
580 hlist_for_each_entry_safe(sdreq, n, tlv_list, node) {
581 pr_debug("tid %d for %s\n", sdreq->tid, sdreq->uri);
582
583 memcpy(skb_put(skb, sdreq->tlv_len), sdreq->tlv,
584 sdreq->tlv_len);
585
586 hlist_del(&sdreq->node);
587
588 hlist_add_head(&sdreq->node, &local->pending_sdreqs);
589 }
590
591 mutex_unlock(&local->sdreq_lock);
592
593 skb_queue_tail(&local->tx_queue, skb);
461 594
462 return 0; 595 return 0;
463} 596}
@@ -532,8 +665,8 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
532 665
533 /* Remote is ready but has not acknowledged our frames */ 666 /* Remote is ready but has not acknowledged our frames */
534 if((sock->remote_ready && 667 if((sock->remote_ready &&
535 skb_queue_len(&sock->tx_pending_queue) >= sock->rw && 668 skb_queue_len(&sock->tx_pending_queue) >= sock->remote_rw &&
536 skb_queue_len(&sock->tx_queue) >= 2 * sock->rw)) { 669 skb_queue_len(&sock->tx_queue) >= 2 * sock->remote_rw)) {
537 pr_err("Pending queue is full %d frames\n", 670 pr_err("Pending queue is full %d frames\n",
538 skb_queue_len(&sock->tx_pending_queue)); 671 skb_queue_len(&sock->tx_pending_queue));
539 return -ENOBUFS; 672 return -ENOBUFS;
@@ -541,7 +674,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
541 674
542 /* Remote is not ready and we've been queueing enough frames */ 675 /* Remote is not ready and we've been queueing enough frames */
543 if ((!sock->remote_ready && 676 if ((!sock->remote_ready &&
544 skb_queue_len(&sock->tx_queue) >= 2 * sock->rw)) { 677 skb_queue_len(&sock->tx_queue) >= 2 * sock->remote_rw)) {
545 pr_err("Tx queue is full %d frames\n", 678 pr_err("Tx queue is full %d frames\n",
546 skb_queue_len(&sock->tx_queue)); 679 skb_queue_len(&sock->tx_queue));
547 return -ENOBUFS; 680 return -ENOBUFS;
@@ -561,7 +694,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
561 694
562 while (remaining_len > 0) { 695 while (remaining_len > 0) {
563 696
564 frag_len = min_t(size_t, sock->miu, remaining_len); 697 frag_len = min_t(size_t, sock->remote_miu, remaining_len);
565 698
566 pr_debug("Fragment %zd bytes remaining %zd", 699 pr_debug("Fragment %zd bytes remaining %zd",
567 frag_len, remaining_len); 700 frag_len, remaining_len);
@@ -621,7 +754,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
621 754
622 while (remaining_len > 0) { 755 while (remaining_len > 0) {
623 756
624 frag_len = min_t(size_t, sock->miu, remaining_len); 757 frag_len = min_t(size_t, sock->remote_miu, remaining_len);
625 758
626 pr_debug("Fragment %zd bytes remaining %zd", 759 pr_debug("Fragment %zd bytes remaining %zd",
627 frag_len, remaining_len); 760 frag_len, remaining_len);
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index b530afadd76c..bb67b98b9797 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -188,6 +188,9 @@ static void local_cleanup(struct nfc_llcp_local *local, bool listen)
188 cancel_work_sync(&local->rx_work); 188 cancel_work_sync(&local->rx_work);
189 cancel_work_sync(&local->timeout_work); 189 cancel_work_sync(&local->timeout_work);
190 kfree_skb(local->rx_pending); 190 kfree_skb(local->rx_pending);
191 del_timer_sync(&local->sdreq_timer);
192 cancel_work_sync(&local->sdreq_timeout_work);
193 nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs);
191} 194}
192 195
193static void local_release(struct kref *ref) 196static void local_release(struct kref *ref)
@@ -265,6 +268,47 @@ static void nfc_llcp_symm_timer(unsigned long data)
265 schedule_work(&local->timeout_work); 268 schedule_work(&local->timeout_work);
266} 269}
267 270
271static void nfc_llcp_sdreq_timeout_work(struct work_struct *work)
272{
273 unsigned long time;
274 HLIST_HEAD(nl_sdres_list);
275 struct hlist_node *n;
276 struct nfc_llcp_sdp_tlv *sdp;
277 struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
278 sdreq_timeout_work);
279
280 mutex_lock(&local->sdreq_lock);
281
282 time = jiffies - msecs_to_jiffies(3 * local->remote_lto);
283
284 hlist_for_each_entry_safe(sdp, n, &local->pending_sdreqs, node) {
285 if (time_after(sdp->time, time))
286 continue;
287
288 sdp->sap = LLCP_SDP_UNBOUND;
289
290 hlist_del(&sdp->node);
291
292 hlist_add_head(&sdp->node, &nl_sdres_list);
293 }
294
295 if (!hlist_empty(&local->pending_sdreqs))
296 mod_timer(&local->sdreq_timer,
297 jiffies + msecs_to_jiffies(3 * local->remote_lto));
298
299 mutex_unlock(&local->sdreq_lock);
300
301 if (!hlist_empty(&nl_sdres_list))
302 nfc_genl_llc_send_sdres(local->dev, &nl_sdres_list);
303}
304
305static void nfc_llcp_sdreq_timer(unsigned long data)
306{
307 struct nfc_llcp_local *local = (struct nfc_llcp_local *) data;
308
309 schedule_work(&local->sdreq_timeout_work);
310}
311
268struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev) 312struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev)
269{ 313{
270 struct nfc_llcp_local *local, *n; 314 struct nfc_llcp_local *local, *n;
@@ -808,8 +852,6 @@ static void nfc_llcp_recv_ui(struct nfc_llcp_local *local,
808 ui_cb->dsap = dsap; 852 ui_cb->dsap = dsap;
809 ui_cb->ssap = ssap; 853 ui_cb->ssap = ssap;
810 854
811 printk("%s %d %d\n", __func__, dsap, ssap);
812
813 pr_debug("%d %d\n", dsap, ssap); 855 pr_debug("%d %d\n", dsap, ssap);
814 856
815 /* We're looking for a bound socket, not a client one */ 857 /* We're looking for a bound socket, not a client one */
@@ -907,7 +949,9 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
907 new_sock = nfc_llcp_sock(new_sk); 949 new_sock = nfc_llcp_sock(new_sk);
908 new_sock->dev = local->dev; 950 new_sock->dev = local->dev;
909 new_sock->local = nfc_llcp_local_get(local); 951 new_sock->local = nfc_llcp_local_get(local);
910 new_sock->miu = local->remote_miu; 952 new_sock->rw = sock->rw;
953 new_sock->miux = sock->miux;
954 new_sock->remote_miu = local->remote_miu;
911 new_sock->nfc_protocol = sock->nfc_protocol; 955 new_sock->nfc_protocol = sock->nfc_protocol;
912 new_sock->dsap = ssap; 956 new_sock->dsap = ssap;
913 new_sock->target_idx = local->target_idx; 957 new_sock->target_idx = local->target_idx;
@@ -961,11 +1005,11 @@ int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock)
961 1005
962 pr_debug("Remote ready %d tx queue len %d remote rw %d", 1006 pr_debug("Remote ready %d tx queue len %d remote rw %d",
963 sock->remote_ready, skb_queue_len(&sock->tx_pending_queue), 1007 sock->remote_ready, skb_queue_len(&sock->tx_pending_queue),
964 sock->rw); 1008 sock->remote_rw);
965 1009
966 /* Try to queue some I frames for transmission */ 1010 /* Try to queue some I frames for transmission */
967 while (sock->remote_ready && 1011 while (sock->remote_ready &&
968 skb_queue_len(&sock->tx_pending_queue) < sock->rw) { 1012 skb_queue_len(&sock->tx_pending_queue) < sock->remote_rw) {
969 struct sk_buff *pdu; 1013 struct sk_buff *pdu;
970 1014
971 pdu = skb_dequeue(&sock->tx_queue); 1015 pdu = skb_dequeue(&sock->tx_queue);
@@ -1186,6 +1230,10 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
1186 u16 tlv_len, offset; 1230 u16 tlv_len, offset;
1187 char *service_name; 1231 char *service_name;
1188 size_t service_name_len; 1232 size_t service_name_len;
1233 struct nfc_llcp_sdp_tlv *sdp;
1234 HLIST_HEAD(llc_sdres_list);
1235 size_t sdres_tlvs_len;
1236 HLIST_HEAD(nl_sdres_list);
1189 1237
1190 dsap = nfc_llcp_dsap(skb); 1238 dsap = nfc_llcp_dsap(skb);
1191 ssap = nfc_llcp_ssap(skb); 1239 ssap = nfc_llcp_ssap(skb);
@@ -1200,6 +1248,7 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
1200 tlv = &skb->data[LLCP_HEADER_SIZE]; 1248 tlv = &skb->data[LLCP_HEADER_SIZE];
1201 tlv_len = skb->len - LLCP_HEADER_SIZE; 1249 tlv_len = skb->len - LLCP_HEADER_SIZE;
1202 offset = 0; 1250 offset = 0;
1251 sdres_tlvs_len = 0;
1203 1252
1204 while (offset < tlv_len) { 1253 while (offset < tlv_len) {
1205 type = tlv[0]; 1254 type = tlv[0];
@@ -1217,14 +1266,14 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
1217 !strncmp(service_name, "urn:nfc:sn:sdp", 1266 !strncmp(service_name, "urn:nfc:sn:sdp",
1218 service_name_len)) { 1267 service_name_len)) {
1219 sap = 1; 1268 sap = 1;
1220 goto send_snl; 1269 goto add_snl;
1221 } 1270 }
1222 1271
1223 llcp_sock = nfc_llcp_sock_from_sn(local, service_name, 1272 llcp_sock = nfc_llcp_sock_from_sn(local, service_name,
1224 service_name_len); 1273 service_name_len);
1225 if (!llcp_sock) { 1274 if (!llcp_sock) {
1226 sap = 0; 1275 sap = 0;
1227 goto send_snl; 1276 goto add_snl;
1228 } 1277 }
1229 1278
1230 /* 1279 /*
@@ -1241,7 +1290,7 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
1241 1290
1242 if (sap == LLCP_SAP_MAX) { 1291 if (sap == LLCP_SAP_MAX) {
1243 sap = 0; 1292 sap = 0;
1244 goto send_snl; 1293 goto add_snl;
1245 } 1294 }
1246 1295
1247 client_count = 1296 client_count =
@@ -1258,8 +1307,37 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
1258 1307
1259 pr_debug("%p %d\n", llcp_sock, sap); 1308 pr_debug("%p %d\n", llcp_sock, sap);
1260 1309
1261send_snl: 1310add_snl:
1262 nfc_llcp_send_snl(local, tid, sap); 1311 sdp = nfc_llcp_build_sdres_tlv(tid, sap);
1312 if (sdp == NULL)
1313 goto exit;
1314
1315 sdres_tlvs_len += sdp->tlv_len;
1316 hlist_add_head(&sdp->node, &llc_sdres_list);
1317 break;
1318
1319 case LLCP_TLV_SDRES:
1320 mutex_lock(&local->sdreq_lock);
1321
1322 pr_debug("LLCP_TLV_SDRES: searching tid %d\n", tlv[2]);
1323
1324 hlist_for_each_entry(sdp, &local->pending_sdreqs, node) {
1325 if (sdp->tid != tlv[2])
1326 continue;
1327
1328 sdp->sap = tlv[3];
1329
1330 pr_debug("Found: uri=%s, sap=%d\n",
1331 sdp->uri, sdp->sap);
1332
1333 hlist_del(&sdp->node);
1334
1335 hlist_add_head(&sdp->node, &nl_sdres_list);
1336
1337 break;
1338 }
1339
1340 mutex_unlock(&local->sdreq_lock);
1263 break; 1341 break;
1264 1342
1265 default: 1343 default:
@@ -1270,6 +1348,13 @@ send_snl:
1270 offset += length + 2; 1348 offset += length + 2;
1271 tlv += length + 2; 1349 tlv += length + 2;
1272 } 1350 }
1351
1352exit:
1353 if (!hlist_empty(&nl_sdres_list))
1354 nfc_genl_llc_send_sdres(local->dev, &nl_sdres_list);
1355
1356 if (!hlist_empty(&llc_sdres_list))
1357 nfc_llcp_send_snl_sdres(local, &llc_sdres_list, sdres_tlvs_len);
1273} 1358}
1274 1359
1275static void nfc_llcp_rx_work(struct work_struct *work) 1360static void nfc_llcp_rx_work(struct work_struct *work)
@@ -1455,6 +1540,13 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
1455 local->remote_miu = LLCP_DEFAULT_MIU; 1540 local->remote_miu = LLCP_DEFAULT_MIU;
1456 local->remote_lto = LLCP_DEFAULT_LTO; 1541 local->remote_lto = LLCP_DEFAULT_LTO;
1457 1542
1543 mutex_init(&local->sdreq_lock);
1544 INIT_HLIST_HEAD(&local->pending_sdreqs);
1545 init_timer(&local->sdreq_timer);
1546 local->sdreq_timer.data = (unsigned long) local;
1547 local->sdreq_timer.function = nfc_llcp_sdreq_timer;
1548 INIT_WORK(&local->sdreq_timeout_work, nfc_llcp_sdreq_timeout_work);
1549
1458 list_add(&local->list, &llcp_devices); 1550 list_add(&local->list, &llcp_devices);
1459 1551
1460 return 0; 1552 return 0;
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h
index 0eae5c509504..7e87a66b02ec 100644
--- a/net/nfc/llcp/llcp.h
+++ b/net/nfc/llcp/llcp.h
@@ -46,6 +46,19 @@ struct llcp_sock_list {
46 rwlock_t lock; 46 rwlock_t lock;
47}; 47};
48 48
49struct nfc_llcp_sdp_tlv {
50 u8 *tlv;
51 u8 tlv_len;
52
53 char *uri;
54 u8 tid;
55 u8 sap;
56
57 unsigned long time;
58
59 struct hlist_node node;
60};
61
49struct nfc_llcp_local { 62struct nfc_llcp_local {
50 struct list_head list; 63 struct list_head list;
51 struct nfc_dev *dev; 64 struct nfc_dev *dev;
@@ -86,6 +99,12 @@ struct nfc_llcp_local {
86 u8 remote_opt; 99 u8 remote_opt;
87 u16 remote_wks; 100 u16 remote_wks;
88 101
102 struct mutex sdreq_lock;
103 struct hlist_head pending_sdreqs;
104 struct timer_list sdreq_timer;
105 struct work_struct sdreq_timeout_work;
106 u8 sdreq_next_tid;
107
89 /* sockets array */ 108 /* sockets array */
90 struct llcp_sock_list sockets; 109 struct llcp_sock_list sockets;
91 struct llcp_sock_list connecting_sockets; 110 struct llcp_sock_list connecting_sockets;
@@ -105,7 +124,12 @@ struct nfc_llcp_sock {
105 char *service_name; 124 char *service_name;
106 size_t service_name_len; 125 size_t service_name_len;
107 u8 rw; 126 u8 rw;
108 u16 miu; 127 u16 miux;
128
129
130 /* Remote link parameters */
131 u8 remote_rw;
132 u16 remote_miu;
109 133
110 /* Link variables */ 134 /* Link variables */
111 u8 send_n; 135 u8 send_n;
@@ -213,12 +237,20 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
213/* Commands API */ 237/* Commands API */
214void nfc_llcp_recv(void *data, struct sk_buff *skb, int err); 238void nfc_llcp_recv(void *data, struct sk_buff *skb, int err);
215u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length); 239u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length);
240struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap);
241struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
242 size_t uri_len);
243void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
244void nfc_llcp_free_sdp_tlv_list(struct hlist_head *sdp_head);
216void nfc_llcp_recv(void *data, struct sk_buff *skb, int err); 245void nfc_llcp_recv(void *data, struct sk_buff *skb, int err);
217int nfc_llcp_disconnect(struct nfc_llcp_sock *sock); 246int nfc_llcp_disconnect(struct nfc_llcp_sock *sock);
218int nfc_llcp_send_symm(struct nfc_dev *dev); 247int nfc_llcp_send_symm(struct nfc_dev *dev);
219int nfc_llcp_send_connect(struct nfc_llcp_sock *sock); 248int nfc_llcp_send_connect(struct nfc_llcp_sock *sock);
220int nfc_llcp_send_cc(struct nfc_llcp_sock *sock); 249int nfc_llcp_send_cc(struct nfc_llcp_sock *sock);
221int nfc_llcp_send_snl(struct nfc_llcp_local *local, u8 tid, u8 sap); 250int nfc_llcp_send_snl_sdres(struct nfc_llcp_local *local,
251 struct hlist_head *tlv_list, size_t tlvs_len);
252int nfc_llcp_send_snl_sdreq(struct nfc_llcp_local *local,
253 struct hlist_head *tlv_list, size_t tlvs_len);
222int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); 254int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason);
223int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); 255int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock);
224int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, 256int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index 5c7cdf3f2a83..f1b377e247fe 100644
--- a/net/nfc/llcp/sock.c
+++ b/net/nfc/llcp/sock.c
@@ -223,6 +223,124 @@ error:
223 return ret; 223 return ret;
224} 224}
225 225
226static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname,
227 char __user *optval, unsigned int optlen)
228{
229 struct sock *sk = sock->sk;
230 struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
231 u32 opt;
232 int err = 0;
233
234 pr_debug("%p optname %d\n", sk, optname);
235
236 if (level != SOL_NFC)
237 return -ENOPROTOOPT;
238
239 lock_sock(sk);
240
241 switch (optname) {
242 case NFC_LLCP_RW:
243 if (sk->sk_state == LLCP_CONNECTED ||
244 sk->sk_state == LLCP_BOUND ||
245 sk->sk_state == LLCP_LISTEN) {
246 err = -EINVAL;
247 break;
248 }
249
250 if (get_user(opt, (u32 __user *) optval)) {
251 err = -EFAULT;
252 break;
253 }
254
255 if (opt > LLCP_MAX_RW) {
256 err = -EINVAL;
257 break;
258 }
259
260 llcp_sock->rw = (u8) opt;
261
262 break;
263
264 case NFC_LLCP_MIUX:
265 if (sk->sk_state == LLCP_CONNECTED ||
266 sk->sk_state == LLCP_BOUND ||
267 sk->sk_state == LLCP_LISTEN) {
268 err = -EINVAL;
269 break;
270 }
271
272 if (get_user(opt, (u32 __user *) optval)) {
273 err = -EFAULT;
274 break;
275 }
276
277 if (opt > LLCP_MAX_MIUX) {
278 err = -EINVAL;
279 break;
280 }
281
282 llcp_sock->miux = (u16) opt;
283
284 break;
285
286 default:
287 err = -ENOPROTOOPT;
288 break;
289 }
290
291 release_sock(sk);
292
293 pr_debug("%p rw %d miux %d\n", llcp_sock,
294 llcp_sock->rw, llcp_sock->miux);
295
296 return err;
297}
298
299static int nfc_llcp_getsockopt(struct socket *sock, int level, int optname,
300 char __user *optval, int __user *optlen)
301{
302 struct sock *sk = sock->sk;
303 struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
304 int len, err = 0;
305
306 pr_debug("%p optname %d\n", sk, optname);
307
308 if (level != SOL_NFC)
309 return -ENOPROTOOPT;
310
311 if (get_user(len, optlen))
312 return -EFAULT;
313
314 len = min_t(u32, len, sizeof(u32));
315
316 lock_sock(sk);
317
318 switch (optname) {
319 case NFC_LLCP_RW:
320 if (put_user(llcp_sock->rw, (u32 __user *) optval))
321 err = -EFAULT;
322
323 break;
324
325 case NFC_LLCP_MIUX:
326 if (put_user(llcp_sock->miux, (u32 __user *) optval))
327 err = -EFAULT;
328
329 break;
330
331 default:
332 err = -ENOPROTOOPT;
333 break;
334 }
335
336 release_sock(sk);
337
338 if (put_user(len, optlen))
339 return -EFAULT;
340
341 return err;
342}
343
226void nfc_llcp_accept_unlink(struct sock *sk) 344void nfc_llcp_accept_unlink(struct sock *sk)
227{ 345{
228 struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); 346 struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
@@ -543,7 +661,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
543 661
544 llcp_sock->dev = dev; 662 llcp_sock->dev = dev;
545 llcp_sock->local = nfc_llcp_local_get(local); 663 llcp_sock->local = nfc_llcp_local_get(local);
546 llcp_sock->miu = llcp_sock->local->remote_miu; 664 llcp_sock->remote_miu = llcp_sock->local->remote_miu;
547 llcp_sock->ssap = nfc_llcp_get_local_ssap(local); 665 llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
548 if (llcp_sock->ssap == LLCP_SAP_MAX) { 666 if (llcp_sock->ssap == LLCP_SAP_MAX) {
549 ret = -ENOMEM; 667 ret = -ENOMEM;
@@ -737,8 +855,8 @@ static const struct proto_ops llcp_sock_ops = {
737 .ioctl = sock_no_ioctl, 855 .ioctl = sock_no_ioctl,
738 .listen = llcp_sock_listen, 856 .listen = llcp_sock_listen,
739 .shutdown = sock_no_shutdown, 857 .shutdown = sock_no_shutdown,
740 .setsockopt = sock_no_setsockopt, 858 .setsockopt = nfc_llcp_setsockopt,
741 .getsockopt = sock_no_getsockopt, 859 .getsockopt = nfc_llcp_getsockopt,
742 .sendmsg = llcp_sock_sendmsg, 860 .sendmsg = llcp_sock_sendmsg,
743 .recvmsg = llcp_sock_recvmsg, 861 .recvmsg = llcp_sock_recvmsg,
744 .mmap = sock_no_mmap, 862 .mmap = sock_no_mmap,
@@ -802,8 +920,10 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp)
802 920
803 llcp_sock->ssap = 0; 921 llcp_sock->ssap = 0;
804 llcp_sock->dsap = LLCP_SAP_SDP; 922 llcp_sock->dsap = LLCP_SAP_SDP;
805 llcp_sock->rw = LLCP_DEFAULT_RW; 923 llcp_sock->rw = LLCP_MAX_RW + 1;
806 llcp_sock->miu = LLCP_DEFAULT_MIU; 924 llcp_sock->miux = LLCP_MAX_MIUX + 1;
925 llcp_sock->remote_rw = LLCP_DEFAULT_RW;
926 llcp_sock->remote_miu = LLCP_DEFAULT_MIU;
807 llcp_sock->send_n = llcp_sock->send_ack_n = 0; 927 llcp_sock->send_n = llcp_sock->send_ack_n = 0;
808 llcp_sock->recv_n = llcp_sock->recv_ack_n = 0; 928 llcp_sock->recv_n = llcp_sock->recv_ack_n = 0;
809 llcp_sock->remote_ready = 1; 929 llcp_sock->remote_ready = 1;
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 504b883439f1..73fd51098f4d 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -53,6 +53,15 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
53 [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 }, 53 [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 },
54 [NFC_ATTR_IM_PROTOCOLS] = { .type = NLA_U32 }, 54 [NFC_ATTR_IM_PROTOCOLS] = { .type = NLA_U32 },
55 [NFC_ATTR_TM_PROTOCOLS] = { .type = NLA_U32 }, 55 [NFC_ATTR_TM_PROTOCOLS] = { .type = NLA_U32 },
56 [NFC_ATTR_LLC_PARAM_LTO] = { .type = NLA_U8 },
57 [NFC_ATTR_LLC_PARAM_RW] = { .type = NLA_U8 },
58 [NFC_ATTR_LLC_PARAM_MIUX] = { .type = NLA_U16 },
59 [NFC_ATTR_LLC_SDP] = { .type = NLA_NESTED },
60};
61
62static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = {
63 [NFC_SDP_ATTR_URI] = { .type = NLA_STRING },
64 [NFC_SDP_ATTR_SAP] = { .type = NLA_U8 },
56}; 65};
57 66
58static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, 67static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
@@ -348,6 +357,74 @@ free_msg:
348 return -EMSGSIZE; 357 return -EMSGSIZE;
349} 358}
350 359
360int nfc_genl_llc_send_sdres(struct nfc_dev *dev, struct hlist_head *sdres_list)
361{
362 struct sk_buff *msg;
363 struct nlattr *sdp_attr, *uri_attr;
364 struct nfc_llcp_sdp_tlv *sdres;
365 struct hlist_node *n;
366 void *hdr;
367 int rc = -EMSGSIZE;
368 int i;
369
370 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
371 if (!msg)
372 return -ENOMEM;
373
374 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
375 NFC_EVENT_LLC_SDRES);
376 if (!hdr)
377 goto free_msg;
378
379 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
380 goto nla_put_failure;
381
382 sdp_attr = nla_nest_start(msg, NFC_ATTR_LLC_SDP);
383 if (sdp_attr == NULL) {
384 rc = -ENOMEM;
385 goto nla_put_failure;
386 }
387
388 i = 1;
389 hlist_for_each_entry_safe(sdres, n, sdres_list, node) {
390 pr_debug("uri: %s, sap: %d\n", sdres->uri, sdres->sap);
391
392 uri_attr = nla_nest_start(msg, i++);
393 if (uri_attr == NULL) {
394 rc = -ENOMEM;
395 goto nla_put_failure;
396 }
397
398 if (nla_put_u8(msg, NFC_SDP_ATTR_SAP, sdres->sap))
399 goto nla_put_failure;
400
401 if (nla_put_string(msg, NFC_SDP_ATTR_URI, sdres->uri))
402 goto nla_put_failure;
403
404 nla_nest_end(msg, uri_attr);
405
406 hlist_del(&sdres->node);
407
408 nfc_llcp_free_sdp_tlv(sdres);
409 }
410
411 nla_nest_end(msg, sdp_attr);
412
413 genlmsg_end(msg, hdr);
414
415 return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
416
417nla_put_failure:
418 genlmsg_cancel(msg, hdr);
419
420free_msg:
421 nlmsg_free(msg);
422
423 nfc_llcp_free_sdp_tlv_list(sdres_list);
424
425 return rc;
426}
427
351static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, 428static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
352 u32 portid, u32 seq, 429 u32 portid, u32 seq,
353 struct netlink_callback *cb, 430 struct netlink_callback *cb,
@@ -859,6 +936,96 @@ exit:
859 return rc; 936 return rc;
860} 937}
861 938
939static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
940{
941 struct nfc_dev *dev;
942 struct nfc_llcp_local *local;
943 struct nlattr *attr, *sdp_attrs[NFC_SDP_ATTR_MAX+1];
944 u32 idx;
945 u8 tid;
946 char *uri;
947 int rc = 0, rem;
948 size_t uri_len, tlvs_len;
949 struct hlist_head sdreq_list;
950 struct nfc_llcp_sdp_tlv *sdreq;
951
952 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
953 !info->attrs[NFC_ATTR_LLC_SDP])
954 return -EINVAL;
955
956 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
957
958 dev = nfc_get_device(idx);
959 if (!dev) {
960 rc = -ENODEV;
961 goto exit;
962 }
963
964 device_lock(&dev->dev);
965
966 if (dev->dep_link_up == false) {
967 rc = -ENOLINK;
968 goto exit;
969 }
970
971 local = nfc_llcp_find_local(dev);
972 if (!local) {
973 nfc_put_device(dev);
974 rc = -ENODEV;
975 goto exit;
976 }
977
978 INIT_HLIST_HEAD(&sdreq_list);
979
980 tlvs_len = 0;
981
982 nla_for_each_nested(attr, info->attrs[NFC_ATTR_LLC_SDP], rem) {
983 rc = nla_parse_nested(sdp_attrs, NFC_SDP_ATTR_MAX, attr,
984 nfc_sdp_genl_policy);
985
986 if (rc != 0) {
987 rc = -EINVAL;
988 goto exit;
989 }
990
991 if (!sdp_attrs[NFC_SDP_ATTR_URI])
992 continue;
993
994 uri_len = nla_len(sdp_attrs[NFC_SDP_ATTR_URI]);
995 if (uri_len == 0)
996 continue;
997
998 uri = nla_data(sdp_attrs[NFC_SDP_ATTR_URI]);
999 if (uri == NULL || *uri == 0)
1000 continue;
1001
1002 tid = local->sdreq_next_tid++;
1003
1004 sdreq = nfc_llcp_build_sdreq_tlv(tid, uri, uri_len);
1005 if (sdreq == NULL) {
1006 rc = -ENOMEM;
1007 goto exit;
1008 }
1009
1010 tlvs_len += sdreq->tlv_len;
1011
1012 hlist_add_head(&sdreq->node, &sdreq_list);
1013 }
1014
1015 if (hlist_empty(&sdreq_list)) {
1016 rc = -EINVAL;
1017 goto exit;
1018 }
1019
1020 rc = nfc_llcp_send_snl_sdreq(local, &sdreq_list, tlvs_len);
1021exit:
1022 device_unlock(&dev->dev);
1023
1024 nfc_put_device(dev);
1025
1026 return rc;
1027}
1028
862static struct genl_ops nfc_genl_ops[] = { 1029static struct genl_ops nfc_genl_ops[] = {
863 { 1030 {
864 .cmd = NFC_CMD_GET_DEVICE, 1031 .cmd = NFC_CMD_GET_DEVICE,
@@ -913,6 +1080,11 @@ static struct genl_ops nfc_genl_ops[] = {
913 .doit = nfc_genl_llc_set_params, 1080 .doit = nfc_genl_llc_set_params,
914 .policy = nfc_genl_policy, 1081 .policy = nfc_genl_policy,
915 }, 1082 },
1083 {
1084 .cmd = NFC_CMD_LLC_SDREQ,
1085 .doit = nfc_genl_llc_sdreq,
1086 .policy = nfc_genl_policy,
1087 },
916}; 1088};
917 1089
918 1090
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h
index 87d914d2876a..94bfe19ba678 100644
--- a/net/nfc/nfc.h
+++ b/net/nfc/nfc.h
@@ -46,6 +46,8 @@ struct nfc_rawsock {
46#define to_rawsock_sk(_tx_work) \ 46#define to_rawsock_sk(_tx_work) \
47 ((struct sock *) container_of(_tx_work, struct nfc_rawsock, tx_work)) 47 ((struct sock *) container_of(_tx_work, struct nfc_rawsock, tx_work))
48 48
49struct nfc_llcp_sdp_tlv;
50
49#ifdef CONFIG_NFC_LLCP 51#ifdef CONFIG_NFC_LLCP
50 52
51void nfc_llcp_mac_is_down(struct nfc_dev *dev); 53void nfc_llcp_mac_is_down(struct nfc_dev *dev);
@@ -59,6 +61,8 @@ int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb);
59struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); 61struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
60int __init nfc_llcp_init(void); 62int __init nfc_llcp_init(void);
61void nfc_llcp_exit(void); 63void nfc_llcp_exit(void);
64void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
65void nfc_llcp_free_sdp_tlv_list(struct hlist_head *head);
62 66
63#else 67#else
64 68
@@ -112,6 +116,14 @@ static inline void nfc_llcp_exit(void)
112{ 116{
113} 117}
114 118
119static inline void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp)
120{
121}
122
123static inline void nfc_llcp_free_sdp_tlv_list(struct hlist_head *sdp_head)
124{
125}
126
115#endif 127#endif
116 128
117int __init rawsock_init(void); 129int __init rawsock_init(void);
@@ -144,6 +156,8 @@ int nfc_genl_dep_link_down_event(struct nfc_dev *dev);
144int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol); 156int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol);
145int nfc_genl_tm_deactivated(struct nfc_dev *dev); 157int nfc_genl_tm_deactivated(struct nfc_dev *dev);
146 158
159int nfc_genl_llc_send_sdres(struct nfc_dev *dev, struct hlist_head *sdres_list);
160
147struct nfc_dev *nfc_get_device(unsigned int idx); 161struct nfc_dev *nfc_get_device(unsigned int idx);
148 162
149static inline void nfc_put_device(struct nfc_dev *dev) 163static inline void nfc_put_device(struct nfc_dev *dev)
diff --git a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c
index 4b5ab21ecb24..d11ac79246e4 100644
--- a/net/rfkill/rfkill-regulator.c
+++ b/net/rfkill/rfkill-regulator.c
@@ -51,7 +51,7 @@ static int rfkill_regulator_set_block(void *data, bool blocked)
51 return 0; 51 return 0;
52} 52}
53 53
54struct rfkill_ops rfkill_regulator_ops = { 54static struct rfkill_ops rfkill_regulator_ops = {
55 .set_block = rfkill_regulator_set_block, 55 .set_block = rfkill_regulator_set_block,
56}; 56};
57 57
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index a4a14e8f55cc..324e8d851dc4 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -46,65 +46,3 @@ int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
46 46
47 return err; 47 return err;
48} 48}
49
50void cfg80211_ch_switch_notify(struct net_device *dev,
51 struct cfg80211_chan_def *chandef)
52{
53 struct wireless_dev *wdev = dev->ieee80211_ptr;
54 struct wiphy *wiphy = wdev->wiphy;
55 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
56
57 trace_cfg80211_ch_switch_notify(dev, chandef);
58
59 wdev_lock(wdev);
60
61 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
62 wdev->iftype != NL80211_IFTYPE_P2P_GO))
63 goto out;
64
65 wdev->channel = chandef->chan;
66 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
67out:
68 wdev_unlock(wdev);
69 return;
70}
71EXPORT_SYMBOL(cfg80211_ch_switch_notify);
72
73bool cfg80211_rx_spurious_frame(struct net_device *dev,
74 const u8 *addr, gfp_t gfp)
75{
76 struct wireless_dev *wdev = dev->ieee80211_ptr;
77 bool ret;
78
79 trace_cfg80211_rx_spurious_frame(dev, addr);
80
81 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
82 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
83 trace_cfg80211_return_bool(false);
84 return false;
85 }
86 ret = nl80211_unexpected_frame(dev, addr, gfp);
87 trace_cfg80211_return_bool(ret);
88 return ret;
89}
90EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
91
92bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
93 const u8 *addr, gfp_t gfp)
94{
95 struct wireless_dev *wdev = dev->ieee80211_ptr;
96 bool ret;
97
98 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
99
100 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
101 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
102 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
103 trace_cfg80211_return_bool(false);
104 return false;
105 }
106 ret = nl80211_unexpected_4addr_frame(dev, addr, gfp);
107 trace_cfg80211_return_bool(ret);
108 return ret;
109}
110EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
diff --git a/net/wireless/core.c b/net/wireless/core.c
index ea4155fe9733..f382cae983ba 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -814,6 +814,46 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
814 rdev->num_running_monitor_ifaces += num; 814 rdev->num_running_monitor_ifaces += num;
815} 815}
816 816
817void cfg80211_leave(struct cfg80211_registered_device *rdev,
818 struct wireless_dev *wdev)
819{
820 struct net_device *dev = wdev->netdev;
821
822 switch (wdev->iftype) {
823 case NL80211_IFTYPE_ADHOC:
824 cfg80211_leave_ibss(rdev, dev, true);
825 break;
826 case NL80211_IFTYPE_P2P_CLIENT:
827 case NL80211_IFTYPE_STATION:
828 mutex_lock(&rdev->sched_scan_mtx);
829 __cfg80211_stop_sched_scan(rdev, false);
830 mutex_unlock(&rdev->sched_scan_mtx);
831
832 wdev_lock(wdev);
833#ifdef CONFIG_CFG80211_WEXT
834 kfree(wdev->wext.ie);
835 wdev->wext.ie = NULL;
836 wdev->wext.ie_len = 0;
837 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
838#endif
839 __cfg80211_disconnect(rdev, dev,
840 WLAN_REASON_DEAUTH_LEAVING, true);
841 cfg80211_mlme_down(rdev, dev);
842 wdev_unlock(wdev);
843 break;
844 case NL80211_IFTYPE_MESH_POINT:
845 cfg80211_leave_mesh(rdev, dev);
846 break;
847 case NL80211_IFTYPE_AP:
848 cfg80211_stop_ap(rdev, dev);
849 break;
850 default:
851 break;
852 }
853
854 wdev->beacon_interval = 0;
855}
856
817static int cfg80211_netdev_notifier_call(struct notifier_block *nb, 857static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
818 unsigned long state, 858 unsigned long state,
819 void *ndev) 859 void *ndev)
@@ -882,38 +922,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
882 dev->priv_flags |= IFF_DONT_BRIDGE; 922 dev->priv_flags |= IFF_DONT_BRIDGE;
883 break; 923 break;
884 case NETDEV_GOING_DOWN: 924 case NETDEV_GOING_DOWN:
885 switch (wdev->iftype) { 925 cfg80211_leave(rdev, wdev);
886 case NL80211_IFTYPE_ADHOC:
887 cfg80211_leave_ibss(rdev, dev, true);
888 break;
889 case NL80211_IFTYPE_P2P_CLIENT:
890 case NL80211_IFTYPE_STATION:
891 mutex_lock(&rdev->sched_scan_mtx);
892 __cfg80211_stop_sched_scan(rdev, false);
893 mutex_unlock(&rdev->sched_scan_mtx);
894
895 wdev_lock(wdev);
896#ifdef CONFIG_CFG80211_WEXT
897 kfree(wdev->wext.ie);
898 wdev->wext.ie = NULL;
899 wdev->wext.ie_len = 0;
900 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
901#endif
902 __cfg80211_disconnect(rdev, dev,
903 WLAN_REASON_DEAUTH_LEAVING, true);
904 cfg80211_mlme_down(rdev, dev);
905 wdev_unlock(wdev);
906 break;
907 case NL80211_IFTYPE_MESH_POINT:
908 cfg80211_leave_mesh(rdev, dev);
909 break;
910 case NL80211_IFTYPE_AP:
911 cfg80211_stop_ap(rdev, dev);
912 break;
913 default:
914 break;
915 }
916 wdev->beacon_interval = 0;
917 break; 926 break;
918 case NETDEV_DOWN: 927 case NETDEV_DOWN:
919 cfg80211_update_iface_num(rdev, wdev->iftype, -1); 928 cfg80211_update_iface_num(rdev, wdev->iftype, -1);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 3aec0e429d8a..d5d06fdea961 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -330,20 +330,15 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
330int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 330int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
331 struct net_device *dev, 331 struct net_device *dev,
332 struct ieee80211_channel *chan, 332 struct ieee80211_channel *chan,
333 const u8 *bssid, const u8 *prev_bssid, 333 const u8 *bssid,
334 const u8 *ssid, int ssid_len, 334 const u8 *ssid, int ssid_len,
335 const u8 *ie, int ie_len, bool use_mfp, 335 struct cfg80211_assoc_request *req);
336 struct cfg80211_crypto_settings *crypt,
337 u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
338 struct ieee80211_ht_cap *ht_capa_mask);
339int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 336int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
340 struct net_device *dev, struct ieee80211_channel *chan, 337 struct net_device *dev,
341 const u8 *bssid, const u8 *prev_bssid, 338 struct ieee80211_channel *chan,
339 const u8 *bssid,
342 const u8 *ssid, int ssid_len, 340 const u8 *ssid, int ssid_len,
343 const u8 *ie, int ie_len, bool use_mfp, 341 struct cfg80211_assoc_request *req);
344 struct cfg80211_crypto_settings *crypt,
345 u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
346 struct ieee80211_ht_cap *ht_capa_mask);
347int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 342int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
348 struct net_device *dev, const u8 *bssid, 343 struct net_device *dev, const u8 *bssid,
349 const u8 *ie, int ie_len, u16 reason, 344 const u8 *ie, int ie_len, u16 reason,
@@ -375,6 +370,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
375 bool no_cck, bool dont_wait_for_ack, u64 *cookie); 370 bool no_cck, bool dont_wait_for_ack, u64 *cookie);
376void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, 371void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
377 const struct ieee80211_ht_cap *ht_capa_mask); 372 const struct ieee80211_ht_cap *ht_capa_mask);
373void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
374 const struct ieee80211_vht_cap *vht_capa_mask);
378 375
379/* SME */ 376/* SME */
380int __cfg80211_connect(struct cfg80211_registered_device *rdev, 377int __cfg80211_connect(struct cfg80211_registered_device *rdev,
@@ -503,6 +500,9 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
503void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, 500void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
504 enum nl80211_iftype iftype, int num); 501 enum nl80211_iftype iftype, int num);
505 502
503void cfg80211_leave(struct cfg80211_registered_device *rdev,
504 struct wireless_dev *wdev);
505
506#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 506#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
507 507
508#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 508#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 55957a284f6c..0bb93f3061a4 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -85,6 +85,7 @@ const struct mesh_setup default_mesh_setup = {
85 .ie = NULL, 85 .ie = NULL,
86 .ie_len = 0, 86 .ie_len = 0,
87 .is_secure = false, 87 .is_secure = false,
88 .user_mpm = false,
88 .beacon_interval = MESH_DEFAULT_BEACON_INTERVAL, 89 .beacon_interval = MESH_DEFAULT_BEACON_INTERVAL,
89 .dtim_period = MESH_DEFAULT_DTIM_PERIOD, 90 .dtim_period = MESH_DEFAULT_DTIM_PERIOD,
90}; 91};
@@ -233,20 +234,6 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
233 return 0; 234 return 0;
234} 235}
235 236
236void cfg80211_notify_new_peer_candidate(struct net_device *dev,
237 const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp)
238{
239 struct wireless_dev *wdev = dev->ieee80211_ptr;
240
241 trace_cfg80211_notify_new_peer_candidate(dev, macaddr);
242 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
243 return;
244
245 nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev,
246 macaddr, ie, ie_len, gfp);
247}
248EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
249
250static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 237static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
251 struct net_device *dev) 238 struct net_device *dev)
252{ 239{
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index caddca35d686..390198bf4b36 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -187,30 +187,6 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
187} 187}
188EXPORT_SYMBOL(cfg80211_send_disassoc); 188EXPORT_SYMBOL(cfg80211_send_disassoc);
189 189
190void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
191 size_t len)
192{
193 struct wireless_dev *wdev = dev->ieee80211_ptr;
194 struct wiphy *wiphy = wdev->wiphy;
195 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
196
197 trace_cfg80211_send_unprot_deauth(dev);
198 nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC);
199}
200EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
201
202void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
203 size_t len)
204{
205 struct wireless_dev *wdev = dev->ieee80211_ptr;
206 struct wiphy *wiphy = wdev->wiphy;
207 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
208
209 trace_cfg80211_send_unprot_disassoc(dev);
210 nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC);
211}
212EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
213
214void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) 190void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
215{ 191{
216 struct wireless_dev *wdev = dev->ieee80211_ptr; 192 struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -367,27 +343,38 @@ void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
367 p1[i] &= p2[i]; 343 p1[i] &= p2[i];
368} 344}
369 345
346/* Do a logical ht_capa &= ht_capa_mask. */
347void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
348 const struct ieee80211_vht_cap *vht_capa_mask)
349{
350 int i;
351 u8 *p1, *p2;
352 if (!vht_capa_mask) {
353 memset(vht_capa, 0, sizeof(*vht_capa));
354 return;
355 }
356
357 p1 = (u8*)(vht_capa);
358 p2 = (u8*)(vht_capa_mask);
359 for (i = 0; i < sizeof(*vht_capa); i++)
360 p1[i] &= p2[i];
361}
362
370int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 363int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
371 struct net_device *dev, 364 struct net_device *dev,
372 struct ieee80211_channel *chan, 365 struct ieee80211_channel *chan,
373 const u8 *bssid, const u8 *prev_bssid, 366 const u8 *bssid,
374 const u8 *ssid, int ssid_len, 367 const u8 *ssid, int ssid_len,
375 const u8 *ie, int ie_len, bool use_mfp, 368 struct cfg80211_assoc_request *req)
376 struct cfg80211_crypto_settings *crypt,
377 u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
378 struct ieee80211_ht_cap *ht_capa_mask)
379{ 369{
380 struct wireless_dev *wdev = dev->ieee80211_ptr; 370 struct wireless_dev *wdev = dev->ieee80211_ptr;
381 struct cfg80211_assoc_request req;
382 int err; 371 int err;
383 bool was_connected = false; 372 bool was_connected = false;
384 373
385 ASSERT_WDEV_LOCK(wdev); 374 ASSERT_WDEV_LOCK(wdev);
386 375
387 memset(&req, 0, sizeof(req)); 376 if (wdev->current_bss && req->prev_bssid &&
388 377 ether_addr_equal(wdev->current_bss->pub.bssid, req->prev_bssid)) {
389 if (wdev->current_bss && prev_bssid &&
390 ether_addr_equal(wdev->current_bss->pub.bssid, prev_bssid)) {
391 /* 378 /*
392 * Trying to reassociate: Allow this to proceed and let the old 379 * Trying to reassociate: Allow this to proceed and let the old
393 * association to be dropped when the new one is completed. 380 * association to be dropped when the new one is completed.
@@ -399,40 +386,30 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
399 } else if (wdev->current_bss) 386 } else if (wdev->current_bss)
400 return -EALREADY; 387 return -EALREADY;
401 388
402 req.ie = ie; 389 cfg80211_oper_and_ht_capa(&req->ht_capa_mask,
403 req.ie_len = ie_len;
404 memcpy(&req.crypto, crypt, sizeof(req.crypto));
405 req.use_mfp = use_mfp;
406 req.prev_bssid = prev_bssid;
407 req.flags = assoc_flags;
408 if (ht_capa)
409 memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
410 if (ht_capa_mask)
411 memcpy(&req.ht_capa_mask, ht_capa_mask,
412 sizeof(req.ht_capa_mask));
413 cfg80211_oper_and_ht_capa(&req.ht_capa_mask,
414 rdev->wiphy.ht_capa_mod_mask); 390 rdev->wiphy.ht_capa_mod_mask);
391 cfg80211_oper_and_vht_capa(&req->vht_capa_mask,
392 rdev->wiphy.vht_capa_mod_mask);
415 393
416 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 394 req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
417 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 395 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
418 if (!req.bss) { 396 if (!req->bss) {
419 if (was_connected) 397 if (was_connected)
420 wdev->sme_state = CFG80211_SME_CONNECTED; 398 wdev->sme_state = CFG80211_SME_CONNECTED;
421 return -ENOENT; 399 return -ENOENT;
422 } 400 }
423 401
424 err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel, 402 err = cfg80211_can_use_chan(rdev, wdev, chan, CHAN_MODE_SHARED);
425 CHAN_MODE_SHARED);
426 if (err) 403 if (err)
427 goto out; 404 goto out;
428 405
429 err = rdev_assoc(rdev, dev, &req); 406 err = rdev_assoc(rdev, dev, req);
430 407
431out: 408out:
432 if (err) { 409 if (err) {
433 if (was_connected) 410 if (was_connected)
434 wdev->sme_state = CFG80211_SME_CONNECTED; 411 wdev->sme_state = CFG80211_SME_CONNECTED;
435 cfg80211_put_bss(&rdev->wiphy, req.bss); 412 cfg80211_put_bss(&rdev->wiphy, req->bss);
436 } 413 }
437 414
438 return err; 415 return err;
@@ -441,21 +418,17 @@ out:
441int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 418int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
442 struct net_device *dev, 419 struct net_device *dev,
443 struct ieee80211_channel *chan, 420 struct ieee80211_channel *chan,
444 const u8 *bssid, const u8 *prev_bssid, 421 const u8 *bssid,
445 const u8 *ssid, int ssid_len, 422 const u8 *ssid, int ssid_len,
446 const u8 *ie, int ie_len, bool use_mfp, 423 struct cfg80211_assoc_request *req)
447 struct cfg80211_crypto_settings *crypt,
448 u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
449 struct ieee80211_ht_cap *ht_capa_mask)
450{ 424{
451 struct wireless_dev *wdev = dev->ieee80211_ptr; 425 struct wireless_dev *wdev = dev->ieee80211_ptr;
452 int err; 426 int err;
453 427
454 mutex_lock(&rdev->devlist_mtx); 428 mutex_lock(&rdev->devlist_mtx);
455 wdev_lock(wdev); 429 wdev_lock(wdev);
456 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, 430 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid,
457 ssid, ssid_len, ie, ie_len, use_mfp, crypt, 431 ssid, ssid_len, req);
458 assoc_flags, ht_capa, ht_capa_mask);
459 wdev_unlock(wdev); 432 wdev_unlock(wdev);
460 mutex_unlock(&rdev->devlist_mtx); 433 mutex_unlock(&rdev->devlist_mtx);
461 434
@@ -577,62 +550,6 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
577 } 550 }
578} 551}
579 552
580void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
581 struct ieee80211_channel *chan,
582 unsigned int duration, gfp_t gfp)
583{
584 struct wiphy *wiphy = wdev->wiphy;
585 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
586
587 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
588 nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, duration, gfp);
589}
590EXPORT_SYMBOL(cfg80211_ready_on_channel);
591
592void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
593 struct ieee80211_channel *chan,
594 gfp_t gfp)
595{
596 struct wiphy *wiphy = wdev->wiphy;
597 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
598
599 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
600 nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan, gfp);
601}
602EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
603
604void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
605 struct station_info *sinfo, gfp_t gfp)
606{
607 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
608 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
609
610 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
611 nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp);
612}
613EXPORT_SYMBOL(cfg80211_new_sta);
614
615void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
616{
617 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
618 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
619
620 trace_cfg80211_del_sta(dev, mac_addr);
621 nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp);
622}
623EXPORT_SYMBOL(cfg80211_del_sta);
624
625void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
626 enum nl80211_connect_failed_reason reason,
627 gfp_t gfp)
628{
629 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
630 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
631
632 nl80211_send_conn_failed_event(rdev, dev, mac_addr, reason, gfp);
633}
634EXPORT_SYMBOL(cfg80211_conn_failed);
635
636struct cfg80211_mgmt_registration { 553struct cfg80211_mgmt_registration {
637 struct list_head list; 554 struct list_head list;
638 555
@@ -909,85 +826,6 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
909} 826}
910EXPORT_SYMBOL(cfg80211_rx_mgmt); 827EXPORT_SYMBOL(cfg80211_rx_mgmt);
911 828
912void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
913 const u8 *buf, size_t len, bool ack, gfp_t gfp)
914{
915 struct wiphy *wiphy = wdev->wiphy;
916 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
917
918 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
919
920 /* Indicate TX status of the Action frame to user space */
921 nl80211_send_mgmt_tx_status(rdev, wdev, cookie, buf, len, ack, gfp);
922}
923EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
924
925void cfg80211_cqm_rssi_notify(struct net_device *dev,
926 enum nl80211_cqm_rssi_threshold_event rssi_event,
927 gfp_t gfp)
928{
929 struct wireless_dev *wdev = dev->ieee80211_ptr;
930 struct wiphy *wiphy = wdev->wiphy;
931 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
932
933 trace_cfg80211_cqm_rssi_notify(dev, rssi_event);
934
935 /* Indicate roaming trigger event to user space */
936 nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp);
937}
938EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
939
940void cfg80211_cqm_pktloss_notify(struct net_device *dev,
941 const u8 *peer, u32 num_packets, gfp_t gfp)
942{
943 struct wireless_dev *wdev = dev->ieee80211_ptr;
944 struct wiphy *wiphy = wdev->wiphy;
945 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
946
947 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
948
949 /* Indicate roaming trigger event to user space */
950 nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp);
951}
952EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
953
954void cfg80211_cqm_txe_notify(struct net_device *dev,
955 const u8 *peer, u32 num_packets,
956 u32 rate, u32 intvl, gfp_t gfp)
957{
958 struct wireless_dev *wdev = dev->ieee80211_ptr;
959 struct wiphy *wiphy = wdev->wiphy;
960 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
961
962 nl80211_send_cqm_txe_notify(rdev, dev, peer, num_packets,
963 rate, intvl, gfp);
964}
965EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
966
967void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
968 const u8 *replay_ctr, gfp_t gfp)
969{
970 struct wireless_dev *wdev = dev->ieee80211_ptr;
971 struct wiphy *wiphy = wdev->wiphy;
972 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
973
974 trace_cfg80211_gtk_rekey_notify(dev, bssid);
975 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
976}
977EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
978
979void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
980 const u8 *bssid, bool preauth, gfp_t gfp)
981{
982 struct wireless_dev *wdev = dev->ieee80211_ptr;
983 struct wiphy *wiphy = wdev->wiphy;
984 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
985
986 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
987 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
988}
989EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
990
991void cfg80211_dfs_channels_update_work(struct work_struct *work) 829void cfg80211_dfs_channels_update_work(struct work_struct *work)
992{ 830{
993 struct delayed_work *delayed_work; 831 struct delayed_work *delayed_work;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d44ab216c0ec..f924d45af1b8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -370,6 +370,14 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
370 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED }, 370 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
371 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 }, 371 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
372 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, }, 372 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
373 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
374 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
375 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
376 .len = NL80211_VHT_CAPABILITY_LEN,
377 },
378 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
379 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
380 .len = IEEE80211_MAX_DATA_LEN },
373}; 381};
374 382
375/* policy for the key attributes */ 383/* policy for the key attributes */
@@ -539,7 +547,8 @@ static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
539} 547}
540 548
541static int nl80211_msg_put_channel(struct sk_buff *msg, 549static int nl80211_msg_put_channel(struct sk_buff *msg,
542 struct ieee80211_channel *chan) 550 struct ieee80211_channel *chan,
551 bool large)
543{ 552{
544 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ, 553 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
545 chan->center_freq)) 554 chan->center_freq))
@@ -554,9 +563,37 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
554 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && 563 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
555 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) 564 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
556 goto nla_put_failure; 565 goto nla_put_failure;
557 if ((chan->flags & IEEE80211_CHAN_RADAR) && 566 if (chan->flags & IEEE80211_CHAN_RADAR) {
558 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) 567 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
559 goto nla_put_failure; 568 goto nla_put_failure;
569 if (large) {
570 u32 time;
571
572 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
573
574 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
575 chan->dfs_state))
576 goto nla_put_failure;
577 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
578 time))
579 goto nla_put_failure;
580 }
581 }
582
583 if (large) {
584 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
585 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
586 goto nla_put_failure;
587 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
588 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
589 goto nla_put_failure;
590 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
591 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
592 goto nla_put_failure;
593 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
594 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
595 goto nla_put_failure;
596 }
560 597
561 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 598 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
562 DBM_TO_MBM(chan->max_power))) 599 DBM_TO_MBM(chan->max_power)))
@@ -832,7 +869,8 @@ nla_put_failure:
832} 869}
833 870
834static int nl80211_put_iface_combinations(struct wiphy *wiphy, 871static int nl80211_put_iface_combinations(struct wiphy *wiphy,
835 struct sk_buff *msg) 872 struct sk_buff *msg,
873 bool large)
836{ 874{
837 struct nlattr *nl_combis; 875 struct nlattr *nl_combis;
838 int i, j; 876 int i, j;
@@ -881,6 +919,10 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
881 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM, 919 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
882 c->max_interfaces)) 920 c->max_interfaces))
883 goto nla_put_failure; 921 goto nla_put_failure;
922 if (large &&
923 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
924 c->radar_detect_widths))
925 goto nla_put_failure;
884 926
885 nla_nest_end(msg, nl_combi); 927 nla_nest_end(msg, nl_combi);
886 } 928 }
@@ -892,412 +934,611 @@ nla_put_failure:
892 return -ENOBUFS; 934 return -ENOBUFS;
893} 935}
894 936
895static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags, 937#ifdef CONFIG_PM
896 struct cfg80211_registered_device *dev) 938static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
939 struct sk_buff *msg)
897{ 940{
898 void *hdr; 941 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp;
899 struct nlattr *nl_bands, *nl_band; 942 struct nlattr *nl_tcp;
900 struct nlattr *nl_freqs, *nl_freq;
901 struct nlattr *nl_rates, *nl_rate;
902 struct nlattr *nl_cmds;
903 enum ieee80211_band band;
904 struct ieee80211_channel *chan;
905 struct ieee80211_rate *rate;
906 int i;
907 const struct ieee80211_txrx_stypes *mgmt_stypes =
908 dev->wiphy.mgmt_stypes;
909 943
910 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY); 944 if (!tcp)
911 if (!hdr) 945 return 0;
912 return -1;
913 946
914 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) || 947 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
915 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)) || 948 if (!nl_tcp)
916 nla_put_u32(msg, NL80211_ATTR_GENERATION, 949 return -ENOBUFS;
917 cfg80211_rdev_list_generation) ||
918 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
919 dev->wiphy.retry_short) ||
920 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
921 dev->wiphy.retry_long) ||
922 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
923 dev->wiphy.frag_threshold) ||
924 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
925 dev->wiphy.rts_threshold) ||
926 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
927 dev->wiphy.coverage_class) ||
928 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
929 dev->wiphy.max_scan_ssids) ||
930 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
931 dev->wiphy.max_sched_scan_ssids) ||
932 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
933 dev->wiphy.max_scan_ie_len) ||
934 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
935 dev->wiphy.max_sched_scan_ie_len) ||
936 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
937 dev->wiphy.max_match_sets))
938 goto nla_put_failure;
939 950
940 if ((dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) && 951 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
941 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN)) 952 tcp->data_payload_max))
942 goto nla_put_failure; 953 return -ENOBUFS;
943 if ((dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
944 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
945 goto nla_put_failure;
946 if ((dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
947 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
948 goto nla_put_failure;
949 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
950 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
951 goto nla_put_failure;
952 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
953 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
954 goto nla_put_failure;
955 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
956 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
957 goto nla_put_failure;
958 954
959 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, 955 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
960 sizeof(u32) * dev->wiphy.n_cipher_suites, 956 tcp->data_payload_max))
961 dev->wiphy.cipher_suites)) 957 return -ENOBUFS;
962 goto nla_put_failure;
963 958
964 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS, 959 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
965 dev->wiphy.max_num_pmkids)) 960 return -ENOBUFS;
966 goto nla_put_failure;
967 961
968 if ((dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) && 962 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
969 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE)) 963 sizeof(*tcp->tok), tcp->tok))
970 goto nla_put_failure; 964 return -ENOBUFS;
971 965
972 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, 966 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
973 dev->wiphy.available_antennas_tx) || 967 tcp->data_interval_max))
974 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, 968 return -ENOBUFS;
975 dev->wiphy.available_antennas_rx))
976 goto nla_put_failure;
977 969
978 if ((dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) && 970 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
979 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD, 971 tcp->wake_payload_max))
980 dev->wiphy.probe_resp_offload)) 972 return -ENOBUFS;
981 goto nla_put_failure;
982 973
983 if ((dev->wiphy.available_antennas_tx || 974 nla_nest_end(msg, nl_tcp);
984 dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { 975 return 0;
985 u32 tx_ant = 0, rx_ant = 0; 976}
986 int res; 977
987 res = rdev_get_antenna(dev, &tx_ant, &rx_ant); 978static int nl80211_send_wowlan(struct sk_buff *msg,
988 if (!res) { 979 struct cfg80211_registered_device *dev,
989 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, 980 bool large)
990 tx_ant) || 981{
991 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, 982 struct nlattr *nl_wowlan;
992 rx_ant)) 983
993 goto nla_put_failure; 984 if (!dev->wiphy.wowlan.flags && !dev->wiphy.wowlan.n_patterns)
994 } 985 return 0;
986
987 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
988 if (!nl_wowlan)
989 return -ENOBUFS;
990
991 if (((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) &&
992 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
993 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) &&
994 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
995 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) &&
996 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
997 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
998 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
999 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
1000 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1001 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
1002 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1003 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
1004 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1005 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
1006 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1007 return -ENOBUFS;
1008
1009 if (dev->wiphy.wowlan.n_patterns) {
1010 struct nl80211_wowlan_pattern_support pat = {
1011 .max_patterns = dev->wiphy.wowlan.n_patterns,
1012 .min_pattern_len = dev->wiphy.wowlan.pattern_min_len,
1013 .max_pattern_len = dev->wiphy.wowlan.pattern_max_len,
1014 .max_pkt_offset = dev->wiphy.wowlan.max_pkt_offset,
1015 };
1016
1017 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1018 sizeof(pat), &pat))
1019 return -ENOBUFS;
995 } 1020 }
996 1021
997 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, 1022 if (large && nl80211_send_wowlan_tcp_caps(dev, msg))
998 dev->wiphy.interface_modes)) 1023 return -ENOBUFS;
999 goto nla_put_failure;
1000 1024
1001 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); 1025 nla_nest_end(msg, nl_wowlan);
1002 if (!nl_bands)
1003 goto nla_put_failure;
1004 1026
1005 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1027 return 0;
1006 if (!dev->wiphy.bands[band]) 1028}
1007 continue; 1029#endif
1008 1030
1009 nl_band = nla_nest_start(msg, band); 1031static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1010 if (!nl_band) 1032 struct ieee80211_supported_band *sband)
1011 goto nla_put_failure; 1033{
1034 struct nlattr *nl_rates, *nl_rate;
1035 struct ieee80211_rate *rate;
1036 int i;
1012 1037
1013 /* add HT info */ 1038 /* add HT info */
1014 if (dev->wiphy.bands[band]->ht_cap.ht_supported && 1039 if (sband->ht_cap.ht_supported &&
1015 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET, 1040 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1016 sizeof(dev->wiphy.bands[band]->ht_cap.mcs), 1041 sizeof(sband->ht_cap.mcs),
1017 &dev->wiphy.bands[band]->ht_cap.mcs) || 1042 &sband->ht_cap.mcs) ||
1018 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA, 1043 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1019 dev->wiphy.bands[band]->ht_cap.cap) || 1044 sband->ht_cap.cap) ||
1020 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR, 1045 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1021 dev->wiphy.bands[band]->ht_cap.ampdu_factor) || 1046 sband->ht_cap.ampdu_factor) ||
1022 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY, 1047 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1023 dev->wiphy.bands[band]->ht_cap.ampdu_density))) 1048 sband->ht_cap.ampdu_density)))
1024 goto nla_put_failure; 1049 return -ENOBUFS;
1025 1050
1026 /* add VHT info */ 1051 /* add VHT info */
1027 if (dev->wiphy.bands[band]->vht_cap.vht_supported && 1052 if (sband->vht_cap.vht_supported &&
1028 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET, 1053 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1029 sizeof(dev->wiphy.bands[band]->vht_cap.vht_mcs), 1054 sizeof(sband->vht_cap.vht_mcs),
1030 &dev->wiphy.bands[band]->vht_cap.vht_mcs) || 1055 &sband->vht_cap.vht_mcs) ||
1031 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA, 1056 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1032 dev->wiphy.bands[band]->vht_cap.cap))) 1057 sband->vht_cap.cap)))
1033 goto nla_put_failure; 1058 return -ENOBUFS;
1034 1059
1035 /* add frequencies */ 1060 /* add bitrates */
1036 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS); 1061 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
1037 if (!nl_freqs) 1062 if (!nl_rates)
1038 goto nla_put_failure; 1063 return -ENOBUFS;
1039 1064
1040 for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) { 1065 for (i = 0; i < sband->n_bitrates; i++) {
1041 nl_freq = nla_nest_start(msg, i); 1066 nl_rate = nla_nest_start(msg, i);
1042 if (!nl_freq) 1067 if (!nl_rate)
1043 goto nla_put_failure; 1068 return -ENOBUFS;
1044 1069
1045 chan = &dev->wiphy.bands[band]->channels[i]; 1070 rate = &sband->bitrates[i];
1071 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1072 rate->bitrate))
1073 return -ENOBUFS;
1074 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1075 nla_put_flag(msg,
1076 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1077 return -ENOBUFS;
1046 1078
1047 if (nl80211_msg_put_channel(msg, chan)) 1079 nla_nest_end(msg, nl_rate);
1048 goto nla_put_failure; 1080 }
1049 1081
1050 nla_nest_end(msg, nl_freq); 1082 nla_nest_end(msg, nl_rates);
1051 }
1052 1083
1053 nla_nest_end(msg, nl_freqs); 1084 return 0;
1085}
1054 1086
1055 /* add bitrates */ 1087static int
1056 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES); 1088nl80211_send_mgmt_stypes(struct sk_buff *msg,
1057 if (!nl_rates) 1089 const struct ieee80211_txrx_stypes *mgmt_stypes)
1058 goto nla_put_failure; 1090{
1091 u16 stypes;
1092 struct nlattr *nl_ftypes, *nl_ifs;
1093 enum nl80211_iftype ift;
1094 int i;
1059 1095
1060 for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) { 1096 if (!mgmt_stypes)
1061 nl_rate = nla_nest_start(msg, i); 1097 return 0;
1062 if (!nl_rate)
1063 goto nla_put_failure;
1064 1098
1065 rate = &dev->wiphy.bands[band]->bitrates[i]; 1099 nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES);
1066 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE, 1100 if (!nl_ifs)
1067 rate->bitrate)) 1101 return -ENOBUFS;
1068 goto nla_put_failure;
1069 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1070 nla_put_flag(msg,
1071 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1072 goto nla_put_failure;
1073 1102
1074 nla_nest_end(msg, nl_rate); 1103 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1104 nl_ftypes = nla_nest_start(msg, ift);
1105 if (!nl_ftypes)
1106 return -ENOBUFS;
1107 i = 0;
1108 stypes = mgmt_stypes[ift].tx;
1109 while (stypes) {
1110 if ((stypes & 1) &&
1111 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1112 (i << 4) | IEEE80211_FTYPE_MGMT))
1113 return -ENOBUFS;
1114 stypes >>= 1;
1115 i++;
1075 } 1116 }
1117 nla_nest_end(msg, nl_ftypes);
1118 }
1076 1119
1077 nla_nest_end(msg, nl_rates); 1120 nla_nest_end(msg, nl_ifs);
1078 1121
1079 nla_nest_end(msg, nl_band); 1122 nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES);
1123 if (!nl_ifs)
1124 return -ENOBUFS;
1125
1126 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1127 nl_ftypes = nla_nest_start(msg, ift);
1128 if (!nl_ftypes)
1129 return -ENOBUFS;
1130 i = 0;
1131 stypes = mgmt_stypes[ift].rx;
1132 while (stypes) {
1133 if ((stypes & 1) &&
1134 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1135 (i << 4) | IEEE80211_FTYPE_MGMT))
1136 return -ENOBUFS;
1137 stypes >>= 1;
1138 i++;
1139 }
1140 nla_nest_end(msg, nl_ftypes);
1080 } 1141 }
1081 nla_nest_end(msg, nl_bands); 1142 nla_nest_end(msg, nl_ifs);
1082 1143
1083 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS); 1144 return 0;
1084 if (!nl_cmds) 1145}
1085 goto nla_put_failure;
1086 1146
1087 i = 0; 1147static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1088#define CMD(op, n) \ 1148 struct sk_buff *msg, u32 portid, u32 seq,
1089 do { \ 1149 int flags, bool split, long *split_start,
1090 if (dev->ops->op) { \ 1150 long *band_start, long *chan_start)
1091 i++; \ 1151{
1092 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \ 1152 void *hdr;
1093 goto nla_put_failure; \ 1153 struct nlattr *nl_bands, *nl_band;
1094 } \ 1154 struct nlattr *nl_freqs, *nl_freq;
1095 } while (0) 1155 struct nlattr *nl_cmds;
1096 1156 enum ieee80211_band band;
1097 CMD(add_virtual_intf, NEW_INTERFACE); 1157 struct ieee80211_channel *chan;
1098 CMD(change_virtual_intf, SET_INTERFACE); 1158 int i;
1099 CMD(add_key, NEW_KEY); 1159 const struct ieee80211_txrx_stypes *mgmt_stypes =
1100 CMD(start_ap, START_AP); 1160 dev->wiphy.mgmt_stypes;
1101 CMD(add_station, NEW_STATION); 1161 long start = 0, start_chan = 0, start_band = 0;
1102 CMD(add_mpath, NEW_MPATH); 1162 u32 features;
1103 CMD(update_mesh_config, SET_MESH_CONFIG); 1163
1104 CMD(change_bss, SET_BSS); 1164 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY);
1105 CMD(auth, AUTHENTICATE); 1165 if (!hdr)
1106 CMD(assoc, ASSOCIATE); 1166 return -ENOBUFS;
1107 CMD(deauth, DEAUTHENTICATE); 1167
1108 CMD(disassoc, DISASSOCIATE); 1168 /* allow always using the variables */
1109 CMD(join_ibss, JOIN_IBSS); 1169 if (!split) {
1110 CMD(join_mesh, JOIN_MESH); 1170 split_start = &start;
1111 CMD(set_pmksa, SET_PMKSA); 1171 band_start = &start_band;
1112 CMD(del_pmksa, DEL_PMKSA); 1172 chan_start = &start_chan;
1113 CMD(flush_pmksa, FLUSH_PMKSA);
1114 if (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
1115 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1116 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1117 CMD(mgmt_tx, FRAME);
1118 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1119 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
1120 i++;
1121 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
1122 goto nla_put_failure;
1123 } 1173 }
1124 if (dev->ops->set_monitor_channel || dev->ops->start_ap || 1174
1125 dev->ops->join_mesh) { 1175 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) ||
1126 i++; 1176 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1127 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL)) 1177 wiphy_name(&dev->wiphy)) ||
1178 nla_put_u32(msg, NL80211_ATTR_GENERATION,
1179 cfg80211_rdev_list_generation))
1180 goto nla_put_failure;
1181
1182 switch (*split_start) {
1183 case 0:
1184 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1185 dev->wiphy.retry_short) ||
1186 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1187 dev->wiphy.retry_long) ||
1188 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1189 dev->wiphy.frag_threshold) ||
1190 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1191 dev->wiphy.rts_threshold) ||
1192 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1193 dev->wiphy.coverage_class) ||
1194 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1195 dev->wiphy.max_scan_ssids) ||
1196 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1197 dev->wiphy.max_sched_scan_ssids) ||
1198 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1199 dev->wiphy.max_scan_ie_len) ||
1200 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1201 dev->wiphy.max_sched_scan_ie_len) ||
1202 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
1203 dev->wiphy.max_match_sets))
1128 goto nla_put_failure; 1204 goto nla_put_failure;
1129 } 1205
1130 CMD(set_wds_peer, SET_WDS_PEER); 1206 if ((dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
1131 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) { 1207 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
1132 CMD(tdls_mgmt, TDLS_MGMT); 1208 goto nla_put_failure;
1133 CMD(tdls_oper, TDLS_OPER); 1209 if ((dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
1134 } 1210 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
1135 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) 1211 goto nla_put_failure;
1136 CMD(sched_scan_start, START_SCHED_SCAN); 1212 if ((dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
1137 CMD(probe_client, PROBE_CLIENT); 1213 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
1138 CMD(set_noack_map, SET_NOACK_MAP); 1214 goto nla_put_failure;
1139 if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) { 1215 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
1140 i++; 1216 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
1141 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS)) 1217 goto nla_put_failure;
1218 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
1219 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
1220 goto nla_put_failure;
1221 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
1222 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
1142 goto nla_put_failure; 1223 goto nla_put_failure;
1143 }
1144 CMD(start_p2p_device, START_P2P_DEVICE);
1145 CMD(set_mcast_rate, SET_MCAST_RATE);
1146 1224
1147#ifdef CONFIG_NL80211_TESTMODE 1225 (*split_start)++;
1148 CMD(testmode_cmd, TESTMODE); 1226 if (split)
1149#endif 1227 break;
1228 case 1:
1229 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1230 sizeof(u32) * dev->wiphy.n_cipher_suites,
1231 dev->wiphy.cipher_suites))
1232 goto nla_put_failure;
1150 1233
1151#undef CMD 1234 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1235 dev->wiphy.max_num_pmkids))
1236 goto nla_put_failure;
1152 1237
1153 if (dev->ops->connect || dev->ops->auth) { 1238 if ((dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
1154 i++; 1239 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
1155 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
1156 goto nla_put_failure; 1240 goto nla_put_failure;
1157 }
1158 1241
1159 if (dev->ops->disconnect || dev->ops->deauth) { 1242 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1160 i++; 1243 dev->wiphy.available_antennas_tx) ||
1161 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT)) 1244 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1245 dev->wiphy.available_antennas_rx))
1162 goto nla_put_failure; 1246 goto nla_put_failure;
1163 }
1164 1247
1165 nla_nest_end(msg, nl_cmds); 1248 if ((dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
1249 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1250 dev->wiphy.probe_resp_offload))
1251 goto nla_put_failure;
1166 1252
1167 if (dev->ops->remain_on_channel && 1253 if ((dev->wiphy.available_antennas_tx ||
1168 (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) && 1254 dev->wiphy.available_antennas_rx) &&
1169 nla_put_u32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, 1255 dev->ops->get_antenna) {
1170 dev->wiphy.max_remain_on_channel_duration)) 1256 u32 tx_ant = 0, rx_ant = 0;
1171 goto nla_put_failure; 1257 int res;
1258 res = rdev_get_antenna(dev, &tx_ant, &rx_ant);
1259 if (!res) {
1260 if (nla_put_u32(msg,
1261 NL80211_ATTR_WIPHY_ANTENNA_TX,
1262 tx_ant) ||
1263 nla_put_u32(msg,
1264 NL80211_ATTR_WIPHY_ANTENNA_RX,
1265 rx_ant))
1266 goto nla_put_failure;
1267 }
1268 }
1172 1269
1173 if ((dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) && 1270 (*split_start)++;
1174 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK)) 1271 if (split)
1175 goto nla_put_failure; 1272 break;
1273 case 2:
1274 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1275 dev->wiphy.interface_modes))
1276 goto nla_put_failure;
1277 (*split_start)++;
1278 if (split)
1279 break;
1280 case 3:
1281 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
1282 if (!nl_bands)
1283 goto nla_put_failure;
1176 1284
1177 if (mgmt_stypes) { 1285 for (band = *band_start; band < IEEE80211_NUM_BANDS; band++) {
1178 u16 stypes; 1286 struct ieee80211_supported_band *sband;
1179 struct nlattr *nl_ftypes, *nl_ifs;
1180 enum nl80211_iftype ift;
1181 1287
1182 nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES); 1288 sband = dev->wiphy.bands[band];
1183 if (!nl_ifs)
1184 goto nla_put_failure;
1185 1289
1186 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) { 1290 if (!sband)
1187 nl_ftypes = nla_nest_start(msg, ift); 1291 continue;
1188 if (!nl_ftypes) 1292
1293 nl_band = nla_nest_start(msg, band);
1294 if (!nl_band)
1189 goto nla_put_failure; 1295 goto nla_put_failure;
1190 i = 0; 1296
1191 stypes = mgmt_stypes[ift].tx; 1297 switch (*chan_start) {
1192 while (stypes) { 1298 case 0:
1193 if ((stypes & 1) && 1299 if (nl80211_send_band_rateinfo(msg, sband))
1194 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1195 (i << 4) | IEEE80211_FTYPE_MGMT))
1196 goto nla_put_failure; 1300 goto nla_put_failure;
1197 stypes >>= 1; 1301 (*chan_start)++;
1198 i++; 1302 if (split)
1303 break;
1304 default:
1305 /* add frequencies */
1306 nl_freqs = nla_nest_start(
1307 msg, NL80211_BAND_ATTR_FREQS);
1308 if (!nl_freqs)
1309 goto nla_put_failure;
1310
1311 for (i = *chan_start - 1;
1312 i < sband->n_channels;
1313 i++) {
1314 nl_freq = nla_nest_start(msg, i);
1315 if (!nl_freq)
1316 goto nla_put_failure;
1317
1318 chan = &sband->channels[i];
1319
1320 if (nl80211_msg_put_channel(msg, chan,
1321 split))
1322 goto nla_put_failure;
1323
1324 nla_nest_end(msg, nl_freq);
1325 if (split)
1326 break;
1327 }
1328 if (i < sband->n_channels)
1329 *chan_start = i + 2;
1330 else
1331 *chan_start = 0;
1332 nla_nest_end(msg, nl_freqs);
1333 }
1334
1335 nla_nest_end(msg, nl_band);
1336
1337 if (split) {
1338 /* start again here */
1339 if (*chan_start)
1340 band--;
1341 break;
1199 } 1342 }
1200 nla_nest_end(msg, nl_ftypes);
1201 } 1343 }
1344 nla_nest_end(msg, nl_bands);
1202 1345
1203 nla_nest_end(msg, nl_ifs); 1346 if (band < IEEE80211_NUM_BANDS)
1347 *band_start = band + 1;
1348 else
1349 *band_start = 0;
1204 1350
1205 nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES); 1351 /* if bands & channels are done, continue outside */
1206 if (!nl_ifs) 1352 if (*band_start == 0 && *chan_start == 0)
1353 (*split_start)++;
1354 if (split)
1355 break;
1356 case 4:
1357 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
1358 if (!nl_cmds)
1207 goto nla_put_failure; 1359 goto nla_put_failure;
1208 1360
1209 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) { 1361 i = 0;
1210 nl_ftypes = nla_nest_start(msg, ift); 1362#define CMD(op, n) \
1211 if (!nl_ftypes) 1363 do { \
1364 if (dev->ops->op) { \
1365 i++; \
1366 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1367 goto nla_put_failure; \
1368 } \
1369 } while (0)
1370
1371 CMD(add_virtual_intf, NEW_INTERFACE);
1372 CMD(change_virtual_intf, SET_INTERFACE);
1373 CMD(add_key, NEW_KEY);
1374 CMD(start_ap, START_AP);
1375 CMD(add_station, NEW_STATION);
1376 CMD(add_mpath, NEW_MPATH);
1377 CMD(update_mesh_config, SET_MESH_CONFIG);
1378 CMD(change_bss, SET_BSS);
1379 CMD(auth, AUTHENTICATE);
1380 CMD(assoc, ASSOCIATE);
1381 CMD(deauth, DEAUTHENTICATE);
1382 CMD(disassoc, DISASSOCIATE);
1383 CMD(join_ibss, JOIN_IBSS);
1384 CMD(join_mesh, JOIN_MESH);
1385 CMD(set_pmksa, SET_PMKSA);
1386 CMD(del_pmksa, DEL_PMKSA);
1387 CMD(flush_pmksa, FLUSH_PMKSA);
1388 if (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
1389 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1390 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1391 CMD(mgmt_tx, FRAME);
1392 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1393 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
1394 i++;
1395 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
1212 goto nla_put_failure; 1396 goto nla_put_failure;
1213 i = 0;
1214 stypes = mgmt_stypes[ift].rx;
1215 while (stypes) {
1216 if ((stypes & 1) &&
1217 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1218 (i << 4) | IEEE80211_FTYPE_MGMT))
1219 goto nla_put_failure;
1220 stypes >>= 1;
1221 i++;
1222 }
1223 nla_nest_end(msg, nl_ftypes);
1224 } 1397 }
1225 nla_nest_end(msg, nl_ifs); 1398 if (dev->ops->set_monitor_channel || dev->ops->start_ap ||
1226 } 1399 dev->ops->join_mesh) {
1400 i++;
1401 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1402 goto nla_put_failure;
1403 }
1404 CMD(set_wds_peer, SET_WDS_PEER);
1405 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1406 CMD(tdls_mgmt, TDLS_MGMT);
1407 CMD(tdls_oper, TDLS_OPER);
1408 }
1409 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
1410 CMD(sched_scan_start, START_SCHED_SCAN);
1411 CMD(probe_client, PROBE_CLIENT);
1412 CMD(set_noack_map, SET_NOACK_MAP);
1413 if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
1414 i++;
1415 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1416 goto nla_put_failure;
1417 }
1418 CMD(start_p2p_device, START_P2P_DEVICE);
1419 CMD(set_mcast_rate, SET_MCAST_RATE);
1227 1420
1228#ifdef CONFIG_PM 1421#ifdef CONFIG_NL80211_TESTMODE
1229 if (dev->wiphy.wowlan.flags || dev->wiphy.wowlan.n_patterns) { 1422 CMD(testmode_cmd, TESTMODE);
1230 struct nlattr *nl_wowlan; 1423#endif
1231 1424
1232 nl_wowlan = nla_nest_start(msg, 1425#undef CMD
1233 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
1234 if (!nl_wowlan)
1235 goto nla_put_failure;
1236 1426
1237 if (((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) && 1427 if (dev->ops->connect || dev->ops->auth) {
1238 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || 1428 i++;
1239 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) && 1429 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
1240 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1241 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) &&
1242 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1243 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
1244 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1245 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
1246 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1247 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
1248 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1249 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
1250 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1251 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
1252 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1253 goto nla_put_failure;
1254 if (dev->wiphy.wowlan.n_patterns) {
1255 struct nl80211_wowlan_pattern_support pat = {
1256 .max_patterns = dev->wiphy.wowlan.n_patterns,
1257 .min_pattern_len =
1258 dev->wiphy.wowlan.pattern_min_len,
1259 .max_pattern_len =
1260 dev->wiphy.wowlan.pattern_max_len,
1261 .max_pkt_offset =
1262 dev->wiphy.wowlan.max_pkt_offset,
1263 };
1264 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1265 sizeof(pat), &pat))
1266 goto nla_put_failure; 1430 goto nla_put_failure;
1267 } 1431 }
1268 1432
1269 nla_nest_end(msg, nl_wowlan); 1433 if (dev->ops->disconnect || dev->ops->deauth) {
1270 } 1434 i++;
1435 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1436 goto nla_put_failure;
1437 }
1438
1439 nla_nest_end(msg, nl_cmds);
1440 (*split_start)++;
1441 if (split)
1442 break;
1443 case 5:
1444 if (dev->ops->remain_on_channel &&
1445 (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
1446 nla_put_u32(msg,
1447 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1448 dev->wiphy.max_remain_on_channel_duration))
1449 goto nla_put_failure;
1450
1451 if ((dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
1452 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
1453 goto nla_put_failure;
1454
1455 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
1456 goto nla_put_failure;
1457 (*split_start)++;
1458 if (split)
1459 break;
1460 case 6:
1461#ifdef CONFIG_PM
1462 if (nl80211_send_wowlan(msg, dev, split))
1463 goto nla_put_failure;
1464 (*split_start)++;
1465 if (split)
1466 break;
1467#else
1468 (*split_start)++;
1271#endif 1469#endif
1470 case 7:
1471 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1472 dev->wiphy.software_iftypes))
1473 goto nla_put_failure;
1272 1474
1273 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, 1475 if (nl80211_put_iface_combinations(&dev->wiphy, msg, split))
1274 dev->wiphy.software_iftypes)) 1476 goto nla_put_failure;
1275 goto nla_put_failure;
1276 1477
1277 if (nl80211_put_iface_combinations(&dev->wiphy, msg)) 1478 (*split_start)++;
1278 goto nla_put_failure; 1479 if (split)
1480 break;
1481 case 8:
1482 if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
1483 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1484 dev->wiphy.ap_sme_capa))
1485 goto nla_put_failure;
1279 1486
1280 if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) && 1487 features = dev->wiphy.features;
1281 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME, 1488 /*
1282 dev->wiphy.ap_sme_capa)) 1489 * We can only add the per-channel limit information if the
1283 goto nla_put_failure; 1490 * dump is split, otherwise it makes it too big. Therefore
1491 * only advertise it in that case.
1492 */
1493 if (split)
1494 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
1495 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
1496 goto nla_put_failure;
1284 1497
1285 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, 1498 if (dev->wiphy.ht_capa_mod_mask &&
1286 dev->wiphy.features)) 1499 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1287 goto nla_put_failure; 1500 sizeof(*dev->wiphy.ht_capa_mod_mask),
1501 dev->wiphy.ht_capa_mod_mask))
1502 goto nla_put_failure;
1288 1503
1289 if (dev->wiphy.ht_capa_mod_mask && 1504 if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
1290 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK, 1505 dev->wiphy.max_acl_mac_addrs &&
1291 sizeof(*dev->wiphy.ht_capa_mod_mask), 1506 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1292 dev->wiphy.ht_capa_mod_mask)) 1507 dev->wiphy.max_acl_mac_addrs))
1293 goto nla_put_failure; 1508 goto nla_put_failure;
1294 1509
1295 if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME && 1510 /*
1296 dev->wiphy.max_acl_mac_addrs && 1511 * Any information below this point is only available to
1297 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX, 1512 * applications that can deal with it being split. This
1298 dev->wiphy.max_acl_mac_addrs)) 1513 * helps ensure that newly added capabilities don't break
1299 goto nla_put_failure; 1514 * older tools by overrunning their buffers.
1515 *
1516 * We still increment split_start so that in the split
1517 * case we'll continue with more data in the next round,
1518 * but break unconditionally so unsplit data stops here.
1519 */
1520 (*split_start)++;
1521 break;
1522 case 9:
1523 if (dev->wiphy.extended_capabilities &&
1524 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1525 dev->wiphy.extended_capabilities_len,
1526 dev->wiphy.extended_capabilities) ||
1527 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1528 dev->wiphy.extended_capabilities_len,
1529 dev->wiphy.extended_capabilities_mask)))
1530 goto nla_put_failure;
1300 1531
1532 if (dev->wiphy.vht_capa_mod_mask &&
1533 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1534 sizeof(*dev->wiphy.vht_capa_mod_mask),
1535 dev->wiphy.vht_capa_mod_mask))
1536 goto nla_put_failure;
1537
1538 /* done */
1539 *split_start = 0;
1540 break;
1541 }
1301 return genlmsg_end(msg, hdr); 1542 return genlmsg_end(msg, hdr);
1302 1543
1303 nla_put_failure: 1544 nla_put_failure:
@@ -1310,39 +1551,80 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1310 int idx = 0, ret; 1551 int idx = 0, ret;
1311 int start = cb->args[0]; 1552 int start = cb->args[0];
1312 struct cfg80211_registered_device *dev; 1553 struct cfg80211_registered_device *dev;
1554 s64 filter_wiphy = -1;
1555 bool split = false;
1556 struct nlattr **tb = nl80211_fam.attrbuf;
1557 int res;
1313 1558
1314 mutex_lock(&cfg80211_mutex); 1559 mutex_lock(&cfg80211_mutex);
1560 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1561 tb, nl80211_fam.maxattr, nl80211_policy);
1562 if (res == 0) {
1563 split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
1564 if (tb[NL80211_ATTR_WIPHY])
1565 filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1566 if (tb[NL80211_ATTR_WDEV])
1567 filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
1568 if (tb[NL80211_ATTR_IFINDEX]) {
1569 struct net_device *netdev;
1570 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1571
1572 netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
1573 if (!netdev) {
1574 mutex_unlock(&cfg80211_mutex);
1575 return -ENODEV;
1576 }
1577 if (netdev->ieee80211_ptr) {
1578 dev = wiphy_to_dev(
1579 netdev->ieee80211_ptr->wiphy);
1580 filter_wiphy = dev->wiphy_idx;
1581 }
1582 dev_put(netdev);
1583 }
1584 }
1585
1315 list_for_each_entry(dev, &cfg80211_rdev_list, list) { 1586 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
1316 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) 1587 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
1317 continue; 1588 continue;
1318 if (++idx <= start) 1589 if (++idx <= start)
1319 continue; 1590 continue;
1320 ret = nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, 1591 if (filter_wiphy != -1 && dev->wiphy_idx != filter_wiphy)
1321 cb->nlh->nlmsg_seq, NLM_F_MULTI, 1592 continue;
1322 dev); 1593 /* attempt to fit multiple wiphy data chunks into the skb */
1323 if (ret < 0) { 1594 do {
1324 /* 1595 ret = nl80211_send_wiphy(dev, skb,
1325 * If sending the wiphy data didn't fit (ENOBUFS or 1596 NETLINK_CB(cb->skb).portid,
1326 * EMSGSIZE returned), this SKB is still empty (so 1597 cb->nlh->nlmsg_seq,
1327 * it's not too big because another wiphy dataset is 1598 NLM_F_MULTI,
1328 * already in the skb) and we've not tried to adjust 1599 split, &cb->args[1],
1329 * the dump allocation yet ... then adjust the alloc 1600 &cb->args[2],
1330 * size to be bigger, and return 1 but with the empty 1601 &cb->args[3]);
1331 * skb. This results in an empty message being RX'ed 1602 if (ret < 0) {
1332 * in userspace, but that is ignored. 1603 /*
1333 * 1604 * If sending the wiphy data didn't fit (ENOBUFS
1334 * We can then retry with the larger buffer. 1605 * or EMSGSIZE returned), this SKB is still
1335 */ 1606 * empty (so it's not too big because another
1336 if ((ret == -ENOBUFS || ret == -EMSGSIZE) && 1607 * wiphy dataset is already in the skb) and
1337 !skb->len && 1608 * we've not tried to adjust the dump allocation
1338 cb->min_dump_alloc < 4096) { 1609 * yet ... then adjust the alloc size to be
1339 cb->min_dump_alloc = 4096; 1610 * bigger, and return 1 but with the empty skb.
1340 mutex_unlock(&cfg80211_mutex); 1611 * This results in an empty message being RX'ed
1341 return 1; 1612 * in userspace, but that is ignored.
1613 *
1614 * We can then retry with the larger buffer.
1615 */
1616 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
1617 !skb->len &&
1618 cb->min_dump_alloc < 4096) {
1619 cb->min_dump_alloc = 4096;
1620 mutex_unlock(&cfg80211_mutex);
1621 return 1;
1622 }
1623 idx--;
1624 break;
1342 } 1625 }
1343 idx--; 1626 } while (cb->args[1] > 0);
1344 break; 1627 break;
1345 }
1346 } 1628 }
1347 mutex_unlock(&cfg80211_mutex); 1629 mutex_unlock(&cfg80211_mutex);
1348 1630
@@ -1360,7 +1642,8 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
1360 if (!msg) 1642 if (!msg)
1361 return -ENOMEM; 1643 return -ENOMEM;
1362 1644
1363 if (nl80211_send_wiphy(msg, info->snd_portid, info->snd_seq, 0, dev) < 0) { 1645 if (nl80211_send_wiphy(dev, msg, info->snd_portid, info->snd_seq, 0,
1646 false, NULL, NULL, NULL) < 0) {
1364 nlmsg_free(msg); 1647 nlmsg_free(msg);
1365 return -ENOBUFS; 1648 return -ENOBUFS;
1366 } 1649 }
@@ -2967,6 +3250,7 @@ static int parse_station_flags(struct genl_info *info,
2967 sta_flags = nla_data(nla); 3250 sta_flags = nla_data(nla);
2968 params->sta_flags_mask = sta_flags->mask; 3251 params->sta_flags_mask = sta_flags->mask;
2969 params->sta_flags_set = sta_flags->set; 3252 params->sta_flags_set = sta_flags->set;
3253 params->sta_flags_set &= params->sta_flags_mask;
2970 if ((params->sta_flags_mask | 3254 if ((params->sta_flags_mask |
2971 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID)) 3255 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
2972 return -EINVAL; 3256 return -EINVAL;
@@ -3320,6 +3604,136 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
3320 return genlmsg_reply(msg, info); 3604 return genlmsg_reply(msg, info);
3321} 3605}
3322 3606
3607int cfg80211_check_station_change(struct wiphy *wiphy,
3608 struct station_parameters *params,
3609 enum cfg80211_station_type statype)
3610{
3611 if (params->listen_interval != -1)
3612 return -EINVAL;
3613 if (params->aid)
3614 return -EINVAL;
3615
3616 /* When you run into this, adjust the code below for the new flag */
3617 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
3618
3619 switch (statype) {
3620 case CFG80211_STA_MESH_PEER_KERNEL:
3621 case CFG80211_STA_MESH_PEER_USER:
3622 /*
3623 * No ignoring the TDLS flag here -- the userspace mesh
3624 * code doesn't have the bug of including TDLS in the
3625 * mask everywhere.
3626 */
3627 if (params->sta_flags_mask &
3628 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3629 BIT(NL80211_STA_FLAG_MFP) |
3630 BIT(NL80211_STA_FLAG_AUTHORIZED)))
3631 return -EINVAL;
3632 break;
3633 case CFG80211_STA_TDLS_PEER_SETUP:
3634 case CFG80211_STA_TDLS_PEER_ACTIVE:
3635 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
3636 return -EINVAL;
3637 /* ignore since it can't change */
3638 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3639 break;
3640 default:
3641 /* disallow mesh-specific things */
3642 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
3643 return -EINVAL;
3644 if (params->local_pm)
3645 return -EINVAL;
3646 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
3647 return -EINVAL;
3648 }
3649
3650 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
3651 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
3652 /* TDLS can't be set, ... */
3653 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
3654 return -EINVAL;
3655 /*
3656 * ... but don't bother the driver with it. This works around
3657 * a hostapd/wpa_supplicant issue -- it always includes the
3658 * TLDS_PEER flag in the mask even for AP mode.
3659 */
3660 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3661 }
3662
3663 if (statype != CFG80211_STA_TDLS_PEER_SETUP) {
3664 /* reject other things that can't change */
3665 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
3666 return -EINVAL;
3667 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
3668 return -EINVAL;
3669 if (params->supported_rates)
3670 return -EINVAL;
3671 if (params->ext_capab || params->ht_capa || params->vht_capa)
3672 return -EINVAL;
3673 }
3674
3675 if (statype != CFG80211_STA_AP_CLIENT) {
3676 if (params->vlan)
3677 return -EINVAL;
3678 }
3679
3680 switch (statype) {
3681 case CFG80211_STA_AP_MLME_CLIENT:
3682 /* Use this only for authorizing/unauthorizing a station */
3683 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
3684 return -EOPNOTSUPP;
3685 break;
3686 case CFG80211_STA_AP_CLIENT:
3687 /* accept only the listed bits */
3688 if (params->sta_flags_mask &
3689 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
3690 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3691 BIT(NL80211_STA_FLAG_ASSOCIATED) |
3692 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
3693 BIT(NL80211_STA_FLAG_WME) |
3694 BIT(NL80211_STA_FLAG_MFP)))
3695 return -EINVAL;
3696
3697 /* but authenticated/associated only if driver handles it */
3698 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
3699 params->sta_flags_mask &
3700 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3701 BIT(NL80211_STA_FLAG_ASSOCIATED)))
3702 return -EINVAL;
3703 break;
3704 case CFG80211_STA_IBSS:
3705 case CFG80211_STA_AP_STA:
3706 /* reject any changes other than AUTHORIZED */
3707 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
3708 return -EINVAL;
3709 break;
3710 case CFG80211_STA_TDLS_PEER_SETUP:
3711 /* reject any changes other than AUTHORIZED or WME */
3712 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
3713 BIT(NL80211_STA_FLAG_WME)))
3714 return -EINVAL;
3715 /* force (at least) rates when authorizing */
3716 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
3717 !params->supported_rates)
3718 return -EINVAL;
3719 break;
3720 case CFG80211_STA_TDLS_PEER_ACTIVE:
3721 /* reject any changes */
3722 return -EINVAL;
3723 case CFG80211_STA_MESH_PEER_KERNEL:
3724 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
3725 return -EINVAL;
3726 break;
3727 case CFG80211_STA_MESH_PEER_USER:
3728 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
3729 return -EINVAL;
3730 break;
3731 }
3732
3733 return 0;
3734}
3735EXPORT_SYMBOL(cfg80211_check_station_change);
3736
3323/* 3737/*
3324 * Get vlan interface making sure it is running and on the right wiphy. 3738 * Get vlan interface making sure it is running and on the right wiphy.
3325 */ 3739 */
@@ -3342,6 +3756,13 @@ static struct net_device *get_vlan(struct genl_info *info,
3342 goto error; 3756 goto error;
3343 } 3757 }
3344 3758
3759 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
3760 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3761 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
3762 ret = -EINVAL;
3763 goto error;
3764 }
3765
3345 if (!netif_running(v)) { 3766 if (!netif_running(v)) {
3346 ret = -ENETDOWN; 3767 ret = -ENETDOWN;
3347 goto error; 3768 goto error;
@@ -3359,21 +3780,13 @@ nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
3359 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 }, 3780 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
3360}; 3781};
3361 3782
3362static int nl80211_set_station_tdls(struct genl_info *info, 3783static int nl80211_parse_sta_wme(struct genl_info *info,
3363 struct station_parameters *params) 3784 struct station_parameters *params)
3364{ 3785{
3365 struct nlattr *tb[NL80211_STA_WME_MAX + 1]; 3786 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
3366 struct nlattr *nla; 3787 struct nlattr *nla;
3367 int err; 3788 int err;
3368 3789
3369 /* Dummy STA entry gets updated once the peer capabilities are known */
3370 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
3371 params->ht_capa =
3372 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
3373 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
3374 params->vht_capa =
3375 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
3376
3377 /* parse WME attributes if present */ 3790 /* parse WME attributes if present */
3378 if (!info->attrs[NL80211_ATTR_STA_WME]) 3791 if (!info->attrs[NL80211_ATTR_STA_WME])
3379 return 0; 3792 return 0;
@@ -3401,18 +3814,34 @@ static int nl80211_set_station_tdls(struct genl_info *info,
3401 return 0; 3814 return 0;
3402} 3815}
3403 3816
3817static int nl80211_set_station_tdls(struct genl_info *info,
3818 struct station_parameters *params)
3819{
3820 /* Dummy STA entry gets updated once the peer capabilities are known */
3821 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
3822 params->ht_capa =
3823 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
3824 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
3825 params->vht_capa =
3826 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
3827
3828 return nl80211_parse_sta_wme(info, params);
3829}
3830
3404static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) 3831static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
3405{ 3832{
3406 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 3833 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3407 int err;
3408 struct net_device *dev = info->user_ptr[1]; 3834 struct net_device *dev = info->user_ptr[1];
3409 struct station_parameters params; 3835 struct station_parameters params;
3410 u8 *mac_addr = NULL; 3836 u8 *mac_addr;
3837 int err;
3411 3838
3412 memset(&params, 0, sizeof(params)); 3839 memset(&params, 0, sizeof(params));
3413 3840
3414 params.listen_interval = -1; 3841 params.listen_interval = -1;
3415 params.plink_state = -1; 3842
3843 if (!rdev->ops->change_station)
3844 return -EOPNOTSUPP;
3416 3845
3417 if (info->attrs[NL80211_ATTR_STA_AID]) 3846 if (info->attrs[NL80211_ATTR_STA_AID])
3418 return -EINVAL; 3847 return -EINVAL;
@@ -3445,19 +3874,23 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
3445 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) 3874 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
3446 return -EINVAL; 3875 return -EINVAL;
3447 3876
3448 if (!rdev->ops->change_station)
3449 return -EOPNOTSUPP;
3450
3451 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params)) 3877 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
3452 return -EINVAL; 3878 return -EINVAL;
3453 3879
3454 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) 3880 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
3455 params.plink_action = 3881 params.plink_action =
3456 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 3882 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
3883 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
3884 return -EINVAL;
3885 }
3457 3886
3458 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) 3887 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
3459 params.plink_state = 3888 params.plink_state =
3460 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); 3889 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
3890 if (params.plink_state >= NUM_NL80211_PLINK_STATES)
3891 return -EINVAL;
3892 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
3893 }
3461 3894
3462 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) { 3895 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) {
3463 enum nl80211_mesh_power_mode pm = nla_get_u32( 3896 enum nl80211_mesh_power_mode pm = nla_get_u32(
@@ -3470,127 +3903,33 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
3470 params.local_pm = pm; 3903 params.local_pm = pm;
3471 } 3904 }
3472 3905
3906 /* Include parameters for TDLS peer (will check later) */
3907 err = nl80211_set_station_tdls(info, &params);
3908 if (err)
3909 return err;
3910
3911 params.vlan = get_vlan(info, rdev);
3912 if (IS_ERR(params.vlan))
3913 return PTR_ERR(params.vlan);
3914
3473 switch (dev->ieee80211_ptr->iftype) { 3915 switch (dev->ieee80211_ptr->iftype) {
3474 case NL80211_IFTYPE_AP: 3916 case NL80211_IFTYPE_AP:
3475 case NL80211_IFTYPE_AP_VLAN: 3917 case NL80211_IFTYPE_AP_VLAN:
3476 case NL80211_IFTYPE_P2P_GO: 3918 case NL80211_IFTYPE_P2P_GO:
3477 /* disallow mesh-specific things */
3478 if (params.plink_action)
3479 return -EINVAL;
3480 if (params.local_pm)
3481 return -EINVAL;
3482
3483 /* TDLS can't be set, ... */
3484 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
3485 return -EINVAL;
3486 /*
3487 * ... but don't bother the driver with it. This works around
3488 * a hostapd/wpa_supplicant issue -- it always includes the
3489 * TLDS_PEER flag in the mask even for AP mode.
3490 */
3491 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3492
3493 /* accept only the listed bits */
3494 if (params.sta_flags_mask &
3495 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
3496 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3497 BIT(NL80211_STA_FLAG_ASSOCIATED) |
3498 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
3499 BIT(NL80211_STA_FLAG_WME) |
3500 BIT(NL80211_STA_FLAG_MFP)))
3501 return -EINVAL;
3502
3503 /* but authenticated/associated only if driver handles it */
3504 if (!(rdev->wiphy.features &
3505 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
3506 params.sta_flags_mask &
3507 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3508 BIT(NL80211_STA_FLAG_ASSOCIATED)))
3509 return -EINVAL;
3510
3511 /* reject other things that can't change */
3512 if (params.supported_rates)
3513 return -EINVAL;
3514 if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
3515 return -EINVAL;
3516 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
3517 return -EINVAL;
3518 if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
3519 info->attrs[NL80211_ATTR_VHT_CAPABILITY])
3520 return -EINVAL;
3521
3522 /* must be last in here for error handling */
3523 params.vlan = get_vlan(info, rdev);
3524 if (IS_ERR(params.vlan))
3525 return PTR_ERR(params.vlan);
3526 break;
3527 case NL80211_IFTYPE_P2P_CLIENT: 3919 case NL80211_IFTYPE_P2P_CLIENT:
3528 case NL80211_IFTYPE_STATION: 3920 case NL80211_IFTYPE_STATION:
3529 /*
3530 * Don't allow userspace to change the TDLS_PEER flag,
3531 * but silently ignore attempts to change it since we
3532 * don't have state here to verify that it doesn't try
3533 * to change the flag.
3534 */
3535 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3536 /* Include parameters for TDLS peer (driver will check) */
3537 err = nl80211_set_station_tdls(info, &params);
3538 if (err)
3539 return err;
3540 /* disallow things sta doesn't support */
3541 if (params.plink_action)
3542 return -EINVAL;
3543 if (params.local_pm)
3544 return -EINVAL;
3545 /* reject any changes other than AUTHORIZED or WME (for TDLS) */
3546 if (params.sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
3547 BIT(NL80211_STA_FLAG_WME)))
3548 return -EINVAL;
3549 break;
3550 case NL80211_IFTYPE_ADHOC: 3921 case NL80211_IFTYPE_ADHOC:
3551 /* disallow things sta doesn't support */
3552 if (params.plink_action)
3553 return -EINVAL;
3554 if (params.local_pm)
3555 return -EINVAL;
3556 if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
3557 info->attrs[NL80211_ATTR_VHT_CAPABILITY])
3558 return -EINVAL;
3559 /* reject any changes other than AUTHORIZED */
3560 if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
3561 return -EINVAL;
3562 break;
3563 case NL80211_IFTYPE_MESH_POINT: 3922 case NL80211_IFTYPE_MESH_POINT:
3564 /* disallow things mesh doesn't support */
3565 if (params.vlan)
3566 return -EINVAL;
3567 if (params.supported_rates)
3568 return -EINVAL;
3569 if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
3570 return -EINVAL;
3571 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
3572 return -EINVAL;
3573 if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
3574 info->attrs[NL80211_ATTR_VHT_CAPABILITY])
3575 return -EINVAL;
3576 /*
3577 * No special handling for TDLS here -- the userspace
3578 * mesh code doesn't have this bug.
3579 */
3580 if (params.sta_flags_mask &
3581 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3582 BIT(NL80211_STA_FLAG_MFP) |
3583 BIT(NL80211_STA_FLAG_AUTHORIZED)))
3584 return -EINVAL;
3585 break; 3923 break;
3586 default: 3924 default:
3587 return -EOPNOTSUPP; 3925 err = -EOPNOTSUPP;
3926 goto out_put_vlan;
3588 } 3927 }
3589 3928
3590 /* be aware of params.vlan when changing code here */ 3929 /* driver will call cfg80211_check_station_change() */
3591
3592 err = rdev_change_station(rdev, dev, mac_addr, &params); 3930 err = rdev_change_station(rdev, dev, mac_addr, &params);
3593 3931
3932 out_put_vlan:
3594 if (params.vlan) 3933 if (params.vlan)
3595 dev_put(params.vlan); 3934 dev_put(params.vlan);
3596 3935
@@ -3607,6 +3946,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3607 3946
3608 memset(&params, 0, sizeof(params)); 3947 memset(&params, 0, sizeof(params));
3609 3948
3949 if (!rdev->ops->add_station)
3950 return -EOPNOTSUPP;
3951
3610 if (!info->attrs[NL80211_ATTR_MAC]) 3952 if (!info->attrs[NL80211_ATTR_MAC])
3611 return -EINVAL; 3953 return -EINVAL;
3612 3954
@@ -3652,50 +3994,32 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3652 params.vht_capa = 3994 params.vht_capa =
3653 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]); 3995 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
3654 3996
3655 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) 3997 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
3656 params.plink_action = 3998 params.plink_action =
3657 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 3999 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
4000 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
4001 return -EINVAL;
4002 }
3658 4003
3659 if (!rdev->ops->add_station) 4004 err = nl80211_parse_sta_wme(info, &params);
3660 return -EOPNOTSUPP; 4005 if (err)
4006 return err;
3661 4007
3662 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params)) 4008 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
3663 return -EINVAL; 4009 return -EINVAL;
3664 4010
4011 /* When you run into this, adjust the code below for the new flag */
4012 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
4013
3665 switch (dev->ieee80211_ptr->iftype) { 4014 switch (dev->ieee80211_ptr->iftype) {
3666 case NL80211_IFTYPE_AP: 4015 case NL80211_IFTYPE_AP:
3667 case NL80211_IFTYPE_AP_VLAN: 4016 case NL80211_IFTYPE_AP_VLAN:
3668 case NL80211_IFTYPE_P2P_GO: 4017 case NL80211_IFTYPE_P2P_GO:
3669 /* parse WME attributes if sta is WME capable */ 4018 /* ignore WME attributes if iface/sta is not capable */
3670 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && 4019 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
3671 (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) && 4020 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
3672 info->attrs[NL80211_ATTR_STA_WME]) { 4021 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
3673 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
3674 struct nlattr *nla;
3675
3676 nla = info->attrs[NL80211_ATTR_STA_WME];
3677 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
3678 nl80211_sta_wme_policy);
3679 if (err)
3680 return err;
3681 4022
3682 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
3683 params.uapsd_queues =
3684 nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]);
3685 if (params.uapsd_queues &
3686 ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
3687 return -EINVAL;
3688
3689 if (tb[NL80211_STA_WME_MAX_SP])
3690 params.max_sp =
3691 nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
3692
3693 if (params.max_sp &
3694 ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
3695 return -EINVAL;
3696
3697 params.sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
3698 }
3699 /* TDLS peers cannot be added */ 4023 /* TDLS peers cannot be added */
3700 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) 4024 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
3701 return -EINVAL; 4025 return -EINVAL;
@@ -3716,6 +4040,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3716 return PTR_ERR(params.vlan); 4040 return PTR_ERR(params.vlan);
3717 break; 4041 break;
3718 case NL80211_IFTYPE_MESH_POINT: 4042 case NL80211_IFTYPE_MESH_POINT:
4043 /* ignore uAPSD data */
4044 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
4045
3719 /* associated is disallowed */ 4046 /* associated is disallowed */
3720 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) 4047 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
3721 return -EINVAL; 4048 return -EINVAL;
@@ -3724,8 +4051,14 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3724 return -EINVAL; 4051 return -EINVAL;
3725 break; 4052 break;
3726 case NL80211_IFTYPE_STATION: 4053 case NL80211_IFTYPE_STATION:
3727 /* associated is disallowed */ 4054 case NL80211_IFTYPE_P2P_CLIENT:
3728 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) 4055 /* ignore uAPSD data */
4056 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
4057
4058 /* these are disallowed */
4059 if (params.sta_flags_mask &
4060 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
4061 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
3729 return -EINVAL; 4062 return -EINVAL;
3730 /* Only TDLS peers can be added */ 4063 /* Only TDLS peers can be added */
3731 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) 4064 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
@@ -3736,6 +4069,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3736 /* ... with external setup is supported */ 4069 /* ... with external setup is supported */
3737 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)) 4070 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
3738 return -EOPNOTSUPP; 4071 return -EOPNOTSUPP;
4072 /*
4073 * Older wpa_supplicant versions always mark the TDLS peer
4074 * as authorized, but it shouldn't yet be.
4075 */
4076 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
3739 break; 4077 break;
3740 default: 4078 default:
3741 return -EOPNOTSUPP; 4079 return -EOPNOTSUPP;
@@ -4280,6 +4618,7 @@ static const struct nla_policy
4280 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, 4618 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
4281 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, 4619 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
4282 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, 4620 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
4621 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
4283 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, 4622 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
4284 .len = IEEE80211_MAX_DATA_LEN }, 4623 .len = IEEE80211_MAX_DATA_LEN },
4285 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG }, 4624 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
@@ -4418,6 +4757,7 @@ do { \
4418static int nl80211_parse_mesh_setup(struct genl_info *info, 4757static int nl80211_parse_mesh_setup(struct genl_info *info,
4419 struct mesh_setup *setup) 4758 struct mesh_setup *setup)
4420{ 4759{
4760 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4421 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1]; 4761 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
4422 4762
4423 if (!info->attrs[NL80211_ATTR_MESH_SETUP]) 4763 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
@@ -4454,8 +4794,14 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
4454 setup->ie = nla_data(ieattr); 4794 setup->ie = nla_data(ieattr);
4455 setup->ie_len = nla_len(ieattr); 4795 setup->ie_len = nla_len(ieattr);
4456 } 4796 }
4797 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
4798 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
4799 return -EINVAL;
4800 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
4457 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); 4801 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
4458 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]); 4802 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
4803 if (setup->is_secure)
4804 setup->user_mpm = true;
4459 4805
4460 return 0; 4806 return 0;
4461} 4807}
@@ -5650,14 +5996,10 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
5650{ 5996{
5651 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 5997 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5652 struct net_device *dev = info->user_ptr[1]; 5998 struct net_device *dev = info->user_ptr[1];
5653 struct cfg80211_crypto_settings crypto;
5654 struct ieee80211_channel *chan; 5999 struct ieee80211_channel *chan;
5655 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; 6000 struct cfg80211_assoc_request req = {};
5656 int err, ssid_len, ie_len = 0; 6001 const u8 *bssid, *ssid;
5657 bool use_mfp = false; 6002 int err, ssid_len = 0;
5658 u32 flags = 0;
5659 struct ieee80211_ht_cap *ht_capa = NULL;
5660 struct ieee80211_ht_cap *ht_capa_mask = NULL;
5661 6003
5662 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 6004 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
5663 return -EINVAL; 6005 return -EINVAL;
@@ -5685,41 +6027,58 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
5685 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); 6027 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
5686 6028
5687 if (info->attrs[NL80211_ATTR_IE]) { 6029 if (info->attrs[NL80211_ATTR_IE]) {
5688 ie = nla_data(info->attrs[NL80211_ATTR_IE]); 6030 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
5689 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 6031 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5690 } 6032 }
5691 6033
5692 if (info->attrs[NL80211_ATTR_USE_MFP]) { 6034 if (info->attrs[NL80211_ATTR_USE_MFP]) {
5693 enum nl80211_mfp mfp = 6035 enum nl80211_mfp mfp =
5694 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]); 6036 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
5695 if (mfp == NL80211_MFP_REQUIRED) 6037 if (mfp == NL80211_MFP_REQUIRED)
5696 use_mfp = true; 6038 req.use_mfp = true;
5697 else if (mfp != NL80211_MFP_NO) 6039 else if (mfp != NL80211_MFP_NO)
5698 return -EINVAL; 6040 return -EINVAL;
5699 } 6041 }
5700 6042
5701 if (info->attrs[NL80211_ATTR_PREV_BSSID]) 6043 if (info->attrs[NL80211_ATTR_PREV_BSSID])
5702 prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]); 6044 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
5703 6045
5704 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT])) 6046 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
5705 flags |= ASSOC_REQ_DISABLE_HT; 6047 req.flags |= ASSOC_REQ_DISABLE_HT;
5706 6048
5707 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) 6049 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
5708 ht_capa_mask = 6050 memcpy(&req.ht_capa_mask,
5709 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]); 6051 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
6052 sizeof(req.ht_capa_mask));
5710 6053
5711 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { 6054 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
5712 if (!ht_capa_mask) 6055 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
5713 return -EINVAL; 6056 return -EINVAL;
5714 ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 6057 memcpy(&req.ht_capa,
6058 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
6059 sizeof(req.ht_capa));
5715 } 6060 }
5716 6061
5717 err = nl80211_crypto_settings(rdev, info, &crypto, 1); 6062 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
6063 req.flags |= ASSOC_REQ_DISABLE_VHT;
6064
6065 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
6066 memcpy(&req.vht_capa_mask,
6067 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
6068 sizeof(req.vht_capa_mask));
6069
6070 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
6071 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
6072 return -EINVAL;
6073 memcpy(&req.vht_capa,
6074 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
6075 sizeof(req.vht_capa));
6076 }
6077
6078 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
5718 if (!err) 6079 if (!err)
5719 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, 6080 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
5720 ssid, ssid_len, ie, ie_len, use_mfp, 6081 ssid, ssid_len, &req);
5721 &crypto, flags, ht_capa,
5722 ht_capa_mask);
5723 6082
5724 return err; 6083 return err;
5725} 6084}
@@ -6299,6 +6658,24 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
6299 sizeof(connect.ht_capa)); 6658 sizeof(connect.ht_capa));
6300 } 6659 }
6301 6660
6661 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
6662 connect.flags |= ASSOC_REQ_DISABLE_VHT;
6663
6664 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
6665 memcpy(&connect.vht_capa_mask,
6666 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
6667 sizeof(connect.vht_capa_mask));
6668
6669 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
6670 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
6671 kfree(connkeys);
6672 return -EINVAL;
6673 }
6674 memcpy(&connect.vht_capa,
6675 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
6676 sizeof(connect.vht_capa));
6677 }
6678
6302 err = cfg80211_connect(rdev, dev, &connect, connkeys); 6679 err = cfg80211_connect(rdev, dev, &connect, connkeys);
6303 if (err) 6680 if (err)
6304 kfree(connkeys); 6681 kfree(connkeys);
@@ -7072,6 +7449,9 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
7072 return err; 7449 return err;
7073 } 7450 }
7074 7451
7452 if (setup.user_mpm)
7453 cfg.auto_open_plinks = false;
7454
7075 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 7455 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
7076 err = nl80211_parse_chandef(rdev, info, &setup.chandef); 7456 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
7077 if (err) 7457 if (err)
@@ -7271,7 +7651,8 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
7271 return -EINVAL; 7651 return -EINVAL;
7272 7652
7273 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) > 7653 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
7274 rdev->wiphy.wowlan.tcp->data_interval_max) 7654 rdev->wiphy.wowlan.tcp->data_interval_max ||
7655 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
7275 return -EINVAL; 7656 return -EINVAL;
7276 7657
7277 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]); 7658 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
@@ -7767,6 +8148,54 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
7767 return 0; 8148 return 0;
7768} 8149}
7769 8150
8151static int nl80211_get_protocol_features(struct sk_buff *skb,
8152 struct genl_info *info)
8153{
8154 void *hdr;
8155 struct sk_buff *msg;
8156
8157 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8158 if (!msg)
8159 return -ENOMEM;
8160
8161 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
8162 NL80211_CMD_GET_PROTOCOL_FEATURES);
8163 if (!hdr)
8164 goto nla_put_failure;
8165
8166 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
8167 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
8168 goto nla_put_failure;
8169
8170 genlmsg_end(msg, hdr);
8171 return genlmsg_reply(msg, info);
8172
8173 nla_put_failure:
8174 kfree_skb(msg);
8175 return -ENOBUFS;
8176}
8177
8178static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
8179{
8180 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8181 struct cfg80211_update_ft_ies_params ft_params;
8182 struct net_device *dev = info->user_ptr[1];
8183
8184 if (!rdev->ops->update_ft_ies)
8185 return -EOPNOTSUPP;
8186
8187 if (!info->attrs[NL80211_ATTR_MDID] ||
8188 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8189 return -EINVAL;
8190
8191 memset(&ft_params, 0, sizeof(ft_params));
8192 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
8193 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8194 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8195
8196 return rdev_update_ft_ies(rdev, dev, &ft_params);
8197}
8198
7770#define NL80211_FLAG_NEED_WIPHY 0x01 8199#define NL80211_FLAG_NEED_WIPHY 0x01
7771#define NL80211_FLAG_NEED_NETDEV 0x02 8200#define NL80211_FLAG_NEED_NETDEV 0x02
7772#define NL80211_FLAG_NEED_RTNL 0x04 8201#define NL80211_FLAG_NEED_RTNL 0x04
@@ -8443,6 +8872,19 @@ static struct genl_ops nl80211_ops[] = {
8443 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 8872 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
8444 NL80211_FLAG_NEED_RTNL, 8873 NL80211_FLAG_NEED_RTNL,
8445 }, 8874 },
8875 {
8876 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
8877 .doit = nl80211_get_protocol_features,
8878 .policy = nl80211_policy,
8879 },
8880 {
8881 .cmd = NL80211_CMD_UPDATE_FT_IES,
8882 .doit = nl80211_update_ft_ies,
8883 .policy = nl80211_policy,
8884 .flags = GENL_ADMIN_PERM,
8885 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
8886 NL80211_FLAG_NEED_RTNL,
8887 },
8446}; 8888};
8447 8889
8448static struct genl_multicast_group nl80211_mlme_mcgrp = { 8890static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -8470,7 +8912,8 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
8470 if (!msg) 8912 if (!msg)
8471 return; 8913 return;
8472 8914
8473 if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) { 8915 if (nl80211_send_wiphy(rdev, msg, 0, 0, 0,
8916 false, NULL, NULL, NULL) < 0) {
8474 nlmsg_free(msg); 8917 nlmsg_free(msg);
8475 return; 8918 return;
8476 } 8919 }
@@ -8794,21 +9237,31 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
8794 NL80211_CMD_DISASSOCIATE, gfp); 9237 NL80211_CMD_DISASSOCIATE, gfp);
8795} 9238}
8796 9239
8797void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev, 9240void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
8798 struct net_device *netdev, const u8 *buf, 9241 size_t len)
8799 size_t len, gfp_t gfp)
8800{ 9242{
8801 nl80211_send_mlme_event(rdev, netdev, buf, len, 9243 struct wireless_dev *wdev = dev->ieee80211_ptr;
8802 NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp); 9244 struct wiphy *wiphy = wdev->wiphy;
9245 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9246
9247 trace_cfg80211_send_unprot_deauth(dev);
9248 nl80211_send_mlme_event(rdev, dev, buf, len,
9249 NL80211_CMD_UNPROT_DEAUTHENTICATE, GFP_ATOMIC);
8803} 9250}
9251EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
8804 9252
8805void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev, 9253void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
8806 struct net_device *netdev, const u8 *buf, 9254 size_t len)
8807 size_t len, gfp_t gfp)
8808{ 9255{
8809 nl80211_send_mlme_event(rdev, netdev, buf, len, 9256 struct wireless_dev *wdev = dev->ieee80211_ptr;
8810 NL80211_CMD_UNPROT_DISASSOCIATE, gfp); 9257 struct wiphy *wiphy = wdev->wiphy;
9258 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9259
9260 trace_cfg80211_send_unprot_disassoc(dev);
9261 nl80211_send_mlme_event(rdev, dev, buf, len,
9262 NL80211_CMD_UNPROT_DISASSOCIATE, GFP_ATOMIC);
8811} 9263}
9264EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
8812 9265
8813static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, 9266static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
8814 struct net_device *netdev, int cmd, 9267 struct net_device *netdev, int cmd,
@@ -9011,14 +9464,19 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
9011 nlmsg_free(msg); 9464 nlmsg_free(msg);
9012} 9465}
9013 9466
9014void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, 9467void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
9015 struct net_device *netdev, 9468 const u8* ie, u8 ie_len, gfp_t gfp)
9016 const u8 *macaddr, const u8* ie, u8 ie_len,
9017 gfp_t gfp)
9018{ 9469{
9470 struct wireless_dev *wdev = dev->ieee80211_ptr;
9471 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
9019 struct sk_buff *msg; 9472 struct sk_buff *msg;
9020 void *hdr; 9473 void *hdr;
9021 9474
9475 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
9476 return;
9477
9478 trace_cfg80211_notify_new_peer_candidate(dev, addr);
9479
9022 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 9480 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
9023 if (!msg) 9481 if (!msg)
9024 return; 9482 return;
@@ -9030,8 +9488,8 @@ void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
9030 } 9488 }
9031 9489
9032 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 9490 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
9033 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || 9491 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
9034 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr) || 9492 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9035 (ie_len && ie && 9493 (ie_len && ie &&
9036 nla_put(msg, NL80211_ATTR_IE, ie_len , ie))) 9494 nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
9037 goto nla_put_failure; 9495 goto nla_put_failure;
@@ -9046,6 +9504,7 @@ void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
9046 genlmsg_cancel(msg, hdr); 9504 genlmsg_cancel(msg, hdr);
9047 nlmsg_free(msg); 9505 nlmsg_free(msg);
9048} 9506}
9507EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
9049 9508
9050void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, 9509void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
9051 struct net_device *netdev, const u8 *addr, 9510 struct net_device *netdev, const u8 *addr,
@@ -9114,7 +9573,7 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
9114 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE); 9573 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
9115 if (!nl_freq) 9574 if (!nl_freq)
9116 goto nla_put_failure; 9575 goto nla_put_failure;
9117 if (nl80211_msg_put_channel(msg, channel_before)) 9576 if (nl80211_msg_put_channel(msg, channel_before, false))
9118 goto nla_put_failure; 9577 goto nla_put_failure;
9119 nla_nest_end(msg, nl_freq); 9578 nla_nest_end(msg, nl_freq);
9120 9579
@@ -9122,7 +9581,7 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
9122 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER); 9581 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
9123 if (!nl_freq) 9582 if (!nl_freq)
9124 goto nla_put_failure; 9583 goto nla_put_failure;
9125 if (nl80211_msg_put_channel(msg, channel_after)) 9584 if (nl80211_msg_put_channel(msg, channel_after, false))
9126 goto nla_put_failure; 9585 goto nla_put_failure;
9127 nla_nest_end(msg, nl_freq); 9586 nla_nest_end(msg, nl_freq);
9128 9587
@@ -9184,31 +9643,42 @@ static void nl80211_send_remain_on_chan_event(
9184 nlmsg_free(msg); 9643 nlmsg_free(msg);
9185} 9644}
9186 9645
9187void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, 9646void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
9188 struct wireless_dev *wdev, u64 cookie, 9647 struct ieee80211_channel *chan,
9189 struct ieee80211_channel *chan, 9648 unsigned int duration, gfp_t gfp)
9190 unsigned int duration, gfp_t gfp)
9191{ 9649{
9650 struct wiphy *wiphy = wdev->wiphy;
9651 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9652
9653 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9192 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL, 9654 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
9193 rdev, wdev, cookie, chan, 9655 rdev, wdev, cookie, chan,
9194 duration, gfp); 9656 duration, gfp);
9195} 9657}
9658EXPORT_SYMBOL(cfg80211_ready_on_channel);
9196 9659
9197void nl80211_send_remain_on_channel_cancel( 9660void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
9198 struct cfg80211_registered_device *rdev, 9661 struct ieee80211_channel *chan,
9199 struct wireless_dev *wdev, 9662 gfp_t gfp)
9200 u64 cookie, struct ieee80211_channel *chan, gfp_t gfp)
9201{ 9663{
9664 struct wiphy *wiphy = wdev->wiphy;
9665 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9666
9667 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9202 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, 9668 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
9203 rdev, wdev, cookie, chan, 0, gfp); 9669 rdev, wdev, cookie, chan, 0, gfp);
9204} 9670}
9671EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9205 9672
9206void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, 9673void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
9207 struct net_device *dev, const u8 *mac_addr, 9674 struct station_info *sinfo, gfp_t gfp)
9208 struct station_info *sinfo, gfp_t gfp)
9209{ 9675{
9676 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
9677 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9210 struct sk_buff *msg; 9678 struct sk_buff *msg;
9211 9679
9680 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
9681
9212 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 9682 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
9213 if (!msg) 9683 if (!msg)
9214 return; 9684 return;
@@ -9222,14 +9692,17 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
9222 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 9692 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
9223 nl80211_mlme_mcgrp.id, gfp); 9693 nl80211_mlme_mcgrp.id, gfp);
9224} 9694}
9695EXPORT_SYMBOL(cfg80211_new_sta);
9225 9696
9226void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, 9697void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
9227 struct net_device *dev, const u8 *mac_addr,
9228 gfp_t gfp)
9229{ 9698{
9699 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
9700 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9230 struct sk_buff *msg; 9701 struct sk_buff *msg;
9231 void *hdr; 9702 void *hdr;
9232 9703
9704 trace_cfg80211_del_sta(dev, mac_addr);
9705
9233 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 9706 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
9234 if (!msg) 9707 if (!msg)
9235 return; 9708 return;
@@ -9254,12 +9727,14 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
9254 genlmsg_cancel(msg, hdr); 9727 genlmsg_cancel(msg, hdr);
9255 nlmsg_free(msg); 9728 nlmsg_free(msg);
9256} 9729}
9730EXPORT_SYMBOL(cfg80211_del_sta);
9257 9731
9258void nl80211_send_conn_failed_event(struct cfg80211_registered_device *rdev, 9732void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
9259 struct net_device *dev, const u8 *mac_addr, 9733 enum nl80211_connect_failed_reason reason,
9260 enum nl80211_connect_failed_reason reason, 9734 gfp_t gfp)
9261 gfp_t gfp)
9262{ 9735{
9736 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
9737 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9263 struct sk_buff *msg; 9738 struct sk_buff *msg;
9264 void *hdr; 9739 void *hdr;
9265 9740
@@ -9288,6 +9763,7 @@ void nl80211_send_conn_failed_event(struct cfg80211_registered_device *rdev,
9288 genlmsg_cancel(msg, hdr); 9763 genlmsg_cancel(msg, hdr);
9289 nlmsg_free(msg); 9764 nlmsg_free(msg);
9290} 9765}
9766EXPORT_SYMBOL(cfg80211_conn_failed);
9291 9767
9292static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, 9768static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
9293 const u8 *addr, gfp_t gfp) 9769 const u8 *addr, gfp_t gfp)
@@ -9332,19 +9808,47 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
9332 return true; 9808 return true;
9333} 9809}
9334 9810
9335bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp) 9811bool cfg80211_rx_spurious_frame(struct net_device *dev,
9812 const u8 *addr, gfp_t gfp)
9336{ 9813{
9337 return __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME, 9814 struct wireless_dev *wdev = dev->ieee80211_ptr;
9338 addr, gfp); 9815 bool ret;
9816
9817 trace_cfg80211_rx_spurious_frame(dev, addr);
9818
9819 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
9820 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
9821 trace_cfg80211_return_bool(false);
9822 return false;
9823 }
9824 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
9825 addr, gfp);
9826 trace_cfg80211_return_bool(ret);
9827 return ret;
9339} 9828}
9829EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
9340 9830
9341bool nl80211_unexpected_4addr_frame(struct net_device *dev, 9831bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
9342 const u8 *addr, gfp_t gfp) 9832 const u8 *addr, gfp_t gfp)
9343{ 9833{
9344 return __nl80211_unexpected_frame(dev, 9834 struct wireless_dev *wdev = dev->ieee80211_ptr;
9345 NL80211_CMD_UNEXPECTED_4ADDR_FRAME, 9835 bool ret;
9346 addr, gfp); 9836
9837 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
9838
9839 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
9840 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
9841 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
9842 trace_cfg80211_return_bool(false);
9843 return false;
9844 }
9845 ret = __nl80211_unexpected_frame(dev,
9846 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
9847 addr, gfp);
9848 trace_cfg80211_return_bool(ret);
9849 return ret;
9347} 9850}
9851EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
9348 9852
9349int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, 9853int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
9350 struct wireless_dev *wdev, u32 nlportid, 9854 struct wireless_dev *wdev, u32 nlportid,
@@ -9384,15 +9888,17 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
9384 return -ENOBUFS; 9888 return -ENOBUFS;
9385} 9889}
9386 9890
9387void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, 9891void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
9388 struct wireless_dev *wdev, u64 cookie, 9892 const u8 *buf, size_t len, bool ack, gfp_t gfp)
9389 const u8 *buf, size_t len, bool ack,
9390 gfp_t gfp)
9391{ 9893{
9894 struct wiphy *wiphy = wdev->wiphy;
9895 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9392 struct net_device *netdev = wdev->netdev; 9896 struct net_device *netdev = wdev->netdev;
9393 struct sk_buff *msg; 9897 struct sk_buff *msg;
9394 void *hdr; 9898 void *hdr;
9395 9899
9900 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
9901
9396 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 9902 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
9397 if (!msg) 9903 if (!msg)
9398 return; 9904 return;
@@ -9420,17 +9926,21 @@ void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
9420 genlmsg_cancel(msg, hdr); 9926 genlmsg_cancel(msg, hdr);
9421 nlmsg_free(msg); 9927 nlmsg_free(msg);
9422} 9928}
9929EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
9423 9930
9424void 9931void cfg80211_cqm_rssi_notify(struct net_device *dev,
9425nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, 9932 enum nl80211_cqm_rssi_threshold_event rssi_event,
9426 struct net_device *netdev, 9933 gfp_t gfp)
9427 enum nl80211_cqm_rssi_threshold_event rssi_event,
9428 gfp_t gfp)
9429{ 9934{
9935 struct wireless_dev *wdev = dev->ieee80211_ptr;
9936 struct wiphy *wiphy = wdev->wiphy;
9937 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9430 struct sk_buff *msg; 9938 struct sk_buff *msg;
9431 struct nlattr *pinfoattr; 9939 struct nlattr *pinfoattr;
9432 void *hdr; 9940 void *hdr;
9433 9941
9942 trace_cfg80211_cqm_rssi_notify(dev, rssi_event);
9943
9434 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 9944 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
9435 if (!msg) 9945 if (!msg)
9436 return; 9946 return;
@@ -9442,7 +9952,7 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
9442 } 9952 }
9443 9953
9444 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 9954 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
9445 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) 9955 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9446 goto nla_put_failure; 9956 goto nla_put_failure;
9447 9957
9448 pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); 9958 pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
@@ -9465,10 +9975,11 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
9465 genlmsg_cancel(msg, hdr); 9975 genlmsg_cancel(msg, hdr);
9466 nlmsg_free(msg); 9976 nlmsg_free(msg);
9467} 9977}
9978EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
9468 9979
9469void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, 9980static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
9470 struct net_device *netdev, const u8 *bssid, 9981 struct net_device *netdev, const u8 *bssid,
9471 const u8 *replay_ctr, gfp_t gfp) 9982 const u8 *replay_ctr, gfp_t gfp)
9472{ 9983{
9473 struct sk_buff *msg; 9984 struct sk_buff *msg;
9474 struct nlattr *rekey_attr; 9985 struct nlattr *rekey_attr;
@@ -9510,9 +10021,22 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
9510 nlmsg_free(msg); 10021 nlmsg_free(msg);
9511} 10022}
9512 10023
9513void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, 10024void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
9514 struct net_device *netdev, int index, 10025 const u8 *replay_ctr, gfp_t gfp)
9515 const u8 *bssid, bool preauth, gfp_t gfp) 10026{
10027 struct wireless_dev *wdev = dev->ieee80211_ptr;
10028 struct wiphy *wiphy = wdev->wiphy;
10029 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
10030
10031 trace_cfg80211_gtk_rekey_notify(dev, bssid);
10032 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
10033}
10034EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
10035
10036static void
10037nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
10038 struct net_device *netdev, int index,
10039 const u8 *bssid, bool preauth, gfp_t gfp)
9516{ 10040{
9517 struct sk_buff *msg; 10041 struct sk_buff *msg;
9518 struct nlattr *attr; 10042 struct nlattr *attr;
@@ -9555,9 +10079,22 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
9555 nlmsg_free(msg); 10079 nlmsg_free(msg);
9556} 10080}
9557 10081
9558void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, 10082void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
9559 struct net_device *netdev, 10083 const u8 *bssid, bool preauth, gfp_t gfp)
9560 struct cfg80211_chan_def *chandef, gfp_t gfp) 10084{
10085 struct wireless_dev *wdev = dev->ieee80211_ptr;
10086 struct wiphy *wiphy = wdev->wiphy;
10087 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
10088
10089 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
10090 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
10091}
10092EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
10093
10094static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
10095 struct net_device *netdev,
10096 struct cfg80211_chan_def *chandef,
10097 gfp_t gfp)
9561{ 10098{
9562 struct sk_buff *msg; 10099 struct sk_buff *msg;
9563 void *hdr; 10100 void *hdr;
@@ -9589,11 +10126,36 @@ void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
9589 nlmsg_free(msg); 10126 nlmsg_free(msg);
9590} 10127}
9591 10128
9592void 10129void cfg80211_ch_switch_notify(struct net_device *dev,
9593nl80211_send_cqm_txe_notify(struct cfg80211_registered_device *rdev, 10130 struct cfg80211_chan_def *chandef)
9594 struct net_device *netdev, const u8 *peer,
9595 u32 num_packets, u32 rate, u32 intvl, gfp_t gfp)
9596{ 10131{
10132 struct wireless_dev *wdev = dev->ieee80211_ptr;
10133 struct wiphy *wiphy = wdev->wiphy;
10134 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
10135
10136 trace_cfg80211_ch_switch_notify(dev, chandef);
10137
10138 wdev_lock(wdev);
10139
10140 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
10141 wdev->iftype != NL80211_IFTYPE_P2P_GO))
10142 goto out;
10143
10144 wdev->channel = chandef->chan;
10145 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
10146out:
10147 wdev_unlock(wdev);
10148 return;
10149}
10150EXPORT_SYMBOL(cfg80211_ch_switch_notify);
10151
10152void cfg80211_cqm_txe_notify(struct net_device *dev,
10153 const u8 *peer, u32 num_packets,
10154 u32 rate, u32 intvl, gfp_t gfp)
10155{
10156 struct wireless_dev *wdev = dev->ieee80211_ptr;
10157 struct wiphy *wiphy = wdev->wiphy;
10158 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9597 struct sk_buff *msg; 10159 struct sk_buff *msg;
9598 struct nlattr *pinfoattr; 10160 struct nlattr *pinfoattr;
9599 void *hdr; 10161 void *hdr;
@@ -9609,7 +10171,7 @@ nl80211_send_cqm_txe_notify(struct cfg80211_registered_device *rdev,
9609 } 10171 }
9610 10172
9611 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 10173 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
9612 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || 10174 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
9613 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) 10175 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer))
9614 goto nla_put_failure; 10176 goto nla_put_failure;
9615 10177
@@ -9638,6 +10200,7 @@ nl80211_send_cqm_txe_notify(struct cfg80211_registered_device *rdev,
9638 genlmsg_cancel(msg, hdr); 10200 genlmsg_cancel(msg, hdr);
9639 nlmsg_free(msg); 10201 nlmsg_free(msg);
9640} 10202}
10203EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
9641 10204
9642void 10205void
9643nl80211_radar_notify(struct cfg80211_registered_device *rdev, 10206nl80211_radar_notify(struct cfg80211_registered_device *rdev,
@@ -9690,15 +10253,18 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
9690 nlmsg_free(msg); 10253 nlmsg_free(msg);
9691} 10254}
9692 10255
9693void 10256void cfg80211_cqm_pktloss_notify(struct net_device *dev,
9694nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 10257 const u8 *peer, u32 num_packets, gfp_t gfp)
9695 struct net_device *netdev, const u8 *peer,
9696 u32 num_packets, gfp_t gfp)
9697{ 10258{
10259 struct wireless_dev *wdev = dev->ieee80211_ptr;
10260 struct wiphy *wiphy = wdev->wiphy;
10261 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9698 struct sk_buff *msg; 10262 struct sk_buff *msg;
9699 struct nlattr *pinfoattr; 10263 struct nlattr *pinfoattr;
9700 void *hdr; 10264 void *hdr;
9701 10265
10266 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
10267
9702 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 10268 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
9703 if (!msg) 10269 if (!msg)
9704 return; 10270 return;
@@ -9710,7 +10276,7 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
9710 } 10276 }
9711 10277
9712 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 10278 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
9713 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || 10279 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
9714 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) 10280 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer))
9715 goto nla_put_failure; 10281 goto nla_put_failure;
9716 10282
@@ -9733,6 +10299,7 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
9733 genlmsg_cancel(msg, hdr); 10299 genlmsg_cancel(msg, hdr);
9734 nlmsg_free(msg); 10300 nlmsg_free(msg);
9735} 10301}
10302EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
9736 10303
9737void cfg80211_probe_status(struct net_device *dev, const u8 *addr, 10304void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
9738 u64 cookie, bool acked, gfp_t gfp) 10305 u64 cookie, bool acked, gfp_t gfp)
@@ -10019,6 +10586,50 @@ static struct notifier_block nl80211_netlink_notifier = {
10019 .notifier_call = nl80211_netlink_notify, 10586 .notifier_call = nl80211_netlink_notify,
10020}; 10587};
10021 10588
10589void cfg80211_ft_event(struct net_device *netdev,
10590 struct cfg80211_ft_event_params *ft_event)
10591{
10592 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
10593 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
10594 struct sk_buff *msg;
10595 void *hdr;
10596 int err;
10597
10598 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
10599
10600 if (!ft_event->target_ap)
10601 return;
10602
10603 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10604 if (!msg)
10605 return;
10606
10607 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
10608 if (!hdr) {
10609 nlmsg_free(msg);
10610 return;
10611 }
10612
10613 nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
10614 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
10615 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap);
10616 if (ft_event->ies)
10617 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies);
10618 if (ft_event->ric_ies)
10619 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
10620 ft_event->ric_ies);
10621
10622 err = genlmsg_end(msg, hdr);
10623 if (err < 0) {
10624 nlmsg_free(msg);
10625 return;
10626 }
10627
10628 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
10629 nl80211_mlme_mcgrp.id, GFP_KERNEL);
10630}
10631EXPORT_SYMBOL(cfg80211_ft_event);
10632
10022/* initialisation/exit functions */ 10633/* initialisation/exit functions */
10023 10634
10024int nl80211_init(void) 10635int nl80211_init(void)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index b061da4919e1..a4073e808c13 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -29,12 +29,6 @@ void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
29void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, 29void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
30 struct net_device *netdev, 30 struct net_device *netdev,
31 const u8 *buf, size_t len, gfp_t gfp); 31 const u8 *buf, size_t len, gfp_t gfp);
32void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
33 struct net_device *netdev,
34 const u8 *buf, size_t len, gfp_t gfp);
35void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
36 struct net_device *netdev,
37 const u8 *buf, size_t len, gfp_t gfp);
38void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, 32void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
39 struct net_device *netdev, 33 struct net_device *netdev,
40 const u8 *addr, gfp_t gfp); 34 const u8 *addr, gfp_t gfp);
@@ -54,10 +48,6 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
54 struct net_device *netdev, u16 reason, 48 struct net_device *netdev, u16 reason,
55 const u8 *ie, size_t ie_len, bool from_ap); 49 const u8 *ie, size_t ie_len, bool from_ap);
56 50
57void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
58 struct net_device *netdev,
59 const u8 *macaddr, const u8* ie, u8 ie_len,
60 gfp_t gfp);
61void 51void
62nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, 52nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
63 struct net_device *netdev, const u8 *addr, 53 struct net_device *netdev, const u8 *addr,
@@ -73,41 +63,10 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
73 struct net_device *netdev, const u8 *bssid, 63 struct net_device *netdev, const u8 *bssid,
74 gfp_t gfp); 64 gfp_t gfp);
75 65
76void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
77 struct wireless_dev *wdev, u64 cookie,
78 struct ieee80211_channel *chan,
79 unsigned int duration, gfp_t gfp);
80void nl80211_send_remain_on_channel_cancel(
81 struct cfg80211_registered_device *rdev,
82 struct wireless_dev *wdev,
83 u64 cookie, struct ieee80211_channel *chan, gfp_t gfp);
84
85void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
86 struct net_device *dev, const u8 *mac_addr,
87 struct station_info *sinfo, gfp_t gfp);
88void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
89 struct net_device *dev, const u8 *mac_addr,
90 gfp_t gfp);
91
92void nl80211_send_conn_failed_event(struct cfg80211_registered_device *rdev,
93 struct net_device *dev, const u8 *mac_addr,
94 enum nl80211_connect_failed_reason reason,
95 gfp_t gfp);
96
97int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, 66int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
98 struct wireless_dev *wdev, u32 nlpid, 67 struct wireless_dev *wdev, u32 nlpid,
99 int freq, int sig_dbm, 68 int freq, int sig_dbm,
100 const u8 *buf, size_t len, gfp_t gfp); 69 const u8 *buf, size_t len, gfp_t gfp);
101void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
102 struct wireless_dev *wdev, u64 cookie,
103 const u8 *buf, size_t len, bool ack,
104 gfp_t gfp);
105
106void
107nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
108 struct net_device *netdev,
109 enum nl80211_cqm_rssi_threshold_event rssi_event,
110 gfp_t gfp);
111 70
112void 71void
113nl80211_radar_notify(struct cfg80211_registered_device *rdev, 72nl80211_radar_notify(struct cfg80211_registered_device *rdev,
@@ -115,31 +74,4 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
115 enum nl80211_radar_event event, 74 enum nl80211_radar_event event,
116 struct net_device *netdev, gfp_t gfp); 75 struct net_device *netdev, gfp_t gfp);
117 76
118void
119nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
120 struct net_device *netdev, const u8 *peer,
121 u32 num_packets, gfp_t gfp);
122
123void
124nl80211_send_cqm_txe_notify(struct cfg80211_registered_device *rdev,
125 struct net_device *netdev, const u8 *peer,
126 u32 num_packets, u32 rate, u32 intvl, gfp_t gfp);
127
128void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
129 struct net_device *netdev, const u8 *bssid,
130 const u8 *replay_ctr, gfp_t gfp);
131
132void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
133 struct net_device *netdev, int index,
134 const u8 *bssid, bool preauth, gfp_t gfp);
135
136void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
137 struct net_device *dev,
138 struct cfg80211_chan_def *chandef, gfp_t gfp);
139
140bool nl80211_unexpected_frame(struct net_device *dev,
141 const u8 *addr, gfp_t gfp);
142bool nl80211_unexpected_4addr_frame(struct net_device *dev,
143 const u8 *addr, gfp_t gfp);
144
145#endif /* __NET_WIRELESS_NL80211_H */ 77#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 422d38291d66..d77e1c1d3a0e 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -6,11 +6,12 @@
6#include "core.h" 6#include "core.h"
7#include "trace.h" 7#include "trace.h"
8 8
9static inline int rdev_suspend(struct cfg80211_registered_device *rdev) 9static inline int rdev_suspend(struct cfg80211_registered_device *rdev,
10 struct cfg80211_wowlan *wowlan)
10{ 11{
11 int ret; 12 int ret;
12 trace_rdev_suspend(&rdev->wiphy, rdev->wowlan); 13 trace_rdev_suspend(&rdev->wiphy, wowlan);
13 ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); 14 ret = rdev->ops->suspend(&rdev->wiphy, wowlan);
14 trace_rdev_return_int(&rdev->wiphy, ret); 15 trace_rdev_return_int(&rdev->wiphy, ret);
15 return ret; 16 return ret;
16} 17}
@@ -887,4 +888,17 @@ static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev,
887 trace_rdev_return_int(&rdev->wiphy, ret); 888 trace_rdev_return_int(&rdev->wiphy, ret);
888 return ret; 889 return ret;
889} 890}
891
892static inline int rdev_update_ft_ies(struct cfg80211_registered_device *rdev,
893 struct net_device *dev,
894 struct cfg80211_update_ft_ies_params *ftie)
895{
896 int ret;
897
898 trace_rdev_update_ft_ies(&rdev->wiphy, dev, ftie);
899 ret = rdev->ops->update_ft_ies(&rdev->wiphy, dev, ftie);
900 trace_rdev_return_int(&rdev->wiphy, ret);
901 return ret;
902}
903
890#endif /* __CFG80211_RDEV_OPS */ 904#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 98532c00242d..e6df52dc8c69 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -184,14 +184,14 @@ static const struct ieee80211_regdomain world_regdom = {
184 NL80211_RRF_NO_IBSS | 184 NL80211_RRF_NO_IBSS |
185 NL80211_RRF_NO_OFDM), 185 NL80211_RRF_NO_OFDM),
186 /* IEEE 802.11a, channel 36..48 */ 186 /* IEEE 802.11a, channel 36..48 */
187 REG_RULE(5180-10, 5240+10, 40, 6, 20, 187 REG_RULE(5180-10, 5240+10, 80, 6, 20,
188 NL80211_RRF_PASSIVE_SCAN | 188 NL80211_RRF_PASSIVE_SCAN |
189 NL80211_RRF_NO_IBSS), 189 NL80211_RRF_NO_IBSS),
190 190
191 /* NB: 5260 MHz - 5700 MHz requies DFS */ 191 /* NB: 5260 MHz - 5700 MHz requires DFS */
192 192
193 /* IEEE 802.11a, channel 149..165 */ 193 /* IEEE 802.11a, channel 149..165 */
194 REG_RULE(5745-10, 5825+10, 40, 6, 20, 194 REG_RULE(5745-10, 5825+10, 80, 6, 20,
195 NL80211_RRF_PASSIVE_SCAN | 195 NL80211_RRF_PASSIVE_SCAN |
196 NL80211_RRF_NO_IBSS), 196 NL80211_RRF_NO_IBSS),
197 197
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index f432bd3755b1..bad4c4b5e4eb 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -159,7 +159,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
159{ 159{
160 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 160 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
161 struct cfg80211_connect_params *params; 161 struct cfg80211_connect_params *params;
162 const u8 *prev_bssid = NULL; 162 struct cfg80211_assoc_request req = {};
163 int err; 163 int err;
164 164
165 ASSERT_WDEV_LOCK(wdev); 165 ASSERT_WDEV_LOCK(wdev);
@@ -186,16 +186,20 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
186 BUG_ON(!rdev->ops->assoc); 186 BUG_ON(!rdev->ops->assoc);
187 wdev->conn->state = CFG80211_CONN_ASSOCIATING; 187 wdev->conn->state = CFG80211_CONN_ASSOCIATING;
188 if (wdev->conn->prev_bssid_valid) 188 if (wdev->conn->prev_bssid_valid)
189 prev_bssid = wdev->conn->prev_bssid; 189 req.prev_bssid = wdev->conn->prev_bssid;
190 err = __cfg80211_mlme_assoc(rdev, wdev->netdev, 190 req.ie = params->ie;
191 params->channel, params->bssid, 191 req.ie_len = params->ie_len;
192 prev_bssid, 192 req.use_mfp = params->mfp != NL80211_MFP_NO;
193 params->ssid, params->ssid_len, 193 req.crypto = params->crypto;
194 params->ie, params->ie_len, 194 req.flags = params->flags;
195 params->mfp != NL80211_MFP_NO, 195 req.ht_capa = params->ht_capa;
196 &params->crypto, 196 req.ht_capa_mask = params->ht_capa_mask;
197 params->flags, &params->ht_capa, 197 req.vht_capa = params->vht_capa;
198 &params->ht_capa_mask); 198 req.vht_capa_mask = params->vht_capa_mask;
199
200 err = __cfg80211_mlme_assoc(rdev, wdev->netdev, params->channel,
201 params->bssid, params->ssid,
202 params->ssid_len, &req);
199 if (err) 203 if (err)
200 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 204 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
201 NULL, 0, 205 NULL, 0,
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 238ee49b3868..8f28b9f798d8 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -83,6 +83,14 @@ static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
83 return 0; 83 return 0;
84} 84}
85 85
86static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
87{
88 struct wireless_dev *wdev;
89
90 list_for_each_entry(wdev, &rdev->wdev_list, list)
91 cfg80211_leave(rdev, wdev);
92}
93
86static int wiphy_suspend(struct device *dev, pm_message_t state) 94static int wiphy_suspend(struct device *dev, pm_message_t state)
87{ 95{
88 struct cfg80211_registered_device *rdev = dev_to_rdev(dev); 96 struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
@@ -90,12 +98,19 @@ static int wiphy_suspend(struct device *dev, pm_message_t state)
90 98
91 rdev->suspend_at = get_seconds(); 99 rdev->suspend_at = get_seconds();
92 100
93 if (rdev->ops->suspend) { 101 rtnl_lock();
94 rtnl_lock(); 102 if (rdev->wiphy.registered) {
95 if (rdev->wiphy.registered) 103 if (!rdev->wowlan)
96 ret = rdev_suspend(rdev); 104 cfg80211_leave_all(rdev);
97 rtnl_unlock(); 105 if (rdev->ops->suspend)
106 ret = rdev_suspend(rdev, rdev->wowlan);
107 if (ret == 1) {
108 /* Driver refuse to configure wowlan */
109 cfg80211_leave_all(rdev);
110 ret = rdev_suspend(rdev, NULL);
111 }
98 } 112 }
113 rtnl_unlock();
99 114
100 return ret; 115 return ret;
101} 116}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index b7a531380e19..ccadef2106ac 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1785,6 +1785,26 @@ TRACE_EVENT(rdev_set_mac_acl,
1785 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->acl_policy) 1785 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->acl_policy)
1786); 1786);
1787 1787
1788TRACE_EVENT(rdev_update_ft_ies,
1789 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
1790 struct cfg80211_update_ft_ies_params *ftie),
1791 TP_ARGS(wiphy, netdev, ftie),
1792 TP_STRUCT__entry(
1793 WIPHY_ENTRY
1794 NETDEV_ENTRY
1795 __field(u16, md)
1796 __dynamic_array(u8, ie, ftie->ie_len)
1797 ),
1798 TP_fast_assign(
1799 WIPHY_ASSIGN;
1800 NETDEV_ASSIGN;
1801 __entry->md = ftie->md;
1802 memcpy(__get_dynamic_array(ie), ftie->ie, ftie->ie_len);
1803 ),
1804 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", md: 0x%x",
1805 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->md)
1806);
1807
1788/************************************************************* 1808/*************************************************************
1789 * cfg80211 exported functions traces * 1809 * cfg80211 exported functions traces *
1790 *************************************************************/ 1810 *************************************************************/
@@ -2413,6 +2433,32 @@ TRACE_EVENT(cfg80211_report_wowlan_wakeup,
2413 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG) 2433 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG)
2414); 2434);
2415 2435
2436TRACE_EVENT(cfg80211_ft_event,
2437 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
2438 struct cfg80211_ft_event_params *ft_event),
2439 TP_ARGS(wiphy, netdev, ft_event),
2440 TP_STRUCT__entry(
2441 WIPHY_ENTRY
2442 NETDEV_ENTRY
2443 __dynamic_array(u8, ies, ft_event->ies_len)
2444 MAC_ENTRY(target_ap)
2445 __dynamic_array(u8, ric_ies, ft_event->ric_ies_len)
2446 ),
2447 TP_fast_assign(
2448 WIPHY_ASSIGN;
2449 NETDEV_ASSIGN;
2450 if (ft_event->ies)
2451 memcpy(__get_dynamic_array(ies), ft_event->ies,
2452 ft_event->ies_len);
2453 MAC_ASSIGN(target_ap, ft_event->target_ap);
2454 if (ft_event->ric_ies)
2455 memcpy(__get_dynamic_array(ric_ies), ft_event->ric_ies,
2456 ft_event->ric_ies_len);
2457 ),
2458 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", target_ap: " MAC_PR_FMT,
2459 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap))
2460);
2461
2416#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ 2462#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
2417 2463
2418#undef TRACE_INCLUDE_PATH 2464#undef TRACE_INCLUDE_PATH