aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/80211.tmpl2
-rw-r--r--drivers/bcma/driver_chipcommon.c5
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c34
-rw-r--r--drivers/bcma/scan.c16
-rw-r--r--drivers/bcma/sprom.c1
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c8
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs_debug.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c36
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c31
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c7
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h8
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c4
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c81
-rw-r--r--drivers/net/wireless/ath/key.c9
-rw-r--r--drivers/net/wireless/b43/b43.h2
-rw-r--r--drivers/net/wireless/b43/main.c23
-rw-r--r--drivers/net/wireless/b43/phy_lp.c12
-rw-r--r--drivers/net/wireless/b43/phy_n.c6
-rw-r--r--drivers/net/wireless/b43/radio_2056.c6
-rw-r--r--drivers/net/wireless/b43/sdio.h4
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c4
-rw-r--r--drivers/net/wireless/b43/tables_phy_lcn.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c30
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c60
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h33
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c50
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h21
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c116
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c117
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c25
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c1801
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c190
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h14
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c495
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h11
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/aiutils.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/d11.h1
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c87
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c362
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.h25
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c40
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h1
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c35
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c14
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pmu.c54
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pmu.h6
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pub.h17
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_wifi.h28
-rw-r--r--drivers/net/wireless/iwlegacy/common.c3
-rw-r--r--drivers/net/wireless/iwlegacy/common.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h38
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c23
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c30
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c29
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c136
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c36
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c38
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c10
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c5
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c8
-rw-r--r--drivers/net/wireless/mwifiex/11ac.c41
-rw-r--r--drivers/net/wireless/mwifiex/11ac.h17
-rw-r--r--drivers/net/wireless/mwifiex/11n.c22
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c12
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c35
-rw-r--r--drivers/net/wireless/mwifiex/decl.h11
-rw-r--r--drivers/net/wireless/mwifiex/fw.h11
-rw-r--r--drivers/net/wireless/mwifiex/init.c6
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h8
-rw-r--r--drivers/net/wireless/mwifiex/join.c23
-rw-r--r--drivers/net/wireless/mwifiex/main.h13
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c47
-rw-r--r--drivers/net/wireless/mwifiex/scan.c11
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c3
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c55
-rw-r--r--drivers/net/wireless/mwifiex/util.c1
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c76
-rw-r--r--drivers/net/wireless/mwl8k.c10
-rw-r--r--drivers/net/wireless/p54/main.c2
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig7
-rw-r--r--drivers/net/wireless/rt2x00/Makefile1
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c92
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h19
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mmio.c216
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mmio.h119
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c174
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h88
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c1
-rw-r--r--drivers/net/wireless/rtlwifi/Kconfig9
-rw-r--r--drivers/net/wireless/rtlwifi/Makefile1
-rw-r--r--drivers/net/wireless/rtlwifi/base.c379
-rw-r--r--drivers/net/wireless/rtlwifi/base.h14
-rw-r--r--drivers/net/wireless/rtlwifi/core.c215
-rw-r--r--drivers/net/wireless/rtlwifi/debug.c5
-rw-r--r--drivers/net/wireless/rtlwifi/debug.h13
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.c53
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.h1
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c150
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h2
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c330
-rw-r--r--drivers/net/wireless/rtlwifi/ps.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/Makefile16
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/def.h324
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/dm.c1794
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/dm.h326
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/fw.c830
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/fw.h301
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.c2530
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.h68
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/led.c157
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/led.h38
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/phy.c2202
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/phy.h236
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.c109
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h327
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c140
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.h97
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/reg.h2258
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/rf.c467
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/rf.h46
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/sw.c400
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/sw.h36
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/table.c643
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/table.h47
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/trx.c817
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/trx.h795
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c101
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c99
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c118
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.h4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/reg.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c324
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c20
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/dm.c32
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/phy.c40
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/reg.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/sw.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/def.h7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.c49
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c150
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.h3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/phy.c61
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/phy.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c296
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.c88
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.h6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.c97
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.h7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c70
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/led.c22
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/trx.c10
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c220
-rw-r--r--drivers/net/wireless/rtlwifi/usb.h5
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h221
-rw-r--r--drivers/net/wireless/ti/wl1251/sdio.c4
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c1
-rw-r--r--drivers/net/wireless/ti/wl12xx/wl12xx.h2
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c25
-rw-r--r--drivers/net/wireless/ti/wl18xx/reg.h29
-rw-r--r--drivers/net/wireless/ti/wl18xx/wl18xx.h4
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.c29
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.h16
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c32
-rw-r--r--drivers/net/wireless/ti/wlcore/debug.h33
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c3
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c9
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c200
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.c4
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c39
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h29
-rw-r--r--drivers/ssb/pci.c23
-rw-r--r--include/linux/bcma/bcma.h54
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h3
-rw-r--r--include/linux/ssb/ssb.h54
-rw-r--r--include/linux/ssb/ssb_regs.h10
-rw-r--r--include/net/bluetooth/bluetooth.h12
-rw-r--r--include/net/bluetooth/hci.h21
-rw-r--r--include/net/bluetooth/hci_core.h28
-rw-r--r--include/net/bluetooth/rfcomm.h6
-rw-r--r--include/net/mac80211.h68
-rw-r--r--net/bluetooth/a2mp.c6
-rw-r--r--net/bluetooth/af_bluetooth.c15
-rw-r--r--net/bluetooth/bnep/sock.c4
-rw-r--r--net/bluetooth/cmtp/sock.c4
-rw-r--r--net/bluetooth/hci_conn.c4
-rw-r--r--net/bluetooth/hci_core.c727
-rw-r--r--net/bluetooth/hci_event.c605
-rw-r--r--net/bluetooth/hci_sock.c9
-rw-r--r--net/bluetooth/hci_sysfs.c4
-rw-r--r--net/bluetooth/hidp/core.c4
-rw-r--r--net/bluetooth/hidp/sock.c4
-rw-r--r--net/bluetooth/l2cap_sock.c4
-rw-r--r--net/bluetooth/mgmt.c680
-rw-r--r--net/bluetooth/rfcomm/core.c167
-rw-r--r--net/bluetooth/rfcomm/sock.c3
-rw-r--r--net/bluetooth/sco.c3
-rw-r--r--net/mac80211/cfg.c29
-rw-r--r--net/mac80211/debugfs_key.c10
-rw-r--r--net/mac80211/debugfs_netdev.c22
-rw-r--r--net/mac80211/driver-ops.h60
-rw-r--r--net/mac80211/ieee80211_i.h11
-rw-r--r--net/mac80211/iface.c17
-rw-r--r--net/mac80211/key.c129
-rw-r--r--net/mac80211/key.h15
-rw-r--r--net/mac80211/main.c22
-rw-r--r--net/mac80211/mesh.c5
-rw-r--r--net/mac80211/mlme.c12
-rw-r--r--net/mac80211/offchannel.c8
-rw-r--r--net/mac80211/pm.c6
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c24
-rw-r--r--net/mac80211/scan.c7
-rw-r--r--net/mac80211/sta_info.c54
-rw-r--r--net/mac80211/sta_info.h9
-rw-r--r--net/mac80211/trace.h35
-rw-r--r--net/mac80211/tx.c8
-rw-r--r--net/mac80211/util.c48
-rw-r--r--net/wireless/core.c4
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/sme.c4
258 files changed, 23444 insertions, 3956 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
index 284ced7a228f..0f6a3edcd44b 100644
--- a/Documentation/DocBook/80211.tmpl
+++ b/Documentation/DocBook/80211.tmpl
@@ -437,7 +437,7 @@
437 </section> 437 </section>
438!Finclude/net/mac80211.h ieee80211_get_buffered_bc 438!Finclude/net/mac80211.h ieee80211_get_buffered_bc
439!Finclude/net/mac80211.h ieee80211_beacon_get 439!Finclude/net/mac80211.h ieee80211_beacon_get
440!Finclude/net/mac80211.h ieee80211_sta_eosp_irqsafe 440!Finclude/net/mac80211.h ieee80211_sta_eosp
441!Finclude/net/mac80211.h ieee80211_frame_release_type 441!Finclude/net/mac80211.h ieee80211_frame_release_type
442!Finclude/net/mac80211.h ieee80211_sta_ps_transition 442!Finclude/net/mac80211.h ieee80211_sta_ps_transition
443!Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni 443!Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index 28fa50ad87be..036c6744b39b 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -25,13 +25,14 @@ static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
25 return value; 25 return value;
26} 26}
27 27
28static u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc) 28u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc)
29{ 29{
30 if (cc->capabilities & BCMA_CC_CAP_PMU) 30 if (cc->capabilities & BCMA_CC_CAP_PMU)
31 return bcma_pmu_get_alp_clock(cc); 31 return bcma_pmu_get_alp_clock(cc);
32 32
33 return 20000000; 33 return 20000000;
34} 34}
35EXPORT_SYMBOL_GPL(bcma_chipco_get_alp_clock);
35 36
36static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc) 37static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc)
37{ 38{
@@ -213,6 +214,7 @@ u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
213 214
214 return res; 215 return res;
215} 216}
217EXPORT_SYMBOL_GPL(bcma_chipco_gpio_out);
216 218
217u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value) 219u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
218{ 220{
@@ -225,6 +227,7 @@ u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
225 227
226 return res; 228 return res;
227} 229}
230EXPORT_SYMBOL_GPL(bcma_chipco_gpio_outen);
228 231
229/* 232/*
230 * If the bit is set to 0, chipcommon controlls this GPIO, 233 * If the bit is set to 0, chipcommon controlls this GPIO,
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index 932b101dee36..edca73af3cc0 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -174,19 +174,35 @@ u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc)
174 struct bcma_bus *bus = cc->core->bus; 174 struct bcma_bus *bus = cc->core->bus;
175 175
176 switch (bus->chipinfo.id) { 176 switch (bus->chipinfo.id) {
177 case BCMA_CHIP_ID_BCM4313:
178 case BCMA_CHIP_ID_BCM43224:
179 case BCMA_CHIP_ID_BCM43225:
180 case BCMA_CHIP_ID_BCM43227:
181 case BCMA_CHIP_ID_BCM43228:
182 case BCMA_CHIP_ID_BCM4331:
183 case BCMA_CHIP_ID_BCM43421:
184 case BCMA_CHIP_ID_BCM43428:
185 case BCMA_CHIP_ID_BCM43431:
177 case BCMA_CHIP_ID_BCM4716: 186 case BCMA_CHIP_ID_BCM4716:
178 case BCMA_CHIP_ID_BCM4748:
179 case BCMA_CHIP_ID_BCM47162: 187 case BCMA_CHIP_ID_BCM47162:
180 case BCMA_CHIP_ID_BCM4313: 188 case BCMA_CHIP_ID_BCM4748:
181 case BCMA_CHIP_ID_BCM5357:
182 case BCMA_CHIP_ID_BCM4749: 189 case BCMA_CHIP_ID_BCM4749:
190 case BCMA_CHIP_ID_BCM5357:
183 case BCMA_CHIP_ID_BCM53572: 191 case BCMA_CHIP_ID_BCM53572:
192 case BCMA_CHIP_ID_BCM6362:
184 /* always 20Mhz */ 193 /* always 20Mhz */
185 return 20000 * 1000; 194 return 20000 * 1000;
186 case BCMA_CHIP_ID_BCM5356:
187 case BCMA_CHIP_ID_BCM4706: 195 case BCMA_CHIP_ID_BCM4706:
196 case BCMA_CHIP_ID_BCM5356:
188 /* always 25Mhz */ 197 /* always 25Mhz */
189 return 25000 * 1000; 198 return 25000 * 1000;
199 case BCMA_CHIP_ID_BCM43460:
200 case BCMA_CHIP_ID_BCM4352:
201 case BCMA_CHIP_ID_BCM4360:
202 if (cc->status & BCMA_CC_CHIPST_4360_XTAL_40MZ)
203 return 40000 * 1000;
204 else
205 return 20000 * 1000;
190 default: 206 default:
191 bcma_warn(bus, "No ALP clock specified for %04X device, pmu rev. %d, using default %d Hz\n", 207 bcma_warn(bus, "No ALP clock specified for %04X device, pmu rev. %d, using default %d Hz\n",
192 bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK); 208 bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
@@ -373,7 +389,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
373 tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT; 389 tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT;
374 bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp); 390 bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp);
375 391
376 tmp = 1 << 10; 392 tmp = BCMA_CC_PMU_CTL_PLL_UPD;
377 break; 393 break;
378 394
379 case BCMA_CHIP_ID_BCM4331: 395 case BCMA_CHIP_ID_BCM4331:
@@ -394,7 +410,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
394 bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, 410 bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
395 0x03000a08); 411 0x03000a08);
396 } 412 }
397 tmp = 1 << 10; 413 tmp = BCMA_CC_PMU_CTL_PLL_UPD;
398 break; 414 break;
399 415
400 case BCMA_CHIP_ID_BCM43224: 416 case BCMA_CHIP_ID_BCM43224:
@@ -427,7 +443,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
427 bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5, 443 bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
428 0x88888815); 444 0x88888815);
429 } 445 }
430 tmp = 1 << 10; 446 tmp = BCMA_CC_PMU_CTL_PLL_UPD;
431 break; 447 break;
432 448
433 case BCMA_CHIP_ID_BCM4716: 449 case BCMA_CHIP_ID_BCM4716:
@@ -461,7 +477,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
461 0x88888815); 477 0x88888815);
462 } 478 }
463 479
464 tmp = 3 << 9; 480 tmp = BCMA_CC_PMU_CTL_PLL_UPD | BCMA_CC_PMU_CTL_NOILPONW;
465 break; 481 break;
466 482
467 case BCMA_CHIP_ID_BCM43227: 483 case BCMA_CHIP_ID_BCM43227:
@@ -497,7 +513,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
497 bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5, 513 bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
498 0x88888815); 514 0x88888815);
499 } 515 }
500 tmp = 1 << 10; 516 tmp = BCMA_CC_PMU_CTL_PLL_UPD;
501 break; 517 break;
502 default: 518 default:
503 bcma_err(bus, "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n", 519 bcma_err(bus, "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n",
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 8d0b57164018..bca9c80056fe 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -137,19 +137,19 @@ static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr)
137 addr); 137 addr);
138} 138}
139 139
140static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr) 140static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 __iomem **eromptr)
141{ 141{
142 u32 ent = readl(*eromptr); 142 u32 ent = readl(*eromptr);
143 (*eromptr)++; 143 (*eromptr)++;
144 return ent; 144 return ent;
145} 145}
146 146
147static void bcma_erom_push_ent(u32 **eromptr) 147static void bcma_erom_push_ent(u32 __iomem **eromptr)
148{ 148{
149 (*eromptr)--; 149 (*eromptr)--;
150} 150}
151 151
152static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr) 152static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 __iomem **eromptr)
153{ 153{
154 u32 ent = bcma_erom_get_ent(bus, eromptr); 154 u32 ent = bcma_erom_get_ent(bus, eromptr);
155 if (!(ent & SCAN_ER_VALID)) 155 if (!(ent & SCAN_ER_VALID))
@@ -159,14 +159,14 @@ static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr)
159 return ent; 159 return ent;
160} 160}
161 161
162static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr) 162static bool bcma_erom_is_end(struct bcma_bus *bus, u32 __iomem **eromptr)
163{ 163{
164 u32 ent = bcma_erom_get_ent(bus, eromptr); 164 u32 ent = bcma_erom_get_ent(bus, eromptr);
165 bcma_erom_push_ent(eromptr); 165 bcma_erom_push_ent(eromptr);
166 return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID)); 166 return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID));
167} 167}
168 168
169static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr) 169static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 __iomem **eromptr)
170{ 170{
171 u32 ent = bcma_erom_get_ent(bus, eromptr); 171 u32 ent = bcma_erom_get_ent(bus, eromptr);
172 bcma_erom_push_ent(eromptr); 172 bcma_erom_push_ent(eromptr);
@@ -175,7 +175,7 @@ static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr)
175 ((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE)); 175 ((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE));
176} 176}
177 177
178static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr) 178static void bcma_erom_skip_component(struct bcma_bus *bus, u32 __iomem **eromptr)
179{ 179{
180 u32 ent; 180 u32 ent;
181 while (1) { 181 while (1) {
@@ -189,7 +189,7 @@ static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr)
189 bcma_erom_push_ent(eromptr); 189 bcma_erom_push_ent(eromptr);
190} 190}
191 191
192static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr) 192static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 __iomem **eromptr)
193{ 193{
194 u32 ent = bcma_erom_get_ent(bus, eromptr); 194 u32 ent = bcma_erom_get_ent(bus, eromptr);
195 if (!(ent & SCAN_ER_VALID)) 195 if (!(ent & SCAN_ER_VALID))
@@ -199,7 +199,7 @@ static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr)
199 return ent; 199 return ent;
200} 200}
201 201
202static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr, 202static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
203 u32 type, u8 port) 203 u32 type, u8 port)
204{ 204{
205 u32 addrl, addrh, sizel, sizeh = 0; 205 u32 addrl, addrh, sizel, sizeh = 0;
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 4adf9ef9a113..8934298a638d 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -217,6 +217,7 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
217 } 217 }
218 218
219 SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0); 219 SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
220 SPEX(board_type, SSB_SPROM1_SPID, ~0, 0);
220 221
221 SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0, 222 SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
222 SSB_SPROM4_TXPID2G0_SHIFT); 223 SSB_SPROM4_TXPID2G0_SHIFT);
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 9959d4cb23dc..1cb51839912d 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -83,8 +83,8 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
83}; 83};
84 84
85static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { 85static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
86 .helper = "sd8688_helper.bin", 86 .helper = "mrvl/sd8688_helper.bin",
87 .firmware = "sd8688.bin", 87 .firmware = "mrvl/sd8688.bin",
88 .reg = &btmrvl_reg_8688, 88 .reg = &btmrvl_reg_8688,
89 .sd_blksz_fw_dl = 64, 89 .sd_blksz_fw_dl = 64,
90}; 90};
@@ -1185,7 +1185,7 @@ MODULE_AUTHOR("Marvell International Ltd.");
1185MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION); 1185MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION);
1186MODULE_VERSION(VERSION); 1186MODULE_VERSION(VERSION);
1187MODULE_LICENSE("GPL v2"); 1187MODULE_LICENSE("GPL v2");
1188MODULE_FIRMWARE("sd8688_helper.bin"); 1188MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
1189MODULE_FIRMWARE("sd8688.bin"); 1189MODULE_FIRMWARE("mrvl/sd8688.bin");
1190MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); 1190MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
1191MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); 1191MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
index 7157f7d311c5..afd1e36d308f 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -1091,7 +1091,7 @@ static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1091 return ret; 1091 return ret;
1092} 1092}
1093 1093
1094static void ar5523_flush(struct ieee80211_hw *hw, bool drop) 1094static void ar5523_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1095{ 1095{
1096 struct ar5523 *ar = hw->priv; 1096 struct ar5523 *ar = hw->priv;
1097 1097
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index c55e5bbafc46..9f589744a9f9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -731,7 +731,8 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
731 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, 731 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
732 AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { 732 AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
733 ath_dbg(common, CALIBRATE, 733 ath_dbg(common, CALIBRATE,
734 "offset calibration failed to complete in 1ms; noisy environment?\n"); 734 "offset calibration failed to complete in %d ms; noisy environment?\n",
735 AH_WAIT_TIMEOUT / 1000);
735 return false; 736 return false;
736 } 737 }
737 REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); 738 REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
@@ -745,7 +746,8 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
745 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 746 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
746 0, AH_WAIT_TIMEOUT)) { 747 0, AH_WAIT_TIMEOUT)) {
747 ath_dbg(common, CALIBRATE, 748 ath_dbg(common, CALIBRATE,
748 "offset calibration failed to complete in 1ms; noisy environment?\n"); 749 "offset calibration failed to complete in %d ms; noisy environment?\n",
750 AH_WAIT_TIMEOUT / 1000);
749 return false; 751 return false;
750 } 752 }
751 753
@@ -841,7 +843,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
841 AR_PHY_AGC_CONTROL_CAL, 843 AR_PHY_AGC_CONTROL_CAL,
842 0, AH_WAIT_TIMEOUT)) { 844 0, AH_WAIT_TIMEOUT)) {
843 ath_dbg(common, CALIBRATE, 845 ath_dbg(common, CALIBRATE,
844 "offset calibration failed to complete in 1ms; noisy environment?\n"); 846 "offset calibration failed to complete in %d ms; noisy environment?\n",
847 AH_WAIT_TIMEOUT / 1000);
845 return false; 848 return false;
846 } 849 }
847 850
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index f76c3ca07a45..639ba7d18ea4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -1126,7 +1126,8 @@ skip_tx_iqcal:
1126 ar9003_hw_rtt_disable(ah); 1126 ar9003_hw_rtt_disable(ah);
1127 1127
1128 ath_dbg(common, CALIBRATE, 1128 ath_dbg(common, CALIBRATE,
1129 "offset calibration failed to complete in 1ms; noisy environment?\n"); 1129 "offset calibration failed to complete in %d ms; noisy environment?\n",
1130 AH_WAIT_TIMEOUT / 1000);
1130 return false; 1131 return false;
1131 } 1132 }
1132 1133
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 67a2a4b3b883..e6307b86363a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -2072,7 +2072,7 @@ int ath9k_init_debug(struct ath_hw *ah)
2072 &fops_modal_eeprom); 2072 &fops_modal_eeprom);
2073 sc->rfs_chan_spec_scan = relay_open("spectral_scan", 2073 sc->rfs_chan_spec_scan = relay_open("spectral_scan",
2074 sc->debug.debugfs_phy, 2074 sc->debug.debugfs_phy,
2075 262144, 4, &rfs_spec_scan_cb, 2075 1024, 256, &rfs_spec_scan_cb,
2076 NULL); 2076 NULL);
2077 debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR, 2077 debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR,
2078 sc->debug.debugfs_phy, sc, 2078 sc->debug.debugfs_phy, sc,
diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c
index ecc81792f2dc..508f8b33f0ef 100644
--- a/drivers/net/wireless/ath/ath9k/dfs.c
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
@@ -193,9 +193,7 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
193 DFS_STAT_INC(sc, pulses_processed); 193 DFS_STAT_INC(sc, pulses_processed);
194 if (pd != NULL && pd->add_pulse(pd, &pe)) { 194 if (pd != NULL && pd->add_pulse(pd, &pe)) {
195 DFS_STAT_INC(sc, radar_detected); 195 DFS_STAT_INC(sc, radar_detected);
196 /* 196 ieee80211_radar_detected(sc->hw);
197 * TODO: forward radar event to DFS management layer
198 */
199 } 197 }
200 } 198 }
201} 199}
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.c b/drivers/net/wireless/ath/ath9k/dfs_debug.c
index 55d28072adeb..b7611b7bbe43 100644
--- a/drivers/net/wireless/ath/ath9k/dfs_debug.c
+++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c
@@ -105,6 +105,24 @@ static ssize_t write_file_dfs(struct file *file, const char __user *user_buf,
105 return count; 105 return count;
106} 106}
107 107
108static ssize_t write_file_simulate_radar(struct file *file,
109 const char __user *user_buf,
110 size_t count, loff_t *ppos)
111{
112 struct ath_softc *sc = file->private_data;
113
114 ieee80211_radar_detected(sc->hw);
115
116 return count;
117}
118
119static const struct file_operations fops_simulate_radar = {
120 .write = write_file_simulate_radar,
121 .open = simple_open,
122 .owner = THIS_MODULE,
123 .llseek = default_llseek,
124};
125
108static const struct file_operations fops_dfs_stats = { 126static const struct file_operations fops_dfs_stats = {
109 .read = read_file_dfs, 127 .read = read_file_dfs,
110 .write = write_file_dfs, 128 .write = write_file_dfs,
@@ -117,4 +135,6 @@ void ath9k_dfs_init_debug(struct ath_softc *sc)
117{ 135{
118 debugfs_create_file("dfs_stats", S_IRUSR, 136 debugfs_create_file("dfs_stats", S_IRUSR,
119 sc->debug.debugfs_phy, sc, &fops_dfs_stats); 137 sc->debug.debugfs_phy, sc, &fops_dfs_stats);
138 debugfs_create_file("dfs_simulate_radar", S_IWUSR,
139 sc->debug.debugfs_phy, sc, &fops_simulate_radar);
120} 140}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4fa2bb167050..3473a797651a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2380,8 +2380,11 @@ static bool ath9k_hw_dfs_tested(struct ath_hw *ah)
2380{ 2380{
2381 2381
2382 switch (ah->hw_version.macVersion) { 2382 switch (ah->hw_version.macVersion) {
2383 /* for temporary testing DFS with 9280 */
2384 case AR_SREV_VERSION_9280:
2383 /* AR9580 will likely be our first target to get testing on */ 2385 /* AR9580 will likely be our first target to get testing on */
2384 case AR_SREV_VERSION_9580: 2386 case AR_SREV_VERSION_9580:
2387 return true;
2385 default: 2388 default:
2386 return false; 2389 return false;
2387 } 2390 }
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index af932c9444de..3be2eb0da84a 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -319,6 +319,10 @@ static void ath9k_reg_notifier(struct wiphy *wiphy,
319 ath9k_ps_wakeup(sc); 319 ath9k_ps_wakeup(sc);
320 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); 320 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
321 sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; 321 sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
322 /* synchronize DFS detector if regulatory domain changed */
323 if (sc->dfs_detector != NULL)
324 sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
325 request->dfs_region);
322 ath9k_ps_restore(sc); 326 ath9k_ps_restore(sc);
323 } 327 }
324} 328}
@@ -727,12 +731,28 @@ static const struct ieee80211_iface_limit if_limits[] = {
727 BIT(NL80211_IFTYPE_P2P_GO) }, 731 BIT(NL80211_IFTYPE_P2P_GO) },
728}; 732};
729 733
730static const struct ieee80211_iface_combination if_comb = { 734
731 .limits = if_limits, 735static const struct ieee80211_iface_limit if_dfs_limits[] = {
732 .n_limits = ARRAY_SIZE(if_limits), 736 { .max = 1, .types = BIT(NL80211_IFTYPE_AP) },
733 .max_interfaces = 2048, 737};
734 .num_different_channels = 1, 738
735 .beacon_int_infra_match = true, 739static const struct ieee80211_iface_combination if_comb[] = {
740 {
741 .limits = if_limits,
742 .n_limits = ARRAY_SIZE(if_limits),
743 .max_interfaces = 2048,
744 .num_different_channels = 1,
745 .beacon_int_infra_match = true,
746 },
747 {
748 .limits = if_dfs_limits,
749 .n_limits = ARRAY_SIZE(if_dfs_limits),
750 .max_interfaces = 1,
751 .num_different_channels = 1,
752 .beacon_int_infra_match = true,
753 .radar_detect_widths = BIT(NL80211_CHAN_NO_HT) |
754 BIT(NL80211_CHAN_HT20),
755 }
736}; 756};
737 757
738void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) 758void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
@@ -763,8 +783,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
763 BIT(NL80211_IFTYPE_ADHOC) | 783 BIT(NL80211_IFTYPE_ADHOC) |
764 BIT(NL80211_IFTYPE_MESH_POINT); 784 BIT(NL80211_IFTYPE_MESH_POINT);
765 785
766 hw->wiphy->iface_combinations = &if_comb; 786 hw->wiphy->iface_combinations = if_comb;
767 hw->wiphy->n_iface_combinations = 1; 787 hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
768 788
769 if (AR_SREV_5416(sc->sc_ah)) 789 if (AR_SREV_5416(sc->sc_ah))
770 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 790 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6e66f9c6782b..1bf52c88004a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -280,6 +280,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
280 if (r) { 280 if (r) {
281 ath_err(common, 281 ath_err(common,
282 "Unable to reset channel, reset status %d\n", r); 282 "Unable to reset channel, reset status %d\n", r);
283
284 ath9k_hw_enable_interrupts(ah);
285 ath9k_queue_reset(sc, RESET_TYPE_BB_HANG);
286
283 goto out; 287 goto out;
284 } 288 }
285 289
@@ -1245,10 +1249,27 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1245 if (old_pos >= 0) 1249 if (old_pos >= 0)
1246 ath_update_survey_nf(sc, old_pos); 1250 ath_update_survey_nf(sc, old_pos);
1247 1251
1248 /* perform spectral scan if requested. */ 1252 /*
1249 if (sc->scanning && sc->spectral_mode == SPECTRAL_CHANSCAN) 1253 * Enable radar pulse detection if on a DFS channel. Spectral
1250 ath9k_spectral_scan_trigger(hw); 1254 * scanning and radar detection can not be used concurrently.
1251 1255 */
1256 if (hw->conf.radar_enabled) {
1257 u32 rxfilter;
1258
1259 /* set HW specific DFS configuration */
1260 ath9k_hw_set_radar_params(ah);
1261 rxfilter = ath9k_hw_getrxfilter(ah);
1262 rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
1263 ATH9K_RX_FILTER_PHYERR;
1264 ath9k_hw_setrxfilter(ah, rxfilter);
1265 ath_dbg(common, DFS, "DFS enabled at freq %d\n",
1266 curchan->center_freq);
1267 } else {
1268 /* perform spectral scan if requested. */
1269 if (sc->scanning &&
1270 sc->spectral_mode == SPECTRAL_CHANSCAN)
1271 ath9k_spectral_scan_trigger(hw);
1272 }
1252 } 1273 }
1253 1274
1254 if (changed & IEEE80211_CONF_CHANGE_POWER) { 1275 if (changed & IEEE80211_CONF_CHANGE_POWER) {
@@ -1745,7 +1766,7 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
1745 mutex_unlock(&sc->mutex); 1766 mutex_unlock(&sc->mutex);
1746} 1767}
1747 1768
1748static void ath9k_flush(struct ieee80211_hw *hw, bool drop) 1769static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1749{ 1770{
1750 struct ath_softc *sc = hw->priv; 1771 struct ath_softc *sc = hw->priv;
1751 struct ath_hw *ah = sc->sc_ah; 1772 struct ath_hw *ah = sc->sc_ah;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index ee156e543147..ee7ca5aecdb0 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -381,6 +381,10 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
381 rfilt = ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST 381 rfilt = ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
382 | ATH9K_RX_FILTER_MCAST; 382 | ATH9K_RX_FILTER_MCAST;
383 383
384 /* if operating on a DFS channel, enable radar pulse detection */
385 if (sc->hw->conf.radar_enabled)
386 rfilt |= ATH9K_RX_FILTER_PHYRADAR | ATH9K_RX_FILTER_PHYERR;
387
384 if (sc->rx.rxfilter & FIF_PROBE_REQ) 388 if (sc->rx.rxfilter & FIF_PROBE_REQ)
385 rfilt |= ATH9K_RX_FILTER_PROBEREQ; 389 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
386 390
@@ -1228,6 +1232,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1228 unlikely(tsf_lower - rs.rs_tstamp > 0x10000000)) 1232 unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
1229 rxs->mactime += 0x100000000ULL; 1233 rxs->mactime += 0x100000000ULL;
1230 1234
1235 if (rs.rs_phyerr == ATH9K_PHYERR_RADAR)
1236 ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
1237
1231 if (rs.rs_status & ATH9K_RXERR_PHY) { 1238 if (rs.rs_status & ATH9K_RXERR_PHY) {
1232 if (ath_process_fft(sc, hdr, &rs, rxs->mactime)) { 1239 if (ath_process_fft(sc, hdr, &rs, rxs->mactime)) {
1233 RX_STAT_INC(rx_spectral); 1240 RX_STAT_INC(rx_spectral);
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 25599741cd8a..9dce106cd6d4 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -70,12 +70,6 @@
70 70
71static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 }; 71static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 };
72 72
73enum carl9170_rf_init_mode {
74 CARL9170_RFI_NONE,
75 CARL9170_RFI_WARM,
76 CARL9170_RFI_COLD,
77};
78
79#define CARL9170_MAX_RX_BUFFER_SIZE 8192 73#define CARL9170_MAX_RX_BUFFER_SIZE 8192
80 74
81enum carl9170_device_state { 75enum carl9170_device_state {
@@ -599,7 +593,7 @@ int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state);
599 593
600/* PHY / RF */ 594/* PHY / RF */
601int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, 595int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
602 enum nl80211_channel_type bw, enum carl9170_rf_init_mode rfi); 596 enum nl80211_channel_type bw);
603int carl9170_get_noisefloor(struct ar9170 *ar); 597int carl9170_get_noisefloor(struct ar9170 *ar);
604 598
605/* FW */ 599/* FW */
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c
index 93fe6003a493..40109be81f7c 100644
--- a/drivers/net/wireless/ath/carl9170/debug.c
+++ b/drivers/net/wireless/ath/carl9170/debug.c
@@ -655,7 +655,7 @@ static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
655 655
656 case 'P': 656 case 'P':
657 err = carl9170_set_channel(ar, ar->hw->conf.channel, 657 err = carl9170_set_channel(ar, ar->hw->conf.channel,
658 ar->hw->conf.channel_type, CARL9170_RFI_COLD); 658 ar->hw->conf.channel_type);
659 if (err < 0) 659 if (err < 0)
660 count = err; 660 count = err;
661 661
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index f293b3ff4756..699c557bc2c7 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -939,7 +939,7 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
939 goto out; 939 goto out;
940 940
941 err = carl9170_set_channel(ar, hw->conf.channel, 941 err = carl9170_set_channel(ar, hw->conf.channel,
942 hw->conf.channel_type, CARL9170_RFI_NONE); 942 hw->conf.channel_type);
943 if (err) 943 if (err)
944 goto out; 944 goto out;
945 945
@@ -1703,7 +1703,7 @@ found:
1703 return 0; 1703 return 0;
1704} 1704}
1705 1705
1706static void carl9170_op_flush(struct ieee80211_hw *hw, bool drop) 1706static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1707{ 1707{
1708 struct ar9170 *ar = hw->priv; 1708 struct ar9170 *ar = hw->priv;
1709 unsigned int vid; 1709 unsigned int vid;
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index b72c09cf43a4..07f82234c860 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1569,16 +1569,14 @@ static enum carl9170_bw nl80211_to_carl(enum nl80211_channel_type type)
1569} 1569}
1570 1570
1571int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, 1571int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1572 enum nl80211_channel_type _bw, 1572 enum nl80211_channel_type _bw)
1573 enum carl9170_rf_init_mode rfi)
1574{ 1573{
1575 const struct carl9170_phy_freq_params *freqpar; 1574 const struct carl9170_phy_freq_params *freqpar;
1576 struct carl9170_rf_init_result rf_res; 1575 struct carl9170_rf_init_result rf_res;
1577 struct carl9170_rf_init rf; 1576 struct carl9170_rf_init rf;
1578 u32 cmd, tmp, offs = 0, new_ht = 0; 1577 u32 tmp, offs = 0, new_ht = 0;
1579 int err; 1578 int err;
1580 enum carl9170_bw bw; 1579 enum carl9170_bw bw;
1581 bool warm_reset;
1582 struct ieee80211_channel *old_channel = NULL; 1580 struct ieee80211_channel *old_channel = NULL;
1583 1581
1584 bw = nl80211_to_carl(_bw); 1582 bw = nl80211_to_carl(_bw);
@@ -1592,51 +1590,27 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1592 /* may be NULL at first setup */ 1590 /* may be NULL at first setup */
1593 if (ar->channel) { 1591 if (ar->channel) {
1594 old_channel = ar->channel; 1592 old_channel = ar->channel;
1595 warm_reset = (old_channel->band != channel->band) ||
1596 (old_channel->center_freq ==
1597 channel->center_freq) ||
1598 (ar->ht_settings != new_ht);
1599
1600 ar->channel = NULL; 1593 ar->channel = NULL;
1601 } else {
1602 warm_reset = true;
1603 } 1594 }
1604 1595
1605 /* HW workaround */ 1596 /* cold reset BB/ADDA */
1606 if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] && 1597 err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET,
1607 channel->center_freq <= 2417) 1598 AR9170_PWR_RESET_BB_COLD_RESET);
1608 warm_reset = true; 1599 if (err)
1609 1600 return err;
1610 if (rfi != CARL9170_RFI_NONE || warm_reset) {
1611 u32 val;
1612
1613 if (rfi == CARL9170_RFI_COLD)
1614 val = AR9170_PWR_RESET_BB_COLD_RESET;
1615 else
1616 val = AR9170_PWR_RESET_BB_WARM_RESET;
1617
1618 /* warm/cold reset BB/ADDA */
1619 err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, val);
1620 if (err)
1621 return err;
1622
1623 err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0);
1624 if (err)
1625 return err;
1626 1601
1627 err = carl9170_init_phy(ar, channel->band); 1602 err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0);
1628 if (err) 1603 if (err)
1629 return err; 1604 return err;
1630 1605
1631 err = carl9170_init_rf_banks_0_7(ar, 1606 err = carl9170_init_phy(ar, channel->band);
1632 channel->band == IEEE80211_BAND_5GHZ); 1607 if (err)
1633 if (err) 1608 return err;
1634 return err;
1635 1609
1636 cmd = CARL9170_CMD_RF_INIT; 1610 err = carl9170_init_rf_banks_0_7(ar,
1637 } else { 1611 channel->band == IEEE80211_BAND_5GHZ);
1638 cmd = CARL9170_CMD_FREQUENCY; 1612 if (err)
1639 } 1613 return err;
1640 1614
1641 err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL); 1615 err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL);
1642 if (err) 1616 if (err)
@@ -1648,8 +1622,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1648 return err; 1622 return err;
1649 1623
1650 err = carl9170_init_rf_bank4_pwr(ar, 1624 err = carl9170_init_rf_bank4_pwr(ar,
1651 channel->band == IEEE80211_BAND_5GHZ, 1625 channel->band == IEEE80211_BAND_5GHZ,
1652 channel->center_freq, bw); 1626 channel->center_freq, bw);
1653 if (err) 1627 if (err)
1654 return err; 1628 return err;
1655 1629
@@ -1703,13 +1677,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1703 rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man); 1677 rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man);
1704 rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi); 1678 rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi);
1705 rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi); 1679 rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi);
1706 1680 rf.finiteLoopCount = cpu_to_le32(2000);
1707 if (rfi != CARL9170_RFI_NONE) 1681 err = carl9170_exec_cmd(ar, CARL9170_CMD_RF_INIT, sizeof(rf), &rf,
1708 rf.finiteLoopCount = cpu_to_le32(2000);
1709 else
1710 rf.finiteLoopCount = cpu_to_le32(1000);
1711
1712 err = carl9170_exec_cmd(ar, cmd, sizeof(rf), &rf,
1713 sizeof(rf_res), &rf_res); 1682 sizeof(rf_res), &rf_res);
1714 if (err) 1683 if (err)
1715 return err; 1684 return err;
@@ -1724,9 +1693,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1724 old_channel->center_freq : -1, channel->center_freq, 1693 old_channel->center_freq : -1, channel->center_freq,
1725 err); 1694 err);
1726 1695
1727 if ((rfi == CARL9170_RFI_COLD) || (ar->chan_fail > 3)) { 1696 if (ar->chan_fail > 3) {
1728 /* 1697 /* We have tried very hard to change to _another_
1729 * We have tried very hard to change to _another_
1730 * channel and we've failed to do so! 1698 * channel and we've failed to do so!
1731 * Chances are that the PHY/RF is no longer 1699 * Chances are that the PHY/RF is no longer
1732 * operable (due to corruptions/fatal events/bugs?) 1700 * operable (due to corruptions/fatal events/bugs?)
@@ -1736,8 +1704,7 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1736 return 0; 1704 return 0;
1737 } 1705 }
1738 1706
1739 err = carl9170_set_channel(ar, channel, _bw, 1707 err = carl9170_set_channel(ar, channel, _bw);
1740 CARL9170_RFI_COLD);
1741 if (err) 1708 if (err)
1742 return err; 1709 return err;
1743 } else { 1710 } else {
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
index 5c54aa43ca2d..1816b4e7dc26 100644
--- a/drivers/net/wireless/ath/key.c
+++ b/drivers/net/wireless/ath/key.c
@@ -45,7 +45,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
45 void *ah = common->ah; 45 void *ah = common->ah;
46 46
47 if (entry >= common->keymax) { 47 if (entry >= common->keymax) {
48 ath_err(common, "keycache entry %u out of range\n", entry); 48 ath_err(common, "keyreset: keycache entry %u out of range\n",
49 entry);
49 return false; 50 return false;
50 } 51 }
51 52
@@ -91,7 +92,8 @@ static bool ath_hw_keysetmac(struct ath_common *common,
91 void *ah = common->ah; 92 void *ah = common->ah;
92 93
93 if (entry >= common->keymax) { 94 if (entry >= common->keymax) {
94 ath_err(common, "keycache entry %u out of range\n", entry); 95 ath_err(common, "keysetmac: keycache entry %u out of range\n",
96 entry);
95 return false; 97 return false;
96 } 98 }
97 99
@@ -133,7 +135,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
133 u32 keyType; 135 u32 keyType;
134 136
135 if (entry >= common->keymax) { 137 if (entry >= common->keymax) {
136 ath_err(common, "keycache entry %u out of range\n", entry); 138 ath_err(common, "set-entry: keycache entry %u out of range\n",
139 entry);
137 return false; 140 return false;
138 } 141 }
139 142
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index fe4a77ee05c9..f5e840104f4b 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -285,7 +285,9 @@ enum {
285#define B43_SHM_SH_DTIMPER 0x0012 /* DTIM period */ 285#define B43_SHM_SH_DTIMPER 0x0012 /* DTIM period */
286#define B43_SHM_SH_NOSLPZNATDTIM 0x004C /* NOSLPZNAT DTIM */ 286#define B43_SHM_SH_NOSLPZNATDTIM 0x004C /* NOSLPZNAT DTIM */
287/* SHM_SHARED beacon/AP variables */ 287/* SHM_SHARED beacon/AP variables */
288#define B43_SHM_SH_BT_BASE0 0x0068 /* Beacon template base 0 */
288#define B43_SHM_SH_BTL0 0x0018 /* Beacon template length 0 */ 289#define B43_SHM_SH_BTL0 0x0018 /* Beacon template length 0 */
290#define B43_SHM_SH_BT_BASE1 0x0468 /* Beacon template base 1 */
289#define B43_SHM_SH_BTL1 0x001A /* Beacon template length 1 */ 291#define B43_SHM_SH_BTL1 0x001A /* Beacon template length 1 */
290#define B43_SHM_SH_BTSFOFF 0x001C /* Beacon TSF offset */ 292#define B43_SHM_SH_BTSFOFF 0x001C /* Beacon TSF offset */
291#define B43_SHM_SH_TIMBPOS 0x001E /* TIM B position in beacon */ 293#define B43_SHM_SH_TIMBPOS 0x001E /* TIM B position in beacon */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c4d0cc582555..4ac73d2f8605 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1310,17 +1310,19 @@ static u32 b43_jssi_read(struct b43_wldev *dev)
1310{ 1310{
1311 u32 val = 0; 1311 u32 val = 0;
1312 1312
1313 val = b43_shm_read16(dev, B43_SHM_SHARED, 0x08A); 1313 val = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_JSSI1);
1314 val <<= 16; 1314 val <<= 16;
1315 val |= b43_shm_read16(dev, B43_SHM_SHARED, 0x088); 1315 val |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_JSSI0);
1316 1316
1317 return val; 1317 return val;
1318} 1318}
1319 1319
1320static void b43_jssi_write(struct b43_wldev *dev, u32 jssi) 1320static void b43_jssi_write(struct b43_wldev *dev, u32 jssi)
1321{ 1321{
1322 b43_shm_write16(dev, B43_SHM_SHARED, 0x088, (jssi & 0x0000FFFF)); 1322 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_JSSI0,
1323 b43_shm_write16(dev, B43_SHM_SHARED, 0x08A, (jssi & 0xFFFF0000) >> 16); 1323 (jssi & 0x0000FFFF));
1324 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_JSSI1,
1325 (jssi & 0xFFFF0000) >> 16);
1324} 1326}
1325 1327
1326static void b43_generate_noise_sample(struct b43_wldev *dev) 1328static void b43_generate_noise_sample(struct b43_wldev *dev)
@@ -1623,7 +1625,7 @@ static void b43_upload_beacon0(struct b43_wldev *dev)
1623 1625
1624 if (wl->beacon0_uploaded) 1626 if (wl->beacon0_uploaded)
1625 return; 1627 return;
1626 b43_write_beacon_template(dev, 0x68, 0x18); 1628 b43_write_beacon_template(dev, B43_SHM_SH_BT_BASE0, B43_SHM_SH_BTL0);
1627 wl->beacon0_uploaded = true; 1629 wl->beacon0_uploaded = true;
1628} 1630}
1629 1631
@@ -1633,7 +1635,7 @@ static void b43_upload_beacon1(struct b43_wldev *dev)
1633 1635
1634 if (wl->beacon1_uploaded) 1636 if (wl->beacon1_uploaded)
1635 return; 1637 return;
1636 b43_write_beacon_template(dev, 0x468, 0x1A); 1638 b43_write_beacon_template(dev, B43_SHM_SH_BT_BASE1, B43_SHM_SH_BTL1);
1637 wl->beacon1_uploaded = true; 1639 wl->beacon1_uploaded = true;
1638} 1640}
1639 1641
@@ -2780,9 +2782,7 @@ static int b43_gpio_init(struct b43_wldev *dev)
2780 switch (dev->dev->bus_type) { 2782 switch (dev->dev->bus_type) {
2781#ifdef CONFIG_B43_BCMA 2783#ifdef CONFIG_B43_BCMA
2782 case B43_BUS_BCMA: 2784 case B43_BUS_BCMA:
2783 bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, 2785 bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, mask, set);
2784 (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc,
2785 BCMA_CC_GPIOCTL) & ~mask) | set);
2786 break; 2786 break;
2787#endif 2787#endif
2788#ifdef CONFIG_B43_SSB 2788#ifdef CONFIG_B43_SSB
@@ -2807,8 +2807,7 @@ static void b43_gpio_cleanup(struct b43_wldev *dev)
2807 switch (dev->dev->bus_type) { 2807 switch (dev->dev->bus_type) {
2808#ifdef CONFIG_B43_BCMA 2808#ifdef CONFIG_B43_BCMA
2809 case B43_BUS_BCMA: 2809 case B43_BUS_BCMA:
2810 bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, 2810 bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, ~0, 0);
2811 0);
2812 break; 2811 break;
2813#endif 2812#endif
2814#ifdef CONFIG_B43_SSB 2813#ifdef CONFIG_B43_SSB
@@ -3116,7 +3115,7 @@ static int b43_chip_init(struct b43_wldev *dev)
3116 3115
3117 /* Probe Response Timeout value */ 3116 /* Probe Response Timeout value */
3118 /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */ 3117 /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
3119 b43_shm_write16(dev, B43_SHM_SHARED, 0x0074, 0x0000); 3118 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRMAXTIME, 0);
3120 3119
3121 /* Initially set the wireless operation mode. */ 3120 /* Initially set the wireless operation mode. */
3122 b43_adjust_opmode(dev); 3121 b43_adjust_opmode(dev);
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 3ae28561f7a4..5ed352ddae9e 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -104,14 +104,8 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev)
104 maxpwr = sprom->maxpwr_bg; 104 maxpwr = sprom->maxpwr_bg;
105 lpphy->max_tx_pwr_med_band = maxpwr; 105 lpphy->max_tx_pwr_med_band = maxpwr;
106 cckpo = sprom->cck2gpo; 106 cckpo = sprom->cck2gpo;
107 /*
108 * We don't read SPROM's opo as specs say. On rev8 SPROMs
109 * opo == ofdm2gpo and we don't know any SSB with LP-PHY
110 * and SPROM rev below 8.
111 */
112 B43_WARN_ON(sprom->revision < 8);
113 ofdmpo = sprom->ofdm2gpo;
114 if (cckpo) { 107 if (cckpo) {
108 ofdmpo = sprom->ofdm2gpo;
115 for (i = 0; i < 4; i++) { 109 for (i = 0; i < 4; i++) {
116 lpphy->tx_max_rate[i] = 110 lpphy->tx_max_rate[i] =
117 maxpwr - (ofdmpo & 0xF) * 2; 111 maxpwr - (ofdmpo & 0xF) * 2;
@@ -124,11 +118,11 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev)
124 ofdmpo >>= 4; 118 ofdmpo >>= 4;
125 } 119 }
126 } else { 120 } else {
127 ofdmpo &= 0xFF; 121 u8 opo = sprom->opo;
128 for (i = 0; i < 4; i++) 122 for (i = 0; i < 4; i++)
129 lpphy->tx_max_rate[i] = maxpwr; 123 lpphy->tx_max_rate[i] = maxpwr;
130 for (i = 4; i < 15; i++) 124 for (i = 4; i < 15; i++)
131 lpphy->tx_max_rate[i] = maxpwr - ofdmpo; 125 lpphy->tx_max_rate[i] = maxpwr - opo;
132 } 126 }
133 } else { /* 5GHz */ 127 } else { /* 5GHz */
134 lpphy->tx_isolation_low_band = sprom->tri5gl; 128 lpphy->tx_isolation_low_band = sprom->tri5gl;
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index e8486c1e091a..f9339e7ea6af 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -2789,10 +2789,6 @@ static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
2789 * Tx and Rx 2789 * Tx and Rx
2790 **************************************************/ 2790 **************************************************/
2791 2791
2792void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
2793{//TODO
2794}
2795
2796static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev) 2792static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev)
2797{//TODO 2793{//TODO
2798} 2794}
@@ -4892,7 +4888,7 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
4892} 4888}
4893 4889
4894/* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N */ 4890/* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N */
4895int b43_phy_initn(struct b43_wldev *dev) 4891static int b43_phy_initn(struct b43_wldev *dev)
4896{ 4892{
4897 struct ssb_sprom *sprom = dev->dev->bus_sprom; 4893 struct ssb_sprom *sprom = dev->dev->bus_sprom;
4898 struct b43_phy *phy = &dev->phy; 4894 struct b43_phy *phy = &dev->phy;
diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c
index ce037fb6789a..b4fd9345d673 100644
--- a/drivers/net/wireless/b43/radio_2056.c
+++ b/drivers/net/wireless/b43/radio_2056.c
@@ -2980,7 +2980,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev8_rx[] = {
2980 .rx = prefix##_rx, \ 2980 .rx = prefix##_rx, \
2981 .rx_length = ARRAY_SIZE(prefix##_rx) 2981 .rx_length = ARRAY_SIZE(prefix##_rx)
2982 2982
2983struct b2056_inittabs_pts b2056_inittabs[] = { 2983static const struct b2056_inittabs_pts b2056_inittabs[] = {
2984 [3] = { INITTABSPTS(b2056_inittab_rev3) }, 2984 [3] = { INITTABSPTS(b2056_inittab_rev3) },
2985 [4] = { INITTABSPTS(b2056_inittab_rev4) }, 2985 [4] = { INITTABSPTS(b2056_inittab_rev4) },
2986 [5] = { INITTABSPTS(b2056_inittab_rev5) }, 2986 [5] = { INITTABSPTS(b2056_inittab_rev5) },
@@ -9035,7 +9035,7 @@ static void b2056_upload_inittab(struct b43_wldev *dev, bool ghz5,
9035void b2056_upload_inittabs(struct b43_wldev *dev, 9035void b2056_upload_inittabs(struct b43_wldev *dev,
9036 bool ghz5, bool ignore_uploadflag) 9036 bool ghz5, bool ignore_uploadflag)
9037{ 9037{
9038 struct b2056_inittabs_pts *pts; 9038 const struct b2056_inittabs_pts *pts;
9039 9039
9040 if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) { 9040 if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) {
9041 B43_WARN_ON(1); 9041 B43_WARN_ON(1);
@@ -9057,7 +9057,7 @@ void b2056_upload_inittabs(struct b43_wldev *dev,
9057 9057
9058void b2056_upload_syn_pll_cp2(struct b43_wldev *dev, bool ghz5) 9058void b2056_upload_syn_pll_cp2(struct b43_wldev *dev, bool ghz5)
9059{ 9059{
9060 struct b2056_inittabs_pts *pts; 9060 const struct b2056_inittabs_pts *pts;
9061 const struct b2056_inittab_entry *e; 9061 const struct b2056_inittab_entry *e;
9062 9062
9063 if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) { 9063 if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) {
diff --git a/drivers/net/wireless/b43/sdio.h b/drivers/net/wireless/b43/sdio.h
index fb633094403a..1e93926f388f 100644
--- a/drivers/net/wireless/b43/sdio.h
+++ b/drivers/net/wireless/b43/sdio.h
@@ -25,12 +25,12 @@ void b43_sdio_exit(void);
25#else /* CONFIG_B43_SDIO */ 25#else /* CONFIG_B43_SDIO */
26 26
27 27
28int b43_sdio_request_irq(struct b43_wldev *dev, 28static inline int b43_sdio_request_irq(struct b43_wldev *dev,
29 void (*handler)(struct b43_wldev *dev)) 29 void (*handler)(struct b43_wldev *dev))
30{ 30{
31 return -ENODEV; 31 return -ENODEV;
32} 32}
33void b43_sdio_free_irq(struct b43_wldev *dev) 33static inline void b43_sdio_free_irq(struct b43_wldev *dev)
34{ 34{
35} 35}
36static inline int b43_sdio_init(void) 36static inline int b43_sdio_init(void)
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index aaca60c6f575..110510d53958 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2800,7 +2800,7 @@ static const struct nphy_rf_control_override_rev7
2800 { 0x0010, 0x344, 0x345, 0x0010, 4 }, 2800 { 0x0010, 0x344, 0x345, 0x0010, 4 },
2801}; 2801};
2802 2802
2803struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_wa_phy6_radio11_ghz2 = { 2803static struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_wa_phy6_radio11_ghz2 = {
2804 { 10, 14, 19, 27 }, 2804 { 10, 14, 19, 27 },
2805 { -5, 6, 10, 15 }, 2805 { -5, 6, 10, 15 },
2806 { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, 2806 { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA },
@@ -2811,7 +2811,7 @@ struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_wa_phy6_radio11_ghz2 = {
2811 0x18, 0x18, 0x18, 2811 0x18, 0x18, 0x18,
2812 0x01D0, 0x5, 2812 0x01D0, 0x5,
2813}; 2813};
2814struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][4] = { 2814static struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][4] = {
2815 { /* 2GHz */ 2815 { /* 2GHz */
2816 { /* PHY rev 3 */ 2816 { /* PHY rev 3 */
2817 { 7, 11, 16, 23 }, 2817 { 7, 11, 16, 23 },
diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c
index 5176363cadf2..e347b8d80ea4 100644
--- a/drivers/net/wireless/b43/tables_phy_lcn.c
+++ b/drivers/net/wireless/b43/tables_phy_lcn.c
@@ -313,7 +313,7 @@ static const u32 b43_lcntab_0x18[] = {
313 * TX gain. 313 * TX gain.
314 **************************************************/ 314 **************************************************/
315 315
316const struct b43_lcntab_tx_gain_tbl_entry 316static const struct b43_lcntab_tx_gain_tbl_entry
317 b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0[B43_LCNTAB_TX_GAIN_SIZE] = { 317 b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0[B43_LCNTAB_TX_GAIN_SIZE] = {
318 { 0x03, 0x00, 0x1f, 0x0, 0x48 }, 318 { 0x03, 0x00, 0x1f, 0x0, 0x48 },
319 { 0x03, 0x00, 0x1f, 0x0, 0x46 }, 319 { 0x03, 0x00, 0x1f, 0x0, 0x46 },
@@ -449,7 +449,7 @@ const struct b43_lcntab_tx_gain_tbl_entry
449 * SW control. 449 * SW control.
450 **************************************************/ 450 **************************************************/
451 451
452const u16 b43_lcntab_sw_ctl_4313_epa_rev0[] = { 452static const u16 b43_lcntab_sw_ctl_4313_epa_rev0[] = {
453 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 453 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
454 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, 454 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
455 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 455 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
@@ -631,7 +631,7 @@ static void b43_phy_lcn_upload_static_tables(struct b43_wldev *dev)
631 lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18); 631 lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18);
632} 632}
633 633
634void b43_phy_lcn_load_tx_gain_tab(struct b43_wldev *dev, 634static void b43_phy_lcn_load_tx_gain_tab(struct b43_wldev *dev,
635 const struct b43_lcntab_tx_gain_tbl_entry *gain_table) 635 const struct b43_lcntab_tx_gain_tbl_entry *gain_table)
636{ 636{
637 u32 i; 637 u32 i;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 11fd1c735589..f3149debede0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -65,7 +65,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
65 u8 data; 65 u8 data;
66 unsigned long flags; 66 unsigned long flags;
67 67
68 brcmf_dbg(TRACE, "Entering: irq %d\n", sdiodev->irq); 68 brcmf_dbg(SDIO, "Entering: irq %d\n", sdiodev->irq);
69 69
70 ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, 70 ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler,
71 sdiodev->irq_flags, "brcmf_oob_intr", 71 sdiodev->irq_flags, "brcmf_oob_intr",
@@ -102,7 +102,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
102 102
103int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) 103int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
104{ 104{
105 brcmf_dbg(TRACE, "Entering\n"); 105 brcmf_dbg(SDIO, "Entering\n");
106 106
107 sdio_claim_host(sdiodev->func[1]); 107 sdio_claim_host(sdiodev->func[1]);
108 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); 108 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
@@ -136,7 +136,7 @@ static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func)
136 136
137int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) 137int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
138{ 138{
139 brcmf_dbg(TRACE, "Entering\n"); 139 brcmf_dbg(SDIO, "Entering\n");
140 140
141 sdio_claim_host(sdiodev->func[1]); 141 sdio_claim_host(sdiodev->func[1]);
142 sdio_claim_irq(sdiodev->func[1], brcmf_sdio_irqhandler); 142 sdio_claim_irq(sdiodev->func[1], brcmf_sdio_irqhandler);
@@ -148,7 +148,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
148 148
149int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) 149int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
150{ 150{
151 brcmf_dbg(TRACE, "Entering\n"); 151 brcmf_dbg(SDIO, "Entering\n");
152 152
153 sdio_claim_host(sdiodev->func[1]); 153 sdio_claim_host(sdiodev->func[1]);
154 sdio_release_irq(sdiodev->func[2]); 154 sdio_release_irq(sdiodev->func[2]);
@@ -253,9 +253,9 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
253 u8 data; 253 u8 data;
254 int retval; 254 int retval;
255 255
256 brcmf_dbg(INFO, "addr:0x%08x\n", addr); 256 brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
257 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); 257 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
258 brcmf_dbg(INFO, "data:0x%02x\n", data); 258 brcmf_dbg(SDIO, "data:0x%02x\n", data);
259 259
260 if (ret) 260 if (ret)
261 *ret = retval; 261 *ret = retval;
@@ -268,9 +268,9 @@ u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
268 u32 data; 268 u32 data;
269 int retval; 269 int retval;
270 270
271 brcmf_dbg(INFO, "addr:0x%08x\n", addr); 271 brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
272 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); 272 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
273 brcmf_dbg(INFO, "data:0x%08x\n", data); 273 brcmf_dbg(SDIO, "data:0x%08x\n", data);
274 274
275 if (ret) 275 if (ret)
276 *ret = retval; 276 *ret = retval;
@@ -283,7 +283,7 @@ void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
283{ 283{
284 int retval; 284 int retval;
285 285
286 brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); 286 brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
287 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); 287 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
288 288
289 if (ret) 289 if (ret)
@@ -295,7 +295,7 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
295{ 295{
296 int retval; 296 int retval;
297 297
298 brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); 298 brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
299 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); 299 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
300 300
301 if (ret) 301 if (ret)
@@ -358,7 +358,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
358 uint width; 358 uint width;
359 int err = 0; 359 int err = 0;
360 360
361 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", 361 brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
362 fn, addr, pkt->len); 362 fn, addr, pkt->len);
363 363
364 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 364 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
@@ -381,7 +381,7 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
381 uint width; 381 uint width;
382 int err = 0; 382 int err = 0;
383 383
384 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", 384 brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
385 fn, addr, pktq->qlen); 385 fn, addr, pktq->qlen);
386 386
387 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 387 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
@@ -428,7 +428,7 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
428 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; 428 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
429 int err = 0; 429 int err = 0;
430 430
431 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", 431 brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
432 fn, addr, pkt->len); 432 fn, addr, pkt->len);
433 433
434 /* Async not implemented yet */ 434 /* Async not implemented yet */
@@ -492,13 +492,13 @@ int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
492int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) 492int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
493{ 493{
494 char t_func = (char)fn; 494 char t_func = (char)fn;
495 brcmf_dbg(TRACE, "Enter\n"); 495 brcmf_dbg(SDIO, "Enter\n");
496 496
497 /* issue abort cmd52 command through F0 */ 497 /* issue abort cmd52 command through F0 */
498 brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, 498 brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
499 SDIO_CCCR_ABORT, &t_func); 499 SDIO_CCCR_ABORT, &t_func);
500 500
501 brcmf_dbg(TRACE, "Exit\n"); 501 brcmf_dbg(SDIO, "Exit\n");
502 return 0; 502 return 0;
503} 503}
504 504
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index d92d373733d7..716548989e4f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -139,7 +139,7 @@ int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
139{ 139{
140 int err_ret; 140 int err_ret;
141 141
142 brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr); 142 brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr);
143 143
144 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait); 144 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait);
145 if (brcmf_pm_resume_error(sdiodev)) 145 if (brcmf_pm_resume_error(sdiodev))
@@ -179,7 +179,7 @@ int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
179 return -EINVAL; 179 return -EINVAL;
180 } 180 }
181 181
182 brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", 182 brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
183 rw, func, addr, nbytes); 183 rw, func, addr, nbytes);
184 184
185 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); 185 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
@@ -252,7 +252,7 @@ brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
252 252
253 struct sk_buff *pkt; 253 struct sk_buff *pkt;
254 254
255 brcmf_dbg(TRACE, "Enter\n"); 255 brcmf_dbg(SDIO, "Enter\n");
256 256
257 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_chain_wait); 257 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_chain_wait);
258 if (brcmf_pm_resume_error(sdiodev)) 258 if (brcmf_pm_resume_error(sdiodev))
@@ -270,7 +270,7 @@ brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
270 write ? "TX" : "RX", pkt, SGCount, addr, 270 write ? "TX" : "RX", pkt, SGCount, addr,
271 pkt_len, err_ret); 271 pkt_len, err_ret);
272 } else { 272 } else {
273 brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n", 273 brcmf_dbg(SDIO, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
274 write ? "TX" : "RX", pkt, SGCount, addr, 274 write ? "TX" : "RX", pkt, SGCount, addr,
275 pkt_len); 275 pkt_len);
276 } 276 }
@@ -280,7 +280,7 @@ brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
280 SGCount++; 280 SGCount++;
281 } 281 }
282 282
283 brcmf_dbg(TRACE, "Exit\n"); 283 brcmf_dbg(SDIO, "Exit\n");
284 return err_ret; 284 return err_ret;
285} 285}
286 286
@@ -295,7 +295,7 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
295 uint pkt_len; 295 uint pkt_len;
296 bool fifo = (fix_inc == SDIOH_DATA_FIX); 296 bool fifo = (fix_inc == SDIOH_DATA_FIX);
297 297
298 brcmf_dbg(TRACE, "Enter\n"); 298 brcmf_dbg(SDIO, "Enter\n");
299 299
300 if (pkt == NULL) 300 if (pkt == NULL)
301 return -EINVAL; 301 return -EINVAL;
@@ -314,7 +314,7 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
314 brcmf_err("%s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=0x%08x\n", 314 brcmf_err("%s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
315 write ? "TX" : "RX", pkt, addr, pkt_len, status); 315 write ? "TX" : "RX", pkt, addr, pkt_len, status);
316 } else { 316 } else {
317 brcmf_dbg(TRACE, "%s xfr'd %p, addr=0x%05x, len=%d\n", 317 brcmf_dbg(SDIO, "%s xfr'd %p, addr=0x%05x, len=%d\n",
318 write ? "TX" : "RX", pkt, addr, pkt_len); 318 write ? "TX" : "RX", pkt, addr, pkt_len);
319 } 319 }
320 320
@@ -350,12 +350,12 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
350 u32 fbraddr; 350 u32 fbraddr;
351 u8 func; 351 u8 func;
352 352
353 brcmf_dbg(TRACE, "\n"); 353 brcmf_dbg(SDIO, "\n");
354 354
355 /* Get the Card's common CIS address */ 355 /* Get the Card's common CIS address */
356 sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev, 356 sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev,
357 SDIO_CCCR_CIS); 357 SDIO_CCCR_CIS);
358 brcmf_dbg(INFO, "Card's Common CIS Ptr = 0x%x\n", 358 brcmf_dbg(SDIO, "Card's Common CIS Ptr = 0x%x\n",
359 sdiodev->func_cis_ptr[0]); 359 sdiodev->func_cis_ptr[0]);
360 360
361 /* Get the Card's function CIS (for each function) */ 361 /* Get the Card's function CIS (for each function) */
@@ -363,7 +363,7 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
363 func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { 363 func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
364 sdiodev->func_cis_ptr[func] = 364 sdiodev->func_cis_ptr[func] =
365 brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr); 365 brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr);
366 brcmf_dbg(INFO, "Function %d CIS Ptr = 0x%x\n", 366 brcmf_dbg(SDIO, "Function %d CIS Ptr = 0x%x\n",
367 func, sdiodev->func_cis_ptr[func]); 367 func, sdiodev->func_cis_ptr[func]);
368 } 368 }
369 369
@@ -382,7 +382,7 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
382{ 382{
383 int err_ret = 0; 383 int err_ret = 0;
384 384
385 brcmf_dbg(TRACE, "\n"); 385 brcmf_dbg(SDIO, "\n");
386 386
387 sdiodev->num_funcs = 2; 387 sdiodev->num_funcs = 2;
388 388
@@ -404,13 +404,13 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
404 404
405out: 405out:
406 sdio_release_host(sdiodev->func[1]); 406 sdio_release_host(sdiodev->func[1]);
407 brcmf_dbg(TRACE, "Done\n"); 407 brcmf_dbg(SDIO, "Done\n");
408 return err_ret; 408 return err_ret;
409} 409}
410 410
411void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev) 411void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
412{ 412{
413 brcmf_dbg(TRACE, "\n"); 413 brcmf_dbg(SDIO, "\n");
414 414
415 /* Disable Function 2 */ 415 /* Disable Function 2 */
416 sdio_claim_host(sdiodev->func[2]); 416 sdio_claim_host(sdiodev->func[2]);
@@ -458,11 +458,11 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
458 struct brcmf_sdio_dev *sdiodev; 458 struct brcmf_sdio_dev *sdiodev;
459 struct brcmf_bus *bus_if; 459 struct brcmf_bus *bus_if;
460 460
461 brcmf_dbg(TRACE, "Enter\n"); 461 brcmf_dbg(SDIO, "Enter\n");
462 brcmf_dbg(TRACE, "Class=%x\n", func->class); 462 brcmf_dbg(SDIO, "Class=%x\n", func->class);
463 brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor); 463 brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
464 brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device); 464 brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
465 brcmf_dbg(TRACE, "Function#: %d\n", func->num); 465 brcmf_dbg(SDIO, "Function#: %d\n", func->num);
466 466
467 /* Consume func num 1 but dont do anything with it. */ 467 /* Consume func num 1 but dont do anything with it. */
468 if (func->num == 1) 468 if (func->num == 1)
@@ -501,13 +501,13 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
501 if (err) 501 if (err)
502 goto fail; 502 goto fail;
503 503
504 brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); 504 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n");
505 err = brcmf_sdio_probe(sdiodev); 505 err = brcmf_sdio_probe(sdiodev);
506 if (err) { 506 if (err) {
507 brcmf_err("F2 error, probe failed %d...\n", err); 507 brcmf_err("F2 error, probe failed %d...\n", err);
508 goto fail; 508 goto fail;
509 } 509 }
510 brcmf_dbg(TRACE, "F2 init completed...\n"); 510 brcmf_dbg(SDIO, "F2 init completed...\n");
511 return 0; 511 return 0;
512 512
513fail: 513fail:
@@ -523,10 +523,10 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
523 struct brcmf_bus *bus_if; 523 struct brcmf_bus *bus_if;
524 struct brcmf_sdio_dev *sdiodev; 524 struct brcmf_sdio_dev *sdiodev;
525 525
526 brcmf_dbg(TRACE, "Enter\n"); 526 brcmf_dbg(SDIO, "Enter\n");
527 brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor); 527 brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
528 brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device); 528 brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
529 brcmf_dbg(TRACE, "Function: %d\n", func->num); 529 brcmf_dbg(SDIO, "Function: %d\n", func->num);
530 530
531 if (func->num != 1 && func->num != 2) 531 if (func->num != 1 && func->num != 2)
532 return; 532 return;
@@ -543,7 +543,7 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
543 kfree(sdiodev); 543 kfree(sdiodev);
544 } 544 }
545 545
546 brcmf_dbg(TRACE, "Exit\n"); 546 brcmf_dbg(SDIO, "Exit\n");
547} 547}
548 548
549#ifdef CONFIG_PM_SLEEP 549#ifdef CONFIG_PM_SLEEP
@@ -554,7 +554,7 @@ static int brcmf_sdio_suspend(struct device *dev)
554 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 554 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
555 int ret = 0; 555 int ret = 0;
556 556
557 brcmf_dbg(TRACE, "\n"); 557 brcmf_dbg(SDIO, "\n");
558 558
559 atomic_set(&sdiodev->suspend, true); 559 atomic_set(&sdiodev->suspend, true);
560 560
@@ -645,7 +645,7 @@ static struct platform_driver brcmf_sdio_pd = {
645 645
646void brcmf_sdio_exit(void) 646void brcmf_sdio_exit(void)
647{ 647{
648 brcmf_dbg(TRACE, "Enter\n"); 648 brcmf_dbg(SDIO, "Enter\n");
649 649
650 sdio_unregister_driver(&brcmf_sdmmc_driver); 650 sdio_unregister_driver(&brcmf_sdmmc_driver);
651 651
@@ -656,7 +656,7 @@ void brcmf_sdio_init(void)
656{ 656{
657 int ret; 657 int ret;
658 658
659 brcmf_dbg(TRACE, "Enter\n"); 659 brcmf_dbg(SDIO, "Enter\n");
660 660
661 ret = platform_driver_register(&brcmf_sdio_pd); 661 ret = platform_driver_register(&brcmf_sdio_pd);
662 662
@@ -666,7 +666,7 @@ void brcmf_sdio_init(void)
666#else 666#else
667void brcmf_sdio_exit(void) 667void brcmf_sdio_exit(void)
668{ 668{
669 brcmf_dbg(TRACE, "Enter\n"); 669 brcmf_dbg(SDIO, "Enter\n");
670 670
671 sdio_unregister_driver(&brcmf_sdmmc_driver); 671 sdio_unregister_driver(&brcmf_sdmmc_driver);
672} 672}
@@ -675,7 +675,7 @@ void brcmf_sdio_init(void)
675{ 675{
676 int ret; 676 int ret;
677 677
678 brcmf_dbg(TRACE, "Enter\n"); 678 brcmf_dbg(SDIO, "Enter\n");
679 679
680 ret = sdio_register_driver(&brcmf_sdmmc_driver); 680 ret = sdio_register_driver(&brcmf_sdmmc_driver);
681 681
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index c7fa20846b32..5249c67b466c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -72,6 +72,7 @@
72#define BRCMF_C_SET_WSEC 134 72#define BRCMF_C_SET_WSEC 134
73#define BRCMF_C_GET_PHY_NOISE 135 73#define BRCMF_C_GET_PHY_NOISE 135
74#define BRCMF_C_GET_BSS_INFO 136 74#define BRCMF_C_GET_BSS_INFO 136
75#define BRCMF_C_GET_BANDLIST 140
75#define BRCMF_C_SET_SCB_TIMEOUT 158 76#define BRCMF_C_SET_SCB_TIMEOUT 158
76#define BRCMF_C_GET_PHYLIST 180 77#define BRCMF_C_GET_PHYLIST 180
77#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 78#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
@@ -475,6 +476,11 @@ struct brcmf_sta_info_le {
475 __le32 rx_decrypt_failures; /* # of packet decrypted failed */ 476 __le32 rx_decrypt_failures; /* # of packet decrypted failed */
476}; 477};
477 478
479struct brcmf_chanspec_list {
480 __le32 count; /* # of entries */
481 __le32 element[1]; /* variable length uint32 list */
482};
483
478/* 484/*
479 * WLC_E_PROBRESP_MSG 485 * WLC_E_PROBRESP_MSG
480 * WLC_E_P2P_PROBREQ_MSG 486 * WLC_E_P2P_PROBREQ_MSG
@@ -542,10 +548,25 @@ struct brcmf_if_event {
542 u8 action; 548 u8 action;
543 u8 flags; 549 u8 flags;
544 u8 bssidx; 550 u8 bssidx;
551 u8 role;
545}; 552};
546 553
547/* forward declaration */ 554/* forward declarations */
548struct brcmf_cfg80211_vif; 555struct brcmf_cfg80211_vif;
556struct brcmf_fws_mac_descriptor;
557
558/**
559 * enum brcmf_netif_stop_reason - reason for stopping netif queue.
560 *
561 * @BRCMF_NETIF_STOP_REASON_FWS_FC:
562 * netif stopped due to firmware signalling flow control.
563 * @BRCMF_NETIF_STOP_REASON_BLOCK_BUS:
564 * netif stopped due to bus blocking.
565 */
566enum brcmf_netif_stop_reason {
567 BRCMF_NETIF_STOP_REASON_FWS_FC = 1,
568 BRCMF_NETIF_STOP_REASON_BLOCK_BUS = 2
569};
549 570
550/** 571/**
551 * struct brcmf_if - interface control information. 572 * struct brcmf_if - interface control information.
@@ -554,9 +575,13 @@ struct brcmf_cfg80211_vif;
554 * @vif: points to cfg80211 specific interface information. 575 * @vif: points to cfg80211 specific interface information.
555 * @ndev: associated network device. 576 * @ndev: associated network device.
556 * @stats: interface specific network statistics. 577 * @stats: interface specific network statistics.
578 * @setmacaddr_work: worker object for setting mac address.
579 * @multicast_work: worker object for multicast provisioning.
580 * @fws_desc: interface specific firmware-signalling descriptor.
557 * @ifidx: interface index in device firmware. 581 * @ifidx: interface index in device firmware.
558 * @bssidx: index of bss associated with this interface. 582 * @bssidx: index of bss associated with this interface.
559 * @mac_addr: assigned mac address. 583 * @mac_addr: assigned mac address.
584 * @netif_stop: bitmap indicates reason why netif queues are stopped.
560 * @pend_8021x_cnt: tracks outstanding number of 802.1x frames. 585 * @pend_8021x_cnt: tracks outstanding number of 802.1x frames.
561 * @pend_8021x_wait: used for signalling change in count. 586 * @pend_8021x_wait: used for signalling change in count.
562 */ 587 */
@@ -567,9 +592,11 @@ struct brcmf_if {
567 struct net_device_stats stats; 592 struct net_device_stats stats;
568 struct work_struct setmacaddr_work; 593 struct work_struct setmacaddr_work;
569 struct work_struct multicast_work; 594 struct work_struct multicast_work;
595 struct brcmf_fws_mac_descriptor *fws_desc;
570 int ifidx; 596 int ifidx;
571 s32 bssidx; 597 s32 bssidx;
572 u8 mac_addr[ETH_ALEN]; 598 u8 mac_addr[ETH_ALEN];
599 u8 netif_stop;
573 atomic_t pend_8021x_cnt; 600 atomic_t pend_8021x_cnt;
574 wait_queue_head_t pend_8021x_wait; 601 wait_queue_head_t pend_8021x_wait;
575}; 602};
@@ -594,6 +621,10 @@ extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
594extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, 621extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx,
595 s32 ifidx, char *name, u8 *mac_addr); 622 s32 ifidx, char *name, u8 *mac_addr);
596extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); 623extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx);
624void brcmf_txflowblock_if(struct brcmf_if *ifp,
625 enum brcmf_netif_stop_reason reason, bool state);
597extern u32 brcmf_get_chip_info(struct brcmf_if *ifp); 626extern u32 brcmf_get_chip_info(struct brcmf_if *ifp);
627extern void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
628 bool success);
598 629
599#endif /* _BRCMF_H_ */ 630#endif /* _BRCMF_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 883ef9063e8a..080395f49fa5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -39,10 +39,12 @@ struct brcmf_bus_dcmd {
39 * @txdata: send a data frame to the dongle (callee disposes skb). 39 * @txdata: send a data frame to the dongle (callee disposes skb).
40 * @txctl: transmit a control request message to dongle. 40 * @txctl: transmit a control request message to dongle.
41 * @rxctl: receive a control response message from dongle. 41 * @rxctl: receive a control response message from dongle.
42 * @gettxq: obtain a reference of bus transmit queue (optional).
42 * 43 *
43 * This structure provides an abstract interface towards the 44 * This structure provides an abstract interface towards the
44 * bus specific driver. For control messages to common driver 45 * bus specific driver. For control messages to common driver
45 * will assure there is only one active transaction. 46 * will assure there is only one active transaction. Unless
47 * indicated otherwise these callbacks are mandatory.
46 */ 48 */
47struct brcmf_bus_ops { 49struct brcmf_bus_ops {
48 int (*init)(struct device *dev); 50 int (*init)(struct device *dev);
@@ -50,6 +52,7 @@ struct brcmf_bus_ops {
50 int (*txdata)(struct device *dev, struct sk_buff *skb); 52 int (*txdata)(struct device *dev, struct sk_buff *skb);
51 int (*txctl)(struct device *dev, unsigned char *msg, uint len); 53 int (*txctl)(struct device *dev, unsigned char *msg, uint len);
52 int (*rxctl)(struct device *dev, unsigned char *msg, uint len); 54 int (*rxctl)(struct device *dev, unsigned char *msg, uint len);
55 struct pktq * (*gettxq)(struct device *dev);
53}; 56};
54 57
55/** 58/**
@@ -115,6 +118,14 @@ int brcmf_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint len)
115 return bus->ops->rxctl(bus->dev, msg, len); 118 return bus->ops->rxctl(bus->dev, msg, len);
116} 119}
117 120
121static inline
122struct pktq *brcmf_bus_gettxq(struct brcmf_bus *bus)
123{
124 if (!bus->ops->gettxq)
125 return ERR_PTR(-ENOENT);
126
127 return bus->ops->gettxq(bus->dev);
128}
118/* 129/*
119 * interface functions from common layer 130 * interface functions from common layer
120 */ 131 */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
index e224bcb90024..59c77aa3b959 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -303,8 +303,8 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
303 303
304 /* Pop BDC header used to convey priority for buses that don't */ 304 /* Pop BDC header used to convey priority for buses that don't */
305 305
306 if (pktbuf->len < BDC_HEADER_LEN) { 306 if (pktbuf->len <= BDC_HEADER_LEN) {
307 brcmf_err("rx data too short (%d < %d)\n", 307 brcmf_dbg(INFO, "rx data too short (%d <= %d)\n",
308 pktbuf->len, BDC_HEADER_LEN); 308 pktbuf->len, BDC_HEADER_LEN);
309 return -EBADE; 309 return -EBADE;
310 } 310 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
index ac792499b46a..202869cd0932 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -130,7 +130,7 @@ ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
130 size_t count, loff_t *ppos) 130 size_t count, loff_t *ppos)
131{ 131{
132 struct brcmf_fws_stats *fwstats = f->private_data; 132 struct brcmf_fws_stats *fwstats = f->private_data;
133 char buf[100]; 133 char buf[650];
134 int res; 134 int res;
135 135
136 /* only allow read from start */ 136 /* only allow read from start */
@@ -138,14 +138,52 @@ ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
138 return 0; 138 return 0;
139 139
140 res = scnprintf(buf, sizeof(buf), 140 res = scnprintf(buf, sizeof(buf),
141 "header_pulls: %u\n" 141 "header_pulls: %u\n"
142 "header_only_pkt: %u\n" 142 "header_only_pkt: %u\n"
143 "tlv_parse_failed: %u\n" 143 "tlv_parse_failed: %u\n"
144 "tlv_invalid_type: %u\n", 144 "tlv_invalid_type: %u\n"
145 "mac_update_fails: %u\n"
146 "ps_update_fails: %u\n"
147 "if_update_fails: %u\n"
148 "pkt2bus: %u\n"
149 "generic_error: %u\n"
150 "rollback_success: %u\n"
151 "rollback_failed: %u\n"
152 "delayq_full: %u\n"
153 "supprq_full: %u\n"
154 "txs_indicate: %u\n"
155 "txs_discard: %u\n"
156 "txs_suppr_core: %u\n"
157 "txs_suppr_ps: %u\n"
158 "txs_tossed: %u\n"
159 "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
160 "fifo_credits_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
145 fwstats->header_pulls, 161 fwstats->header_pulls,
146 fwstats->header_only_pkt, 162 fwstats->header_only_pkt,
147 fwstats->tlv_parse_failed, 163 fwstats->tlv_parse_failed,
148 fwstats->tlv_invalid_type); 164 fwstats->tlv_invalid_type,
165 fwstats->mac_update_failed,
166 fwstats->mac_ps_update_failed,
167 fwstats->if_update_failed,
168 fwstats->pkt2bus,
169 fwstats->generic_error,
170 fwstats->rollback_success,
171 fwstats->rollback_failed,
172 fwstats->delayq_full_error,
173 fwstats->supprq_full_error,
174 fwstats->txs_indicate,
175 fwstats->txs_discard,
176 fwstats->txs_supp_core,
177 fwstats->txs_supp_ps,
178 fwstats->txs_tossed,
179 fwstats->send_pkts[0], fwstats->send_pkts[1],
180 fwstats->send_pkts[2], fwstats->send_pkts[3],
181 fwstats->send_pkts[4],
182 fwstats->fifo_credits_sent[0],
183 fwstats->fifo_credits_sent[1],
184 fwstats->fifo_credits_sent[2],
185 fwstats->fifo_credits_sent[3],
186 fwstats->fifo_credits_sent[4]);
149 187
150 return simple_read_from_buffer(data, count, ppos, buf, res); 188 return simple_read_from_buffer(data, count, ppos, buf, res);
151} 189}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index 4bc646bde16f..009c87bfd9ae 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -34,6 +34,7 @@
34#define BRCMF_SCAN_VAL 0x00004000 34#define BRCMF_SCAN_VAL 0x00004000
35#define BRCMF_CONN_VAL 0x00008000 35#define BRCMF_CONN_VAL 0x00008000
36#define BRCMF_CDC_VAL 0x00010000 36#define BRCMF_CDC_VAL 0x00010000
37#define BRCMF_SDIO_VAL 0x00020000
37 38
38/* set default print format */ 39/* set default print format */
39#undef pr_fmt 40#undef pr_fmt
@@ -92,6 +93,7 @@ do { \
92 93
93#define brcmf_dbg_hex_dump(test, data, len, fmt, ...) \ 94#define brcmf_dbg_hex_dump(test, data, len, fmt, ...) \
94do { \ 95do { \
96 trace_brcmf_hexdump((void *)data, len); \
95 if (test) \ 97 if (test) \
96 brcmu_dbg_hex_dump(data, len, fmt, ##__VA_ARGS__); \ 98 brcmu_dbg_hex_dump(data, len, fmt, ##__VA_ARGS__); \
97} while (0) 99} while (0)
@@ -137,6 +139,25 @@ struct brcmf_fws_stats {
137 u32 tlv_invalid_type; 139 u32 tlv_invalid_type;
138 u32 header_only_pkt; 140 u32 header_only_pkt;
139 u32 header_pulls; 141 u32 header_pulls;
142 u32 pkt2bus;
143 u32 send_pkts[5];
144 u32 fifo_credits_sent[5];
145 u32 fifo_credits_back[6];
146 u32 generic_error;
147 u32 mac_update_failed;
148 u32 mac_ps_update_failed;
149 u32 if_update_failed;
150 u32 packet_request_failed;
151 u32 credit_request_failed;
152 u32 rollback_success;
153 u32 rollback_failed;
154 u32 delayq_full_error;
155 u32 supprq_full_error;
156 u32 txs_indicate;
157 u32 txs_discard;
158 u32 txs_supp_core;
159 u32 txs_supp_ps;
160 u32 txs_tossed;
140}; 161};
141 162
142struct brcmf_pub; 163struct brcmf_pub;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index fa5a2af04d46..763a84eba216 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -223,18 +223,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
223 goto done; 223 goto done;
224 } 224 }
225 225
226 /* handle ethernet header */ 226 ret = brcmf_fws_process_skb(ifp, skb);
227 eh = (struct ethhdr *)(skb->data);
228 if (is_multicast_ether_addr(eh->h_dest))
229 drvr->tx_multicast++;
230 if (ntohs(eh->h_proto) == ETH_P_PAE)
231 atomic_inc(&ifp->pend_8021x_cnt);
232
233 /* If the protocol uses a data header, apply it */
234 brcmf_proto_hdrpush(drvr, ifp->ifidx, 0, skb);
235
236 /* Use bus module to send data frame */
237 ret = brcmf_bus_txdata(drvr->bus_if, skb);
238 227
239done: 228done:
240 if (ret) { 229 if (ret) {
@@ -248,9 +237,27 @@ done:
248 return NETDEV_TX_OK; 237 return NETDEV_TX_OK;
249} 238}
250 239
240void brcmf_txflowblock_if(struct brcmf_if *ifp,
241 enum brcmf_netif_stop_reason reason, bool state)
242{
243 if (!ifp)
244 return;
245
246 brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n",
247 ifp->bssidx, ifp->netif_stop, reason, state);
248 if (state) {
249 if (!ifp->netif_stop)
250 netif_stop_queue(ifp->ndev);
251 ifp->netif_stop |= reason;
252 } else {
253 ifp->netif_stop &= ~reason;
254 if (!ifp->netif_stop)
255 netif_wake_queue(ifp->ndev);
256 }
257}
258
251void brcmf_txflowblock(struct device *dev, bool state) 259void brcmf_txflowblock(struct device *dev, bool state)
252{ 260{
253 struct net_device *ndev;
254 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 261 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
255 struct brcmf_pub *drvr = bus_if->drvr; 262 struct brcmf_pub *drvr = bus_if->drvr;
256 int i; 263 int i;
@@ -258,13 +265,8 @@ void brcmf_txflowblock(struct device *dev, bool state)
258 brcmf_dbg(TRACE, "Enter\n"); 265 brcmf_dbg(TRACE, "Enter\n");
259 266
260 for (i = 0; i < BRCMF_MAX_IFS; i++) 267 for (i = 0; i < BRCMF_MAX_IFS; i++)
261 if (drvr->iflist[i]) { 268 brcmf_txflowblock_if(drvr->iflist[i],
262 ndev = drvr->iflist[i]->ndev; 269 BRCMF_NETIF_STOP_REASON_BLOCK_BUS, state);
263 if (state)
264 netif_stop_queue(ndev);
265 else
266 netif_wake_queue(ndev);
267 }
268} 270}
269 271
270void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) 272void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
@@ -321,13 +323,8 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
321 /* Strip header, count, deliver upward */ 323 /* Strip header, count, deliver upward */
322 skb_pull(skb, ETH_HLEN); 324 skb_pull(skb, ETH_HLEN);
323 325
324 /* Process special event packets and then discard them */ 326 /* Process special event packets */
325 brcmf_fweh_process_skb(drvr, skb, &ifidx); 327 brcmf_fweh_process_skb(drvr, skb);
326
327 if (drvr->iflist[ifidx]) {
328 ifp = drvr->iflist[ifidx];
329 ifp->ndev->last_rx = jiffies;
330 }
331 328
332 if (!(ifp->ndev->flags & IFF_UP)) { 329 if (!(ifp->ndev->flags & IFF_UP)) {
333 brcmu_pkt_buf_free_skb(skb); 330 brcmu_pkt_buf_free_skb(skb);
@@ -350,14 +347,13 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
350 } 347 }
351} 348}
352 349
353void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) 350void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
351 bool success)
354{ 352{
355 u8 ifidx; 353 struct brcmf_if *ifp;
356 struct ethhdr *eh; 354 struct ethhdr *eh;
355 u8 ifidx;
357 u16 type; 356 u16 type;
358 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
359 struct brcmf_pub *drvr = bus_if->drvr;
360 struct brcmf_if *ifp;
361 int res; 357 int res;
362 358
363 res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp); 359 res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
@@ -378,11 +374,24 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
378 } 374 }
379 if (!success) 375 if (!success)
380 ifp->stats.tx_errors++; 376 ifp->stats.tx_errors++;
381
382done: 377done:
383 brcmu_pkt_buf_free_skb(txp); 378 brcmu_pkt_buf_free_skb(txp);
384} 379}
385 380
381void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
382{
383 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
384 struct brcmf_pub *drvr = bus_if->drvr;
385
386 /* await txstatus signal for firmware if active */
387 if (brcmf_fws_fc_active(drvr->fws)) {
388 if (!success)
389 brcmf_fws_bustxfail(drvr->fws, txp);
390 } else {
391 brcmf_txfinalize(drvr, txp, success);
392 }
393}
394
386static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) 395static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
387{ 396{
388 struct brcmf_if *ifp = netdev_priv(ndev); 397 struct brcmf_if *ifp = netdev_priv(ndev);
@@ -741,28 +750,35 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
741 } 750 }
742 } 751 }
743 752
744 /* Allocate netdev, including space for private structure */ 753 if (!brcmf_p2p_enable && bssidx == 1) {
745 ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup); 754 /* this is P2P_DEVICE interface */
746 if (!ndev) { 755 brcmf_dbg(INFO, "allocate non-netdev interface\n");
747 brcmf_err("OOM - alloc_netdev\n"); 756 ifp = kzalloc(sizeof(*ifp), GFP_KERNEL);
748 return ERR_PTR(-ENOMEM); 757 } else {
758 brcmf_dbg(INFO, "allocate netdev interface\n");
759 /* Allocate netdev, including space for private structure */
760 ndev = alloc_netdev(sizeof(*ifp), name, ether_setup);
761 if (!ndev) {
762 brcmf_err("OOM - alloc_netdev\n");
763 return ERR_PTR(-ENOMEM);
764 }
765
766 ifp = netdev_priv(ndev);
767 ifp->ndev = ndev;
749 } 768 }
750 769
751 ifp = netdev_priv(ndev);
752 ifp->ndev = ndev;
753 ifp->drvr = drvr; 770 ifp->drvr = drvr;
754 drvr->iflist[bssidx] = ifp; 771 drvr->iflist[bssidx] = ifp;
755 ifp->ifidx = ifidx; 772 ifp->ifidx = ifidx;
756 ifp->bssidx = bssidx; 773 ifp->bssidx = bssidx;
757 774
758
759 init_waitqueue_head(&ifp->pend_8021x_wait); 775 init_waitqueue_head(&ifp->pend_8021x_wait);
760 776
761 if (mac_addr != NULL) 777 if (mac_addr != NULL)
762 memcpy(ifp->mac_addr, mac_addr, ETH_ALEN); 778 memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
763 779
764 brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n", 780 brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
765 current->pid, ifp->ndev->name, ifp->mac_addr); 781 current->pid, name, ifp->mac_addr);
766 782
767 return ifp; 783 return ifp;
768} 784}
@@ -794,11 +810,13 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
794 } 810 }
795 811
796 unregister_netdev(ifp->ndev); 812 unregister_netdev(ifp->ndev);
797 drvr->iflist[bssidx] = NULL;
798 if (bssidx == 0) 813 if (bssidx == 0)
799 brcmf_cfg80211_detach(drvr->config); 814 brcmf_cfg80211_detach(drvr->config);
800 free_netdev(ifp->ndev); 815 free_netdev(ifp->ndev);
816 } else {
817 kfree(ifp);
801 } 818 }
819 drvr->iflist[bssidx] = NULL;
802} 820}
803 821
804int brcmf_attach(uint bus_hdrlen, struct device *dev) 822int brcmf_attach(uint bus_hdrlen, struct device *dev)
@@ -882,6 +900,7 @@ int brcmf_bus_start(struct device *dev)
882 900
883 drvr->fw_signals = true; 901 drvr->fw_signals = true;
884 (void)brcmf_fws_init(drvr); 902 (void)brcmf_fws_init(drvr);
903 brcmf_fws_add_interface(ifp);
885 904
886 drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev); 905 drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
887 if (drvr->config == NULL) { 906 if (drvr->config == NULL) {
@@ -899,8 +918,10 @@ fail:
899 brcmf_err("failed: %d\n", ret); 918 brcmf_err("failed: %d\n", ret);
900 if (drvr->config) 919 if (drvr->config)
901 brcmf_cfg80211_detach(drvr->config); 920 brcmf_cfg80211_detach(drvr->config);
902 if (drvr->fws) 921 if (drvr->fws) {
922 brcmf_fws_del_interface(ifp);
903 brcmf_fws_deinit(drvr); 923 brcmf_fws_deinit(drvr);
924 }
904 free_netdev(ifp->ndev); 925 free_netdev(ifp->ndev);
905 drvr->iflist[0] = NULL; 926 drvr->iflist[0] = NULL;
906 if (p2p_ifp) { 927 if (p2p_ifp) {
@@ -956,16 +977,17 @@ void brcmf_detach(struct device *dev)
956 977
957 /* make sure primary interface removed last */ 978 /* make sure primary interface removed last */
958 for (i = BRCMF_MAX_IFS-1; i > -1; i--) 979 for (i = BRCMF_MAX_IFS-1; i > -1; i--)
959 if (drvr->iflist[i]) 980 if (drvr->iflist[i]) {
981 brcmf_fws_del_interface(drvr->iflist[i]);
960 brcmf_del_if(drvr, i); 982 brcmf_del_if(drvr, i);
983 }
961 984
962 brcmf_bus_detach(drvr); 985 brcmf_bus_detach(drvr);
963 986
964 if (drvr->prot) 987 if (drvr->prot)
965 brcmf_proto_detach(drvr); 988 brcmf_proto_detach(drvr);
966 989
967 if (drvr->fws) 990 brcmf_fws_deinit(drvr);
968 brcmf_fws_deinit(drvr);
969 991
970 brcmf_debugfs_detach(drvr); 992 brcmf_debugfs_detach(drvr);
971 bus_if->drvr = NULL; 993 bus_if->drvr = NULL;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 9a2edd3f0a5c..4ff2d3c52ee6 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -94,6 +94,7 @@ struct rte_console {
94 94
95#include "dhd_bus.h" 95#include "dhd_bus.h"
96#include "dhd_dbg.h" 96#include "dhd_dbg.h"
97#include "tracepoint.h"
97 98
98#define TXQLEN 2048 /* bulk tx queue length */ 99#define TXQLEN 2048 /* bulk tx queue length */
99#define TXHI (TXQLEN - 256) /* turn on flow control above TXHI */ 100#define TXHI (TXQLEN - 256) /* turn on flow control above TXHI */
@@ -675,7 +676,7 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
675 u8 clkctl, clkreq, devctl; 676 u8 clkctl, clkreq, devctl;
676 unsigned long timeout; 677 unsigned long timeout;
677 678
678 brcmf_dbg(TRACE, "Enter\n"); 679 brcmf_dbg(SDIO, "Enter\n");
679 680
680 clkctl = 0; 681 clkctl = 0;
681 682
@@ -713,7 +714,7 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
713 devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; 714 devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
714 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, 715 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
715 devctl, &err); 716 devctl, &err);
716 brcmf_dbg(INFO, "CLKCTL: set PENDING\n"); 717 brcmf_dbg(SDIO, "CLKCTL: set PENDING\n");
717 bus->clkstate = CLK_PENDING; 718 bus->clkstate = CLK_PENDING;
718 719
719 return 0; 720 return 0;
@@ -750,7 +751,7 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
750 751
751 /* Mark clock available */ 752 /* Mark clock available */
752 bus->clkstate = CLK_AVAIL; 753 bus->clkstate = CLK_AVAIL;
753 brcmf_dbg(INFO, "CLKCTL: turned ON\n"); 754 brcmf_dbg(SDIO, "CLKCTL: turned ON\n");
754 755
755#if defined(DEBUG) 756#if defined(DEBUG)
756 if (!bus->alp_only) { 757 if (!bus->alp_only) {
@@ -775,7 +776,7 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
775 bus->clkstate = CLK_SDONLY; 776 bus->clkstate = CLK_SDONLY;
776 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 777 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
777 clkreq, &err); 778 clkreq, &err);
778 brcmf_dbg(INFO, "CLKCTL: turned OFF\n"); 779 brcmf_dbg(SDIO, "CLKCTL: turned OFF\n");
779 if (err) { 780 if (err) {
780 brcmf_err("Failed access turning clock off: %d\n", 781 brcmf_err("Failed access turning clock off: %d\n",
781 err); 782 err);
@@ -788,7 +789,7 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
788/* Change idle/active SD state */ 789/* Change idle/active SD state */
789static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on) 790static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on)
790{ 791{
791 brcmf_dbg(TRACE, "Enter\n"); 792 brcmf_dbg(SDIO, "Enter\n");
792 793
793 if (on) 794 if (on)
794 bus->clkstate = CLK_SDONLY; 795 bus->clkstate = CLK_SDONLY;
@@ -805,7 +806,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
805 uint oldstate = bus->clkstate; 806 uint oldstate = bus->clkstate;
806#endif /* DEBUG */ 807#endif /* DEBUG */
807 808
808 brcmf_dbg(TRACE, "Enter\n"); 809 brcmf_dbg(SDIO, "Enter\n");
809 810
810 /* Early exit if we're already there */ 811 /* Early exit if we're already there */
811 if (bus->clkstate == target) { 812 if (bus->clkstate == target) {
@@ -849,7 +850,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
849 break; 850 break;
850 } 851 }
851#ifdef DEBUG 852#ifdef DEBUG
852 brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate); 853 brcmf_dbg(SDIO, "%d -> %d\n", oldstate, bus->clkstate);
853#endif /* DEBUG */ 854#endif /* DEBUG */
854 855
855 return 0; 856 return 0;
@@ -862,7 +863,7 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
862 u8 fcbits; 863 u8 fcbits;
863 int ret; 864 int ret;
864 865
865 brcmf_dbg(TRACE, "Enter\n"); 866 brcmf_dbg(SDIO, "Enter\n");
866 867
867 /* Read mailbox data and ack that we did so */ 868 /* Read mailbox data and ack that we did so */
868 ret = r_sdreg32(bus, &hmb_data, 869 ret = r_sdreg32(bus, &hmb_data,
@@ -875,7 +876,7 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
875 876
876 /* Dongle recomposed rx frames, accept them again */ 877 /* Dongle recomposed rx frames, accept them again */
877 if (hmb_data & HMB_DATA_NAKHANDLED) { 878 if (hmb_data & HMB_DATA_NAKHANDLED) {
878 brcmf_dbg(INFO, "Dongle reports NAK handled, expect rtx of %d\n", 879 brcmf_dbg(SDIO, "Dongle reports NAK handled, expect rtx of %d\n",
879 bus->rx_seq); 880 bus->rx_seq);
880 if (!bus->rxskip) 881 if (!bus->rxskip)
881 brcmf_err("unexpected NAKHANDLED!\n"); 882 brcmf_err("unexpected NAKHANDLED!\n");
@@ -896,7 +897,7 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
896 "expecting %d\n", 897 "expecting %d\n",
897 bus->sdpcm_ver, SDPCM_PROT_VERSION); 898 bus->sdpcm_ver, SDPCM_PROT_VERSION);
898 else 899 else
899 brcmf_dbg(INFO, "Dongle ready, protocol version %d\n", 900 brcmf_dbg(SDIO, "Dongle ready, protocol version %d\n",
900 bus->sdpcm_ver); 901 bus->sdpcm_ver);
901 } 902 }
902 903
@@ -970,7 +971,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
970 if (!retries) 971 if (!retries)
971 brcmf_err("count never zeroed: last 0x%04x\n", lastrbc); 972 brcmf_err("count never zeroed: last 0x%04x\n", lastrbc);
972 else 973 else
973 brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries); 974 brcmf_dbg(SDIO, "flush took %d iterations\n", 0xffff - retries);
974 975
975 if (rtx) { 976 if (rtx) {
976 bus->sdcnt.rxrtx++; 977 bus->sdcnt.rxrtx++;
@@ -1173,7 +1174,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1173 /* If packets, issue read(s) and send up packet chain */ 1174 /* If packets, issue read(s) and send up packet chain */
1174 /* Return sequence numbers consumed? */ 1175 /* Return sequence numbers consumed? */
1175 1176
1176 brcmf_dbg(TRACE, "start: glomd %p glom %p\n", 1177 brcmf_dbg(SDIO, "start: glomd %p glom %p\n",
1177 bus->glomd, skb_peek(&bus->glom)); 1178 bus->glomd, skb_peek(&bus->glom));
1178 1179
1179 /* If there's a descriptor, generate the packet chain */ 1180 /* If there's a descriptor, generate the packet chain */
@@ -1781,7 +1782,6 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1781 u8 *frame; 1782 u8 *frame;
1782 u16 len, pad = 0; 1783 u16 len, pad = 0;
1783 u32 swheader; 1784 u32 swheader;
1784 struct sk_buff *new;
1785 int i; 1785 int i;
1786 1786
1787 brcmf_dbg(TRACE, "Enter\n"); 1787 brcmf_dbg(TRACE, "Enter\n");
@@ -1795,27 +1795,14 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1795 brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n", 1795 brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n",
1796 skb_headroom(pkt), pad); 1796 skb_headroom(pkt), pad);
1797 bus->sdiodev->bus_if->tx_realloc++; 1797 bus->sdiodev->bus_if->tx_realloc++;
1798 new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN); 1798 ret = skb_cow(pkt, BRCMF_SDALIGN);
1799 if (!new) { 1799 if (ret)
1800 brcmf_err("couldn't allocate new %d-byte packet\n",
1801 pkt->len + BRCMF_SDALIGN);
1802 ret = -ENOMEM;
1803 goto done; 1800 goto done;
1804 } 1801 pad = ((unsigned long)frame % BRCMF_SDALIGN);
1805
1806 pkt_align(new, pkt->len, BRCMF_SDALIGN);
1807 memcpy(new->data, pkt->data, pkt->len);
1808 brcmu_pkt_buf_free_skb(pkt);
1809 pkt = new;
1810 frame = (u8 *) (pkt->data);
1811 /* precondition: (frame % BRCMF_SDALIGN) == 0) */
1812 pad = 0;
1813 } else {
1814 skb_push(pkt, pad);
1815 frame = (u8 *) (pkt->data);
1816 /* precondition: pad + SDPCM_HDRLEN <= pkt->len */
1817 memset(frame, 0, pad + SDPCM_HDRLEN);
1818 } 1802 }
1803 skb_push(pkt, pad);
1804 frame = (u8 *) (pkt->data);
1805 memset(frame, 0, pad + SDPCM_HDRLEN);
1819 } 1806 }
1820 /* precondition: pad < BRCMF_SDALIGN */ 1807 /* precondition: pad < BRCMF_SDALIGN */
1821 1808
@@ -1830,8 +1817,8 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1830 (((pad + 1817 (((pad +
1831 SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); 1818 SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
1832 1819
1833 put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN); 1820 *(((__le32 *) frame) + 1) = cpu_to_le32(swheader);
1834 put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); 1821 *(((__le32 *) frame) + 2) = 0;
1835 1822
1836#ifdef DEBUG 1823#ifdef DEBUG
1837 tx_packets[pkt->priority]++; 1824 tx_packets[pkt->priority]++;
@@ -1897,7 +1884,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1897done: 1884done:
1898 /* restore pkt buffer pointer before calling tx complete routine */ 1885 /* restore pkt buffer pointer before calling tx complete routine */
1899 skb_pull(pkt, SDPCM_HDRLEN + pad); 1886 skb_pull(pkt, SDPCM_HDRLEN + pad);
1900 brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); 1887 brcmf_txcomplete(bus->sdiodev->dev, pkt, ret == 0);
1901 return ret; 1888 return ret;
1902} 1889}
1903 1890
@@ -2131,7 +2118,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2131 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 2118 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2132 } 2119 }
2133 2120
2134 brcmf_dbg(INFO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", 2121 brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
2135 devctl, clkctl); 2122 devctl, clkctl);
2136 2123
2137 if (SBSDIO_HTAV(clkctl)) { 2124 if (SBSDIO_HTAV(clkctl)) {
@@ -2307,6 +2294,15 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2307 } 2294 }
2308} 2295}
2309 2296
2297static struct pktq *brcmf_sdbrcm_bus_gettxq(struct device *dev)
2298{
2299 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2300 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
2301 struct brcmf_sdio *bus = sdiodev->bus;
2302
2303 return &bus->txq;
2304}
2305
2310static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) 2306static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
2311{ 2307{
2312 int ret = -EBADE; 2308 int ret = -EBADE;
@@ -2392,7 +2388,7 @@ brcmf_sdbrcm_membytes(struct brcmf_sdio *bus, bool write, u32 address, u8 *data,
2392 2388
2393 /* Do the transfer(s) */ 2389 /* Do the transfer(s) */
2394 while (size) { 2390 while (size) {
2395 brcmf_dbg(INFO, "%s %d bytes at offset 0x%08x in window 0x%08x\n", 2391 brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
2396 write ? "write" : "read", dsize, 2392 write ? "write" : "read", dsize,
2397 sdaddr, address & SBSDIO_SBWINDOW_MASK); 2393 sdaddr, address & SBSDIO_SBWINDOW_MASK);
2398 bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write, 2394 bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write,
@@ -2625,10 +2621,10 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2625 msecs_to_jiffies(2000)); 2621 msecs_to_jiffies(2000));
2626 2622
2627 if (!bus->ctrl_frame_stat) { 2623 if (!bus->ctrl_frame_stat) {
2628 brcmf_dbg(INFO, "ctrl_frame_stat == false\n"); 2624 brcmf_dbg(SDIO, "ctrl_frame_stat == false\n");
2629 ret = 0; 2625 ret = 0;
2630 } else { 2626 } else {
2631 brcmf_dbg(INFO, "ctrl_frame_stat == true\n"); 2627 brcmf_dbg(SDIO, "ctrl_frame_stat == true\n");
2632 ret = -1; 2628 ret = -1;
2633 } 2629 }
2634 } 2630 }
@@ -2699,7 +2695,7 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2699 2695
2700 addr = le32_to_cpu(addr_le); 2696 addr = le32_to_cpu(addr_le);
2701 2697
2702 brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr); 2698 brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
2703 2699
2704 /* 2700 /*
2705 * Check if addr is valid. 2701 * Check if addr is valid.
@@ -2726,8 +2722,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2726 sh->console_addr = le32_to_cpu(sh_le.console_addr); 2722 sh->console_addr = le32_to_cpu(sh_le.console_addr);
2727 sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr); 2723 sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
2728 2724
2729 if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { 2725 if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
2730 brcmf_err("sdpcm_shared version mismatch: dhd %d dongle %d\n", 2726 brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
2731 SDPCM_SHARED_VERSION, 2727 SDPCM_SHARED_VERSION,
2732 sh->flags & SDPCM_SHARED_VERSION_MASK); 2728 sh->flags & SDPCM_SHARED_VERSION_MASK);
2733 return -EPROTO; 2729 return -EPROTO;
@@ -2809,21 +2805,18 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
2809 int error, res; 2805 int error, res;
2810 char buf[350]; 2806 char buf[350];
2811 struct brcmf_trap_info tr; 2807 struct brcmf_trap_info tr;
2812 int nbytes;
2813 loff_t pos = 0; 2808 loff_t pos = 0;
2814 2809
2815 if ((sh->flags & SDPCM_SHARED_TRAP) == 0) 2810 if ((sh->flags & SDPCM_SHARED_TRAP) == 0) {
2811 brcmf_dbg(INFO, "no trap in firmware\n");
2816 return 0; 2812 return 0;
2813 }
2817 2814
2818 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, 2815 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
2819 sizeof(struct brcmf_trap_info)); 2816 sizeof(struct brcmf_trap_info));
2820 if (error < 0) 2817 if (error < 0)
2821 return error; 2818 return error;
2822 2819
2823 nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
2824 if (nbytes < 0)
2825 return nbytes;
2826
2827 res = scnprintf(buf, sizeof(buf), 2820 res = scnprintf(buf, sizeof(buf),
2828 "dongle trap info: type 0x%x @ epc 0x%08x\n" 2821 "dongle trap info: type 0x%x @ epc 0x%08x\n"
2829 " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" 2822 " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
@@ -2839,12 +2832,7 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
2839 le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), 2832 le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
2840 le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); 2833 le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
2841 2834
2842 error = simple_read_from_buffer(data+nbytes, count, &pos, buf, res); 2835 return simple_read_from_buffer(data, count, &pos, buf, res);
2843 if (error < 0)
2844 return error;
2845
2846 nbytes += error;
2847 return nbytes;
2848} 2836}
2849 2837
2850static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, 2838static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
@@ -2926,14 +2914,20 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data,
2926 error = brcmf_sdio_assert_info(bus, &sh, data, count); 2914 error = brcmf_sdio_assert_info(bus, &sh, data, count);
2927 if (error < 0) 2915 if (error < 0)
2928 goto done; 2916 goto done;
2929
2930 nbytes = error; 2917 nbytes = error;
2931 error = brcmf_sdio_trap_info(bus, &sh, data, count); 2918
2919 error = brcmf_sdio_trap_info(bus, &sh, data+nbytes, count);
2920 if (error < 0)
2921 goto done;
2922 nbytes += error;
2923
2924 error = brcmf_sdio_dump_console(bus, &sh, data+nbytes, count);
2932 if (error < 0) 2925 if (error < 0)
2933 goto done; 2926 goto done;
2927 nbytes += error;
2934 2928
2935 error += nbytes; 2929 error = nbytes;
2936 *ppos += error; 2930 *ppos += nbytes;
2937done: 2931done:
2938 return error; 2932 return error;
2939} 2933}
@@ -3309,15 +3303,15 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
3309 goto err; 3303 goto err;
3310 } 3304 }
3311 3305
3312 /* External image takes precedence if specified */
3313 if (brcmf_sdbrcm_download_code_file(bus)) { 3306 if (brcmf_sdbrcm_download_code_file(bus)) {
3314 brcmf_err("dongle image file download failed\n"); 3307 brcmf_err("dongle image file download failed\n");
3315 goto err; 3308 goto err;
3316 } 3309 }
3317 3310
3318 /* External nvram takes precedence if specified */ 3311 if (brcmf_sdbrcm_download_nvram(bus)) {
3319 if (brcmf_sdbrcm_download_nvram(bus))
3320 brcmf_err("dongle nvram file download failed\n"); 3312 brcmf_err("dongle nvram file download failed\n");
3313 goto err;
3314 }
3321 3315
3322 /* Take arm out of reset */ 3316 /* Take arm out of reset */
3323 if (brcmf_sdbrcm_download_state(bus, false)) { 3317 if (brcmf_sdbrcm_download_state(bus, false)) {
@@ -3848,6 +3842,7 @@ static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
3848 .txdata = brcmf_sdbrcm_bus_txdata, 3842 .txdata = brcmf_sdbrcm_bus_txdata,
3849 .txctl = brcmf_sdbrcm_bus_txctl, 3843 .txctl = brcmf_sdbrcm_bus_txctl,
3850 .rxctl = brcmf_sdbrcm_bus_rxctl, 3844 .rxctl = brcmf_sdbrcm_bus_rxctl,
3845 .gettxq = brcmf_sdbrcm_bus_gettxq,
3851}; 3846};
3852 3847
3853void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) 3848void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index e9d6f91a1f2b..5a64280e6485 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -20,6 +20,8 @@
20 20
21#include "dhd.h" 21#include "dhd.h"
22#include "dhd_dbg.h" 22#include "dhd_dbg.h"
23#include "tracepoint.h"
24#include "fwsignal.h"
23#include "fweh.h" 25#include "fweh.h"
24#include "fwil.h" 26#include "fwil.h"
25 27
@@ -154,7 +156,7 @@ static int brcmf_fweh_call_event_handler(struct brcmf_if *ifp,
154 fweh = &ifp->drvr->fweh; 156 fweh = &ifp->drvr->fweh;
155 157
156 /* handle the event if valid interface and handler */ 158 /* handle the event if valid interface and handler */
157 if (ifp->ndev && fweh->evt_handler[code]) 159 if (fweh->evt_handler[code])
158 err = fweh->evt_handler[code](ifp, emsg, data); 160 err = fweh->evt_handler[code](ifp, emsg, data);
159 else 161 else
160 brcmf_err("unhandled event %d ignored\n", code); 162 brcmf_err("unhandled event %d ignored\n", code);
@@ -179,9 +181,9 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
179 struct brcmf_if *ifp; 181 struct brcmf_if *ifp;
180 int err = 0; 182 int err = 0;
181 183
182 brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u\n", 184 brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u role: %u\n",
183 ifevent->action, ifevent->ifidx, 185 ifevent->action, ifevent->ifidx, ifevent->bssidx,
184 ifevent->bssidx, ifevent->flags); 186 ifevent->flags, ifevent->role);
185 187
186 if (ifevent->ifidx >= BRCMF_MAX_IFS) { 188 if (ifevent->ifidx >= BRCMF_MAX_IFS) {
187 brcmf_err("invalid interface index: %u\n", 189 brcmf_err("invalid interface index: %u\n",
@@ -198,15 +200,20 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
198 emsg->ifname, emsg->addr); 200 emsg->ifname, emsg->addr);
199 if (IS_ERR(ifp)) 201 if (IS_ERR(ifp))
200 return; 202 return;
201 203 brcmf_fws_add_interface(ifp);
202 if (!drvr->fweh.evt_handler[BRCMF_E_IF]) 204 if (!drvr->fweh.evt_handler[BRCMF_E_IF])
203 err = brcmf_net_attach(ifp, false); 205 err = brcmf_net_attach(ifp, false);
204 } 206 }
205 207
208 if (ifevent->action == BRCMF_E_IF_CHANGE)
209 brcmf_fws_reset_interface(ifp);
210
206 err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); 211 err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
207 212
208 if (ifevent->action == BRCMF_E_IF_DEL) 213 if (ifevent->action == BRCMF_E_IF_DEL) {
214 brcmf_fws_del_interface(ifp);
209 brcmf_del_if(drvr, ifevent->bssidx); 215 brcmf_del_if(drvr, ifevent->bssidx);
216 }
210} 217}
211 218
212/** 219/**
@@ -400,13 +407,12 @@ int brcmf_fweh_activate_events(struct brcmf_if *ifp)
400 * 407 *
401 * @drvr: driver information object. 408 * @drvr: driver information object.
402 * @event_packet: event packet to process. 409 * @event_packet: event packet to process.
403 * @ifidx: index of the firmware interface (may change).
404 * 410 *
405 * If the packet buffer contains a firmware event message it will 411 * If the packet buffer contains a firmware event message it will
406 * dispatch the event to a registered handler (using worker). 412 * dispatch the event to a registered handler (using worker).
407 */ 413 */
408void brcmf_fweh_process_event(struct brcmf_pub *drvr, 414void brcmf_fweh_process_event(struct brcmf_pub *drvr,
409 struct brcmf_event *event_packet, u8 *ifidx) 415 struct brcmf_event *event_packet)
410{ 416{
411 enum brcmf_fweh_event_code code; 417 enum brcmf_fweh_event_code code;
412 struct brcmf_fweh_info *fweh = &drvr->fweh; 418 struct brcmf_fweh_info *fweh = &drvr->fweh;
@@ -418,7 +424,6 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
418 /* get event info */ 424 /* get event info */
419 code = get_unaligned_be32(&event_packet->msg.event_type); 425 code = get_unaligned_be32(&event_packet->msg.event_type);
420 datalen = get_unaligned_be32(&event_packet->msg.datalen); 426 datalen = get_unaligned_be32(&event_packet->msg.datalen);
421 *ifidx = event_packet->msg.ifidx;
422 data = &event_packet[1]; 427 data = &event_packet[1];
423 428
424 if (code >= BRCMF_E_LAST) 429 if (code >= BRCMF_E_LAST)
@@ -435,7 +440,7 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
435 return; 440 return;
436 441
437 event->code = code; 442 event->code = code;
438 event->ifidx = *ifidx; 443 event->ifidx = event_packet->msg.ifidx;
439 444
440 /* use memcpy to get aligned event message */ 445 /* use memcpy to get aligned event message */
441 memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); 446 memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg));
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index 8c39b51dcccf..6ec5db9c60a5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -187,10 +187,10 @@ void brcmf_fweh_unregister(struct brcmf_pub *drvr,
187 enum brcmf_fweh_event_code code); 187 enum brcmf_fweh_event_code code);
188int brcmf_fweh_activate_events(struct brcmf_if *ifp); 188int brcmf_fweh_activate_events(struct brcmf_if *ifp);
189void brcmf_fweh_process_event(struct brcmf_pub *drvr, 189void brcmf_fweh_process_event(struct brcmf_pub *drvr,
190 struct brcmf_event *event_packet, u8 *ifidx); 190 struct brcmf_event *event_packet);
191 191
192static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, 192static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
193 struct sk_buff *skb, u8 *ifidx) 193 struct sk_buff *skb)
194{ 194{
195 struct brcmf_event *event_packet; 195 struct brcmf_event *event_packet;
196 u8 *data; 196 u8 *data;
@@ -213,7 +213,7 @@ static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
213 if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) 213 if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT)
214 return; 214 return;
215 215
216 brcmf_fweh_process_event(drvr, event_packet, ifidx); 216 brcmf_fweh_process_event(drvr, event_packet);
217} 217}
218 218
219#endif /* FWEH_H_ */ 219#endif /* FWEH_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index 8d1def935b8d..04f395930d86 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -25,6 +25,7 @@
25#include "dhd.h" 25#include "dhd.h"
26#include "dhd_bus.h" 26#include "dhd_bus.h"
27#include "dhd_dbg.h" 27#include "dhd_dbg.h"
28#include "tracepoint.h"
28#include "fwil.h" 29#include "fwil.h"
29 30
30 31
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 071d55f9cd4d..b3c608ee37cf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -14,17 +14,22 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/module.h>
17#include <linux/if_ether.h> 18#include <linux/if_ether.h>
18#include <linux/spinlock.h> 19#include <linux/spinlock.h>
19#include <linux/skbuff.h> 20#include <linux/skbuff.h>
20#include <linux/netdevice.h> 21#include <linux/netdevice.h>
22#include <linux/etherdevice.h>
21#include <linux/err.h> 23#include <linux/err.h>
22#include <uapi/linux/nl80211.h> 24#include <uapi/linux/nl80211.h>
25#include <net/cfg80211.h>
23 26
24#include <brcmu_utils.h> 27#include <brcmu_utils.h>
25#include <brcmu_wifi.h> 28#include <brcmu_wifi.h>
26#include "dhd.h" 29#include "dhd.h"
30#include "dhd_proto.h"
27#include "dhd_dbg.h" 31#include "dhd_dbg.h"
32#include "dhd_bus.h"
28#include "fwil.h" 33#include "fwil.h"
29#include "fweh.h" 34#include "fweh.h"
30#include "fwsignal.h" 35#include "fwsignal.h"
@@ -54,7 +59,7 @@
54 BRCMF_FWS_TLV_DEF(RSSI, 8, 1) \ 59 BRCMF_FWS_TLV_DEF(RSSI, 8, 1) \
55 BRCMF_FWS_TLV_DEF(INTERFACE_OPEN, 9, 1) \ 60 BRCMF_FWS_TLV_DEF(INTERFACE_OPEN, 9, 1) \
56 BRCMF_FWS_TLV_DEF(INTERFACE_CLOSE, 10, 1) \ 61 BRCMF_FWS_TLV_DEF(INTERFACE_CLOSE, 10, 1) \
57 BRCMF_FWS_TLV_DEF(FIFO_CREDITBACK, 11, 8) \ 62 BRCMF_FWS_TLV_DEF(FIFO_CREDITBACK, 11, 6) \
58 BRCMF_FWS_TLV_DEF(PENDING_TRAFFIC_BMP, 12, 2) \ 63 BRCMF_FWS_TLV_DEF(PENDING_TRAFFIC_BMP, 12, 2) \
59 BRCMF_FWS_TLV_DEF(MAC_REQUEST_PACKET, 13, 3) \ 64 BRCMF_FWS_TLV_DEF(MAC_REQUEST_PACKET, 13, 3) \
60 BRCMF_FWS_TLV_DEF(HOST_REORDER_RXPKTS, 14, 10) \ 65 BRCMF_FWS_TLV_DEF(HOST_REORDER_RXPKTS, 14, 10) \
@@ -62,7 +67,7 @@
62 BRCMF_FWS_TLV_DEF(COMP_TXSTATUS, 19, 1) \ 67 BRCMF_FWS_TLV_DEF(COMP_TXSTATUS, 19, 1) \
63 BRCMF_FWS_TLV_DEF(FILLER, 255, 0) 68 BRCMF_FWS_TLV_DEF(FILLER, 255, 0)
64 69
65/** 70/*
66 * enum brcmf_fws_tlv_type - definition of tlv identifiers. 71 * enum brcmf_fws_tlv_type - definition of tlv identifiers.
67 */ 72 */
68#define BRCMF_FWS_TLV_DEF(name, id, len) \ 73#define BRCMF_FWS_TLV_DEF(name, id, len) \
@@ -73,18 +78,18 @@ enum brcmf_fws_tlv_type {
73}; 78};
74#undef BRCMF_FWS_TLV_DEF 79#undef BRCMF_FWS_TLV_DEF
75 80
76/** 81/*
77 * enum brcmf_fws_tlv_len - length values for tlvs. 82 * enum brcmf_fws_tlv_len - definition of tlv lengths.
78 */ 83 */
79#define BRCMF_FWS_TLV_DEF(name, id, len) \ 84#define BRCMF_FWS_TLV_DEF(name, id, len) \
80 BRCMF_FWS_TYPE_ ## name ## _LEN = len, 85 BRCMF_FWS_TYPE_ ## name ## _LEN = (len),
81enum brcmf_fws_tlv_len { 86enum brcmf_fws_tlv_len {
82 BRCMF_FWS_TLV_DEFLIST 87 BRCMF_FWS_TLV_DEFLIST
83}; 88};
84#undef BRCMF_FWS_TLV_DEF 89#undef BRCMF_FWS_TLV_DEF
85 90
86#ifdef DEBUG 91#ifdef DEBUG
87/** 92/*
88 * brcmf_fws_tlv_names - array of tlv names. 93 * brcmf_fws_tlv_names - array of tlv names.
89 */ 94 */
90#define BRCMF_FWS_TLV_DEF(name, id, len) \ 95#define BRCMF_FWS_TLV_DEF(name, id, len) \
@@ -114,43 +119,109 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
114} 119}
115#endif /* DEBUG */ 120#endif /* DEBUG */
116 121
117/** 122/*
118 * flags used to enable tlv signalling from firmware. 123 * flags used to enable tlv signalling from firmware.
119 */ 124 */
120#define BRCMF_FWS_FLAGS_RSSI_SIGNALS 0x0001 125#define BRCMF_FWS_FLAGS_RSSI_SIGNALS 0x0001
121#define BRCMF_FWS_FLAGS_XONXOFF_SIGNALS 0x0002 126#define BRCMF_FWS_FLAGS_XONXOFF_SIGNALS 0x0002
122#define BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS 0x0004 127#define BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS 0x0004
123#define BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE 0x0008 128#define BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE 0x0008
124#define BRCMF_FWS_FLAGS_PSQ_GENERATIONFSM_ENABLE 0x0010 129#define BRCMF_FWS_FLAGS_PSQ_GENERATIONFSM_ENABLE 0x0010
125#define BRCMF_FWS_FLAGS_PSQ_ZERO_BUFFER_ENABLE 0x0020 130#define BRCMF_FWS_FLAGS_PSQ_ZERO_BUFFER_ENABLE 0x0020
126#define BRCMF_FWS_FLAGS_HOST_RXREORDER_ACTIVE 0x0040 131#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 132
140#define BRCMF_FWS_MAC_DESC_TABLE_SIZE 32 133#define BRCMF_FWS_MAC_DESC_TABLE_SIZE 32
141#define BRCMF_FWS_MAX_IFNUM 16
142#define BRCMF_FWS_MAC_DESC_ID_INVALID 0xff 134#define BRCMF_FWS_MAC_DESC_ID_INVALID 0xff
143 135
144#define BRCMF_FWS_HOSTIF_FLOWSTATE_OFF 0 136#define BRCMF_FWS_HOSTIF_FLOWSTATE_OFF 0
145#define BRCMF_FWS_HOSTIF_FLOWSTATE_ON 1 137#define BRCMF_FWS_HOSTIF_FLOWSTATE_ON 1
138#define BRCMF_FWS_FLOWCONTROL_HIWATER 128
139#define BRCMF_FWS_FLOWCONTROL_LOWATER 64
140
141#define BRCMF_FWS_PSQ_PREC_COUNT ((NL80211_NUM_ACS + 1) * 2)
142#define BRCMF_FWS_PSQ_LEN 256
143
144#define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01
145#define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02
146 146
147/** 147/**
148 * FWFC packet identifier 148 * enum brcmf_fws_skb_state - indicates processing state of skb.
149 *
150 * @BRCMF_FWS_SKBSTATE_NEW: sk_buff is newly arrived in the driver.
151 * @BRCMF_FWS_SKBSTATE_DELAYED: sk_buff had to wait on queue.
152 * @BRCMF_FWS_SKBSTATE_SUPPRESSED: sk_buff has been suppressed by firmware.
153 */
154enum brcmf_fws_skb_state {
155 BRCMF_FWS_SKBSTATE_NEW,
156 BRCMF_FWS_SKBSTATE_DELAYED,
157 BRCMF_FWS_SKBSTATE_SUPPRESSED
158};
159
160/**
161 * struct brcmf_skbuff_cb - control buffer associated with skbuff.
162 *
163 * @if_flags: holds interface index and packet related flags.
164 * @htod: host to device packet identifier (used in PKTTAG tlv).
165 * @state: transmit state of the packet.
166 * @mac: descriptor related to destination for this packet.
167 *
168 * This information is stored in control buffer struct sk_buff::cb, which
169 * provides 48 bytes of storage so this structure should not exceed that.
170 */
171struct brcmf_skbuff_cb {
172 u16 if_flags;
173 u32 htod;
174 enum brcmf_fws_skb_state state;
175 struct brcmf_fws_mac_descriptor *mac;
176};
177
178/*
179 * macro casting skbuff control buffer to struct brcmf_skbuff_cb.
180 */
181#define brcmf_skbcb(skb) ((struct brcmf_skbuff_cb *)((skb)->cb))
182
183/*
184 * sk_buff control if flags
185 *
186 * b[11] - packet sent upon firmware request.
187 * b[10] - packet only contains signalling data.
188 * b[9] - packet is a tx packet.
189 * b[8] - packet uses FIFO credit (non-pspoll).
190 * b[7] - interface in AP mode.
191 * b[6:4] - AC FIFO number.
192 * b[3:0] - interface index.
193 */
194#define BRCMF_SKB_IF_FLAGS_REQUESTED_MASK 0x0800
195#define BRCMF_SKB_IF_FLAGS_REQUESTED_SHIFT 11
196#define BRCMF_SKB_IF_FLAGS_SIGNAL_ONLY_MASK 0x0400
197#define BRCMF_SKB_IF_FLAGS_SIGNAL_ONLY_SHIFT 10
198#define BRCMF_SKB_IF_FLAGS_TRANSMIT_MASK 0x0200
199#define BRCMF_SKB_IF_FLAGS_TRANSMIT_SHIFT 9
200#define BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK 0x0100
201#define BRCMF_SKB_IF_FLAGS_CREDITCHECK_SHIFT 8
202#define BRCMF_SKB_IF_FLAGS_IF_AP_MASK 0x0080
203#define BRCMF_SKB_IF_FLAGS_IF_AP_SHIFT 7
204#define BRCMF_SKB_IF_FLAGS_FIFO_MASK 0x0070
205#define BRCMF_SKB_IF_FLAGS_FIFO_SHIFT 4
206#define BRCMF_SKB_IF_FLAGS_INDEX_MASK 0x000f
207#define BRCMF_SKB_IF_FLAGS_INDEX_SHIFT 0
208
209#define brcmf_skb_if_flags_set_field(skb, field, value) \
210 brcmu_maskset16(&(brcmf_skbcb(skb)->if_flags), \
211 BRCMF_SKB_IF_FLAGS_ ## field ## _MASK, \
212 BRCMF_SKB_IF_FLAGS_ ## field ## _SHIFT, (value))
213#define brcmf_skb_if_flags_get_field(skb, field) \
214 brcmu_maskget16(brcmf_skbcb(skb)->if_flags, \
215 BRCMF_SKB_IF_FLAGS_ ## field ## _MASK, \
216 BRCMF_SKB_IF_FLAGS_ ## field ## _SHIFT)
217
218/*
219 * sk_buff control packet identifier
149 * 220 *
150 * 32-bit packet identifier used in PKTTAG tlv from host to dongle. 221 * 32-bit packet identifier used in PKTTAG tlv from host to dongle.
151 * 222 *
152 * - Generated at the host (e.g. dhd) 223 * - Generated at the host (e.g. dhd)
153 * - Seen as a generic sequence number by wlc except the flags field 224 * - Seen as a generic sequence number by firmware except for the flags field.
154 * 225 *
155 * Generation : b[31] => generation number for this packet [host->fw] 226 * Generation : b[31] => generation number for this packet [host->fw]
156 * OR, current generation number [fw->host] 227 * OR, current generation number [fw->host]
@@ -159,35 +230,1057 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
159 * h-slot : b[23:8] => hanger-slot 230 * h-slot : b[23:8] => hanger-slot
160 * freerun : b[7:0] => A free running counter 231 * freerun : b[7:0] => A free running counter
161 */ 232 */
162#define BRCMF_FWS_PKTTAG_GENERATION_MASK 0x80000000 233#define BRCMF_SKB_HTOD_TAG_GENERATION_MASK 0x80000000
163#define BRCMF_FWS_PKTTAG_GENERATION_SHIFT 31 234#define BRCMF_SKB_HTOD_TAG_GENERATION_SHIFT 31
164#define BRCMF_FWS_PKTTAG_FLAGS_MASK 0x78000000 235#define BRCMF_SKB_HTOD_TAG_FLAGS_MASK 0x78000000
165#define BRCMF_FWS_PKTTAG_FLAGS_SHIFT 27 236#define BRCMF_SKB_HTOD_TAG_FLAGS_SHIFT 27
166#define BRCMF_FWS_PKTTAG_FIFO_MASK 0x07000000 237#define BRCMF_SKB_HTOD_TAG_FIFO_MASK 0x07000000
167#define BRCMF_FWS_PKTTAG_FIFO_SHIFT 24 238#define BRCMF_SKB_HTOD_TAG_FIFO_SHIFT 24
168#define BRCMF_FWS_PKTTAG_HSLOT_MASK 0x00ffff00 239#define BRCMF_SKB_HTOD_TAG_HSLOT_MASK 0x00ffff00
169#define BRCMF_FWS_PKTTAG_HSLOT_SHIFT 8 240#define BRCMF_SKB_HTOD_TAG_HSLOT_SHIFT 8
170#define BRCMF_FWS_PKTTAG_FREERUN_MASK 0x000000ff 241#define BRCMF_SKB_HTOD_TAG_FREERUN_MASK 0x000000ff
171#define BRCMF_FWS_PKTTAG_FREERUN_SHIFT 0 242#define BRCMF_SKB_HTOD_TAG_FREERUN_SHIFT 0
172 243
173#define brcmf_fws_pkttag_set_field(var, field, value) \ 244#define brcmf_skb_htod_tag_set_field(skb, field, value) \
174 brcmu_maskset32((var), BRCMF_FWS_PKTTAG_ ## field ## _MASK, \ 245 brcmu_maskset32(&(brcmf_skbcb(skb)->htod), \
175 BRCMF_FWS_PKTTAG_ ## field ## _SHIFT, (value)) 246 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \
176#define brcmf_fws_pkttag_get_field(var, field) \ 247 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT, (value))
177 brcmu_maskget32((var), BRCMF_FWS_PKTTAG_ ## field ## _MASK, \ 248#define brcmf_skb_htod_tag_get_field(skb, field) \
178 BRCMF_FWS_PKTTAG_ ## field ## _SHIFT) 249 brcmu_maskget32(brcmf_skbcb(skb)->htod, \
250 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \
251 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT)
252
253#define BRCMF_FWS_TXSTAT_GENERATION_MASK 0x80000000
254#define BRCMF_FWS_TXSTAT_GENERATION_SHIFT 31
255#define BRCMF_FWS_TXSTAT_FLAGS_MASK 0x78000000
256#define BRCMF_FWS_TXSTAT_FLAGS_SHIFT 27
257#define BRCMF_FWS_TXSTAT_FIFO_MASK 0x07000000
258#define BRCMF_FWS_TXSTAT_FIFO_SHIFT 24
259#define BRCMF_FWS_TXSTAT_HSLOT_MASK 0x00FFFF00
260#define BRCMF_FWS_TXSTAT_HSLOT_SHIFT 8
261#define BRCMF_FWS_TXSTAT_PKTID_MASK 0x00FFFFFF
262#define BRCMF_FWS_TXSTAT_PKTID_SHIFT 0
263
264#define brcmf_txstatus_get_field(txs, field) \
265 brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \
266 BRCMF_FWS_TXSTAT_ ## field ## _SHIFT)
267
268/**
269 * enum brcmf_fws_fifo - fifo indices used by dongle firmware.
270 *
271 * @BRCMF_FWS_FIFO_AC_BK: fifo for background traffic.
272 * @BRCMF_FWS_FIFO_AC_BE: fifo for best-effort traffic.
273 * @BRCMF_FWS_FIFO_AC_VI: fifo for video traffic.
274 * @BRCMF_FWS_FIFO_AC_VO: fifo for voice traffic.
275 * @BRCMF_FWS_FIFO_BCMC: fifo for broadcast/multicast (AP only).
276 * @BRCMF_FWS_FIFO_ATIM: fifo for ATIM (AP only).
277 * @BRCMF_FWS_FIFO_COUNT: number of fifos.
278 */
279enum brcmf_fws_fifo {
280 BRCMF_FWS_FIFO_AC_BK,
281 BRCMF_FWS_FIFO_AC_BE,
282 BRCMF_FWS_FIFO_AC_VI,
283 BRCMF_FWS_FIFO_AC_VO,
284 BRCMF_FWS_FIFO_BCMC,
285 BRCMF_FWS_FIFO_ATIM,
286 BRCMF_FWS_FIFO_COUNT
287};
288
289/**
290 * enum brcmf_fws_txstatus - txstatus flag values.
291 *
292 * @BRCMF_FWS_TXSTATUS_DISCARD:
293 * host is free to discard the packet.
294 * @BRCMF_FWS_TXSTATUS_CORE_SUPPRESS:
295 * 802.11 core suppressed the packet.
296 * @BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS:
297 * firmware suppress the packet as device is already in PS mode.
298 * @BRCMF_FWS_TXSTATUS_FW_TOSSED:
299 * firmware tossed the packet.
300 */
301enum brcmf_fws_txstatus {
302 BRCMF_FWS_TXSTATUS_DISCARD,
303 BRCMF_FWS_TXSTATUS_CORE_SUPPRESS,
304 BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS,
305 BRCMF_FWS_TXSTATUS_FW_TOSSED
306};
307
308enum brcmf_fws_fcmode {
309 BRCMF_FWS_FCMODE_NONE,
310 BRCMF_FWS_FCMODE_IMPLIED_CREDIT,
311 BRCMF_FWS_FCMODE_EXPLICIT_CREDIT
312};
313
314enum brcmf_fws_mac_desc_state {
315 BRCMF_FWS_STATE_OPEN = 1,
316 BRCMF_FWS_STATE_CLOSE
317};
318
319/**
320 * struct brcmf_fws_mac_descriptor - firmware signalling data per node/interface
321 *
322 * @occupied: slot is in use.
323 * @mac_handle: handle for mac entry determined by firmware.
324 * @interface_id: interface index.
325 * @state: current state.
326 * @suppressed: mac entry is suppressed.
327 * @generation: generation bit.
328 * @ac_bitmap: ac queue bitmap.
329 * @requested_credit: credits requested by firmware.
330 * @ea: ethernet address.
331 * @seq: per-node free-running sequence.
332 * @psq: power-save queue.
333 * @transit_count: packet in transit to firmware.
334 */
335struct brcmf_fws_mac_descriptor {
336 u8 occupied;
337 u8 mac_handle;
338 u8 interface_id;
339 u8 state;
340 bool suppressed;
341 u8 generation;
342 u8 ac_bitmap;
343 u8 requested_credit;
344 u8 requested_packet;
345 u8 ea[ETH_ALEN];
346 u8 seq[BRCMF_FWS_FIFO_COUNT];
347 struct pktq psq;
348 int transit_count;
349 int suppress_count;
350 int suppr_transit_count;
351 bool send_tim_signal;
352 u8 traffic_pending_bmp;
353 u8 traffic_lastreported_bmp;
354};
355
356#define BRCMF_FWS_HANGER_MAXITEMS 1024
357
358/**
359 * enum brcmf_fws_hanger_item_state - state of hanger item.
360 *
361 * @BRCMF_FWS_HANGER_ITEM_STATE_FREE: item is free for use.
362 * @BRCMF_FWS_HANGER_ITEM_STATE_INUSE: item is in use.
363 * @BRCMF_FWS_HANGER_ITEM_STATE_INUSE_SUPPRESSED: item was suppressed.
364 */
365enum brcmf_fws_hanger_item_state {
366 BRCMF_FWS_HANGER_ITEM_STATE_FREE = 1,
367 BRCMF_FWS_HANGER_ITEM_STATE_INUSE,
368 BRCMF_FWS_HANGER_ITEM_STATE_INUSE_SUPPRESSED
369};
370
371
372/**
373 * struct brcmf_fws_hanger_item - single entry for tx pending packet.
374 *
375 * @state: entry is either free or occupied.
376 * @gen: generation.
377 * @pkt: packet itself.
378 */
379struct brcmf_fws_hanger_item {
380 enum brcmf_fws_hanger_item_state state;
381 u8 gen;
382 struct sk_buff *pkt;
383};
384
385/**
386 * struct brcmf_fws_hanger - holds packets awaiting firmware txstatus.
387 *
388 * @pushed: packets pushed to await txstatus.
389 * @popped: packets popped upon handling txstatus.
390 * @failed_to_push: packets that could not be pushed.
391 * @failed_to_pop: packets that could not be popped.
392 * @failed_slotfind: packets for which failed to find an entry.
393 * @slot_pos: last returned item index for a free entry.
394 * @items: array of hanger items.
395 */
396struct brcmf_fws_hanger {
397 u32 pushed;
398 u32 popped;
399 u32 failed_to_push;
400 u32 failed_to_pop;
401 u32 failed_slotfind;
402 u32 slot_pos;
403 struct brcmf_fws_hanger_item items[BRCMF_FWS_HANGER_MAXITEMS];
404};
405
406struct brcmf_fws_macdesc_table {
407 struct brcmf_fws_mac_descriptor nodes[BRCMF_FWS_MAC_DESC_TABLE_SIZE];
408 struct brcmf_fws_mac_descriptor iface[BRCMF_MAX_IFS];
409 struct brcmf_fws_mac_descriptor other;
410};
179 411
180struct brcmf_fws_info { 412struct brcmf_fws_info {
181 struct brcmf_pub *drvr; 413 struct brcmf_pub *drvr;
182 struct brcmf_fws_stats stats; 414 struct brcmf_fws_stats stats;
415 struct brcmf_fws_hanger hanger;
416 enum brcmf_fws_fcmode fcmode;
417 struct brcmf_fws_macdesc_table desc;
418 struct workqueue_struct *fws_wq;
419 struct work_struct fws_dequeue_work;
420 u32 fifo_enqpkt[BRCMF_FWS_FIFO_COUNT];
421 int fifo_credit[BRCMF_FWS_FIFO_COUNT];
422 int deq_node_pos[BRCMF_FWS_FIFO_COUNT];
423 u32 fifo_credit_map;
424 u32 fifo_delay_map;
183}; 425};
184 426
427/*
428 * brcmf_fws_prio2fifo - mapping from 802.1d priority to firmware fifo index.
429 */
430static const int brcmf_fws_prio2fifo[] = {
431 BRCMF_FWS_FIFO_AC_BE,
432 BRCMF_FWS_FIFO_AC_BK,
433 BRCMF_FWS_FIFO_AC_BK,
434 BRCMF_FWS_FIFO_AC_BE,
435 BRCMF_FWS_FIFO_AC_VI,
436 BRCMF_FWS_FIFO_AC_VI,
437 BRCMF_FWS_FIFO_AC_VO,
438 BRCMF_FWS_FIFO_AC_VO
439};
440
441static int fcmode;
442module_param(fcmode, int, S_IRUSR);
443MODULE_PARM_DESC(fcmode, "mode of firmware signalled flow control");
444
445#define BRCMF_FWS_TLV_DEF(name, id, len) \
446 case BRCMF_FWS_TYPE_ ## name: \
447 return len;
448
449/**
450 * brcmf_fws_get_tlv_len() - returns defined length for given tlv id.
451 *
452 * @fws: firmware-signalling information.
453 * @id: identifier of the TLV.
454 *
455 * Return: the specified length for the given TLV; Otherwise -EINVAL.
456 */
457static int brcmf_fws_get_tlv_len(struct brcmf_fws_info *fws,
458 enum brcmf_fws_tlv_type id)
459{
460 switch (id) {
461 BRCMF_FWS_TLV_DEFLIST
462 default:
463 fws->stats.tlv_invalid_type++;
464 break;
465 }
466 return -EINVAL;
467}
468#undef BRCMF_FWS_TLV_DEF
469
470static bool brcmf_fws_ifidx_match(struct sk_buff *skb, void *arg)
471{
472 u32 ifidx = brcmf_skb_if_flags_get_field(skb, INDEX);
473 return ifidx == *(int *)arg;
474}
475
476static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q,
477 int ifidx)
478{
479 bool (*matchfn)(struct sk_buff *, void *) = NULL;
480 struct sk_buff *skb;
481 int prec;
482
483 if (ifidx != -1)
484 matchfn = brcmf_fws_ifidx_match;
485 for (prec = 0; prec < q->num_prec; prec++) {
486 skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx);
487 while (skb) {
488 brcmu_pkt_buf_free_skb(skb);
489 skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx);
490 }
491 }
492}
493
494static void brcmf_fws_hanger_init(struct brcmf_fws_hanger *hanger)
495{
496 int i;
497
498 brcmf_dbg(TRACE, "enter\n");
499 memset(hanger, 0, sizeof(*hanger));
500 for (i = 0; i < ARRAY_SIZE(hanger->items); i++)
501 hanger->items[i].state = BRCMF_FWS_HANGER_ITEM_STATE_FREE;
502}
503
504static u32 brcmf_fws_hanger_get_free_slot(struct brcmf_fws_hanger *h)
505{
506 u32 i;
507
508 brcmf_dbg(TRACE, "enter\n");
509 i = (h->slot_pos + 1) % BRCMF_FWS_HANGER_MAXITEMS;
510
511 while (i != h->slot_pos) {
512 if (h->items[i].state == BRCMF_FWS_HANGER_ITEM_STATE_FREE) {
513 h->slot_pos = i;
514 goto done;
515 }
516 i++;
517 if (i == BRCMF_FWS_HANGER_MAXITEMS)
518 i = 0;
519 }
520 brcmf_err("all slots occupied\n");
521 h->failed_slotfind++;
522 i = BRCMF_FWS_HANGER_MAXITEMS;
523done:
524 brcmf_dbg(TRACE, "exit: %d\n", i);
525 return i;
526}
527
528static int brcmf_fws_hanger_pushpkt(struct brcmf_fws_hanger *h,
529 struct sk_buff *pkt, u32 slot_id)
530{
531 brcmf_dbg(TRACE, "enter\n");
532 if (slot_id >= BRCMF_FWS_HANGER_MAXITEMS)
533 return -ENOENT;
534
535 if (h->items[slot_id].state != BRCMF_FWS_HANGER_ITEM_STATE_FREE) {
536 brcmf_err("slot is not free\n");
537 h->failed_to_push++;
538 return -EINVAL;
539 }
540
541 h->items[slot_id].state = BRCMF_FWS_HANGER_ITEM_STATE_INUSE;
542 h->items[slot_id].pkt = pkt;
543 h->pushed++;
544 return 0;
545}
546
547static int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h,
548 u32 slot_id, struct sk_buff **pktout,
549 bool remove_item)
550{
551 brcmf_dbg(TRACE, "enter\n");
552 if (slot_id >= BRCMF_FWS_HANGER_MAXITEMS)
553 return -ENOENT;
554
555 if (h->items[slot_id].state == BRCMF_FWS_HANGER_ITEM_STATE_FREE) {
556 brcmf_err("entry not in use\n");
557 h->failed_to_pop++;
558 return -EINVAL;
559 }
560
561 *pktout = h->items[slot_id].pkt;
562 if (remove_item) {
563 h->items[slot_id].state = BRCMF_FWS_HANGER_ITEM_STATE_FREE;
564 h->items[slot_id].pkt = NULL;
565 h->items[slot_id].gen = 0xff;
566 h->popped++;
567 }
568 return 0;
569}
570
571static int brcmf_fws_hanger_mark_suppressed(struct brcmf_fws_hanger *h,
572 u32 slot_id, u8 gen)
573{
574 brcmf_dbg(TRACE, "enter\n");
575
576 if (slot_id >= BRCMF_FWS_HANGER_MAXITEMS)
577 return -ENOENT;
578
579 h->items[slot_id].gen = gen;
580
581 if (h->items[slot_id].state != BRCMF_FWS_HANGER_ITEM_STATE_INUSE) {
582 brcmf_err("entry not in use\n");
583 return -EINVAL;
584 }
585
586 h->items[slot_id].state = BRCMF_FWS_HANGER_ITEM_STATE_INUSE_SUPPRESSED;
587 return 0;
588}
589
590static int brcmf_fws_hanger_get_genbit(struct brcmf_fws_hanger *hanger,
591 struct sk_buff *pkt, u32 slot_id,
592 int *gen)
593{
594 brcmf_dbg(TRACE, "enter\n");
595 *gen = 0xff;
596
597 if (slot_id >= BRCMF_FWS_HANGER_MAXITEMS)
598 return -ENOENT;
599
600 if (hanger->items[slot_id].state == BRCMF_FWS_HANGER_ITEM_STATE_FREE) {
601 brcmf_err("slot not in use\n");
602 return -EINVAL;
603 }
604
605 *gen = hanger->items[slot_id].gen;
606 return 0;
607}
608
609static void brcmf_fws_hanger_cleanup(struct brcmf_fws_info *fws,
610 bool (*fn)(struct sk_buff *, void *),
611 int ifidx)
612{
613 struct brcmf_fws_hanger *h = &fws->hanger;
614 struct sk_buff *skb;
615 int i;
616 enum brcmf_fws_hanger_item_state s;
617
618 brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
619 for (i = 0; i < ARRAY_SIZE(h->items); i++) {
620 s = h->items[i].state;
621 if (s == BRCMF_FWS_HANGER_ITEM_STATE_INUSE ||
622 s == BRCMF_FWS_HANGER_ITEM_STATE_INUSE_SUPPRESSED) {
623 skb = h->items[i].pkt;
624 if (fn == NULL || fn(skb, &ifidx)) {
625 /* suppress packets freed from psq */
626 if (s == BRCMF_FWS_HANGER_ITEM_STATE_INUSE)
627 brcmu_pkt_buf_free_skb(skb);
628 h->items[i].state =
629 BRCMF_FWS_HANGER_ITEM_STATE_FREE;
630 }
631 }
632 }
633}
634
635static void brcmf_fws_init_mac_descriptor(struct brcmf_fws_mac_descriptor *desc,
636 u8 *addr, u8 ifidx)
637{
638 brcmf_dbg(TRACE,
639 "enter: desc %p ea=%pM, ifidx=%u\n", desc, addr, ifidx);
640 desc->occupied = 1;
641 desc->state = BRCMF_FWS_STATE_OPEN;
642 desc->requested_credit = 0;
643 /* depending on use may need ifp->bssidx instead */
644 desc->interface_id = ifidx;
645 desc->ac_bitmap = 0xff; /* update this when handling APSD */
646 if (addr)
647 memcpy(&desc->ea[0], addr, ETH_ALEN);
648}
649
650static
651void brcmf_fws_clear_mac_descriptor(struct brcmf_fws_mac_descriptor *desc)
652{
653 brcmf_dbg(TRACE,
654 "enter: ea=%pM, ifidx=%u\n", desc->ea, desc->interface_id);
655 desc->occupied = 0;
656 desc->state = BRCMF_FWS_STATE_CLOSE;
657 desc->requested_credit = 0;
658}
659
660static struct brcmf_fws_mac_descriptor *
661brcmf_fws_mac_descriptor_lookup(struct brcmf_fws_info *fws, u8 *ea)
662{
663 struct brcmf_fws_mac_descriptor *entry;
664 int i;
665
666 brcmf_dbg(TRACE, "enter: ea=%pM\n", ea);
667 if (ea == NULL)
668 return ERR_PTR(-EINVAL);
669
670 entry = &fws->desc.nodes[0];
671 for (i = 0; i < ARRAY_SIZE(fws->desc.nodes); i++) {
672 if (entry->occupied && !memcmp(entry->ea, ea, ETH_ALEN))
673 return entry;
674 entry++;
675 }
676
677 return ERR_PTR(-ENOENT);
678}
679
680static struct brcmf_fws_mac_descriptor*
681brcmf_fws_find_mac_desc(struct brcmf_fws_info *fws, int ifidx, u8 *da)
682{
683 struct brcmf_fws_mac_descriptor *entry = &fws->desc.other;
684 struct brcmf_if *ifp;
685 bool multicast;
686
687 brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
688
689 multicast = is_multicast_ether_addr(da);
690 ifp = fws->drvr->iflist[ifidx ? ifidx + 1 : 0];
691 if (WARN_ON(!ifp))
692 goto done;
693
694 /* Multicast destination and P2P clients get the interface entry.
695 * STA gets the interface entry if there is no exact match. For
696 * example, TDLS destinations have their own entry.
697 */
698 entry = NULL;
699 if (multicast && ifp->fws_desc)
700 entry = ifp->fws_desc;
701
702 if (entry != NULL && multicast)
703 goto done;
704
705 entry = brcmf_fws_mac_descriptor_lookup(fws, da);
706 if (IS_ERR(entry))
707 entry = &fws->desc.other;
708
709done:
710 brcmf_dbg(TRACE, "exit: entry=%p\n", entry);
711 return entry;
712}
713
714static bool brcmf_fws_mac_desc_ready(struct brcmf_fws_mac_descriptor *entry,
715 int fifo)
716{
717 bool ready;
718
719 /*
720 * destination entry is ready when firmware says it is OPEN
721 * and there are no packets enqueued for it.
722 */
723 ready = entry->state == BRCMF_FWS_STATE_OPEN &&
724 !entry->suppressed &&
725 brcmu_pktq_mlen(&entry->psq, 3 << (fifo * 2)) == 0;
726
727 /*
728 * Or when the destination entry is CLOSED, but firmware has
729 * specifically requested packets for this entry.
730 */
731 ready = ready || (entry->state == BRCMF_FWS_STATE_CLOSE &&
732 (entry->requested_credit + entry->requested_packet));
733 return ready;
734}
735
736static void brcmf_fws_mac_desc_cleanup(struct brcmf_fws_info *fws,
737 struct brcmf_fws_mac_descriptor *entry,
738 int ifidx)
739{
740 brcmf_dbg(TRACE, "enter: entry=(ea=%pM, ifid=%d), ifidx=%d\n",
741 entry->ea, entry->interface_id, ifidx);
742 if (entry->occupied && (ifidx == -1 || ifidx == entry->interface_id)) {
743 brcmf_dbg(TRACE, "flush psq: ifidx=%d, qlen=%d\n",
744 ifidx, entry->psq.len);
745 brcmf_fws_psq_flush(fws, &entry->psq, ifidx);
746 entry->occupied = !!(entry->psq.len);
747 }
748}
749
750static void brcmf_fws_bus_txq_cleanup(struct brcmf_fws_info *fws,
751 bool (*fn)(struct sk_buff *, void *),
752 int ifidx)
753{
754 struct brcmf_fws_hanger_item *hi;
755 struct pktq *txq;
756 struct sk_buff *skb;
757 int prec;
758 u32 hslot;
759
760 brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
761 txq = brcmf_bus_gettxq(fws->drvr->bus_if);
762 if (IS_ERR(txq)) {
763 brcmf_dbg(TRACE, "no txq to clean up\n");
764 return;
765 }
766
767 for (prec = 0; prec < txq->num_prec; prec++) {
768 skb = brcmu_pktq_pdeq_match(txq, prec, fn, &ifidx);
769 while (skb) {
770 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
771 hi = &fws->hanger.items[hslot];
772 WARN_ON(skb != hi->pkt);
773 hi->state = BRCMF_FWS_HANGER_ITEM_STATE_FREE;
774 brcmu_pkt_buf_free_skb(skb);
775 skb = brcmu_pktq_pdeq_match(txq, prec, fn, &ifidx);
776 }
777 }
778}
779
780static void brcmf_fws_cleanup(struct brcmf_fws_info *fws, int ifidx)
781{
782 int i;
783 struct brcmf_fws_mac_descriptor *table;
784 bool (*matchfn)(struct sk_buff *, void *) = NULL;
785
786 brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
787 if (fws == NULL)
788 return;
789
790 if (ifidx != -1)
791 matchfn = brcmf_fws_ifidx_match;
792
793 /* cleanup individual nodes */
794 table = &fws->desc.nodes[0];
795 for (i = 0; i < ARRAY_SIZE(fws->desc.nodes); i++)
796 brcmf_fws_mac_desc_cleanup(fws, &table[i], ifidx);
797
798 brcmf_fws_mac_desc_cleanup(fws, &fws->desc.other, ifidx);
799 brcmf_fws_bus_txq_cleanup(fws, matchfn, ifidx);
800 brcmf_fws_hanger_cleanup(fws, matchfn, ifidx);
801}
802
803static void brcmf_fws_tim_update(struct brcmf_fws_info *ctx,
804 struct brcmf_fws_mac_descriptor *entry,
805 int prec)
806{
807 brcmf_dbg(TRACE, "enter: ea=%pM\n", entry->ea);
808 if (entry->state == BRCMF_FWS_STATE_CLOSE) {
809 /* check delayedQ and suppressQ in one call using bitmap */
810 if (brcmu_pktq_mlen(&entry->psq, 3 << (prec * 2)) == 0)
811 entry->traffic_pending_bmp =
812 entry->traffic_pending_bmp & ~NBITVAL(prec);
813 else
814 entry->traffic_pending_bmp =
815 entry->traffic_pending_bmp | NBITVAL(prec);
816 }
817 /* request a TIM update to firmware at the next piggyback opportunity */
818 if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp)
819 entry->send_tim_signal = true;
820}
821
822static void
823brcmf_fws_flow_control_check(struct brcmf_fws_info *fws, struct pktq *pq,
824 u8 if_id)
825{
826 struct brcmf_if *ifp = fws->drvr->iflist[if_id];
827
828 brcmf_dbg(TRACE,
829 "enter: bssidx=%d, ifidx=%d\n", ifp->bssidx, ifp->ifidx);
830 if (WARN_ON(!ifp))
831 return;
832
833 if ((ifp->netif_stop & BRCMF_NETIF_STOP_REASON_FWS_FC) &&
834 pq->len <= BRCMF_FWS_FLOWCONTROL_LOWATER)
835 brcmf_txflowblock_if(ifp,
836 BRCMF_NETIF_STOP_REASON_FWS_FC, false);
837 if (!(ifp->netif_stop & BRCMF_NETIF_STOP_REASON_FWS_FC) &&
838 pq->len >= BRCMF_FWS_FLOWCONTROL_HIWATER)
839 brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FWS_FC, true);
840 return;
841}
842
185static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi) 843static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi)
186{ 844{
187 brcmf_dbg(CTL, "rssi %d\n", rssi); 845 brcmf_dbg(CTL, "rssi %d\n", rssi);
188 return 0; 846 return 0;
189} 847}
190 848
849static
850int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
851{
852 struct brcmf_fws_mac_descriptor *entry, *existing;
853 u8 mac_handle;
854 u8 ifidx;
855 u8 *addr;
856
857 mac_handle = *data++;
858 ifidx = *data++;
859 addr = data;
860
861 entry = &fws->desc.nodes[mac_handle & 0x1F];
862 if (type == BRCMF_FWS_TYPE_MACDESC_DEL) {
863 brcmf_dbg(TRACE, "deleting mac %pM idx %d\n", addr, ifidx);
864 if (entry->occupied)
865 brcmf_fws_clear_mac_descriptor(entry);
866 else
867 fws->stats.mac_update_failed++;
868 return 0;
869 }
870
871 brcmf_dbg(TRACE,
872 "add mac %pM handle %u idx %d\n", addr, mac_handle, ifidx);
873 existing = brcmf_fws_mac_descriptor_lookup(fws, addr);
874 if (IS_ERR(existing)) {
875 if (!entry->occupied) {
876 entry->mac_handle = mac_handle;
877 brcmf_fws_init_mac_descriptor(entry, addr, ifidx);
878 brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT,
879 BRCMF_FWS_PSQ_LEN);
880 } else {
881 fws->stats.mac_update_failed++;
882 }
883 } else {
884 if (entry != existing) {
885 brcmf_dbg(TRACE, "relocate mac\n");
886 memcpy(entry, existing,
887 offsetof(struct brcmf_fws_mac_descriptor, psq));
888 entry->mac_handle = mac_handle;
889 brcmf_fws_clear_mac_descriptor(existing);
890 } else {
891 brcmf_dbg(TRACE, "use existing\n");
892 WARN_ON(entry->mac_handle != mac_handle);
893 /* TODO: what should we do here: continue, reinit, .. */
894 }
895 }
896 return 0;
897}
898
899static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
900 u8 type, u8 *data)
901{
902 struct brcmf_fws_mac_descriptor *entry;
903 u8 mac_handle;
904 int i;
905
906 mac_handle = data[0];
907 entry = &fws->desc.nodes[mac_handle & 0x1F];
908 if (!entry->occupied) {
909 fws->stats.mac_ps_update_failed++;
910 return -ESRCH;
911 }
912
913 /* a state update should wipe old credits? */
914 entry->requested_credit = 0;
915 if (type == BRCMF_FWS_TYPE_MAC_OPEN) {
916 entry->state = BRCMF_FWS_STATE_OPEN;
917 } else {
918 entry->state = BRCMF_FWS_STATE_CLOSE;
919 for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++)
920 brcmf_fws_tim_update(fws, entry, i);
921 }
922 return 0;
923}
924
925static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
926 u8 type, u8 *data)
927{
928 struct brcmf_fws_mac_descriptor *entry;
929 u8 ifidx;
930 int ret;
931
932 ifidx = data[0];
933
934 brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
935 if (ifidx >= BRCMF_MAX_IFS) {
936 ret = -ERANGE;
937 goto fail;
938 }
939
940 entry = &fws->desc.iface[ifidx];
941 if (!entry->occupied) {
942 ret = -ESRCH;
943 goto fail;
944 }
945
946 switch (type) {
947 case BRCMF_FWS_TYPE_INTERFACE_OPEN:
948 entry->state = BRCMF_FWS_STATE_OPEN;
949 return 0;
950 case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
951 entry->state = BRCMF_FWS_STATE_CLOSE;
952 return 0;
953 default:
954 ret = -EINVAL;
955 break;
956 }
957fail:
958 fws->stats.if_update_failed++;
959 return ret;
960}
961
962static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type,
963 u8 *data)
964{
965 struct brcmf_fws_mac_descriptor *entry;
966
967 entry = &fws->desc.nodes[data[1] & 0x1F];
968 if (!entry->occupied) {
969 if (type == BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT)
970 fws->stats.credit_request_failed++;
971 else
972 fws->stats.packet_request_failed++;
973 return -ESRCH;
974 }
975
976 if (type == BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT)
977 entry->requested_credit = data[0];
978 else
979 entry->requested_packet = data[0];
980
981 entry->ac_bitmap = data[2];
982 return 0;
983}
984
985static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
986 u8 fifo, u8 credits)
987{
988 if (!credits)
989 return;
990
991 fws->fifo_credit_map |= 1 << fifo;
992 fws->fifo_credit[fifo] += credits;
993}
994
995static void brcmf_fws_schedule_deq(struct brcmf_fws_info *fws)
996{
997 /* only schedule dequeue when there are credits for delayed traffic */
998 if (fws->fifo_credit_map & fws->fifo_delay_map)
999 queue_work(fws->fws_wq, &fws->fws_dequeue_work);
1000}
1001
1002static void brcmf_skb_pick_up_credit(struct brcmf_fws_info *fws, int fifo,
1003 struct sk_buff *p)
1004{
1005 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(p)->mac;
1006
1007 if (brcmf_skbcb(p)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) {
1008 if (fws->fcmode != BRCMF_FWS_FCMODE_IMPLIED_CREDIT)
1009 return;
1010 brcmf_fws_return_credits(fws, fifo, 1);
1011 } else {
1012 /*
1013 * if this packet did not count against FIFO credit, it
1014 * must have taken a requested_credit from the destination
1015 * entry (for pspoll etc.)
1016 */
1017 if (!brcmf_skb_if_flags_get_field(p, REQUESTED))
1018 entry->requested_credit++;
1019 }
1020 brcmf_fws_schedule_deq(fws);
1021}
1022
1023static int brcmf_fws_enq(struct brcmf_fws_info *fws,
1024 enum brcmf_fws_skb_state state, int fifo,
1025 struct sk_buff *p)
1026{
1027 int prec = 2 * fifo;
1028 u32 *qfull_stat = &fws->stats.delayq_full_error;
1029
1030 struct brcmf_fws_mac_descriptor *entry;
1031
1032 entry = brcmf_skbcb(p)->mac;
1033 if (entry == NULL) {
1034 brcmf_err("no mac descriptor found for skb %p\n", p);
1035 return -ENOENT;
1036 }
1037
1038 brcmf_dbg(TRACE, "enter: ea=%pM, qlen=%d\n", entry->ea, entry->psq.len);
1039 if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
1040 prec += 1;
1041 qfull_stat = &fws->stats.supprq_full_error;
1042 }
1043
1044 if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) {
1045 *qfull_stat += 1;
1046 return -ENFILE;
1047 }
1048
1049 /* increment total enqueued packet count */
1050 fws->fifo_delay_map |= 1 << fifo;
1051 fws->fifo_enqpkt[fifo]++;
1052
1053 /* update the sk_buff state */
1054 brcmf_skbcb(p)->state = state;
1055 if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED)
1056 entry->suppress_count++;
1057
1058 /*
1059 * A packet has been pushed so update traffic
1060 * availability bitmap, if applicable
1061 */
1062 brcmf_fws_tim_update(fws, entry, fifo);
1063 brcmf_fws_flow_control_check(fws, &entry->psq,
1064 brcmf_skb_if_flags_get_field(p, INDEX));
1065 return 0;
1066}
1067
1068static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo)
1069{
1070 struct brcmf_fws_mac_descriptor *table;
1071 struct brcmf_fws_mac_descriptor *entry;
1072 struct sk_buff *p;
1073 int use_credit = 1;
1074 int num_nodes;
1075 int node_pos;
1076 int prec_out;
1077 int pmsk = 3;
1078 int i;
1079
1080 table = (struct brcmf_fws_mac_descriptor *)&fws->desc;
1081 num_nodes = sizeof(fws->desc) / sizeof(struct brcmf_fws_mac_descriptor);
1082 node_pos = fws->deq_node_pos[fifo];
1083
1084 for (i = 0; i < num_nodes; i++) {
1085 entry = &table[(node_pos + i) % num_nodes];
1086 if (!entry->occupied)
1087 continue;
1088
1089 if (entry->suppressed)
1090 pmsk = 2;
1091 p = brcmu_pktq_mdeq(&entry->psq, pmsk << (fifo * 2), &prec_out);
1092 if (p == NULL) {
1093 if (entry->suppressed) {
1094 if (entry->suppr_transit_count >
1095 entry->suppress_count)
1096 return NULL;
1097 entry->suppressed = false;
1098 p = brcmu_pktq_mdeq(&entry->psq,
1099 1 << (fifo * 2), &prec_out);
1100 }
1101 }
1102 if (p == NULL)
1103 continue;
1104
1105 /* did the packet come from suppress sub-queue? */
1106 if (entry->requested_credit > 0) {
1107 entry->requested_credit--;
1108 /*
1109 * if the packet was pulled out while destination is in
1110 * closed state but had a non-zero packets requested,
1111 * then this should not count against the FIFO credit.
1112 * That is due to the fact that the firmware will
1113 * most likely hold onto this packet until a suitable
1114 * time later to push it to the appropriate AC FIFO.
1115 */
1116 if (entry->state == BRCMF_FWS_STATE_CLOSE)
1117 use_credit = 0;
1118 } else if (entry->requested_packet > 0) {
1119 entry->requested_packet--;
1120 brcmf_skb_if_flags_set_field(p, REQUESTED, 1);
1121 if (entry->state == BRCMF_FWS_STATE_CLOSE)
1122 use_credit = 0;
1123 }
1124 brcmf_skb_if_flags_set_field(p, CREDITCHECK, use_credit);
1125
1126 /* move dequeue position to ensure fair round-robin */
1127 fws->deq_node_pos[fifo] = (node_pos + i + 1) % num_nodes;
1128 brcmf_fws_flow_control_check(fws, &entry->psq,
1129 brcmf_skb_if_flags_get_field(p,
1130 INDEX)
1131 );
1132 /*
1133 * A packet has been picked up, update traffic
1134 * availability bitmap, if applicable
1135 */
1136 brcmf_fws_tim_update(fws, entry, fifo);
1137
1138 /*
1139 * decrement total enqueued fifo packets and
1140 * clear delay bitmap if done.
1141 */
1142 fws->fifo_enqpkt[fifo]--;
1143 if (fws->fifo_enqpkt[fifo] == 0)
1144 fws->fifo_delay_map &= ~(1 << fifo);
1145 goto done;
1146 }
1147 p = NULL;
1148done:
1149 brcmf_dbg(TRACE, "exit: fifo %d skb %p\n", fifo, p);
1150 return p;
1151}
1152
1153static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1154 struct sk_buff *skb, u32 genbit)
1155{
1156 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
1157 u32 hslot;
1158 int ret;
1159
1160 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
1161
1162 /* this packet was suppressed */
1163 if (!entry->suppressed || entry->generation != genbit) {
1164 entry->suppressed = true;
1165 entry->suppress_count = brcmu_pktq_mlen(&entry->psq,
1166 1 << (fifo * 2 + 1));
1167 entry->suppr_transit_count = entry->transit_count;
1168 }
1169
1170 entry->generation = genbit;
1171
1172 ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb);
1173 if (ret != 0) {
1174 /* suppress q is full, drop this packet */
1175 brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
1176 true);
1177 } else {
1178 /*
1179 * Mark suppressed to avoid a double free during
1180 * wlfc cleanup
1181 */
1182 brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot,
1183 genbit);
1184 entry->suppress_count++;
1185 }
1186
1187 return ret;
1188}
1189
1190static int
1191brcmf_fws_txstatus_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1192 u32 genbit)
1193{
1194 u32 fifo;
1195 int ret;
1196 bool remove_from_hanger = true;
1197 struct sk_buff *skb;
1198 struct brcmf_fws_mac_descriptor *entry = NULL;
1199
1200 brcmf_dbg(TRACE, "status: flags=0x%X, hslot=%d\n",
1201 flags, hslot);
1202
1203 if (flags == BRCMF_FWS_TXSTATUS_DISCARD)
1204 fws->stats.txs_discard++;
1205 else if (flags == BRCMF_FWS_TXSTATUS_CORE_SUPPRESS) {
1206 fws->stats.txs_supp_core++;
1207 remove_from_hanger = false;
1208 } else if (flags == BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS) {
1209 fws->stats.txs_supp_ps++;
1210 remove_from_hanger = false;
1211 } else if (flags == BRCMF_FWS_TXSTATUS_FW_TOSSED)
1212 fws->stats.txs_tossed++;
1213 else
1214 brcmf_err("unexpected txstatus\n");
1215
1216 ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
1217 remove_from_hanger);
1218 if (ret != 0) {
1219 brcmf_err("no packet in hanger slot: hslot=%d\n", hslot);
1220 return ret;
1221 }
1222
1223 entry = brcmf_skbcb(skb)->mac;
1224 if (WARN_ON(!entry)) {
1225 brcmu_pkt_buf_free_skb(skb);
1226 return -EINVAL;
1227 }
1228
1229 /* pick up the implicit credit from this packet */
1230 fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
1231 brcmf_skb_pick_up_credit(fws, fifo, skb);
1232
1233 if (!remove_from_hanger)
1234 ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit);
1235
1236 if (remove_from_hanger || ret) {
1237 entry->transit_count--;
1238 if (entry->suppressed)
1239 entry->suppr_transit_count--;
1240
1241 brcmf_txfinalize(fws->drvr, skb, true);
1242 }
1243 return 0;
1244}
1245
1246static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
1247 u8 *data)
1248{
1249 int i;
1250
1251 if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) {
1252 brcmf_dbg(INFO, "ignored\n");
1253 return 0;
1254 }
1255
1256 brcmf_dbg(TRACE, "enter: data %pM\n", data);
1257 for (i = 0; i < BRCMF_FWS_FIFO_COUNT; i++)
1258 brcmf_fws_return_credits(fws, i, data[i]);
1259
1260 brcmf_dbg(INFO, "map: credit %x delay %x\n", fws->fifo_credit_map,
1261 fws->fifo_delay_map);
1262 brcmf_fws_schedule_deq(fws);
1263 return 0;
1264}
1265
1266static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
1267{
1268 __le32 status_le;
1269 u32 status;
1270 u32 hslot;
1271 u32 genbit;
1272 u8 flags;
1273
1274 fws->stats.txs_indicate++;
1275 memcpy(&status_le, data, sizeof(status_le));
1276 status = le32_to_cpu(status_le);
1277 flags = brcmf_txstatus_get_field(status, FLAGS);
1278 hslot = brcmf_txstatus_get_field(status, HSLOT);
1279 genbit = brcmf_txstatus_get_field(status, GENERATION);
1280
1281 return brcmf_fws_txstatus_process(fws, flags, hslot, genbit);
1282}
1283
191static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data) 1284static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data)
192{ 1285{
193 __le32 timestamp; 1286 __le32 timestamp;
@@ -213,51 +1306,32 @@ do { \
213#define brcmf_fws_unlock(drvr, flags) \ 1306#define brcmf_fws_unlock(drvr, flags) \
214 spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags)) 1307 spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
215 1308
216int brcmf_fws_init(struct brcmf_pub *drvr) 1309static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
1310 const struct brcmf_event_msg *e,
1311 void *data)
217{ 1312{
218 u32 tlv; 1313 struct brcmf_fws_info *fws = ifp->drvr->fws;
219 int rc; 1314 int i;
220 1315 ulong flags;
221 /* enable rssi signals */ 1316 u8 *credits = data;
222 tlv = drvr->fw_signals ? BRCMF_FWS_FLAGS_RSSI_SIGNALS : 0;
223
224 spin_lock_init(&drvr->fws_spinlock);
225 1317
226 drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL); 1318 if (e->datalen < BRCMF_FWS_FIFO_COUNT) {
227 if (!drvr->fws) { 1319 brcmf_err("event payload too small (%d)\n", e->datalen);
228 rc = -ENOMEM; 1320 return -EINVAL;
229 goto fail;
230 } 1321 }
231 1322
232 /* enable proptxtstatus signaling by default */ 1323 brcmf_dbg(TRACE, "enter: credits %pM\n", credits);
233 rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv); 1324 brcmf_fws_lock(ifp->drvr, flags);
234 if (rc < 0) { 1325 for (i = 0; i < ARRAY_SIZE(fws->fifo_credit); i++) {
235 brcmf_err("failed to set bdcv2 tlv signaling\n"); 1326 if (*credits)
236 goto fail; 1327 fws->fifo_credit_map |= 1 << i;
1328 else
1329 fws->fifo_credit_map &= ~(1 << i);
1330 fws->fifo_credit[i] = *credits++;
237 } 1331 }
238 /* set linkage back */ 1332 brcmf_fws_schedule_deq(fws);
239 drvr->fws->drvr = drvr; 1333 brcmf_fws_unlock(ifp->drvr, flags);
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; 1334 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} 1335}
262 1336
263int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, 1337int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
@@ -304,57 +1378,50 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
304 len = signal_data[1]; 1378 len = signal_data[1];
305 data = signal_data + 2; 1379 data = signal_data + 2;
306 1380
1381 brcmf_dbg(INFO, "tlv type=%d (%s), len=%d, data[0]=%d\n", type,
1382 brcmf_fws_get_tlv_name(type), len, *data);
1383
307 /* abort parsing when length invalid */ 1384 /* abort parsing when length invalid */
308 if (data_len < len + 2) 1385 if (data_len < len + 2)
309 break; 1386 break;
310 1387
311 brcmf_dbg(INFO, "tlv type=%d (%s), len=%d\n", type, 1388 if (len != brcmf_fws_get_tlv_len(fws, 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; 1389 break;
324 case BRCMF_FWS_TYPE_PKTTAG: 1390
325 WARN_ON(len != BRCMF_FWS_TYPE_PKTTAG_LEN); 1391 switch (type) {
1392 case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
1393 case BRCMF_FWS_TYPE_COMP_TXSTATUS:
326 break; 1394 break;
327 case BRCMF_FWS_TYPE_MACDESC_ADD: 1395 case BRCMF_FWS_TYPE_MACDESC_ADD:
328 case BRCMF_FWS_TYPE_MACDESC_DEL: 1396 case BRCMF_FWS_TYPE_MACDESC_DEL:
329 WARN_ON(len != BRCMF_FWS_TYPE_MACDESC_ADD_LEN); 1397 brcmf_fws_macdesc_indicate(fws, type, data);
330 break; 1398 break;
331 case BRCMF_FWS_TYPE_RSSI: 1399 case BRCMF_FWS_TYPE_MAC_OPEN:
332 WARN_ON(len != BRCMF_FWS_TYPE_RSSI_LEN); 1400 case BRCMF_FWS_TYPE_MAC_CLOSE:
333 brcmf_fws_rssi_indicate(fws, *(s8 *)data); 1401 brcmf_fws_macdesc_state_indicate(fws, type, data);
334 break; 1402 break;
335 case BRCMF_FWS_TYPE_INTERFACE_OPEN: 1403 case BRCMF_FWS_TYPE_INTERFACE_OPEN:
336 case BRCMF_FWS_TYPE_INTERFACE_CLOSE: 1404 case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
337 WARN_ON(len != BRCMF_FWS_TYPE_INTERFACE_OPEN_LEN); 1405 brcmf_fws_interface_state_indicate(fws, type, data);
338 break; 1406 break;
339 case BRCMF_FWS_TYPE_FIFO_CREDITBACK: 1407 case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT:
340 WARN_ON(len != BRCMF_FWS_TYPE_FIFO_CREDITBACK_LEN); 1408 case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET:
1409 brcmf_fws_request_indicate(fws, type, data);
341 break; 1410 break;
342 case BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP: 1411 case BRCMF_FWS_TYPE_TXSTATUS:
343 WARN_ON(len != BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN); 1412 brcmf_fws_txstatus_indicate(fws, data);
344 break; 1413 break;
345 case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET: 1414 case BRCMF_FWS_TYPE_FIFO_CREDITBACK:
346 WARN_ON(len != BRCMF_FWS_TYPE_MAC_REQUEST_PACKET_LEN); 1415 brcmf_fws_fifocreditback_indicate(fws, data);
347 break; 1416 break;
348 case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS: 1417 case BRCMF_FWS_TYPE_RSSI:
349 WARN_ON(len != BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS_LEN); 1418 brcmf_fws_rssi_indicate(fws, *data);
350 break; 1419 break;
351 case BRCMF_FWS_TYPE_TRANS_ID: 1420 case BRCMF_FWS_TYPE_TRANS_ID:
352 WARN_ON(len != BRCMF_FWS_TYPE_TRANS_ID_LEN);
353 brcmf_fws_dbg_seqnum_check(fws, data); 1421 brcmf_fws_dbg_seqnum_check(fws, data);
354 break; 1422 break;
355 case BRCMF_FWS_TYPE_COMP_TXSTATUS: 1423 case BRCMF_FWS_TYPE_PKTTAG:
356 WARN_ON(len != BRCMF_FWS_TYPE_COMP_TXSTATUS_LEN); 1424 case BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP:
357 break;
358 default: 1425 default:
359 fws->stats.tlv_invalid_type++; 1426 fws->stats.tlv_invalid_type++;
360 break; 1427 break;
@@ -380,3 +1447,505 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
380 brcmf_fws_unlock(drvr, flags); 1447 brcmf_fws_unlock(drvr, flags);
381 return 0; 1448 return 0;
382} 1449}
1450
1451static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
1452{
1453 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
1454 u8 *wlh;
1455 u16 data_offset = 0;
1456 u8 fillers;
1457 __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
1458
1459 brcmf_dbg(TRACE, "enter: ea=%pM, ifidx=%u, pkttag=0x%08X\n",
1460 entry->ea, entry->interface_id, le32_to_cpu(pkttag));
1461 if (entry->send_tim_signal)
1462 data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
1463
1464 /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
1465 data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN;
1466 fillers = round_up(data_offset, 4) - data_offset;
1467 data_offset += fillers;
1468
1469 skb_push(skb, data_offset);
1470 wlh = skb->data;
1471
1472 wlh[0] = BRCMF_FWS_TYPE_PKTTAG;
1473 wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN;
1474 memcpy(&wlh[2], &pkttag, sizeof(pkttag));
1475 wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2;
1476
1477 if (entry->send_tim_signal) {
1478 entry->send_tim_signal = 0;
1479 wlh[0] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP;
1480 wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
1481 wlh[2] = entry->mac_handle;
1482 wlh[3] = entry->traffic_pending_bmp;
1483 wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2;
1484 entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
1485 }
1486 if (fillers)
1487 memset(wlh, BRCMF_FWS_TYPE_FILLER, fillers);
1488
1489 brcmf_proto_hdrpush(fws->drvr, brcmf_skb_if_flags_get_field(skb, INDEX),
1490 data_offset >> 2, skb);
1491 return 0;
1492}
1493
1494static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
1495 struct sk_buff *p)
1496{
1497 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
1498 struct brcmf_fws_mac_descriptor *entry = skcb->mac;
1499 int rc = 0;
1500 bool header_needed;
1501 int hslot = BRCMF_FWS_HANGER_MAXITEMS;
1502 u8 free_ctr;
1503 u8 ifidx;
1504 u8 flags;
1505
1506 header_needed = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED;
1507
1508 if (header_needed) {
1509 /* obtaining free slot may fail, but that will be caught
1510 * by the hanger push. This assures the packet has a BDC
1511 * header upon return.
1512 */
1513 hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
1514 free_ctr = entry->seq[fifo];
1515 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
1516 brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr);
1517 brcmf_skb_htod_tag_set_field(p, GENERATION, 1);
1518 entry->transit_count++;
1519 }
1520 brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
1521 brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
1522
1523 flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
1524 if (!(skcb->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)) {
1525 /*
1526 Indicate that this packet is being sent in response to an
1527 explicit request from the firmware side.
1528 */
1529 flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED;
1530 }
1531 brcmf_skb_htod_tag_set_field(p, FLAGS, flags);
1532 if (header_needed) {
1533 brcmf_fws_hdrpush(fws, p);
1534 rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
1535 if (rc)
1536 brcmf_err("hanger push failed: rc=%d\n", rc);
1537 } else {
1538 int gen;
1539
1540 /* remove old header */
1541 rc = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, p);
1542 if (rc == 0) {
1543 hslot = brcmf_skb_htod_tag_get_field(p, HSLOT);
1544 brcmf_fws_hanger_get_genbit(&fws->hanger, p,
1545 hslot, &gen);
1546 brcmf_skb_htod_tag_set_field(p, GENERATION, gen);
1547
1548 /* push new header */
1549 brcmf_fws_hdrpush(fws, p);
1550 }
1551 }
1552
1553 return rc;
1554}
1555
1556static int
1557brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, struct sk_buff *skb)
1558{
1559 /*
1560 put the packet back to the head of queue
1561
1562 - suppressed packet goes back to suppress sub-queue
1563 - pull out the header, if new or delayed packet
1564
1565 Note: hslot is used only when header removal is done.
1566 */
1567 struct brcmf_fws_mac_descriptor *entry;
1568 enum brcmf_fws_skb_state state;
1569 struct sk_buff *pktout;
1570 int rc = 0;
1571 int fifo;
1572 int hslot;
1573 u8 ifidx;
1574
1575 fifo = brcmf_skb_if_flags_get_field(skb, FIFO);
1576 state = brcmf_skbcb(skb)->state;
1577 entry = brcmf_skbcb(skb)->mac;
1578
1579 if (entry != NULL) {
1580 if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
1581 /* wl-header is saved for suppressed packets */
1582 pktout = brcmu_pktq_penq_head(&entry->psq, 2 * fifo + 1,
1583 skb);
1584 if (pktout == NULL) {
1585 brcmf_err("suppress queue full\n");
1586 rc = -ENOSPC;
1587 }
1588 } else {
1589 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
1590
1591 /* remove header first */
1592 rc = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
1593 if (rc) {
1594 brcmf_err("header removal failed\n");
1595 /* free the hanger slot */
1596 brcmf_fws_hanger_poppkt(&fws->hanger, hslot,
1597 &pktout, true);
1598 brcmf_txfinalize(fws->drvr, skb, false);
1599 rc = -EINVAL;
1600 goto fail;
1601 }
1602
1603 /* delay-q packets are going to delay-q */
1604 pktout = brcmu_pktq_penq_head(&entry->psq,
1605 2 * fifo, skb);
1606 if (pktout == NULL) {
1607 brcmf_err("delay queue full\n");
1608 rc = -ENOSPC;
1609 }
1610
1611 /* free the hanger slot */
1612 brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &pktout,
1613 true);
1614
1615 /* decrement sequence count */
1616 entry->seq[fifo]--;
1617 }
1618 /*
1619 if this packet did not count against FIFO credit, it must have
1620 taken a requested_credit from the firmware (for pspoll etc.)
1621 */
1622 if (!(brcmf_skbcb(skb)->if_flags &
1623 BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK))
1624 entry->requested_credit++;
1625 } else {
1626 brcmf_err("no mac entry linked\n");
1627 rc = -ENOENT;
1628 }
1629
1630
1631fail:
1632 if (rc)
1633 fws->stats.rollback_failed++;
1634 else
1635 fws->stats.rollback_success++;
1636 return rc;
1637}
1638
1639static int brcmf_fws_consume_credit(struct brcmf_fws_info *fws, int fifo,
1640 struct sk_buff *skb)
1641{
1642 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
1643 int *credit = &fws->fifo_credit[fifo];
1644 int use_credit = 1;
1645
1646 brcmf_dbg(TRACE, "enter: ac=%d, credits=%d\n", fifo, *credit);
1647
1648 if (entry->requested_credit > 0) {
1649 /*
1650 * if the packet was pulled out while destination is in
1651 * closed state but had a non-zero packets requested,
1652 * then this should not count against the FIFO credit.
1653 * That is due to the fact that the firmware will
1654 * most likely hold onto this packet until a suitable
1655 * time later to push it to the appropriate AC FIFO.
1656 */
1657 entry->requested_credit--;
1658 if (entry->state == BRCMF_FWS_STATE_CLOSE)
1659 use_credit = 0;
1660 } else if (entry->requested_packet > 0) {
1661 entry->requested_packet--;
1662 brcmf_skb_if_flags_set_field(skb, REQUESTED, 1);
1663 if (entry->state == BRCMF_FWS_STATE_CLOSE)
1664 use_credit = 0;
1665 }
1666 brcmf_skb_if_flags_set_field(skb, CREDITCHECK, use_credit);
1667 if (!use_credit) {
1668 brcmf_dbg(TRACE, "exit: no creditcheck set\n");
1669 return 0;
1670 }
1671
1672 if (!(*credit)) {
1673 brcmf_dbg(TRACE, "exit: credits depleted\n");
1674 return -ENAVAIL;
1675 }
1676 (*credit)--;
1677 if (!(*credit))
1678 fws->fifo_credit_map &= ~(1 << fifo);
1679 brcmf_dbg(TRACE, "exit: ac=%d, credits=%d\n", fifo, *credit);
1680 return 0;
1681}
1682
1683static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
1684 struct sk_buff *skb)
1685{
1686 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb);
1687 struct brcmf_fws_mac_descriptor *entry;
1688 struct brcmf_bus *bus = fws->drvr->bus_if;
1689 int rc;
1690
1691 entry = skcb->mac;
1692 if (IS_ERR(entry))
1693 return PTR_ERR(entry);
1694
1695 rc = brcmf_fws_precommit_skb(fws, fifo, skb);
1696 if (rc < 0) {
1697 fws->stats.generic_error++;
1698 goto rollback;
1699 }
1700
1701 rc = brcmf_bus_txdata(bus, skb);
1702 if (rc < 0)
1703 goto rollback;
1704
1705 entry->seq[fifo]++;
1706 fws->stats.pkt2bus++;
1707 if (brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) {
1708 fws->stats.send_pkts[fifo]++;
1709 fws->stats.fifo_credits_sent[fifo]++;
1710 }
1711
1712 return rc;
1713
1714rollback:
1715 rc = brcmf_fws_rollback_toq(fws, skb);
1716 return rc;
1717}
1718
1719int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
1720{
1721 struct brcmf_pub *drvr = ifp->drvr;
1722 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb);
1723 struct ethhdr *eh = (struct ethhdr *)(skb->data);
1724 ulong flags;
1725 u8 ifidx = ifp->ifidx;
1726 int fifo = BRCMF_FWS_FIFO_BCMC;
1727 bool multicast = is_multicast_ether_addr(eh->h_dest);
1728
1729 /* determine the priority */
1730 if (!skb->priority)
1731 skb->priority = cfg80211_classify8021d(skb);
1732
1733 drvr->tx_multicast += !!multicast;
1734 if (ntohs(eh->h_proto) == ETH_P_PAE)
1735 atomic_inc(&ifp->pend_8021x_cnt);
1736
1737 if (!brcmf_fws_fc_active(drvr->fws)) {
1738 /* If the protocol uses a data header, apply it */
1739 brcmf_proto_hdrpush(drvr, ifidx, 0, skb);
1740
1741 /* Use bus module to send data frame */
1742 return brcmf_bus_txdata(drvr->bus_if, skb);
1743 }
1744
1745 /* set control buffer information */
1746 skcb->if_flags = 0;
1747 skcb->mac = brcmf_fws_find_mac_desc(drvr->fws, ifidx, eh->h_dest);
1748 skcb->state = BRCMF_FWS_SKBSTATE_NEW;
1749 brcmf_skb_if_flags_set_field(skb, INDEX, ifidx);
1750 if (!multicast)
1751 fifo = brcmf_fws_prio2fifo[skb->priority];
1752 brcmf_skb_if_flags_set_field(skb, FIFO, fifo);
1753
1754 brcmf_dbg(TRACE, "ea=%pM, multi=%d, fifo=%d\n", eh->h_dest,
1755 multicast, fifo);
1756
1757 brcmf_fws_lock(drvr, flags);
1758 if (!brcmf_fws_mac_desc_ready(skcb->mac, fifo) ||
1759 (!multicast &&
1760 brcmf_fws_consume_credit(drvr->fws, fifo, skb) < 0)) {
1761 /* enqueue the packet in delayQ */
1762 drvr->fws->fifo_delay_map |= 1 << fifo;
1763 brcmf_fws_enq(drvr->fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb);
1764 } else {
1765 brcmf_fws_commit_skb(drvr->fws, fifo, skb);
1766 }
1767 brcmf_fws_unlock(drvr, flags);
1768 return 0;
1769}
1770
1771void brcmf_fws_reset_interface(struct brcmf_if *ifp)
1772{
1773 struct brcmf_fws_mac_descriptor *entry = ifp->fws_desc;
1774
1775 brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx);
1776 if (!entry)
1777 return;
1778
1779 brcmf_fws_init_mac_descriptor(entry, ifp->mac_addr, ifp->ifidx);
1780}
1781
1782void brcmf_fws_add_interface(struct brcmf_if *ifp)
1783{
1784 struct brcmf_fws_info *fws = ifp->drvr->fws;
1785 struct brcmf_fws_mac_descriptor *entry;
1786
1787 brcmf_dbg(TRACE, "enter: idx=%d, mac=%pM\n",
1788 ifp->bssidx, ifp->mac_addr);
1789 if (!ifp->ndev || !ifp->drvr->fw_signals)
1790 return;
1791
1792 entry = &fws->desc.iface[ifp->ifidx];
1793 ifp->fws_desc = entry;
1794 brcmf_fws_init_mac_descriptor(entry, ifp->mac_addr, ifp->ifidx);
1795 brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT,
1796 BRCMF_FWS_PSQ_LEN);
1797}
1798
1799void brcmf_fws_del_interface(struct brcmf_if *ifp)
1800{
1801 struct brcmf_fws_mac_descriptor *entry = ifp->fws_desc;
1802
1803 brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx);
1804 if (!entry)
1805 return;
1806
1807 ifp->fws_desc = NULL;
1808 brcmf_fws_clear_mac_descriptor(entry);
1809 brcmf_fws_cleanup(ifp->drvr->fws, ifp->ifidx);
1810}
1811
1812static void brcmf_fws_dequeue_worker(struct work_struct *worker)
1813{
1814 struct brcmf_fws_info *fws;
1815 struct sk_buff *skb;
1816 ulong flags;
1817 int fifo;
1818 int credit;
1819
1820 fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work);
1821
1822 brcmf_dbg(TRACE, "enter: fws=%p\n", fws);
1823 brcmf_fws_lock(fws->drvr, flags);
1824 for (fifo = NL80211_NUM_ACS; fifo >= 0; fifo--) {
1825 brcmf_dbg(TRACE, "fifo %d credit %d\n", fifo,
1826 fws->fifo_credit[fifo]);
1827 for (credit = 0; credit < fws->fifo_credit[fifo]; /* nop */) {
1828 skb = brcmf_fws_deq(fws, fifo);
1829 if (!skb)
1830 break;
1831 if (!brcmf_fws_commit_skb(fws, fifo, skb) &&
1832 brcmf_skbcb(skb)->if_flags &
1833 BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)
1834 credit++;
1835 }
1836 fws->fifo_credit[fifo] -= credit;
1837 }
1838 brcmf_fws_unlock(fws->drvr, flags);
1839}
1840
1841int brcmf_fws_init(struct brcmf_pub *drvr)
1842{
1843 u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS;
1844 int rc;
1845
1846 if (!drvr->fw_signals)
1847 return 0;
1848
1849 spin_lock_init(&drvr->fws_spinlock);
1850
1851 drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL);
1852 if (!drvr->fws) {
1853 rc = -ENOMEM;
1854 goto fail;
1855 }
1856
1857 /* set linkage back */
1858 drvr->fws->drvr = drvr;
1859 drvr->fws->fcmode = fcmode;
1860
1861 drvr->fws->fws_wq = create_singlethread_workqueue("brcmf_fws_wq");
1862 if (drvr->fws->fws_wq == NULL) {
1863 brcmf_err("workqueue creation failed\n");
1864 rc = -EBADF;
1865 goto fail;
1866 }
1867 INIT_WORK(&drvr->fws->fws_dequeue_work, brcmf_fws_dequeue_worker);
1868
1869 /* enable firmware signalling if fcmode active */
1870 if (drvr->fws->fcmode != BRCMF_FWS_FCMODE_NONE)
1871 tlv |= BRCMF_FWS_FLAGS_XONXOFF_SIGNALS |
1872 BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS |
1873 BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE;
1874
1875 rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv);
1876 if (rc < 0) {
1877 brcmf_err("failed to set bdcv2 tlv signaling\n");
1878 goto fail;
1879 }
1880
1881 if (brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP,
1882 brcmf_fws_notify_credit_map)) {
1883 brcmf_err("register credit map handler failed\n");
1884 goto fail;
1885 }
1886
1887 brcmf_fws_hanger_init(&drvr->fws->hanger);
1888 brcmf_fws_init_mac_descriptor(&drvr->fws->desc.other, NULL, 0);
1889 brcmu_pktq_init(&drvr->fws->desc.other.psq, BRCMF_FWS_PSQ_PREC_COUNT,
1890 BRCMF_FWS_PSQ_LEN);
1891
1892 /* create debugfs file for statistics */
1893 brcmf_debugfs_create_fws_stats(drvr, &drvr->fws->stats);
1894
1895 /* TODO: remove upon feature delivery */
1896 brcmf_err("%s bdcv2 tlv signaling [%x]\n",
1897 drvr->fw_signals ? "enabled" : "disabled", tlv);
1898 return 0;
1899
1900fail:
1901 /* disable flow control entirely */
1902 drvr->fw_signals = false;
1903 brcmf_fws_deinit(drvr);
1904 return rc;
1905}
1906
1907void brcmf_fws_deinit(struct brcmf_pub *drvr)
1908{
1909 struct brcmf_fws_info *fws = drvr->fws;
1910 ulong flags;
1911
1912 if (!fws)
1913 return;
1914
1915 /* cleanup */
1916 brcmf_fws_lock(drvr, flags);
1917 brcmf_fws_cleanup(fws, -1);
1918 drvr->fws = NULL;
1919 brcmf_fws_unlock(drvr, flags);
1920
1921 /* free top structure */
1922 kfree(fws);
1923}
1924
1925bool brcmf_fws_fc_active(struct brcmf_fws_info *fws)
1926{
1927 if (!fws)
1928 return false;
1929
1930 brcmf_dbg(TRACE, "enter: mode=%d\n", fws->fcmode);
1931 return fws->fcmode != BRCMF_FWS_FCMODE_NONE;
1932}
1933
1934void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
1935{
1936 ulong flags;
1937
1938 brcmf_fws_lock(fws->drvr, flags);
1939 brcmf_fws_txstatus_process(fws, BRCMF_FWS_TXSTATUS_FW_TOSSED,
1940 brcmf_skb_htod_tag_get_field(skb, HSLOT), 0);
1941 /* the packet never reached firmware so reclaim credit */
1942 if (fws->fcmode == BRCMF_FWS_FCMODE_EXPLICIT_CREDIT &&
1943 brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) {
1944 brcmf_fws_return_credits(fws,
1945 brcmf_skb_htod_tag_get_field(skb,
1946 FIFO),
1947 1);
1948 brcmf_fws_schedule_deq(fws);
1949 }
1950 brcmf_fws_unlock(fws->drvr, flags);
1951}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
index e728eea72bb4..fbe483d23752 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
@@ -20,6 +20,14 @@
20 20
21int brcmf_fws_init(struct brcmf_pub *drvr); 21int brcmf_fws_init(struct brcmf_pub *drvr);
22void brcmf_fws_deinit(struct brcmf_pub *drvr); 22void brcmf_fws_deinit(struct brcmf_pub *drvr);
23bool brcmf_fws_fc_active(struct brcmf_fws_info *fws);
23int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, 24int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
24 struct sk_buff *skb); 25 struct sk_buff *skb);
26int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb);
27
28void brcmf_fws_reset_interface(struct brcmf_if *ifp);
29void brcmf_fws_add_interface(struct brcmf_if *ifp);
30void brcmf_fws_del_interface(struct brcmf_if *ifp);
31void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb);
32
25#endif /* FWSIGNAL_H_ */ 33#endif /* FWSIGNAL_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 4166e642068b..94ff045df2b3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -15,6 +15,7 @@
15 */ 15 */
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/netdevice.h> 17#include <linux/netdevice.h>
18#include <linux/etherdevice.h>
18#include <net/cfg80211.h> 19#include <net/cfg80211.h>
19 20
20#include <brcmu_wifi.h> 21#include <brcmu_wifi.h>
@@ -455,7 +456,9 @@ static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac)
455{ 456{
456 s32 ret = 0; 457 s32 ret = 0;
457 458
459 brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
458 brcmf_fil_iovar_int_set(ifp, "apsta", 1); 460 brcmf_fil_iovar_int_set(ifp, "apsta", 1);
461 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
459 462
460 /* In case of COB type, firmware has default mac address 463 /* In case of COB type, firmware has default mac address
461 * After Initializing firmware, we have to set current mac address to 464 * After Initializing firmware, we have to set current mac address to
@@ -473,28 +476,35 @@ static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac)
473 * brcmf_p2p_generate_bss_mac() - derive mac addresses for P2P. 476 * brcmf_p2p_generate_bss_mac() - derive mac addresses for P2P.
474 * 477 *
475 * @p2p: P2P specific data. 478 * @p2p: P2P specific data.
479 * @dev_addr: optional device address.
476 * 480 *
477 * P2P needs mac addresses for P2P device and interface. These are 481 * P2P needs mac addresses for P2P device and interface. If no device
478 * derived from the primary net device, ie. the permanent ethernet 482 * address it specified, these are derived from the primary net device, ie.
479 * address of the device. 483 * the permanent ethernet address of the device.
480 */ 484 */
481static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p) 485static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr)
482{ 486{
483 struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; 487 struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
484 struct brcmf_if *p2p_ifp = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->ifp; 488 bool local_admin = false;
489
490 if (!dev_addr || is_zero_ether_addr(dev_addr)) {
491 dev_addr = pri_ifp->mac_addr;
492 local_admin = true;
493 }
485 494
486 /* Generate the P2P Device Address. This consists of the device's 495 /* Generate the P2P Device Address. This consists of the device's
487 * primary MAC address with the locally administered bit set. 496 * primary MAC address with the locally administered bit set.
488 */ 497 */
489 memcpy(p2p->dev_addr, pri_ifp->mac_addr, ETH_ALEN); 498 memcpy(p2p->dev_addr, dev_addr, ETH_ALEN);
490 p2p->dev_addr[0] |= 0x02; 499 if (local_admin)
491 memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN); 500 p2p->dev_addr[0] |= 0x02;
492 501
493 /* Generate the P2P Interface Address. If the discovery and connection 502 /* Generate the P2P Interface Address. If the discovery and connection
494 * BSSCFGs need to simultaneously co-exist, then this address must be 503 * BSSCFGs need to simultaneously co-exist, then this address must be
495 * different from the P2P Device Address, but also locally administered. 504 * different from the P2P Device Address, but also locally administered.
496 */ 505 */
497 memcpy(p2p->int_addr, p2p->dev_addr, ETH_ALEN); 506 memcpy(p2p->int_addr, p2p->dev_addr, ETH_ALEN);
507 p2p->int_addr[0] |= 0x02;
498 p2p->int_addr[4] ^= 0x80; 508 p2p->int_addr[4] ^= 0x80;
499} 509}
500 510
@@ -773,7 +783,7 @@ exit:
773 * validates the channels in the request. 783 * validates the channels in the request.
774 */ 784 */
775static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg, 785static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
776 struct net_device *ndev, 786 struct brcmf_if *ifp,
777 struct cfg80211_scan_request *request, 787 struct cfg80211_scan_request *request,
778 u16 action) 788 u16 action)
779{ 789{
@@ -1261,7 +1271,7 @@ static void
1261brcmf_p2p_stop_wait_next_action_frame(struct brcmf_cfg80211_info *cfg) 1271brcmf_p2p_stop_wait_next_action_frame(struct brcmf_cfg80211_info *cfg)
1262{ 1272{
1263 struct brcmf_p2p_info *p2p = &cfg->p2p; 1273 struct brcmf_p2p_info *p2p = &cfg->p2p;
1264 struct net_device *ndev = cfg->escan_info.ndev; 1274 struct brcmf_if *ifp = cfg->escan_info.ifp;
1265 1275
1266 if (test_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status) && 1276 if (test_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status) &&
1267 (test_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status) || 1277 (test_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status) ||
@@ -1271,12 +1281,12 @@ brcmf_p2p_stop_wait_next_action_frame(struct brcmf_cfg80211_info *cfg)
1271 * So abort scan for off channel completion. 1281 * So abort scan for off channel completion.
1272 */ 1282 */
1273 if (p2p->af_sent_channel) 1283 if (p2p->af_sent_channel)
1274 brcmf_notify_escan_complete(cfg, ndev, true, true); 1284 brcmf_notify_escan_complete(cfg, ifp, true, true);
1275 } else if (test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN, 1285 } else if (test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
1276 &p2p->status)) { 1286 &p2p->status)) {
1277 brcmf_dbg(TRACE, "*** Wake UP ** abort listen for next af frame\n"); 1287 brcmf_dbg(TRACE, "*** Wake UP ** abort listen for next af frame\n");
1278 /* So abort scan to cancel listen */ 1288 /* So abort scan to cancel listen */
1279 brcmf_notify_escan_complete(cfg, ndev, true, true); 1289 brcmf_notify_escan_complete(cfg, ifp, true, true);
1280 } 1290 }
1281} 1291}
1282 1292
@@ -1384,7 +1394,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
1384 /* After complete GO Negotiation, roll back to mpc mode */ 1394 /* After complete GO Negotiation, roll back to mpc mode */
1385 if ((action == P2P_PAF_GON_CONF) || 1395 if ((action == P2P_PAF_GON_CONF) ||
1386 (action == P2P_PAF_PROVDIS_RSP)) 1396 (action == P2P_PAF_PROVDIS_RSP))
1387 brcmf_set_mpc(ifp->ndev, 1); 1397 brcmf_set_mpc(ifp, 1);
1388 if (action == P2P_PAF_GON_CONF) { 1398 if (action == P2P_PAF_GON_CONF) {
1389 brcmf_dbg(TRACE, "P2P: GO_NEG_PHASE status cleared\n"); 1399 brcmf_dbg(TRACE, "P2P: GO_NEG_PHASE status cleared\n");
1390 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status); 1400 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
@@ -1421,7 +1431,8 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
1421 CHSPEC_IS2G(chanspec) ? 1431 CHSPEC_IS2G(chanspec) ?
1422 IEEE80211_BAND_2GHZ : 1432 IEEE80211_BAND_2GHZ :
1423 IEEE80211_BAND_5GHZ); 1433 IEEE80211_BAND_5GHZ);
1424 wdev = ifp->ndev->ieee80211_ptr; 1434
1435 wdev = &ifp->vif->wdev;
1425 cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len, 1436 cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len,
1426 GFP_ATOMIC); 1437 GFP_ATOMIC);
1427 1438
@@ -1637,6 +1648,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
1637 struct brcmf_fil_af_params_le *af_params) 1648 struct brcmf_fil_af_params_le *af_params)
1638{ 1649{
1639 struct brcmf_p2p_info *p2p = &cfg->p2p; 1650 struct brcmf_p2p_info *p2p = &cfg->p2p;
1651 struct brcmf_if *ifp = netdev_priv(ndev);
1640 struct brcmf_fil_action_frame_le *action_frame; 1652 struct brcmf_fil_action_frame_le *action_frame;
1641 struct brcmf_config_af_params config_af_params; 1653 struct brcmf_config_af_params config_af_params;
1642 struct afx_hdl *afx_hdl = &p2p->afx_hdl; 1654 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
@@ -1725,7 +1737,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
1725 1737
1726 /* To make sure to send successfully action frame, turn off mpc */ 1738 /* To make sure to send successfully action frame, turn off mpc */
1727 if (config_af_params.mpc_onoff == 0) 1739 if (config_af_params.mpc_onoff == 0)
1728 brcmf_set_mpc(ndev, 0); 1740 brcmf_set_mpc(ifp, 0);
1729 1741
1730 /* set status and destination address before sending af */ 1742 /* set status and destination address before sending af */
1731 if (p2p->next_af_subtype != P2P_PAF_SUBTYPE_INVALID) { 1743 if (p2p->next_af_subtype != P2P_PAF_SUBTYPE_INVALID) {
@@ -1753,7 +1765,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
1753 * care of current piggback algo, lets abort the scan here 1765 * care of current piggback algo, lets abort the scan here
1754 * itself. 1766 * itself.
1755 */ 1767 */
1756 brcmf_notify_escan_complete(cfg, ndev, true, true); 1768 brcmf_notify_escan_complete(cfg, ifp, true, true);
1757 1769
1758 /* update channel */ 1770 /* update channel */
1759 af_params->channel = cpu_to_le32(afx_hdl->peer_chan); 1771 af_params->channel = cpu_to_le32(afx_hdl->peer_chan);
@@ -1820,7 +1832,7 @@ exit:
1820 clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status); 1832 clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status);
1821 /* if all done, turn mpc on again */ 1833 /* if all done, turn mpc on again */
1822 if (config_af_params.mpc_onoff == 1) 1834 if (config_af_params.mpc_onoff == 1)
1823 brcmf_set_mpc(ndev, 1); 1835 brcmf_set_mpc(ifp, 1);
1824 1836
1825 return ack; 1837 return ack;
1826} 1838}
@@ -1839,7 +1851,6 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
1839 struct brcmf_cfg80211_info *cfg = ifp->drvr->config; 1851 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1840 struct brcmf_p2p_info *p2p = &cfg->p2p; 1852 struct brcmf_p2p_info *p2p = &cfg->p2p;
1841 struct afx_hdl *afx_hdl = &p2p->afx_hdl; 1853 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1842 struct wireless_dev *wdev;
1843 struct brcmf_cfg80211_vif *vif = ifp->vif; 1854 struct brcmf_cfg80211_vif *vif = ifp->vif;
1844 struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data; 1855 struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data;
1845 u16 chanspec = be16_to_cpu(rxframe->chanspec); 1856 u16 chanspec = be16_to_cpu(rxframe->chanspec);
@@ -1882,8 +1893,9 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
1882 CHSPEC_IS2G(chanspec) ? 1893 CHSPEC_IS2G(chanspec) ?
1883 IEEE80211_BAND_2GHZ : 1894 IEEE80211_BAND_2GHZ :
1884 IEEE80211_BAND_5GHZ); 1895 IEEE80211_BAND_5GHZ);
1885 wdev = ifp->ndev->ieee80211_ptr; 1896
1886 cfg80211_rx_mgmt(wdev, freq, 0, mgmt_frame, mgmt_frame_len, GFP_ATOMIC); 1897 cfg80211_rx_mgmt(&vif->wdev, freq, 0, mgmt_frame, mgmt_frame_len,
1898 GFP_ATOMIC);
1887 1899
1888 brcmf_dbg(INFO, "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n", 1900 brcmf_dbg(INFO, "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n",
1889 mgmt_frame_len, e->datalen, chanspec, freq); 1901 mgmt_frame_len, e->datalen, chanspec, freq);
@@ -1934,7 +1946,8 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
1934 1946
1935 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif; 1947 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
1936 1948
1937 brcmf_p2p_generate_bss_mac(p2p); 1949 brcmf_p2p_generate_bss_mac(p2p, NULL);
1950 memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
1938 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr); 1951 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
1939 1952
1940 /* Initialize P2P Discovery in the firmware */ 1953 /* Initialize P2P Discovery in the firmware */
@@ -2040,13 +2053,13 @@ int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
2040 brcmf_err("vif for P2PAPI_BSSCFG_PRIMARY does not exist\n"); 2053 brcmf_err("vif for P2PAPI_BSSCFG_PRIMARY does not exist\n");
2041 return -EPERM; 2054 return -EPERM;
2042 } 2055 }
2043 brcmf_notify_escan_complete(cfg, vif->ifp->ndev, true, true); 2056 brcmf_notify_escan_complete(cfg, vif->ifp, true, true);
2044 vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif; 2057 vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif;
2045 if (!vif) { 2058 if (!vif) {
2046 brcmf_err("vif for P2PAPI_BSSCFG_CONNECTION does not exist\n"); 2059 brcmf_err("vif for P2PAPI_BSSCFG_CONNECTION does not exist\n");
2047 return -EPERM; 2060 return -EPERM;
2048 } 2061 }
2049 brcmf_set_mpc(vif->ifp->ndev, 0); 2062 brcmf_set_mpc(vif->ifp, 0);
2050 2063
2051 /* In concurrency case, STA may be already associated in a particular */ 2064 /* In concurrency case, STA may be already associated in a particular */
2052 /* channel. so retrieve the current channel of primary interface and */ 2065 /* channel. so retrieve the current channel of primary interface and */
@@ -2124,13 +2137,105 @@ static int brcmf_p2p_release_p2p_if(struct brcmf_cfg80211_vif *vif)
2124} 2137}
2125 2138
2126/** 2139/**
2140 * brcmf_p2p_create_p2pdev() - create a P2P_DEVICE virtual interface.
2141 *
2142 * @p2p: P2P specific data.
2143 * @wiphy: wiphy device of new interface.
2144 * @addr: mac address for this new interface.
2145 */
2146static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
2147 struct wiphy *wiphy,
2148 u8 *addr)
2149{
2150 struct brcmf_cfg80211_vif *p2p_vif;
2151 struct brcmf_if *p2p_ifp;
2152 struct brcmf_if *pri_ifp;
2153 int err;
2154 u32 bssidx;
2155
2156 if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
2157 return ERR_PTR(-ENOSPC);
2158
2159 p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE,
2160 false);
2161 if (IS_ERR(p2p_vif)) {
2162 brcmf_err("could not create discovery vif\n");
2163 return (struct wireless_dev *)p2p_vif;
2164 }
2165
2166 pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
2167 brcmf_p2p_generate_bss_mac(p2p, addr);
2168 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
2169
2170 brcmf_cfg80211_arm_vif_event(p2p->cfg, p2p_vif);
2171
2172 /* Initialize P2P Discovery in the firmware */
2173 err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
2174 if (err < 0) {
2175 brcmf_err("set p2p_disc error\n");
2176 brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL);
2177 goto fail;
2178 }
2179
2180 /* wait for firmware event */
2181 err = brcmf_cfg80211_wait_vif_event_timeout(p2p->cfg, BRCMF_E_IF_ADD,
2182 msecs_to_jiffies(1500));
2183 brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL);
2184 if (!err) {
2185 brcmf_err("timeout occurred\n");
2186 err = -EIO;
2187 goto fail;
2188 }
2189
2190 /* discovery interface created */
2191 p2p_ifp = p2p_vif->ifp;
2192 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
2193 memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
2194 memcpy(&p2p_vif->wdev.address, p2p->dev_addr, sizeof(p2p->dev_addr));
2195
2196 /* verify bsscfg index for P2P discovery */
2197 err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
2198 if (err < 0) {
2199 brcmf_err("retrieving discover bsscfg index failed\n");
2200 goto fail;
2201 }
2202
2203 WARN_ON(p2p_ifp->bssidx != bssidx);
2204
2205 init_completion(&p2p->send_af_done);
2206 INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
2207 init_completion(&p2p->afx_hdl.act_frm_scan);
2208 init_completion(&p2p->wait_next_af);
2209
2210 return &p2p_vif->wdev;
2211
2212fail:
2213 brcmf_free_vif(p2p_vif);
2214 return ERR_PTR(err);
2215}
2216
2217/**
2218 * brcmf_p2p_delete_p2pdev() - delete P2P_DEVICE virtual interface.
2219 *
2220 * @vif: virtual interface object to delete.
2221 */
2222static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_vif *vif)
2223{
2224 struct brcmf_p2p_info *p2p = &vif->ifp->drvr->config->p2p;
2225
2226 cfg80211_unregister_wdev(&vif->wdev);
2227 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
2228 brcmf_free_vif(vif);
2229}
2230
2231/**
2127 * brcmf_p2p_add_vif() - create a new P2P virtual interface. 2232 * brcmf_p2p_add_vif() - create a new P2P virtual interface.
2128 * 2233 *
2129 * @wiphy: wiphy device of new interface. 2234 * @wiphy: wiphy device of new interface.
2130 * @name: name of the new interface. 2235 * @name: name of the new interface.
2131 * @type: nl80211 interface type. 2236 * @type: nl80211 interface type.
2132 * @flags: TBD 2237 * @flags: not used.
2133 * @params: TBD 2238 * @params: contains mac address for P2P device.
2134 */ 2239 */
2135struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, 2240struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2136 enum nl80211_iftype type, u32 *flags, 2241 enum nl80211_iftype type, u32 *flags,
@@ -2157,6 +2262,9 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2157 iftype = BRCMF_FIL_P2P_IF_GO; 2262 iftype = BRCMF_FIL_P2P_IF_GO;
2158 mode = WL_MODE_AP; 2263 mode = WL_MODE_AP;
2159 break; 2264 break;
2265 case NL80211_IFTYPE_P2P_DEVICE:
2266 return brcmf_p2p_create_p2pdev(&cfg->p2p, wiphy,
2267 params->macaddr);
2160 default: 2268 default:
2161 return ERR_PTR(-EOPNOTSUPP); 2269 return ERR_PTR(-EOPNOTSUPP);
2162 } 2270 }
@@ -2244,6 +2352,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2244 break; 2352 break;
2245 2353
2246 case NL80211_IFTYPE_P2P_DEVICE: 2354 case NL80211_IFTYPE_P2P_DEVICE:
2355 brcmf_p2p_delete_p2pdev(vif);
2356 return 0;
2247 default: 2357 default:
2248 return -ENOTSUPP; 2358 return -ENOTSUPP;
2249 break; 2359 break;
@@ -2275,3 +2385,33 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2275 2385
2276 return err; 2386 return err;
2277} 2387}
2388
2389int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev)
2390{
2391 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2392 struct brcmf_p2p_info *p2p = &cfg->p2p;
2393 struct brcmf_cfg80211_vif *vif;
2394 int err;
2395
2396 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
2397 mutex_lock(&cfg->usr_sync);
2398 err = brcmf_p2p_enable_discovery(p2p);
2399 if (!err)
2400 set_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state);
2401 mutex_unlock(&cfg->usr_sync);
2402 return err;
2403}
2404
2405void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev)
2406{
2407 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2408 struct brcmf_p2p_info *p2p = &cfg->p2p;
2409 struct brcmf_cfg80211_vif *vif;
2410
2411 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
2412 mutex_lock(&cfg->usr_sync);
2413 (void)brcmf_p2p_deinit_discovery(p2p);
2414 brcmf_abort_scanning(cfg);
2415 clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state);
2416 mutex_unlock(&cfg->usr_sync);
2417}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
index 35efc7a67644..9df1f7a681e0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
@@ -73,6 +73,20 @@ TRACE_EVENT(brcmf_dbg,
73 TP_printk("%s: %s", __get_str(func), __get_str(msg)) 73 TP_printk("%s: %s", __get_str(func), __get_str(msg))
74); 74);
75 75
76TRACE_EVENT(brcmf_hexdump,
77 TP_PROTO(void *data, size_t len),
78 TP_ARGS(data, len),
79 TP_STRUCT__entry(
80 __field(unsigned long, len)
81 __dynamic_array(u8, hdata, len)
82 ),
83 TP_fast_assign(
84 __entry->len = len;
85 memcpy(__get_dynamic_array(hdata), data, len);
86 ),
87 TP_printk("hexdump [length=%lu]", __entry->len)
88);
89
76#ifdef CONFIG_BRCM_TRACING 90#ifdef CONFIG_BRCM_TRACING
77 91
78#undef TRACE_INCLUDE_PATH 92#undef TRACE_INCLUDE_PATH
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 804473fc5c5e..62699203869d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -26,6 +26,7 @@
26#include <brcmu_wifi.h> 26#include <brcmu_wifi.h>
27#include "dhd.h" 27#include "dhd.h"
28#include "dhd_dbg.h" 28#include "dhd_dbg.h"
29#include "tracepoint.h"
29#include "fwil_types.h" 30#include "fwil_types.h"
30#include "p2p.h" 31#include "p2p.h"
31#include "wl_cfg80211.h" 32#include "wl_cfg80211.h"
@@ -182,64 +183,6 @@ static struct ieee80211_channel __wl_5ghz_a_channels[] = {
182 CHAN5G(216, 0), 183 CHAN5G(216, 0),
183}; 184};
184 185
185static struct ieee80211_channel __wl_5ghz_n_channels[] = {
186 CHAN5G(32, 0), CHAN5G(34, 0),
187 CHAN5G(36, 0), CHAN5G(38, 0),
188 CHAN5G(40, 0), CHAN5G(42, 0),
189 CHAN5G(44, 0), CHAN5G(46, 0),
190 CHAN5G(48, 0), CHAN5G(50, 0),
191 CHAN5G(52, 0), CHAN5G(54, 0),
192 CHAN5G(56, 0), CHAN5G(58, 0),
193 CHAN5G(60, 0), CHAN5G(62, 0),
194 CHAN5G(64, 0), CHAN5G(66, 0),
195 CHAN5G(68, 0), CHAN5G(70, 0),
196 CHAN5G(72, 0), CHAN5G(74, 0),
197 CHAN5G(76, 0), CHAN5G(78, 0),
198 CHAN5G(80, 0), CHAN5G(82, 0),
199 CHAN5G(84, 0), CHAN5G(86, 0),
200 CHAN5G(88, 0), CHAN5G(90, 0),
201 CHAN5G(92, 0), CHAN5G(94, 0),
202 CHAN5G(96, 0), CHAN5G(98, 0),
203 CHAN5G(100, 0), CHAN5G(102, 0),
204 CHAN5G(104, 0), CHAN5G(106, 0),
205 CHAN5G(108, 0), CHAN5G(110, 0),
206 CHAN5G(112, 0), CHAN5G(114, 0),
207 CHAN5G(116, 0), CHAN5G(118, 0),
208 CHAN5G(120, 0), CHAN5G(122, 0),
209 CHAN5G(124, 0), CHAN5G(126, 0),
210 CHAN5G(128, 0), CHAN5G(130, 0),
211 CHAN5G(132, 0), CHAN5G(134, 0),
212 CHAN5G(136, 0), CHAN5G(138, 0),
213 CHAN5G(140, 0), CHAN5G(142, 0),
214 CHAN5G(144, 0), CHAN5G(145, 0),
215 CHAN5G(146, 0), CHAN5G(147, 0),
216 CHAN5G(148, 0), CHAN5G(149, 0),
217 CHAN5G(150, 0), CHAN5G(151, 0),
218 CHAN5G(152, 0), CHAN5G(153, 0),
219 CHAN5G(154, 0), CHAN5G(155, 0),
220 CHAN5G(156, 0), CHAN5G(157, 0),
221 CHAN5G(158, 0), CHAN5G(159, 0),
222 CHAN5G(160, 0), CHAN5G(161, 0),
223 CHAN5G(162, 0), CHAN5G(163, 0),
224 CHAN5G(164, 0), CHAN5G(165, 0),
225 CHAN5G(166, 0), CHAN5G(168, 0),
226 CHAN5G(170, 0), CHAN5G(172, 0),
227 CHAN5G(174, 0), CHAN5G(176, 0),
228 CHAN5G(178, 0), CHAN5G(180, 0),
229 CHAN5G(182, 0), CHAN5G(184, 0),
230 CHAN5G(186, 0), CHAN5G(188, 0),
231 CHAN5G(190, 0), CHAN5G(192, 0),
232 CHAN5G(194, 0), CHAN5G(196, 0),
233 CHAN5G(198, 0), CHAN5G(200, 0),
234 CHAN5G(202, 0), CHAN5G(204, 0),
235 CHAN5G(206, 0), CHAN5G(208, 0),
236 CHAN5G(210, 0), CHAN5G(212, 0),
237 CHAN5G(214, 0), CHAN5G(216, 0),
238 CHAN5G(218, 0), CHAN5G(220, 0),
239 CHAN5G(222, 0), CHAN5G(224, 0),
240 CHAN5G(226, 0), CHAN5G(228, 0),
241};
242
243static struct ieee80211_supported_band __wl_band_2ghz = { 186static struct ieee80211_supported_band __wl_band_2ghz = {
244 .band = IEEE80211_BAND_2GHZ, 187 .band = IEEE80211_BAND_2GHZ,
245 .channels = __wl_2ghz_channels, 188 .channels = __wl_2ghz_channels,
@@ -256,12 +199,28 @@ static struct ieee80211_supported_band __wl_band_5ghz_a = {
256 .n_bitrates = wl_a_rates_size, 199 .n_bitrates = wl_a_rates_size,
257}; 200};
258 201
259static struct ieee80211_supported_band __wl_band_5ghz_n = { 202/* This is to override regulatory domains defined in cfg80211 module (reg.c)
260 .band = IEEE80211_BAND_5GHZ, 203 * By default world regulatory domain defined in reg.c puts the flags
261 .channels = __wl_5ghz_n_channels, 204 * NL80211_RRF_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for
262 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels), 205 * 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't
263 .bitrates = wl_a_rates, 206 * start p2p operations on 5GHz channels. All the changes in world regulatory
264 .n_bitrates = wl_a_rates_size, 207 * domain are to be done here.
208 */
209static const struct ieee80211_regdomain brcmf_regdom = {
210 .n_reg_rules = 4,
211 .alpha2 = "99",
212 .reg_rules = {
213 /* IEEE 802.11b/g, channels 1..11 */
214 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
215 /* If any */
216 /* IEEE 802.11 channel 14 - Only JP enables
217 * this and for 802.11b only
218 */
219 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
220 /* IEEE 802.11a, channel 36..64 */
221 REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
222 /* IEEE 802.11a, channel 100..165 */
223 REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
265}; 224};
266 225
267static const u32 __wl_cipher_suites[] = { 226static const u32 __wl_cipher_suites[] = {
@@ -523,17 +482,16 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
523 return ERR_PTR(-EOPNOTSUPP); 482 return ERR_PTR(-EOPNOTSUPP);
524 case NL80211_IFTYPE_P2P_CLIENT: 483 case NL80211_IFTYPE_P2P_CLIENT:
525 case NL80211_IFTYPE_P2P_GO: 484 case NL80211_IFTYPE_P2P_GO:
485 case NL80211_IFTYPE_P2P_DEVICE:
526 return brcmf_p2p_add_vif(wiphy, name, type, flags, params); 486 return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
527 case NL80211_IFTYPE_UNSPECIFIED: 487 case NL80211_IFTYPE_UNSPECIFIED:
528 case NL80211_IFTYPE_P2P_DEVICE:
529 default: 488 default:
530 return ERR_PTR(-EINVAL); 489 return ERR_PTR(-EINVAL);
531 } 490 }
532} 491}
533 492
534void brcmf_set_mpc(struct net_device *ndev, int mpc) 493void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
535{ 494{
536 struct brcmf_if *ifp = netdev_priv(ndev);
537 s32 err = 0; 495 s32 err = 0;
538 496
539 if (check_vif_up(ifp->vif)) { 497 if (check_vif_up(ifp->vif)) {
@@ -546,10 +504,9 @@ void brcmf_set_mpc(struct net_device *ndev, int mpc)
546 } 504 }
547} 505}
548 506
549s32 507s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
550brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, 508 struct brcmf_if *ifp, bool aborted,
551 struct net_device *ndev, 509 bool fw_abort)
552 bool aborted, bool fw_abort)
553{ 510{
554 struct brcmf_scan_params_le params_le; 511 struct brcmf_scan_params_le params_le;
555 struct cfg80211_scan_request *scan_request; 512 struct cfg80211_scan_request *scan_request;
@@ -580,7 +537,7 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
580 /* Scan is aborted by setting channel_list[0] to -1 */ 537 /* Scan is aborted by setting channel_list[0] to -1 */
581 params_le.channel_list[0] = cpu_to_le16(-1); 538 params_le.channel_list[0] = cpu_to_le16(-1);
582 /* E-Scan (or anyother type) can be aborted by SCAN */ 539 /* E-Scan (or anyother type) can be aborted by SCAN */
583 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN, 540 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
584 &params_le, sizeof(params_le)); 541 &params_le, sizeof(params_le));
585 if (err) 542 if (err)
586 brcmf_err("Scan abort failed\n"); 543 brcmf_err("Scan abort failed\n");
@@ -594,12 +551,12 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
594 cfg->sched_escan = false; 551 cfg->sched_escan = false;
595 if (!aborted) 552 if (!aborted)
596 cfg80211_sched_scan_results(cfg_to_wiphy(cfg)); 553 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
597 brcmf_set_mpc(ndev, 1); 554 brcmf_set_mpc(ifp, 1);
598 } else if (scan_request) { 555 } else if (scan_request) {
599 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n", 556 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
600 aborted ? "Aborted" : "Done"); 557 aborted ? "Aborted" : "Done");
601 cfg80211_scan_done(scan_request, aborted); 558 cfg80211_scan_done(scan_request, aborted);
602 brcmf_set_mpc(ndev, 1); 559 brcmf_set_mpc(ifp, 1);
603 } 560 }
604 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) 561 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
605 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n"); 562 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
@@ -619,9 +576,9 @@ int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
619 576
620 if (ndev) { 577 if (ndev) {
621 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) && 578 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
622 cfg->escan_info.ndev == ndev) 579 cfg->escan_info.ifp == netdev_priv(ndev))
623 brcmf_notify_escan_complete(cfg, ndev, true, 580 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
624 true); 581 true, true);
625 582
626 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1); 583 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
627 } 584 }
@@ -637,9 +594,9 @@ int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
637 return -EOPNOTSUPP; 594 return -EOPNOTSUPP;
638 case NL80211_IFTYPE_P2P_CLIENT: 595 case NL80211_IFTYPE_P2P_CLIENT:
639 case NL80211_IFTYPE_P2P_GO: 596 case NL80211_IFTYPE_P2P_GO:
597 case NL80211_IFTYPE_P2P_DEVICE:
640 return brcmf_p2p_del_vif(wiphy, wdev); 598 return brcmf_p2p_del_vif(wiphy, wdev);
641 case NL80211_IFTYPE_UNSPECIFIED: 599 case NL80211_IFTYPE_UNSPECIFIED:
642 case NL80211_IFTYPE_P2P_DEVICE:
643 default: 600 default:
644 return -EINVAL; 601 return -EINVAL;
645 } 602 }
@@ -803,7 +760,7 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
803} 760}
804 761
805static s32 762static s32
806brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev, 763brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
807 struct cfg80211_scan_request *request, u16 action) 764 struct cfg80211_scan_request *request, u16 action)
808{ 765{
809 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE + 766 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
@@ -832,8 +789,7 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
832 params->action = cpu_to_le16(action); 789 params->action = cpu_to_le16(action);
833 params->sync_id = cpu_to_le16(0x1234); 790 params->sync_id = cpu_to_le16(0x1234);
834 791
835 err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan", 792 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
836 params, params_size);
837 if (err) { 793 if (err) {
838 if (err == -EBUSY) 794 if (err == -EBUSY)
839 brcmf_dbg(INFO, "system busy : escan canceled\n"); 795 brcmf_dbg(INFO, "system busy : escan canceled\n");
@@ -848,7 +804,7 @@ exit:
848 804
849static s32 805static s32
850brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy, 806brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
851 struct net_device *ndev, struct cfg80211_scan_request *request) 807 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
852{ 808{
853 s32 err; 809 s32 err;
854 u32 passive_scan; 810 u32 passive_scan;
@@ -856,35 +812,35 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
856 struct escan_info *escan = &cfg->escan_info; 812 struct escan_info *escan = &cfg->escan_info;
857 813
858 brcmf_dbg(SCAN, "Enter\n"); 814 brcmf_dbg(SCAN, "Enter\n");
859 escan->ndev = ndev; 815 escan->ifp = ifp;
860 escan->wiphy = wiphy; 816 escan->wiphy = wiphy;
861 escan->escan_state = WL_ESCAN_STATE_SCANNING; 817 escan->escan_state = WL_ESCAN_STATE_SCANNING;
862 passive_scan = cfg->active_scan ? 0 : 1; 818 passive_scan = cfg->active_scan ? 0 : 1;
863 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN, 819 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
864 passive_scan); 820 passive_scan);
865 if (err) { 821 if (err) {
866 brcmf_err("error (%d)\n", err); 822 brcmf_err("error (%d)\n", err);
867 return err; 823 return err;
868 } 824 }
869 brcmf_set_mpc(ndev, 0); 825 brcmf_set_mpc(ifp, 0);
870 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf; 826 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
871 results->version = 0; 827 results->version = 0;
872 results->count = 0; 828 results->count = 0;
873 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE; 829 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
874 830
875 err = escan->run(cfg, ndev, request, WL_ESCAN_ACTION_START); 831 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
876 if (err) 832 if (err)
877 brcmf_set_mpc(ndev, 1); 833 brcmf_set_mpc(ifp, 1);
878 return err; 834 return err;
879} 835}
880 836
881static s32 837static s32
882brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, 838brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
883 struct cfg80211_scan_request *request, 839 struct cfg80211_scan_request *request,
884 struct cfg80211_ssid *this_ssid) 840 struct cfg80211_ssid *this_ssid)
885{ 841{
886 struct brcmf_if *ifp = netdev_priv(ndev); 842 struct brcmf_if *ifp = vif->ifp;
887 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); 843 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
888 struct cfg80211_ssid *ssids; 844 struct cfg80211_ssid *ssids;
889 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int; 845 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
890 u32 passive_scan; 846 u32 passive_scan;
@@ -910,10 +866,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
910 } 866 }
911 867
912 /* If scan req comes for p2p0, send it over primary I/F */ 868 /* If scan req comes for p2p0, send it over primary I/F */
913 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) { 869 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
914 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; 870 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
915 ndev = ifp->ndev;
916 }
917 871
918 /* Arm scan timeout timer */ 872 /* Arm scan timeout timer */
919 mod_timer(&cfg->escan_timeout, jiffies + 873 mod_timer(&cfg->escan_timeout, jiffies +
@@ -934,11 +888,11 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
934 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 888 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
935 if (escan_req) { 889 if (escan_req) {
936 cfg->escan_info.run = brcmf_run_escan; 890 cfg->escan_info.run = brcmf_run_escan;
937 err = brcmf_p2p_scan_prep(wiphy, request, ifp->vif); 891 err = brcmf_p2p_scan_prep(wiphy, request, vif);
938 if (err) 892 if (err)
939 goto scan_out; 893 goto scan_out;
940 894
941 err = brcmf_do_escan(cfg, wiphy, ndev, request); 895 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
942 if (err) 896 if (err)
943 goto scan_out; 897 goto scan_out;
944 } else { 898 } else {
@@ -962,7 +916,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
962 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err); 916 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
963 goto scan_out; 917 goto scan_out;
964 } 918 }
965 brcmf_set_mpc(ndev, 0); 919 brcmf_set_mpc(ifp, 0);
966 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, 920 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
967 &sr->ssid_le, sizeof(sr->ssid_le)); 921 &sr->ssid_le, sizeof(sr->ssid_le));
968 if (err) { 922 if (err) {
@@ -972,7 +926,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
972 else 926 else
973 brcmf_err("WLC_SCAN error (%d)\n", err); 927 brcmf_err("WLC_SCAN error (%d)\n", err);
974 928
975 brcmf_set_mpc(ndev, 1); 929 brcmf_set_mpc(ifp, 1);
976 goto scan_out; 930 goto scan_out;
977 } 931 }
978 } 932 }
@@ -990,16 +944,15 @@ scan_out:
990static s32 944static s32
991brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) 945brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
992{ 946{
993 struct net_device *ndev = request->wdev->netdev; 947 struct brcmf_cfg80211_vif *vif;
994 s32 err = 0; 948 s32 err = 0;
995 949
996 brcmf_dbg(TRACE, "Enter\n"); 950 brcmf_dbg(TRACE, "Enter\n");
997 951 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
998 if (!check_vif_up(container_of(request->wdev, 952 if (!check_vif_up(vif))
999 struct brcmf_cfg80211_vif, wdev)))
1000 return -EIO; 953 return -EIO;
1001 954
1002 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL); 955 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1003 956
1004 if (err) 957 if (err)
1005 brcmf_err("scan error (%d)\n", err); 958 brcmf_err("scan error (%d)\n", err);
@@ -1891,8 +1844,10 @@ static s32
1891brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, 1844brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1892 u8 key_idx, const u8 *mac_addr, struct key_params *params) 1845 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1893{ 1846{
1847 struct brcmf_if *ifp = netdev_priv(ndev);
1894 struct brcmf_wsec_key key; 1848 struct brcmf_wsec_key key;
1895 s32 err = 0; 1849 s32 err = 0;
1850 u8 keybuf[8];
1896 1851
1897 memset(&key, 0, sizeof(key)); 1852 memset(&key, 0, sizeof(key));
1898 key.index = (u32) key_idx; 1853 key.index = (u32) key_idx;
@@ -1916,8 +1871,9 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1916 brcmf_dbg(CONN, "Setting the key index %d\n", key.index); 1871 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1917 memcpy(key.data, params->key, key.len); 1872 memcpy(key.data, params->key, key.len);
1918 1873
1919 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) { 1874 if ((ifp->vif->mode != WL_MODE_AP) &&
1920 u8 keybuf[8]; 1875 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
1876 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
1921 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 1877 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1922 memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); 1878 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1923 memcpy(&key.data[16], keybuf, sizeof(keybuf)); 1879 memcpy(&key.data[16], keybuf, sizeof(keybuf));
@@ -2013,7 +1969,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2013 break; 1969 break;
2014 case WLAN_CIPHER_SUITE_TKIP: 1970 case WLAN_CIPHER_SUITE_TKIP:
2015 if (ifp->vif->mode != WL_MODE_AP) { 1971 if (ifp->vif->mode != WL_MODE_AP) {
2016 brcmf_dbg(CONN, "Swapping key\n"); 1972 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2017 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 1973 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2018 memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); 1974 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2019 memcpy(&key.data[16], keybuf, sizeof(keybuf)); 1975 memcpy(&key.data[16], keybuf, sizeof(keybuf));
@@ -2118,8 +2074,7 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2118 err = -EAGAIN; 2074 err = -EAGAIN;
2119 goto done; 2075 goto done;
2120 } 2076 }
2121 switch (wsec & ~SES_OW_ENABLED) { 2077 if (wsec & WEP_ENABLED) {
2122 case WEP_ENABLED:
2123 sec = &profile->sec; 2078 sec = &profile->sec;
2124 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { 2079 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2125 params.cipher = WLAN_CIPHER_SUITE_WEP40; 2080 params.cipher = WLAN_CIPHER_SUITE_WEP40;
@@ -2128,16 +2083,13 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2128 params.cipher = WLAN_CIPHER_SUITE_WEP104; 2083 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2129 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n"); 2084 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2130 } 2085 }
2131 break; 2086 } else if (wsec & TKIP_ENABLED) {
2132 case TKIP_ENABLED:
2133 params.cipher = WLAN_CIPHER_SUITE_TKIP; 2087 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2134 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n"); 2088 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2135 break; 2089 } else if (wsec & AES_ENABLED) {
2136 case AES_ENABLED:
2137 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; 2090 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2138 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); 2091 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2139 break; 2092 } else {
2140 default:
2141 brcmf_err("Invalid algo (0x%x)\n", wsec); 2093 brcmf_err("Invalid algo (0x%x)\n", wsec);
2142 err = -EINVAL; 2094 err = -EINVAL;
2143 goto done; 2095 goto done;
@@ -2511,7 +2463,7 @@ void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2511 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); 2463 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2512 if (cfg->scan_request) { 2464 if (cfg->scan_request) {
2513 escan->escan_state = WL_ESCAN_STATE_IDLE; 2465 escan->escan_state = WL_ESCAN_STATE_IDLE;
2514 brcmf_notify_escan_complete(cfg, escan->ndev, true, true); 2466 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2515 } 2467 }
2516 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 2468 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2517 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); 2469 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
@@ -2523,7 +2475,7 @@ static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2523 container_of(work, struct brcmf_cfg80211_info, 2475 container_of(work, struct brcmf_cfg80211_info,
2524 escan_timeout_work); 2476 escan_timeout_work);
2525 2477
2526 brcmf_notify_escan_complete(cfg, cfg->escan_info.ndev, true, true); 2478 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2527} 2479}
2528 2480
2529static void brcmf_escan_timeout(unsigned long data) 2481static void brcmf_escan_timeout(unsigned long data)
@@ -2574,7 +2526,6 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2574 const struct brcmf_event_msg *e, void *data) 2526 const struct brcmf_event_msg *e, void *data)
2575{ 2527{
2576 struct brcmf_cfg80211_info *cfg = ifp->drvr->config; 2528 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2577 struct net_device *ndev = ifp->ndev;
2578 s32 status; 2529 s32 status;
2579 s32 err = 0; 2530 s32 err = 0;
2580 struct brcmf_escan_result_le *escan_result_le; 2531 struct brcmf_escan_result_le *escan_result_le;
@@ -2587,9 +2538,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2587 2538
2588 status = e->status; 2539 status = e->status;
2589 2540
2590 if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { 2541 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2591 brcmf_err("scan not ready ndev %p drv_status %x\n", ndev, 2542 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2592 !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2593 return -EPERM; 2543 return -EPERM;
2594 } 2544 }
2595 2545
@@ -2660,7 +2610,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2660 cfg->escan_info.escan_buf; 2610 cfg->escan_info.escan_buf;
2661 brcmf_inform_bss(cfg); 2611 brcmf_inform_bss(cfg);
2662 aborted = status != BRCMF_E_STATUS_SUCCESS; 2612 aborted = status != BRCMF_E_STATUS_SUCCESS;
2663 brcmf_notify_escan_complete(cfg, ndev, aborted, 2613 brcmf_notify_escan_complete(cfg, ifp, aborted,
2664 false); 2614 false);
2665 } else 2615 } else
2666 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n", 2616 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
@@ -2738,7 +2688,7 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2738 brcmf_abort_scanning(cfg); 2688 brcmf_abort_scanning(cfg);
2739 2689
2740 /* Turn off watchdog timer */ 2690 /* Turn off watchdog timer */
2741 brcmf_set_mpc(ndev, 1); 2691 brcmf_set_mpc(netdev_priv(ndev), 1);
2742 2692
2743exit: 2693exit:
2744 brcmf_dbg(TRACE, "Exit\n"); 2694 brcmf_dbg(TRACE, "Exit\n");
@@ -2896,7 +2846,6 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2896 const struct brcmf_event_msg *e, void *data) 2846 const struct brcmf_event_msg *e, void *data)
2897{ 2847{
2898 struct brcmf_cfg80211_info *cfg = ifp->drvr->config; 2848 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2899 struct net_device *ndev = ifp->ndev;
2900 struct brcmf_pno_net_info_le *netinfo, *netinfo_start; 2849 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2901 struct cfg80211_scan_request *request = NULL; 2850 struct cfg80211_scan_request *request = NULL;
2902 struct cfg80211_ssid *ssid = NULL; 2851 struct cfg80211_ssid *ssid = NULL;
@@ -2980,7 +2929,7 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2980 } 2929 }
2981 2930
2982 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 2931 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2983 err = brcmf_do_escan(cfg, wiphy, ndev, request); 2932 err = brcmf_do_escan(cfg, wiphy, ifp, request);
2984 if (err) { 2933 if (err) {
2985 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 2934 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2986 goto out_err; 2935 goto out_err;
@@ -3137,7 +3086,7 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3137 brcmf_dbg(SCAN, "enter\n"); 3086 brcmf_dbg(SCAN, "enter\n");
3138 brcmf_dev_pno_clean(ndev); 3087 brcmf_dev_pno_clean(ndev);
3139 if (cfg->sched_escan) 3088 if (cfg->sched_escan)
3140 brcmf_notify_escan_complete(cfg, ndev, true, true); 3089 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3141 return 0; 3090 return 0;
3142} 3091}
3143 3092
@@ -3709,7 +3658,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3709 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len); 3658 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3710 } 3659 }
3711 3660
3712 brcmf_set_mpc(ndev, 0); 3661 brcmf_set_mpc(ifp, 0);
3713 3662
3714 /* find the RSN_IE */ 3663 /* find the RSN_IE */
3715 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, 3664 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
@@ -3817,15 +3766,16 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3817 3766
3818exit: 3767exit:
3819 if (err) 3768 if (err)
3820 brcmf_set_mpc(ndev, 1); 3769 brcmf_set_mpc(ifp, 1);
3821 return err; 3770 return err;
3822} 3771}
3823 3772
3824static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) 3773static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3825{ 3774{
3826 struct brcmf_if *ifp = netdev_priv(ndev); 3775 struct brcmf_if *ifp = netdev_priv(ndev);
3827 s32 err = -EPERM; 3776 s32 err;
3828 struct brcmf_fil_bss_enable_le bss_enable; 3777 struct brcmf_fil_bss_enable_le bss_enable;
3778 struct brcmf_join_params join_params;
3829 3779
3830 brcmf_dbg(TRACE, "Enter\n"); 3780 brcmf_dbg(TRACE, "Enter\n");
3831 3781
@@ -3833,16 +3783,21 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3833 /* Due to most likely deauths outstanding we sleep */ 3783 /* Due to most likely deauths outstanding we sleep */
3834 /* first to make sure they get processed by fw. */ 3784 /* first to make sure they get processed by fw. */
3835 msleep(400); 3785 msleep(400);
3836 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0); 3786
3837 if (err < 0) { 3787 memset(&join_params, 0, sizeof(join_params));
3838 brcmf_err("setting AP mode failed %d\n", err); 3788 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3839 goto exit; 3789 &join_params, sizeof(join_params));
3840 } 3790 if (err < 0)
3791 brcmf_err("SET SSID error (%d)\n", err);
3841 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); 3792 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3842 if (err < 0) { 3793 if (err < 0)
3843 brcmf_err("BRCMF_C_UP error %d\n", err); 3794 brcmf_err("BRCMF_C_UP error %d\n", err);
3844 goto exit; 3795 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3845 } 3796 if (err < 0)
3797 brcmf_err("setting AP mode failed %d\n", err);
3798 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3799 if (err < 0)
3800 brcmf_err("setting INFRA mode failed %d\n", err);
3846 } else { 3801 } else {
3847 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx); 3802 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3848 bss_enable.enable = cpu_to_le32(0); 3803 bss_enable.enable = cpu_to_le32(0);
@@ -3851,11 +3806,10 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3851 if (err < 0) 3806 if (err < 0)
3852 brcmf_err("bss_enable config failed %d\n", err); 3807 brcmf_err("bss_enable config failed %d\n", err);
3853 } 3808 }
3854 brcmf_set_mpc(ndev, 1); 3809 brcmf_set_mpc(ifp, 1);
3855 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); 3810 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3856 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); 3811 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3857 3812
3858exit:
3859 return err; 3813 return err;
3860} 3814}
3861 3815
@@ -3909,13 +3863,13 @@ brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3909 struct wireless_dev *wdev, 3863 struct wireless_dev *wdev,
3910 u16 frame_type, bool reg) 3864 u16 frame_type, bool reg)
3911{ 3865{
3912 struct brcmf_if *ifp = netdev_priv(wdev->netdev); 3866 struct brcmf_cfg80211_vif *vif;
3913 struct brcmf_cfg80211_vif *vif = ifp->vif;
3914 u16 mgmt_type; 3867 u16 mgmt_type;
3915 3868
3916 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg); 3869 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3917 3870
3918 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4; 3871 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3872 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
3919 if (reg) 3873 if (reg)
3920 vif->mgmt_rx_reg |= BIT(mgmt_type); 3874 vif->mgmt_rx_reg |= BIT(mgmt_type);
3921 else 3875 else
@@ -3931,7 +3885,6 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3931{ 3885{
3932 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 3886 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3933 const struct ieee80211_mgmt *mgmt; 3887 const struct ieee80211_mgmt *mgmt;
3934 struct brcmf_if *ifp;
3935 struct brcmf_cfg80211_vif *vif; 3888 struct brcmf_cfg80211_vif *vif;
3936 s32 err = 0; 3889 s32 err = 0;
3937 s32 ie_offset; 3890 s32 ie_offset;
@@ -3967,8 +3920,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3967 ie_offset = DOT11_MGMT_HDR_LEN + 3920 ie_offset = DOT11_MGMT_HDR_LEN +
3968 DOT11_BCN_PRB_FIXED_LEN; 3921 DOT11_BCN_PRB_FIXED_LEN;
3969 ie_len = len - ie_offset; 3922 ie_len = len - ie_offset;
3970 ifp = netdev_priv(wdev->netdev); 3923 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
3971 vif = ifp->vif;
3972 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) 3924 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
3973 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif; 3925 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
3974 err = brcmf_vif_set_mgmt_ie(vif, 3926 err = brcmf_vif_set_mgmt_ie(vif,
@@ -4003,7 +3955,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4003 *cookie, le16_to_cpu(action_frame->len), 3955 *cookie, le16_to_cpu(action_frame->len),
4004 chan->center_freq); 3956 chan->center_freq);
4005 3957
4006 ack = brcmf_p2p_send_action_frame(cfg, wdev->netdev, 3958 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4007 af_params); 3959 af_params);
4008 3960
4009 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack, 3961 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
@@ -4075,6 +4027,8 @@ static struct cfg80211_ops wl_cfg80211_ops = {
4075 .mgmt_tx = brcmf_cfg80211_mgmt_tx, 4027 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4076 .remain_on_channel = brcmf_p2p_remain_on_channel, 4028 .remain_on_channel = brcmf_p2p_remain_on_channel,
4077 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel, 4029 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4030 .start_p2p_device = brcmf_p2p_start_device,
4031 .stop_p2p_device = brcmf_p2p_stop_device,
4078#ifdef CONFIG_NL80211_TESTMODE 4032#ifdef CONFIG_NL80211_TESTMODE
4079 .testmode_cmd = brcmf_cfg80211_testmode 4033 .testmode_cmd = brcmf_cfg80211_testmode
4080#endif 4034#endif
@@ -4162,6 +4116,11 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4162 BIT(IEEE80211_STYPE_AUTH >> 4) | 4116 BIT(IEEE80211_STYPE_AUTH >> 4) |
4163 BIT(IEEE80211_STYPE_DEAUTH >> 4) | 4117 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4164 BIT(IEEE80211_STYPE_ACTION >> 4) 4118 BIT(IEEE80211_STYPE_ACTION >> 4)
4119 },
4120 [NL80211_IFTYPE_P2P_DEVICE] = {
4121 .tx = 0xffff,
4122 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4123 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4165 } 4124 }
4166}; 4125};
4167 4126
@@ -4188,13 +4147,6 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4188 wiphy->iface_combinations = brcmf_iface_combos; 4147 wiphy->iface_combinations = brcmf_iface_combos;
4189 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); 4148 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4190 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; 4149 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4191 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
4192 * it as 11a by default.
4193 * This will be updated with
4194 * 11n phy tables in
4195 * "ifconfig up"
4196 * if phy has 11n capability
4197 */
4198 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 4150 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4199 wiphy->cipher_suites = __wl_cipher_suites; 4151 wiphy->cipher_suites = __wl_cipher_suites;
4200 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); 4152 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
@@ -4204,6 +4156,9 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4204 wiphy->mgmt_stypes = brcmf_txrx_stypes; 4156 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4205 wiphy->max_remain_on_channel_duration = 5000; 4157 wiphy->max_remain_on_channel_duration = 5000;
4206 brcmf_wiphy_pno_params(wiphy); 4158 brcmf_wiphy_pno_params(wiphy);
4159 brcmf_dbg(INFO, "Registering custom regulatory\n");
4160 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
4161 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4207 err = wiphy_register(wiphy); 4162 err = wiphy_register(wiphy);
4208 if (err < 0) { 4163 if (err < 0) {
4209 brcmf_err("Could not register wiphy device (%d)\n", err); 4164 brcmf_err("Could not register wiphy device (%d)\n", err);
@@ -4622,9 +4577,11 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4622 4577
4623 ifp->vif = vif; 4578 ifp->vif = vif;
4624 vif->ifp = ifp; 4579 vif->ifp = ifp;
4625 vif->wdev.netdev = ifp->ndev; 4580 if (ifp->ndev) {
4626 ifp->ndev->ieee80211_ptr = &vif->wdev; 4581 vif->wdev.netdev = ifp->ndev;
4627 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy)); 4582 ifp->ndev->ieee80211_ptr = &vif->wdev;
4583 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4584 }
4628 mutex_unlock(&event->vif_event_lock); 4585 mutex_unlock(&event->vif_event_lock);
4629 wake_up(&event->vif_wq); 4586 wake_up(&event->vif_wq);
4630 return 0; 4587 return 0;
@@ -4927,34 +4884,248 @@ dongle_scantime_out:
4927 return err; 4884 return err;
4928} 4885}
4929 4886
4930static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg) 4887
4888static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
4889{
4890 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4891 struct ieee80211_channel *band_chan_arr;
4892 struct brcmf_chanspec_list *list;
4893 s32 err;
4894 u8 *pbuf;
4895 u32 i, j;
4896 u32 total;
4897 u16 chanspec;
4898 enum ieee80211_band band;
4899 u32 channel;
4900 u32 *n_cnt;
4901 bool ht40_allowed;
4902 u32 index;
4903 u32 ht40_flag;
4904 bool update;
4905 u32 array_size;
4906
4907 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4908
4909 if (pbuf == NULL)
4910 return -ENOMEM;
4911
4912 list = (struct brcmf_chanspec_list *)pbuf;
4913
4914 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
4915 BRCMF_DCMD_MEDLEN);
4916 if (err) {
4917 brcmf_err("get chanspecs error (%d)\n", err);
4918 goto exit;
4919 }
4920
4921 __wl_band_2ghz.n_channels = 0;
4922 __wl_band_5ghz_a.n_channels = 0;
4923
4924 total = le32_to_cpu(list->count);
4925 for (i = 0; i < total; i++) {
4926 chanspec = (u16)le32_to_cpu(list->element[i]);
4927 channel = CHSPEC_CHANNEL(chanspec);
4928
4929 if (CHSPEC_IS40(chanspec)) {
4930 if (CHSPEC_SB_UPPER(chanspec))
4931 channel += CH_10MHZ_APART;
4932 else
4933 channel -= CH_10MHZ_APART;
4934 } else if (CHSPEC_IS80(chanspec)) {
4935 brcmf_dbg(INFO, "HT80 center channel : %d\n",
4936 channel);
4937 continue;
4938 }
4939 if (CHSPEC_IS2G(chanspec) && (channel >= CH_MIN_2G_CHANNEL) &&
4940 (channel <= CH_MAX_2G_CHANNEL)) {
4941 band_chan_arr = __wl_2ghz_channels;
4942 array_size = ARRAY_SIZE(__wl_2ghz_channels);
4943 n_cnt = &__wl_band_2ghz.n_channels;
4944 band = IEEE80211_BAND_2GHZ;
4945 ht40_allowed = (bw_cap == WLC_N_BW_40ALL);
4946 } else if (CHSPEC_IS5G(chanspec) &&
4947 channel >= CH_MIN_5G_CHANNEL) {
4948 band_chan_arr = __wl_5ghz_a_channels;
4949 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
4950 n_cnt = &__wl_band_5ghz_a.n_channels;
4951 band = IEEE80211_BAND_5GHZ;
4952 ht40_allowed = !(bw_cap == WLC_N_BW_20ALL);
4953 } else {
4954 brcmf_err("Invalid channel Sepc. 0x%x.\n", chanspec);
4955 continue;
4956 }
4957 if (!ht40_allowed && CHSPEC_IS40(chanspec))
4958 continue;
4959 update = false;
4960 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
4961 if (band_chan_arr[j].hw_value == channel) {
4962 update = true;
4963 break;
4964 }
4965 }
4966 if (update)
4967 index = j;
4968 else
4969 index = *n_cnt;
4970 if (index < array_size) {
4971 band_chan_arr[index].center_freq =
4972 ieee80211_channel_to_frequency(channel, band);
4973 band_chan_arr[index].hw_value = channel;
4974
4975 if (CHSPEC_IS40(chanspec) && ht40_allowed) {
4976 /* assuming the order is HT20, HT40 Upper,
4977 * HT40 lower from chanspecs
4978 */
4979 ht40_flag = band_chan_arr[index].flags &
4980 IEEE80211_CHAN_NO_HT40;
4981 if (CHSPEC_SB_UPPER(chanspec)) {
4982 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
4983 band_chan_arr[index].flags &=
4984 ~IEEE80211_CHAN_NO_HT40;
4985 band_chan_arr[index].flags |=
4986 IEEE80211_CHAN_NO_HT40PLUS;
4987 } else {
4988 /* It should be one of
4989 * IEEE80211_CHAN_NO_HT40 or
4990 * IEEE80211_CHAN_NO_HT40PLUS
4991 */
4992 band_chan_arr[index].flags &=
4993 ~IEEE80211_CHAN_NO_HT40;
4994 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
4995 band_chan_arr[index].flags |=
4996 IEEE80211_CHAN_NO_HT40MINUS;
4997 }
4998 } else {
4999 band_chan_arr[index].flags =
5000 IEEE80211_CHAN_NO_HT40;
5001 if (band == IEEE80211_BAND_2GHZ)
5002 channel |= WL_CHANSPEC_BAND_2G;
5003 else
5004 channel |= WL_CHANSPEC_BAND_5G;
5005 channel |= WL_CHANSPEC_BW_20;
5006 err = brcmf_fil_bsscfg_int_get(ifp,
5007 "per_chan_info",
5008 &channel);
5009 if (!err) {
5010 if (channel & WL_CHAN_RADAR)
5011 band_chan_arr[index].flags |=
5012 (IEEE80211_CHAN_RADAR |
5013 IEEE80211_CHAN_NO_IBSS);
5014 if (channel & WL_CHAN_PASSIVE)
5015 band_chan_arr[index].flags |=
5016 IEEE80211_CHAN_PASSIVE_SCAN;
5017 }
5018 }
5019 if (!update)
5020 (*n_cnt)++;
5021 }
5022 }
5023exit:
5024 kfree(pbuf);
5025 return err;
5026}
5027
5028
5029static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4931{ 5030{
4932 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); 5031 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4933 struct wiphy *wiphy; 5032 struct wiphy *wiphy;
4934 s32 phy_list; 5033 s32 phy_list;
5034 u32 band_list[3];
5035 u32 nmode;
5036 u32 bw_cap = 0;
4935 s8 phy; 5037 s8 phy;
4936 s32 err = 0; 5038 s32 err;
5039 u32 nband;
5040 s32 i;
5041 struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
5042 s32 index;
4937 5043
4938 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, 5044 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
4939 &phy_list, sizeof(phy_list)); 5045 &phy_list, sizeof(phy_list));
4940 if (err) { 5046 if (err) {
4941 brcmf_err("error (%d)\n", err); 5047 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
4942 return err; 5048 return err;
4943 } 5049 }
4944 5050
4945 phy = ((char *)&phy_list)[0]; 5051 phy = ((char *)&phy_list)[0];
4946 brcmf_dbg(INFO, "%c phy\n", phy); 5052 brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
4947 if (phy == 'n' || phy == 'a') { 5053
4948 wiphy = cfg_to_wiphy(cfg); 5054
4949 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n; 5055 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5056 &band_list, sizeof(band_list));
5057 if (err) {
5058 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5059 return err;
5060 }
5061 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5062 band_list[0], band_list[1], band_list[2]);
5063
5064 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5065 if (err) {
5066 brcmf_err("nmode error (%d)\n", err);
5067 } else {
5068 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &bw_cap);
5069 if (err)
5070 brcmf_err("mimo_bw_cap error (%d)\n", err);
5071 }
5072 brcmf_dbg(INFO, "nmode=%d, mimo_bw_cap=%d\n", nmode, bw_cap);
5073
5074 err = brcmf_construct_reginfo(cfg, bw_cap);
5075 if (err) {
5076 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5077 return err;
4950 } 5078 }
4951 5079
5080 nband = band_list[0];
5081 memset(bands, 0, sizeof(bands));
5082
5083 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5084 index = -1;
5085 if ((band_list[i] == WLC_BAND_5G) &&
5086 (__wl_band_5ghz_a.n_channels > 0)) {
5087 index = IEEE80211_BAND_5GHZ;
5088 bands[index] = &__wl_band_5ghz_a;
5089 if ((bw_cap == WLC_N_BW_40ALL) ||
5090 (bw_cap == WLC_N_BW_20IN2G_40IN5G))
5091 bands[index]->ht_cap.cap |=
5092 IEEE80211_HT_CAP_SGI_40;
5093 } else if ((band_list[i] == WLC_BAND_2G) &&
5094 (__wl_band_2ghz.n_channels > 0)) {
5095 index = IEEE80211_BAND_2GHZ;
5096 bands[index] = &__wl_band_2ghz;
5097 if (bw_cap == WLC_N_BW_40ALL)
5098 bands[index]->ht_cap.cap |=
5099 IEEE80211_HT_CAP_SGI_40;
5100 }
5101
5102 if ((index >= 0) && nmode) {
5103 bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5104 bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5105 bands[index]->ht_cap.ht_supported = true;
5106 bands[index]->ht_cap.ampdu_factor =
5107 IEEE80211_HT_MAX_AMPDU_64K;
5108 bands[index]->ht_cap.ampdu_density =
5109 IEEE80211_HT_MPDU_DENSITY_16;
5110 /* An HT shall support all EQM rates for one spatial
5111 * stream
5112 */
5113 bands[index]->ht_cap.mcs.rx_mask[0] = 0xff;
5114 }
5115 }
5116
5117 wiphy = cfg_to_wiphy(cfg);
5118 wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5119 wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5120 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5121
4952 return err; 5122 return err;
4953} 5123}
4954 5124
5125
4955static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg) 5126static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4956{ 5127{
4957 return wl_update_wiphybands(cfg); 5128 return brcmf_update_wiphybands(cfg);
4958} 5129}
4959 5130
4960static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) 5131static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index 8b5d4989906c..2907437ef438 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -238,9 +238,8 @@ struct escan_info {
238 u32 escan_state; 238 u32 escan_state;
239 u8 escan_buf[WL_ESCAN_BUF_SIZE]; 239 u8 escan_buf[WL_ESCAN_BUF_SIZE];
240 struct wiphy *wiphy; 240 struct wiphy *wiphy;
241 struct net_device *ndev; 241 struct brcmf_if *ifp;
242 s32 (*run)(struct brcmf_cfg80211_info *cfg, 242 s32 (*run)(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
243 struct net_device *ndev,
244 struct cfg80211_scan_request *request, u16 action); 243 struct cfg80211_scan_request *request, u16 action);
245}; 244};
246 245
@@ -493,9 +492,9 @@ bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg);
493int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg, 492int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
494 u8 action, ulong timeout); 493 u8 action, ulong timeout);
495s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, 494s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
496 struct net_device *ndev, 495 struct brcmf_if *ifp, bool aborted,
497 bool aborted, bool fw_abort); 496 bool fw_abort);
498void brcmf_set_mpc(struct net_device *ndev, int mpc); 497void brcmf_set_mpc(struct brcmf_if *ndev, int mpc);
499void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg); 498void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg);
500 499
501#endif /* _wl_cfg80211_h_ */ 500#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
index f0888a9ee32e..e4fd1ee3d690 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
@@ -318,12 +318,6 @@
318#define IS_SIM(chippkg) \ 318#define IS_SIM(chippkg) \
319 ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) 319 ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
320 320
321#ifdef DEBUG
322#define SI_MSG(fmt, ...) pr_debug(fmt, ##__VA_ARGS__)
323#else
324#define SI_MSG(fmt, ...) no_printk(fmt, ##__VA_ARGS__)
325#endif /* DEBUG */
326
327#define GOODCOREADDR(x, b) \ 321#define GOODCOREADDR(x, b) \
328 (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ 322 (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
329 IS_ALIGNED((x), SI_CORE_SIZE)) 323 IS_ALIGNED((x), SI_CORE_SIZE))
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/d11.h b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
index 3f659e09f1cc..9035cc4d6ff3 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/d11.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
@@ -457,6 +457,7 @@ struct d11regs {
457/*== maccontrol register ==*/ 457/*== maccontrol register ==*/
458#define MCTL_GMODE (1U << 31) 458#define MCTL_GMODE (1U << 31)
459#define MCTL_DISCARD_PMQ (1 << 30) 459#define MCTL_DISCARD_PMQ (1 << 30)
460#define MCTL_TBTTHOLD (1 << 28)
460#define MCTL_WAKE (1 << 26) 461#define MCTL_WAKE (1 << 26)
461#define MCTL_HPS (1 << 25) 462#define MCTL_HPS (1 << 25)
462#define MCTL_PROMISC (1 << 24) 463#define MCTL_PROMISC (1 << 24)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index c70cf7b654cd..cd837860cd42 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2010 Broadcom Corporation 2 * Copyright (c) 2010 Broadcom Corporation
3 * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de>
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * 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 * purpose with or without fee is hereby granted, provided that the above
@@ -356,18 +357,26 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
356{ 357{
357 struct brcms_info *wl = hw->priv; 358 struct brcms_info *wl = hw->priv;
358 359
359 /* Just STA for now */ 360 /* Just STA, AP and ADHOC for now */
360 if (vif->type != NL80211_IFTYPE_STATION) { 361 if (vif->type != NL80211_IFTYPE_STATION &&
362 vif->type != NL80211_IFTYPE_AP &&
363 vif->type != NL80211_IFTYPE_ADHOC) {
361 brcms_err(wl->wlc->hw->d11core, 364 brcms_err(wl->wlc->hw->d11core,
362 "%s: Attempt to add type %d, only STA for now\n", 365 "%s: Attempt to add type %d, only STA, AP and AdHoc for now\n",
363 __func__, vif->type); 366 __func__, vif->type);
364 return -EOPNOTSUPP; 367 return -EOPNOTSUPP;
365 } 368 }
366 369
367 spin_lock_bh(&wl->lock); 370 spin_lock_bh(&wl->lock);
368 memcpy(wl->pub->cur_etheraddr, vif->addr, sizeof(vif->addr));
369 wl->mute_tx = false; 371 wl->mute_tx = false;
370 brcms_c_mute(wl->wlc, false); 372 brcms_c_mute(wl->wlc, false);
373 if (vif->type == NL80211_IFTYPE_STATION)
374 brcms_c_start_station(wl->wlc, vif->addr);
375 else if (vif->type == NL80211_IFTYPE_AP)
376 brcms_c_start_ap(wl->wlc, vif->addr, vif->bss_conf.bssid,
377 vif->bss_conf.ssid, vif->bss_conf.ssid_len);
378 else if (vif->type == NL80211_IFTYPE_ADHOC)
379 brcms_c_start_adhoc(wl->wlc, vif->addr);
371 spin_unlock_bh(&wl->lock); 380 spin_unlock_bh(&wl->lock);
372 381
373 return 0; 382 return 0;
@@ -519,14 +528,43 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
519 brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid); 528 brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
520 spin_unlock_bh(&wl->lock); 529 spin_unlock_bh(&wl->lock);
521 } 530 }
522 if (changed & BSS_CHANGED_BEACON) 531 if (changed & BSS_CHANGED_SSID) {
532 /* BSSID changed, for whatever reason (IBSS and managed mode) */
533 spin_lock_bh(&wl->lock);
534 brcms_c_set_ssid(wl->wlc, info->ssid, info->ssid_len);
535 spin_unlock_bh(&wl->lock);
536 }
537 if (changed & BSS_CHANGED_BEACON) {
523 /* Beacon data changed, retrieve new beacon (beaconing modes) */ 538 /* Beacon data changed, retrieve new beacon (beaconing modes) */
524 brcms_err(core, "%s: beacon changed\n", __func__); 539 struct sk_buff *beacon;
540 u16 tim_offset = 0;
541
542 spin_lock_bh(&wl->lock);
543 beacon = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL);
544 brcms_c_set_new_beacon(wl->wlc, beacon, tim_offset,
545 info->dtim_period);
546 spin_unlock_bh(&wl->lock);
547 }
548
549 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
550 struct sk_buff *probe_resp;
551
552 spin_lock_bh(&wl->lock);
553 probe_resp = ieee80211_proberesp_get(hw, vif);
554 brcms_c_set_new_probe_resp(wl->wlc, probe_resp);
555 spin_unlock_bh(&wl->lock);
556 }
525 557
526 if (changed & BSS_CHANGED_BEACON_ENABLED) { 558 if (changed & BSS_CHANGED_BEACON_ENABLED) {
527 /* Beaconing should be enabled/disabled (beaconing modes) */ 559 /* Beaconing should be enabled/disabled (beaconing modes) */
528 brcms_err(core, "%s: Beacon enabled: %s\n", __func__, 560 brcms_err(core, "%s: Beacon enabled: %s\n", __func__,
529 info->enable_beacon ? "true" : "false"); 561 info->enable_beacon ? "true" : "false");
562 if (info->enable_beacon &&
563 hw->wiphy->flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) {
564 brcms_c_enable_probe_resp(wl->wlc, true);
565 } else {
566 brcms_c_enable_probe_resp(wl->wlc, false);
567 }
530 } 568 }
531 569
532 if (changed & BSS_CHANGED_CQM) { 570 if (changed & BSS_CHANGED_CQM) {
@@ -724,7 +762,7 @@ static bool brcms_tx_flush_completed(struct brcms_info *wl)
724 return result; 762 return result;
725} 763}
726 764
727static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop) 765static void brcms_ops_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
728{ 766{
729 struct brcms_info *wl = hw->priv; 767 struct brcms_info *wl = hw->priv;
730 int ret; 768 int ret;
@@ -739,6 +777,28 @@ static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
739 "ret=%d\n", jiffies_to_msecs(ret)); 777 "ret=%d\n", jiffies_to_msecs(ret));
740} 778}
741 779
780static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
781{
782 struct brcms_info *wl = hw->priv;
783 u64 tsf;
784
785 spin_lock_bh(&wl->lock);
786 tsf = brcms_c_tsf_get(wl->wlc);
787 spin_unlock_bh(&wl->lock);
788
789 return tsf;
790}
791
792static void brcms_ops_set_tsf(struct ieee80211_hw *hw,
793 struct ieee80211_vif *vif, u64 tsf)
794{
795 struct brcms_info *wl = hw->priv;
796
797 spin_lock_bh(&wl->lock);
798 brcms_c_tsf_set(wl->wlc, tsf);
799 spin_unlock_bh(&wl->lock);
800}
801
742static const struct ieee80211_ops brcms_ops = { 802static const struct ieee80211_ops brcms_ops = {
743 .tx = brcms_ops_tx, 803 .tx = brcms_ops_tx,
744 .start = brcms_ops_start, 804 .start = brcms_ops_start,
@@ -755,6 +815,8 @@ static const struct ieee80211_ops brcms_ops = {
755 .ampdu_action = brcms_ops_ampdu_action, 815 .ampdu_action = brcms_ops_ampdu_action,
756 .rfkill_poll = brcms_ops_rfkill_poll, 816 .rfkill_poll = brcms_ops_rfkill_poll,
757 .flush = brcms_ops_flush, 817 .flush = brcms_ops_flush,
818 .get_tsf = brcms_ops_get_tsf,
819 .set_tsf = brcms_ops_set_tsf,
758}; 820};
759 821
760void brcms_dpc(unsigned long data) 822void brcms_dpc(unsigned long data)
@@ -996,7 +1058,16 @@ static int ieee_hw_init(struct ieee80211_hw *hw)
996 1058
997 /* channel change time is dependent on chip and band */ 1059 /* channel change time is dependent on chip and band */
998 hw->channel_change_time = 7 * 1000; 1060 hw->channel_change_time = 7 * 1000;
999 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 1061 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1062 BIT(NL80211_IFTYPE_AP) |
1063 BIT(NL80211_IFTYPE_ADHOC);
1064
1065 /*
1066 * deactivate sending probe responses by ucude, because this will
1067 * cause problems when WPS is used.
1068 *
1069 * hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
1070 */
1000 1071
1001 hw->rate_control_algorithm = "minstrel_ht"; 1072 hw->rate_control_algorithm = "minstrel_ht";
1002 1073
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 0c8e998bfb1e..59d438409dfb 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2010 Broadcom Corporation 2 * Copyright (c) 2010 Broadcom Corporation
3 * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de>
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * 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 * purpose with or without fee is hereby granted, provided that the above
@@ -448,6 +449,10 @@ static void brcms_c_detach_mfree(struct brcms_c_info *wlc)
448 kfree(wlc->corestate); 449 kfree(wlc->corestate);
449 kfree(wlc->hw->bandstate[0]); 450 kfree(wlc->hw->bandstate[0]);
450 kfree(wlc->hw); 451 kfree(wlc->hw);
452 if (wlc->beacon)
453 dev_kfree_skb_any(wlc->beacon);
454 if (wlc->probe_resp)
455 dev_kfree_skb_any(wlc->probe_resp);
451 456
452 /* free the wlc */ 457 /* free the wlc */
453 kfree(wlc); 458 kfree(wlc);
@@ -1069,7 +1074,7 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1069 1074
1070static void brcms_c_tbtt(struct brcms_c_info *wlc) 1075static void brcms_c_tbtt(struct brcms_c_info *wlc)
1071{ 1076{
1072 if (!wlc->bsscfg->BSS) 1077 if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC)
1073 /* 1078 /*
1074 * DirFrmQ is now valid...defer setting until end 1079 * DirFrmQ is now valid...defer setting until end
1075 * of ATIM window 1080 * of ATIM window
@@ -2163,6 +2168,32 @@ void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode)
2163 } 2168 }
2164} 2169}
2165 2170
2171void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr)
2172{
2173 memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
2174 wlc->bsscfg->type = BRCMS_TYPE_STATION;
2175}
2176
2177void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, const u8 *bssid,
2178 u8 *ssid, size_t ssid_len)
2179{
2180 brcms_c_set_ssid(wlc, ssid, ssid_len);
2181
2182 memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
2183 memcpy(wlc->bsscfg->BSSID, bssid, sizeof(wlc->bsscfg->BSSID));
2184 wlc->bsscfg->type = BRCMS_TYPE_AP;
2185
2186 brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, MCTL_AP | MCTL_INFRA);
2187}
2188
2189void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr)
2190{
2191 memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
2192 wlc->bsscfg->type = BRCMS_TYPE_ADHOC;
2193
2194 brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, 0);
2195}
2196
2166/* Initialize GPIOs that are controlled by D11 core */ 2197/* Initialize GPIOs that are controlled by D11 core */
2167static void brcms_c_gpio_init(struct brcms_c_info *wlc) 2198static void brcms_c_gpio_init(struct brcms_c_info *wlc)
2168{ 2199{
@@ -3043,8 +3074,6 @@ static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
3043 */ 3074 */
3044static bool brcms_c_ps_allowed(struct brcms_c_info *wlc) 3075static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
3045{ 3076{
3046 struct brcms_bss_cfg *cfg = wlc->bsscfg;
3047
3048 /* disallow PS when one of the following global conditions meets */ 3077 /* disallow PS when one of the following global conditions meets */
3049 if (!wlc->pub->associated) 3078 if (!wlc->pub->associated)
3050 return false; 3079 return false;
@@ -3053,16 +3082,11 @@ static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
3053 if (wlc->filter_flags & FIF_PROMISC_IN_BSS) 3082 if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
3054 return false; 3083 return false;
3055 3084
3056 if (cfg->associated) { 3085 if (wlc->bsscfg->type == BRCMS_TYPE_AP)
3057 /* 3086 return false;
3058 * disallow PS when one of the following
3059 * bsscfg specific conditions meets
3060 */
3061 if (!cfg->BSS)
3062 return false;
3063 3087
3088 if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC)
3064 return false; 3089 return false;
3065 }
3066 3090
3067 return true; 3091 return true;
3068} 3092}
@@ -3771,7 +3795,7 @@ static int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
3771 struct brcms_c_info *wlc = bsscfg->wlc; 3795 struct brcms_c_info *wlc = bsscfg->wlc;
3772 3796
3773 /* enter the MAC addr into the RXE match registers */ 3797 /* enter the MAC addr into the RXE match registers */
3774 brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, bsscfg->cur_etheraddr); 3798 brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, wlc->pub->cur_etheraddr);
3775 3799
3776 brcms_c_ampdu_macaddr_upd(wlc); 3800 brcms_c_ampdu_macaddr_upd(wlc);
3777 3801
@@ -3787,6 +3811,15 @@ static void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg)
3787 brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID); 3811 brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID);
3788} 3812}
3789 3813
3814void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, size_t ssid_len)
3815{
3816 u8 len = min_t(u8, sizeof(wlc->bsscfg->SSID), ssid_len);
3817 memset(wlc->bsscfg->SSID, 0, sizeof(wlc->bsscfg->SSID));
3818
3819 memcpy(wlc->bsscfg->SSID, ssid, len);
3820 wlc->bsscfg->SSID_len = len;
3821}
3822
3790static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot) 3823static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
3791{ 3824{
3792 wlc_hw->shortslot = shortslot; 3825 wlc_hw->shortslot = shortslot;
@@ -3821,7 +3854,7 @@ static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
3821 if (wlc->home_chanspec != chanspec) { 3854 if (wlc->home_chanspec != chanspec) {
3822 wlc->home_chanspec = chanspec; 3855 wlc->home_chanspec = chanspec;
3823 3856
3824 if (wlc->bsscfg->associated) 3857 if (wlc->pub->associated)
3825 wlc->bsscfg->current_bss->chanspec = chanspec; 3858 wlc->bsscfg->current_bss->chanspec = chanspec;
3826 } 3859 }
3827} 3860}
@@ -4091,10 +4124,14 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
4091 *shm_entry++); 4124 *shm_entry++);
4092 } 4125 }
4093 4126
4094 if (suspend) { 4127 if (suspend)
4095 brcms_c_suspend_mac_and_wait(wlc); 4128 brcms_c_suspend_mac_and_wait(wlc);
4129
4130 brcms_c_update_beacon(wlc);
4131 brcms_c_update_probe_resp(wlc, false);
4132
4133 if (suspend)
4096 brcms_c_enable_mac(wlc); 4134 brcms_c_enable_mac(wlc);
4097 }
4098} 4135}
4099 4136
4100static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) 4137static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
@@ -4332,7 +4369,6 @@ static void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
4332 4369
4333 /* WME QoS mode is Auto by default */ 4370 /* WME QoS mode is Auto by default */
4334 wlc->pub->_ampdu = AMPDU_AGG_HOST; 4371 wlc->pub->_ampdu = AMPDU_AGG_HOST;
4335 wlc->pub->bcmerror = 0;
4336} 4372}
4337 4373
4338static uint brcms_c_attach_module(struct brcms_c_info *wlc) 4374static uint brcms_c_attach_module(struct brcms_c_info *wlc)
@@ -5072,8 +5108,8 @@ int brcms_c_up(struct brcms_c_info *wlc)
5072 struct brcms_bss_cfg *bsscfg = wlc->bsscfg; 5108 struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
5073 mboolset(wlc->pub->radio_disabled, 5109 mboolset(wlc->pub->radio_disabled,
5074 WL_RADIO_HW_DISABLE); 5110 WL_RADIO_HW_DISABLE);
5075 5111 if (bsscfg->type == BRCMS_TYPE_STATION ||
5076 if (bsscfg->enable && bsscfg->BSS) 5112 bsscfg->type == BRCMS_TYPE_ADHOC)
5077 brcms_err(wlc->hw->d11core, 5113 brcms_err(wlc->hw->d11core,
5078 "wl%d: up: rfdisable -> " 5114 "wl%d: up: rfdisable -> "
5079 "bsscfg_disable()\n", 5115 "bsscfg_disable()\n",
@@ -5434,7 +5470,7 @@ static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc)
5434 u8 r; 5470 u8 r;
5435 bool war = false; 5471 bool war = false;
5436 5472
5437 if (wlc->bsscfg->associated) 5473 if (wlc->pub->associated)
5438 r = wlc->bsscfg->current_bss->rateset.rates[0]; 5474 r = wlc->bsscfg->current_bss->rateset.rates[0];
5439 else 5475 else
5440 r = wlc->default_bss->rateset.rates[0]; 5476 r = wlc->default_bss->rateset.rates[0];
@@ -5528,7 +5564,7 @@ int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
5528 /* merge rateset coming in with the current mcsset */ 5564 /* merge rateset coming in with the current mcsset */
5529 if (wlc->pub->_n_enab & SUPPORT_11N) { 5565 if (wlc->pub->_n_enab & SUPPORT_11N) {
5530 struct brcms_bss_info *mcsset_bss; 5566 struct brcms_bss_info *mcsset_bss;
5531 if (wlc->bsscfg->associated) 5567 if (wlc->pub->associated)
5532 mcsset_bss = wlc->bsscfg->current_bss; 5568 mcsset_bss = wlc->bsscfg->current_bss;
5533 else 5569 else
5534 mcsset_bss = wlc->default_bss; 5570 mcsset_bss = wlc->default_bss;
@@ -5543,12 +5579,36 @@ int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
5543 return bcmerror; 5579 return bcmerror;
5544} 5580}
5545 5581
5582static void brcms_c_time_lock(struct brcms_c_info *wlc)
5583{
5584 bcma_set32(wlc->hw->d11core, D11REGOFFS(maccontrol), MCTL_TBTTHOLD);
5585 /* Commit the write */
5586 bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
5587}
5588
5589static void brcms_c_time_unlock(struct brcms_c_info *wlc)
5590{
5591 bcma_mask32(wlc->hw->d11core, D11REGOFFS(maccontrol), ~MCTL_TBTTHOLD);
5592 /* Commit the write */
5593 bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
5594}
5595
5546int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period) 5596int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
5547{ 5597{
5598 u32 bcnint_us;
5599
5548 if (period == 0) 5600 if (period == 0)
5549 return -EINVAL; 5601 return -EINVAL;
5550 5602
5551 wlc->default_bss->beacon_period = period; 5603 wlc->default_bss->beacon_period = period;
5604
5605 bcnint_us = period << 10;
5606 brcms_c_time_lock(wlc);
5607 bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfprep),
5608 (bcnint_us << CFPREP_CBI_SHIFT));
5609 bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfpstart), bcnint_us);
5610 brcms_c_time_unlock(wlc);
5611
5552 return 0; 5612 return 0;
5553} 5613}
5554 5614
@@ -7291,72 +7351,110 @@ brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
7291 } 7351 }
7292} 7352}
7293 7353
7294/* Max buffering needed for beacon template/prb resp template is 142 bytes. 7354int brcms_c_get_header_len(void)
7295 *
7296 * PLCP header is 6 bytes.
7297 * 802.11 A3 header is 24 bytes.
7298 * Max beacon frame body template length is 112 bytes.
7299 * Max probe resp frame body template length is 110 bytes.
7300 *
7301 * *len on input contains the max length of the packet available.
7302 *
7303 * The *len value is set to the number of bytes in buf used, and starts
7304 * with the PLCP and included up to, but not including, the 4 byte FCS.
7305 */
7306static void
7307brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
7308 u32 bcn_rspec,
7309 struct brcms_bss_cfg *cfg, u16 *buf, int *len)
7310{ 7355{
7311 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; 7356 return TXOFF;
7312 struct cck_phy_hdr *plcp; 7357}
7313 struct ieee80211_mgmt *h;
7314 int hdr_len, body_len;
7315
7316 hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
7317 7358
7318 /* calc buffer size provided for frame body */ 7359static void brcms_c_beacon_write(struct brcms_c_info *wlc,
7319 body_len = *len - hdr_len; 7360 struct sk_buff *beacon, u16 tim_offset,
7320 /* return actual size */ 7361 u16 dtim_period, bool bcn0, bool bcn1)
7321 *len = hdr_len + body_len; 7362{
7363 size_t len;
7364 struct ieee80211_tx_info *tx_info;
7365 struct brcms_hardware *wlc_hw = wlc->hw;
7366 struct ieee80211_hw *ieee_hw = brcms_c_pub(wlc)->ieee_hw;
7322 7367
7323 /* format PHY and MAC headers */ 7368 /* Get tx_info */
7324 memset(buf, 0, hdr_len); 7369 tx_info = IEEE80211_SKB_CB(beacon);
7325 7370
7326 plcp = (struct cck_phy_hdr *) buf; 7371 len = min_t(size_t, beacon->len, BCN_TMPL_LEN);
7372 wlc->bcn_rspec = ieee80211_get_tx_rate(ieee_hw, tx_info)->hw_value;
7327 7373
7328 /* 7374 brcms_c_compute_plcp(wlc, wlc->bcn_rspec,
7329 * PLCP for Probe Response frames are filled in from 7375 len + FCS_LEN - D11_PHY_HDR_LEN, beacon->data);
7330 * core's rate table
7331 */
7332 if (type == IEEE80211_STYPE_BEACON)
7333 /* fill in PLCP */
7334 brcms_c_compute_plcp(wlc, bcn_rspec,
7335 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
7336 (u8 *) plcp);
7337 7376
7338 /* "Regular" and 16 MBSS but not for 4 MBSS */ 7377 /* "Regular" and 16 MBSS but not for 4 MBSS */
7339 /* Update the phytxctl for the beacon based on the rspec */ 7378 /* Update the phytxctl for the beacon based on the rspec */
7340 brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec); 7379 brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
7341 7380
7342 h = (struct ieee80211_mgmt *)&plcp[1]; 7381 if (bcn0) {
7382 /* write the probe response into the template region */
7383 brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE,
7384 (len + 3) & ~3, beacon->data);
7343 7385
7344 /* fill in 802.11 header */ 7386 /* write beacon length to SCR */
7345 h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type); 7387 brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len);
7388 }
7389 if (bcn1) {
7390 /* write the probe response into the template region */
7391 brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE,
7392 (len + 3) & ~3, beacon->data);
7346 7393
7347 /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ 7394 /* write beacon length to SCR */
7348 /* A1 filled in by MAC for prb resp, broadcast for bcn */ 7395 brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len);
7349 if (type == IEEE80211_STYPE_BEACON) 7396 }
7350 memcpy(&h->da, &ether_bcast, ETH_ALEN);
7351 memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
7352 memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
7353 7397
7354 /* SEQ filled in by MAC */ 7398 if (tim_offset != 0) {
7399 brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON,
7400 tim_offset + D11B_PHY_HDR_LEN);
7401 brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, dtim_period);
7402 } else {
7403 brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON,
7404 len + D11B_PHY_HDR_LEN);
7405 brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, 0);
7406 }
7355} 7407}
7356 7408
7357int brcms_c_get_header_len(void) 7409static void brcms_c_update_beacon_hw(struct brcms_c_info *wlc,
7410 struct sk_buff *beacon, u16 tim_offset,
7411 u16 dtim_period)
7358{ 7412{
7359 return TXOFF; 7413 struct brcms_hardware *wlc_hw = wlc->hw;
7414 struct bcma_device *core = wlc_hw->d11core;
7415
7416 /* Hardware beaconing for this config */
7417 u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
7418
7419 /* Check if both templates are in use, if so sched. an interrupt
7420 * that will call back into this routine
7421 */
7422 if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid)
7423 /* clear any previous status */
7424 bcma_write32(core, D11REGOFFS(macintstatus), MI_BCNTPL);
7425
7426 if (wlc->beacon_template_virgin) {
7427 wlc->beacon_template_virgin = false;
7428 brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true,
7429 true);
7430 /* mark beacon0 valid */
7431 bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD);
7432 return;
7433 }
7434
7435 /* Check that after scheduling the interrupt both of the
7436 * templates are still busy. if not clear the int. & remask
7437 */
7438 if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid) {
7439 wlc->defmacintmask |= MI_BCNTPL;
7440 return;
7441 }
7442
7443 if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN0VLD)) {
7444 brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true,
7445 false);
7446 /* mark beacon0 valid */
7447 bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD);
7448 return;
7449 }
7450 if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN1VLD)) {
7451 brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period,
7452 false, true);
7453 /* mark beacon0 valid */
7454 bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN1VLD);
7455 return;
7456 }
7457 return;
7360} 7458}
7361 7459
7362/* 7460/*
@@ -7366,9 +7464,57 @@ void brcms_c_update_beacon(struct brcms_c_info *wlc)
7366{ 7464{
7367 struct brcms_bss_cfg *bsscfg = wlc->bsscfg; 7465 struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
7368 7466
7369 if (bsscfg->up && !bsscfg->BSS) 7467 if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
7468 bsscfg->type == BRCMS_TYPE_ADHOC)) {
7370 /* Clear the soft intmask */ 7469 /* Clear the soft intmask */
7371 wlc->defmacintmask &= ~MI_BCNTPL; 7470 wlc->defmacintmask &= ~MI_BCNTPL;
7471 if (!wlc->beacon)
7472 return;
7473 brcms_c_update_beacon_hw(wlc, wlc->beacon,
7474 wlc->beacon_tim_offset,
7475 wlc->beacon_dtim_period);
7476 }
7477}
7478
7479void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon,
7480 u16 tim_offset, u16 dtim_period)
7481{
7482 if (!beacon)
7483 return;
7484 if (wlc->beacon)
7485 dev_kfree_skb_any(wlc->beacon);
7486 wlc->beacon = beacon;
7487
7488 /* add PLCP */
7489 skb_push(wlc->beacon, D11_PHY_HDR_LEN);
7490 wlc->beacon_tim_offset = tim_offset;
7491 wlc->beacon_dtim_period = dtim_period;
7492 brcms_c_update_beacon(wlc);
7493}
7494
7495void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
7496 struct sk_buff *probe_resp)
7497{
7498 if (!probe_resp)
7499 return;
7500 if (wlc->probe_resp)
7501 dev_kfree_skb_any(wlc->probe_resp);
7502 wlc->probe_resp = probe_resp;
7503
7504 /* add PLCP */
7505 skb_push(wlc->probe_resp, D11_PHY_HDR_LEN);
7506 brcms_c_update_probe_resp(wlc, false);
7507}
7508
7509void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable)
7510{
7511 /*
7512 * prevent ucode from sending probe responses by setting the timeout
7513 * to 1, it can not send it in that time frame.
7514 */
7515 wlc->prb_resp_timeout = enable ? BRCMS_PRB_RESP_TIMEOUT : 1;
7516 brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
7517 /* TODO: if (enable) => also deactivate receiving of probe request */
7372} 7518}
7373 7519
7374/* Write ssid into shared memory */ 7520/* Write ssid into shared memory */
@@ -7390,30 +7536,19 @@ brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
7390static void 7536static void
7391brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc, 7537brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
7392 struct brcms_bss_cfg *cfg, 7538 struct brcms_bss_cfg *cfg,
7539 struct sk_buff *probe_resp,
7393 bool suspend) 7540 bool suspend)
7394{ 7541{
7395 u16 *prb_resp; 7542 int len;
7396 int len = BCN_TMPL_LEN;
7397
7398 prb_resp = kmalloc(BCN_TMPL_LEN, GFP_ATOMIC);
7399 if (!prb_resp)
7400 return;
7401
7402 /*
7403 * write the probe response to hardware, or save in
7404 * the config structure
7405 */
7406 7543
7407 /* create the probe response template */ 7544 len = min_t(size_t, probe_resp->len, BCN_TMPL_LEN);
7408 brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
7409 cfg, prb_resp, &len);
7410 7545
7411 if (suspend) 7546 if (suspend)
7412 brcms_c_suspend_mac_and_wait(wlc); 7547 brcms_c_suspend_mac_and_wait(wlc);
7413 7548
7414 /* write the probe response into the template region */ 7549 /* write the probe response into the template region */
7415 brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE, 7550 brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
7416 (len + 3) & ~3, prb_resp); 7551 (len + 3) & ~3, probe_resp->data);
7417 7552
7418 /* write the length of the probe response frame (+PLCP/-FCS) */ 7553 /* write the length of the probe response frame (+PLCP/-FCS) */
7419 brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len); 7554 brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
@@ -7427,13 +7562,11 @@ brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
7427 * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table() 7562 * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
7428 * by subtracting the PLCP len and adding the FCS. 7563 * by subtracting the PLCP len and adding the FCS.
7429 */ 7564 */
7430 len += (-D11_PHY_HDR_LEN + FCS_LEN); 7565 brcms_c_mod_prb_rsp_rate_table(wlc,
7431 brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len); 7566 (u16)len + FCS_LEN - D11_PHY_HDR_LEN);
7432 7567
7433 if (suspend) 7568 if (suspend)
7434 brcms_c_enable_mac(wlc); 7569 brcms_c_enable_mac(wlc);
7435
7436 kfree(prb_resp);
7437} 7570}
7438 7571
7439void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) 7572void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
@@ -7441,8 +7574,13 @@ void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
7441 struct brcms_bss_cfg *bsscfg = wlc->bsscfg; 7574 struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
7442 7575
7443 /* update AP or IBSS probe responses */ 7576 /* update AP or IBSS probe responses */
7444 if (bsscfg->up && !bsscfg->BSS) 7577 if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
7445 brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); 7578 bsscfg->type == BRCMS_TYPE_ADHOC)) {
7579 if (!wlc->probe_resp)
7580 return;
7581 brcms_c_bss_update_probe_resp(wlc, bsscfg, wlc->probe_resp,
7582 suspend);
7583 }
7446} 7584}
7447 7585
7448int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, 7586int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
@@ -7481,7 +7619,6 @@ void brcms_c_scan_stop(struct brcms_c_info *wlc)
7481void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state) 7619void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
7482{ 7620{
7483 wlc->pub->associated = state; 7621 wlc->pub->associated = state;
7484 wlc->bsscfg->associated = state;
7485} 7622}
7486 7623
7487/* 7624/*
@@ -7526,6 +7663,36 @@ void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
7526 brcms_c_bcn_li_upd(wlc); 7663 brcms_c_bcn_li_upd(wlc);
7527} 7664}
7528 7665
7666u64 brcms_c_tsf_get(struct brcms_c_info *wlc)
7667{
7668 u32 tsf_h, tsf_l;
7669 u64 tsf;
7670
7671 brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
7672
7673 tsf = tsf_h;
7674 tsf <<= 32;
7675 tsf |= tsf_l;
7676
7677 return tsf;
7678}
7679
7680void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf)
7681{
7682 u32 tsf_h, tsf_l;
7683
7684 brcms_c_time_lock(wlc);
7685
7686 tsf_l = tsf;
7687 tsf_h = (tsf >> 32);
7688
7689 /* read the tsf timer low, then high to get an atomic read */
7690 bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerlow), tsf_l);
7691 bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerhigh), tsf_h);
7692
7693 brcms_c_time_unlock(wlc);
7694}
7695
7529int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr) 7696int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
7530{ 7697{
7531 uint qdbm; 7698 uint qdbm;
@@ -7737,6 +7904,10 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
7737 brcms_rfkill_set_hw_state(wlc->wl); 7904 brcms_rfkill_set_hw_state(wlc->wl);
7738 } 7905 }
7739 7906
7907 /* BCN template is available */
7908 if (macintstatus & MI_BCNTPL)
7909 brcms_c_update_beacon(wlc);
7910
7740 /* it isn't done and needs to be resched if macintstatus is non-zero */ 7911 /* it isn't done and needs to be resched if macintstatus is non-zero */
7741 return wlc->macintstatus != 0; 7912 return wlc->macintstatus != 0;
7742 7913
@@ -7765,7 +7936,7 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
7765 brcms_c_set_bssid(wlc->bsscfg); 7936 brcms_c_set_bssid(wlc->bsscfg);
7766 7937
7767 /* Update tsf_cfprep if associated and up */ 7938 /* Update tsf_cfprep if associated and up */
7768 if (wlc->pub->associated && wlc->bsscfg->up) { 7939 if (wlc->pub->associated && wlc->pub->up) {
7769 u32 bi; 7940 u32 bi;
7770 7941
7771 /* get beacon period and convert to uS */ 7942 /* get beacon period and convert to uS */
@@ -7873,6 +8044,7 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
7873 pub->unit = unit; 8044 pub->unit = unit;
7874 pub->_piomode = piomode; 8045 pub->_piomode = piomode;
7875 wlc->bandinit_pending = false; 8046 wlc->bandinit_pending = false;
8047 wlc->beacon_template_virgin = true;
7876 8048
7877 /* populate struct brcms_c_info with default values */ 8049 /* populate struct brcms_c_info with default values */
7878 brcms_c_info_init(wlc, unit); 8050 brcms_c_info_init(wlc, unit);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index fb447747c2c6..b5d7a38b53fe 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -492,6 +492,8 @@ struct brcms_c_info {
492 bool radio_monitor; 492 bool radio_monitor;
493 bool going_down; 493 bool going_down;
494 494
495 bool beacon_template_virgin;
496
495 struct brcms_timer *wdtimer; 497 struct brcms_timer *wdtimer;
496 struct brcms_timer *radio_timer; 498 struct brcms_timer *radio_timer;
497 499
@@ -561,6 +563,11 @@ struct brcms_c_info {
561 563
562 struct wiphy *wiphy; 564 struct wiphy *wiphy;
563 struct scb pri_scb; 565 struct scb pri_scb;
566
567 struct sk_buff *beacon;
568 u16 beacon_tim_offset;
569 u16 beacon_dtim_period;
570 struct sk_buff *probe_resp;
564}; 571};
565 572
566/* antsel module specific state */ 573/* antsel module specific state */
@@ -576,14 +583,17 @@ struct antsel_info {
576 struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */ 583 struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
577}; 584};
578 585
586enum brcms_bss_type {
587 BRCMS_TYPE_STATION,
588 BRCMS_TYPE_AP,
589 BRCMS_TYPE_ADHOC,
590};
591
579/* 592/*
580 * BSS configuration state 593 * BSS configuration state
581 * 594 *
582 * wlc: wlc to which this bsscfg belongs to. 595 * wlc: wlc to which this bsscfg belongs to.
583 * up: is this configuration up operational 596 * type: interface type
584 * enable: is this configuration enabled
585 * associated: is BSS in ASSOCIATED state
586 * BSS: infraustructure or adhoc
587 * SSID_len: the length of SSID 597 * SSID_len: the length of SSID
588 * SSID: SSID string 598 * SSID: SSID string
589 * 599 *
@@ -599,14 +609,10 @@ struct antsel_info {
599 */ 609 */
600struct brcms_bss_cfg { 610struct brcms_bss_cfg {
601 struct brcms_c_info *wlc; 611 struct brcms_c_info *wlc;
602 bool up; 612 enum brcms_bss_type type;
603 bool enable;
604 bool associated;
605 bool BSS;
606 u8 SSID_len; 613 u8 SSID_len;
607 u8 SSID[IEEE80211_MAX_SSID_LEN]; 614 u8 SSID[IEEE80211_MAX_SSID_LEN];
608 u8 BSSID[ETH_ALEN]; 615 u8 BSSID[ETH_ALEN];
609 u8 cur_etheraddr[ETH_ALEN];
610 struct brcms_bss_info *current_bss; 616 struct brcms_bss_info *current_bss;
611}; 617};
612 618
@@ -631,7 +637,6 @@ extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
631extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw, 637extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
632 struct ieee80211_sta *sta, 638 struct ieee80211_sta *sta,
633 void (*dma_callback_fn)); 639 void (*dma_callback_fn));
634extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
635extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend); 640extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
636extern int brcms_c_set_nmode(struct brcms_c_info *wlc); 641extern int brcms_c_set_nmode(struct brcms_c_info *wlc);
637extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, 642extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
index 91937c5025ce..b0fd807f2b2b 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
@@ -198,8 +198,6 @@ u16 read_radio_reg(struct brcms_phy *pi, u16 addr)
198 198
199void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val) 199void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
200{ 200{
201 struct si_info *sii = container_of(pi->sh->sih, struct si_info, pub);
202
203 if ((D11REV_GE(pi->sh->corerev, 24)) || 201 if ((D11REV_GE(pi->sh->corerev, 24)) ||
204 (D11REV_IS(pi->sh->corerev, 22) 202 (D11REV_IS(pi->sh->corerev, 22)
205 && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { 203 && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
@@ -211,7 +209,7 @@ void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
211 bcma_write16(pi->d11core, D11REGOFFS(phy4wdatalo), val); 209 bcma_write16(pi->d11core, D11REGOFFS(phy4wdatalo), val);
212 } 210 }
213 211
214 if ((sii->icbus->hosttype == BCMA_HOSTTYPE_PCI) && 212 if ((pi->d11core->bus->hosttype == BCMA_HOSTTYPE_PCI) &&
215 (++pi->phy_wreg >= pi->phy_wreg_limit)) { 213 (++pi->phy_wreg >= pi->phy_wreg_limit)) {
216 (void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol)); 214 (void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
217 pi->phy_wreg = 0; 215 pi->phy_wreg = 0;
@@ -297,10 +295,8 @@ void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
297 if (addr == 0x72) 295 if (addr == 0x72)
298 (void)bcma_read16(pi->d11core, D11REGOFFS(phyregdata)); 296 (void)bcma_read16(pi->d11core, D11REGOFFS(phyregdata));
299#else 297#else
300 struct si_info *sii = container_of(pi->sh->sih, struct si_info, pub);
301
302 bcma_write32(pi->d11core, D11REGOFFS(phyregaddr), addr | (val << 16)); 298 bcma_write32(pi->d11core, D11REGOFFS(phyregaddr), addr | (val << 16));
303 if ((sii->icbus->hosttype == BCMA_HOSTTYPE_PCI) && 299 if ((pi->d11core->bus->hosttype == BCMA_HOSTTYPE_PCI) &&
304 (++pi->phy_wreg >= pi->phy_wreg_limit)) { 300 (++pi->phy_wreg >= pi->phy_wreg_limit)) {
305 pi->phy_wreg = 0; 301 pi->phy_wreg = 0;
306 (void)bcma_read16(pi->d11core, D11REGOFFS(phyversion)); 302 (void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
@@ -374,7 +370,6 @@ struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp)
374 if (sh == NULL) 370 if (sh == NULL)
375 return NULL; 371 return NULL;
376 372
377 sh->sih = shp->sih;
378 sh->physhim = shp->physhim; 373 sh->physhim = shp->physhim;
379 sh->unit = shp->unit; 374 sh->unit = shp->unit;
380 sh->corerev = shp->corerev; 375 sh->corerev = shp->corerev;
@@ -2911,29 +2906,24 @@ void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode)
2911 mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2); 2906 mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
2912 2907
2913 } 2908 }
2914 ai_cc_reg(pi->sh->sih, 2909
2915 offsetof(struct chipcregs, gpiocontrol), 2910 bcma_chipco_gpio_control(&pi->d11core->bus->drv_cc,
2916 ~0x0, 0x0); 2911 0x0, 0x0);
2917 ai_cc_reg(pi->sh->sih, 2912 bcma_chipco_gpio_out(&pi->d11core->bus->drv_cc,
2918 offsetof(struct chipcregs, gpioout), 2913 ~0x40, 0x40);
2919 0x40, 0x40); 2914 bcma_chipco_gpio_outen(&pi->d11core->bus->drv_cc,
2920 ai_cc_reg(pi->sh->sih, 2915 ~0x40, 0x40);
2921 offsetof(struct chipcregs, gpioouten),
2922 0x40, 0x40);
2923 } else { 2916 } else {
2924 mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2); 2917 mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
2925 2918
2926 mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2); 2919 mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
2927 2920
2928 ai_cc_reg(pi->sh->sih, 2921 bcma_chipco_gpio_out(&pi->d11core->bus->drv_cc,
2929 offsetof(struct chipcregs, gpioout), 2922 ~0x40, 0x00);
2930 0x40, 0x00); 2923 bcma_chipco_gpio_outen(&pi->d11core->bus->drv_cc,
2931 ai_cc_reg(pi->sh->sih, 2924 ~0x40, 0x00);
2932 offsetof(struct chipcregs, gpioouten), 2925 bcma_chipco_gpio_control(&pi->d11core->bus->drv_cc,
2933 0x40, 0x0); 2926 0x0, 0x40);
2934 ai_cc_reg(pi->sh->sih,
2935 offsetof(struct chipcregs, gpiocontrol),
2936 ~0x0, 0x40);
2937 } 2927 }
2938 } 2928 }
2939} 2929}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
index af00e2c2b266..1dc767c31653 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
@@ -488,7 +488,6 @@ struct lcnphy_cal_results {
488struct shared_phy { 488struct shared_phy {
489 struct brcms_phy *phy_head; 489 struct brcms_phy *phy_head;
490 uint unit; 490 uint unit;
491 struct si_pub *sih;
492 struct phy_shim_info *physhim; 491 struct phy_shim_info *physhim;
493 uint corerev; 492 uint corerev;
494 u32 machwcap; 493 u32 machwcap;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index 18d37645e2cd..3d6b16ce4687 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -1595,11 +1595,15 @@ wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, u16 chanspec)
1595 if (channel == 1 || channel == 2 || channel == 3 || 1595 if (channel == 1 || channel == 2 || channel == 3 ||
1596 channel == 4 || channel == 9 || 1596 channel == 4 || channel == 9 ||
1597 channel == 10 || channel == 11 || channel == 12) { 1597 channel == 10 || channel == 11 || channel == 12) {
1598 si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04); 1598 bcma_chipco_pll_write(&pi->d11core->bus->drv_cc, 0x2,
1599 si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0); 1599 0x03000c04);
1600 si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0); 1600 bcma_chipco_pll_maskset(&pi->d11core->bus->drv_cc, 0x3,
1601 1601 ~0x00ffffff, 0x0);
1602 si_pmu_pllupd(pi->sh->sih); 1602 bcma_chipco_pll_write(&pi->d11core->bus->drv_cc, 0x4,
1603 0x200005c0);
1604
1605 bcma_cc_set32(&pi->d11core->bus->drv_cc, BCMA_CC_PMU_CTL,
1606 BCMA_CC_PMU_CTL_PLL_UPD);
1603 write_phy_reg(pi, 0x942, 0); 1607 write_phy_reg(pi, 0x942, 0);
1604 wlc_lcnphy_txrx_spur_avoidance_mode(pi, false); 1608 wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
1605 pi_lcn->lcnphy_spurmod = false; 1609 pi_lcn->lcnphy_spurmod = false;
@@ -1607,11 +1611,15 @@ wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, u16 chanspec)
1607 1611
1608 write_phy_reg(pi, 0x425, 0x5907); 1612 write_phy_reg(pi, 0x425, 0x5907);
1609 } else { 1613 } else {
1610 si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04); 1614 bcma_chipco_pll_write(&pi->d11core->bus->drv_cc, 0x2,
1611 si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333); 1615 0x03140c04);
1612 si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820); 1616 bcma_chipco_pll_maskset(&pi->d11core->bus->drv_cc, 0x3,
1613 1617 ~0x00ffffff, 0x333333);
1614 si_pmu_pllupd(pi->sh->sih); 1618 bcma_chipco_pll_write(&pi->d11core->bus->drv_cc, 0x4,
1619 0x202c2820);
1620
1621 bcma_cc_set32(&pi->d11core->bus->drv_cc, BCMA_CC_PMU_CTL,
1622 BCMA_CC_PMU_CTL_PLL_UPD);
1615 write_phy_reg(pi, 0x942, 0); 1623 write_phy_reg(pi, 0x942, 0);
1616 wlc_lcnphy_txrx_spur_avoidance_mode(pi, true); 1624 wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
1617 1625
@@ -4755,9 +4763,10 @@ void wlc_phy_init_lcnphy(struct brcms_phy *pi)
4755 4763
4756 wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec); 4764 wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
4757 4765
4758 si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9); 4766 bcma_chipco_regctl_maskset(&pi->d11core->bus->drv_cc, 0, ~0xf, 0x9);
4759 4767
4760 si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD); 4768 bcma_chipco_chipctl_maskset(&pi->d11core->bus->drv_cc, 0, 0x0,
4769 0x03CDDDDD);
4761 4770
4762 if ((pi->sh->boardflags & BFL_FEM) 4771 if ((pi->sh->boardflags & BFL_FEM)
4763 && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) 4772 && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
@@ -4968,7 +4977,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
4968 pi->hwpwrctrl_capable = true; 4977 pi->hwpwrctrl_capable = true;
4969 } 4978 }
4970 4979
4971 pi->xtalfreq = si_pmu_alp_clock(pi->sh->sih); 4980 pi->xtalfreq = bcma_chipco_get_alp_clock(&pi->d11core->bus->drv_cc);
4972 pi_lcn->lcnphy_papd_rxGnCtrl_init = 0; 4981 pi_lcn->lcnphy_papd_rxGnCtrl_init = 0;
4973 4982
4974 pi->pi_fptr.init = wlc_phy_init_lcnphy; 4983 pi->pi_fptr.init = wlc_phy_init_lcnphy;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
index 65db9b7458dc..3e9f5b25be63 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
@@ -19321,14 +19321,13 @@ void wlc_phy_init_nphy(struct brcms_phy *pi)
19321 (pi->sh->chippkg == BCMA_PKG_ID_BCM4718))) { 19321 (pi->sh->chippkg == BCMA_PKG_ID_BCM4718))) {
19322 if ((pi->sh->boardflags & BFL_EXTLNA) && 19322 if ((pi->sh->boardflags & BFL_EXTLNA) &&
19323 (CHSPEC_IS2G(pi->radio_chanspec))) 19323 (CHSPEC_IS2G(pi->radio_chanspec)))
19324 ai_cc_reg(pi->sh->sih, 19324 bcma_cc_set32(&pi->d11core->bus->drv_cc,
19325 offsetof(struct chipcregs, chipcontrol), 19325 BCMA_CC_CHIPCTL, 0x40);
19326 0x40, 0x40);
19327 } 19326 }
19328 19327
19329 if ((!PHY_IPA(pi)) && (pi->sh->chip == BCMA_CHIP_ID_BCM5357)) 19328 if ((!PHY_IPA(pi)) && (pi->sh->chip == BCMA_CHIP_ID_BCM5357))
19330 si_pmu_chipcontrol(pi->sh->sih, 1, CCTRL5357_EXTPA, 19329 bcma_chipco_chipctl_maskset(&pi->d11core->bus->drv_cc, 1,
19331 CCTRL5357_EXTPA); 19330 ~CCTRL5357_EXTPA, CCTRL5357_EXTPA);
19332 19331
19333 if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) && 19332 if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
19334 CHSPEC_IS40(pi->radio_chanspec)) { 19333 CHSPEC_IS40(pi->radio_chanspec)) {
@@ -21133,7 +21132,6 @@ wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, u16 chanspec,
21133 const struct nphy_sfo_cfg *ci) 21132 const struct nphy_sfo_cfg *ci)
21134{ 21133{
21135 u16 val; 21134 u16 val;
21136 struct si_info *sii = container_of(pi->sh->sih, struct si_info, pub);
21137 21135
21138 val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; 21136 val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
21139 if (CHSPEC_IS5G(chanspec) && !val) { 21137 if (CHSPEC_IS5G(chanspec) && !val) {
@@ -21221,11 +21219,11 @@ wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, u16 chanspec,
21221 21219
21222 if ((pi->sh->chip == BCMA_CHIP_ID_BCM4716) || 21220 if ((pi->sh->chip == BCMA_CHIP_ID_BCM4716) ||
21223 (pi->sh->chip == BCMA_CHIP_ID_BCM43225)) { 21221 (pi->sh->chip == BCMA_CHIP_ID_BCM43225)) {
21224 bcma_pmu_spuravoid_pllupdate(&sii->icbus->drv_cc, 21222 bcma_pmu_spuravoid_pllupdate(&pi->d11core->bus->drv_cc,
21225 spuravoid); 21223 spuravoid);
21226 } else { 21224 } else {
21227 wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false); 21225 wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false);
21228 bcma_pmu_spuravoid_pllupdate(&sii->icbus->drv_cc, 21226 bcma_pmu_spuravoid_pllupdate(&pi->d11core->bus->drv_cc,
21229 spuravoid); 21227 spuravoid);
21230 wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true); 21228 wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true);
21231 } 21229 }
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c
index 7e9df566c733..71b80381f3ad 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c
@@ -115,60 +115,6 @@ u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
115 return (u16) delay; 115 return (u16) delay;
116} 116}
117 117
118/* Read/write a chipcontrol reg */
119u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
120{
121 ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol_addr), ~0, reg);
122 return ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol_data),
123 mask, val);
124}
125
126/* Read/write a regcontrol reg */
127u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
128{
129 ai_cc_reg(sih, offsetof(struct chipcregs, regcontrol_addr), ~0, reg);
130 return ai_cc_reg(sih, offsetof(struct chipcregs, regcontrol_data),
131 mask, val);
132}
133
134/* Read/write a pllcontrol reg */
135u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
136{
137 ai_cc_reg(sih, offsetof(struct chipcregs, pllcontrol_addr), ~0, reg);
138 return ai_cc_reg(sih, offsetof(struct chipcregs, pllcontrol_data),
139 mask, val);
140}
141
142/* PMU PLL update */
143void si_pmu_pllupd(struct si_pub *sih)
144{
145 ai_cc_reg(sih, offsetof(struct chipcregs, pmucontrol),
146 PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
147}
148
149/* query alp/xtal clock frequency */
150u32 si_pmu_alp_clock(struct si_pub *sih)
151{
152 u32 clock = ALP_CLOCK;
153
154 /* bail out with default */
155 if (!(ai_get_cccaps(sih) & CC_CAP_PMU))
156 return clock;
157
158 switch (ai_get_chip_id(sih)) {
159 case BCMA_CHIP_ID_BCM43224:
160 case BCMA_CHIP_ID_BCM43225:
161 case BCMA_CHIP_ID_BCM4313:
162 /* always 20Mhz */
163 clock = 20000 * 1000;
164 break;
165 default:
166 break;
167 }
168
169 return clock;
170}
171
172u32 si_pmu_measure_alpclk(struct si_pub *sih) 118u32 si_pmu_measure_alpclk(struct si_pub *sih)
173{ 119{
174 struct si_info *sii = container_of(sih, struct si_info, pub); 120 struct si_info *sii = container_of(sih, struct si_info, pub);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.h b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
index f7cff873578b..20e2012d5a3a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
@@ -21,12 +21,6 @@
21#include "types.h" 21#include "types.h"
22 22
23extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih); 23extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih);
24extern void si_pmu_sprom_enable(struct si_pub *sih, bool enable);
25extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
26extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
27extern u32 si_pmu_alp_clock(struct si_pub *sih);
28extern void si_pmu_pllupd(struct si_pub *sih);
29extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
30extern u32 si_pmu_measure_alpclk(struct si_pub *sih); 24extern u32 si_pmu_measure_alpclk(struct si_pub *sih);
31 25
32#endif /* _BRCM_PMU_H_ */ 26#endif /* _BRCM_PMU_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index b0f14b7b8616..d36ea5e1cc49 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -164,8 +164,6 @@ struct brcms_pub {
164 164
165 u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */ 165 u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */
166 166
167 int bcmerror; /* last bcm error */
168
169 u32 radio_disabled; /* bit vector for radio disabled reasons */ 167 u32 radio_disabled; /* bit vector for radio disabled reasons */
170 168
171 u16 boardrev; /* version # of particular board */ 169 u16 boardrev; /* version # of particular board */
@@ -326,10 +324,25 @@ extern void brcms_c_set_shortslot_override(struct brcms_c_info *wlc,
326 s8 sslot_override); 324 s8 sslot_override);
327extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, 325extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
328 u8 interval); 326 u8 interval);
327extern u64 brcms_c_tsf_get(struct brcms_c_info *wlc);
328extern void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf);
329extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); 329extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
330extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); 330extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
331extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); 331extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
332extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); 332extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
333extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc); 333extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
334extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr);
335extern void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr,
336 const u8 *bssid, u8 *ssid, size_t ssid_len);
337extern void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr);
338extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
339extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
340 struct sk_buff *beacon, u16 tim_offset,
341 u16 dtim_period);
342extern void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
343 struct sk_buff *probe_resp);
344extern void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable);
345extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid,
346 size_t ssid_len);
334 347
335#endif /* _BRCM_PUB_H_ */ 348#endif /* _BRCM_PUB_H_ */
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
index c11a290a1edf..0505cc065e0d 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
@@ -32,8 +32,9 @@
32#define CH_20MHZ_APART 4 32#define CH_20MHZ_APART 4
33#define CH_10MHZ_APART 2 33#define CH_10MHZ_APART 2
34#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ 34#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
35#define CH_MIN_2G_CHANNEL 1
35#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ 36#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
36#define BRCM_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL /* legacy define */ 37#define CH_MIN_5G_CHANNEL 34
37 38
38/* bandstate array indices */ 39/* bandstate array indices */
39#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */ 40#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */
@@ -60,6 +61,7 @@
60#define WL_CHANSPEC_BW_10 0x0400 61#define WL_CHANSPEC_BW_10 0x0400
61#define WL_CHANSPEC_BW_20 0x0800 62#define WL_CHANSPEC_BW_20 0x0800
62#define WL_CHANSPEC_BW_40 0x0C00 63#define WL_CHANSPEC_BW_40 0x0C00
64#define WL_CHANSPEC_BW_80 0x2000
63 65
64#define WL_CHANSPEC_BAND_MASK 0xf000 66#define WL_CHANSPEC_BAND_MASK 0xf000
65#define WL_CHANSPEC_BAND_SHIFT 12 67#define WL_CHANSPEC_BAND_SHIFT 12
@@ -67,6 +69,25 @@
67#define WL_CHANSPEC_BAND_2G 0x2000 69#define WL_CHANSPEC_BAND_2G 0x2000
68#define INVCHANSPEC 255 70#define INVCHANSPEC 255
69 71
72#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */
73#define WL_CHAN_VALID_SW (1 << 1) /* valid with country sett. */
74#define WL_CHAN_BAND_5G (1 << 2) /* 5GHz-band channel */
75#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */
76#define WL_CHAN_INACTIVE (1 << 4) /* inactive due to radar */
77#define WL_CHAN_PASSIVE (1 << 5) /* channel in passive mode */
78#define WL_CHAN_RESTRICTED (1 << 6) /* restricted use channel */
79
80/* values for band specific 40MHz capabilities */
81#define WLC_N_BW_20ALL 0
82#define WLC_N_BW_40ALL 1
83#define WLC_N_BW_20IN2G_40IN5G 2
84
85/* band types */
86#define WLC_BAND_AUTO 0 /* auto-select */
87#define WLC_BAND_5G 1 /* 5 Ghz */
88#define WLC_BAND_2G 2 /* 2.4 Ghz */
89#define WLC_BAND_ALL 3 /* all bands */
90
70#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK)) 91#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
71#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) 92#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
72 93
@@ -79,10 +100,11 @@
79#define CHSPEC_IS20(chspec) \ 100#define CHSPEC_IS20(chspec) \
80 (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) 101 (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
81 102
82#ifndef CHSPEC_IS40
83#define CHSPEC_IS40(chspec) \ 103#define CHSPEC_IS40(chspec) \
84 (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) 104 (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
85#endif 105
106#define CHSPEC_IS80(chspec) \
107 (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80)
86 108
87#define CHSPEC_IS5G(chspec) \ 109#define CHSPEC_IS5G(chspec) \
88 (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) 110 (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 5b79819d7bed..3613b3a81ad2 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -4701,8 +4701,7 @@ out:
4701} 4701}
4702EXPORT_SYMBOL(il_mac_change_interface); 4702EXPORT_SYMBOL(il_mac_change_interface);
4703 4703
4704void 4704void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
4705il_mac_flush(struct ieee80211_hw *hw, bool drop)
4706{ 4705{
4707 struct il_priv *il = hw->priv; 4706 struct il_priv *il = hw->priv;
4708 unsigned long timeout = jiffies + msecs_to_jiffies(500); 4707 unsigned long timeout = jiffies + msecs_to_jiffies(500);
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index 10986aaf9085..f8246f2d88f9 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1720,7 +1720,7 @@ void il_mac_remove_interface(struct ieee80211_hw *hw,
1720 struct ieee80211_vif *vif); 1720 struct ieee80211_vif *vif);
1721int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1721int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1722 enum nl80211_iftype newtype, bool newp2p); 1722 enum nl80211_iftype newtype, bool newp2p);
1723void il_mac_flush(struct ieee80211_hw *hw, bool drop); 1723void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
1724int il_alloc_txq_mem(struct il_priv *il); 1724int il_alloc_txq_mem(struct il_priv *il);
1725void il_free_txq_mem(struct il_priv *il); 1725void il_free_txq_mem(struct il_priv *il);
1726 1726
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index c7cd2dffa5cd..a7294fa4d7e5 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1100,7 +1100,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
1100 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; 1100 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
1101} 1101}
1102 1102
1103static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) 1103static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1104{ 1104{
1105 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1105 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1106 1106
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 3ce4e9d5082d..498300577ac0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1266,7 +1266,3 @@ module_param_named(auto_agg, iwlwifi_mod_params.auto_agg,
1266 bool, S_IRUGO); 1266 bool, S_IRUGO);
1267MODULE_PARM_DESC(auto_agg, 1267MODULE_PARM_DESC(auto_agg,
1268 "enable agg w/o check traffic load (default: enable)"); 1268 "enable agg w/o check traffic load (default: enable)");
1269
1270module_param_named(5ghz_disable, iwlwifi_mod_params.disable_5ghz,
1271 bool, S_IRUGO);
1272MODULE_PARM_DESC(5ghz_disable, "disable 5GHz band (default: 0 [enabled])");
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 435618574240..c4c446d41eb0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -154,6 +154,19 @@ struct iwl_tlv_calib_ctrl {
154 __le32 event_trigger; 154 __le32 event_trigger;
155} __packed; 155} __packed;
156 156
157enum iwl_fw_phy_cfg {
158 FW_PHY_CFG_RADIO_TYPE_POS = 0,
159 FW_PHY_CFG_RADIO_TYPE = 0x3 << FW_PHY_CFG_RADIO_TYPE_POS,
160 FW_PHY_CFG_RADIO_STEP_POS = 2,
161 FW_PHY_CFG_RADIO_STEP = 0x3 << FW_PHY_CFG_RADIO_STEP_POS,
162 FW_PHY_CFG_RADIO_DASH_POS = 4,
163 FW_PHY_CFG_RADIO_DASH = 0x3 << FW_PHY_CFG_RADIO_DASH_POS,
164 FW_PHY_CFG_TX_CHAIN_POS = 16,
165 FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
166 FW_PHY_CFG_RX_CHAIN_POS = 20,
167 FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
168};
169
157/** 170/**
158 * struct iwl_fw - variables associated with the firmware 171 * struct iwl_fw - variables associated with the firmware
159 * 172 *
@@ -190,4 +203,16 @@ struct iwl_fw {
190 bool mvm_fw; 203 bool mvm_fw;
191}; 204};
192 205
206static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw)
207{
208 return (fw->phy_config & FW_PHY_CFG_TX_CHAIN) >>
209 FW_PHY_CFG_TX_CHAIN_POS;
210}
211
212static inline u8 iwl_fw_valid_rx_ant(const struct iwl_fw *fw)
213{
214 return (fw->phy_config & FW_PHY_CFG_RX_CHAIN) >>
215 FW_PHY_CFG_RX_CHAIN_POS;
216}
217
193#endif /* __iwl_fw_h__ */ 218#endif /* __iwl_fw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index 3cc39ffe8ba5..d6f6c37c09fd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -103,7 +103,6 @@ enum iwl_power_level {
103 * @ant_coupling: antenna coupling in dB, default = 0 103 * @ant_coupling: antenna coupling in dB, default = 0
104 * @bt_ch_announce: BT channel inhibition, default = enable 104 * @bt_ch_announce: BT channel inhibition, default = enable
105 * @auto_agg: enable agg. without check, default = true 105 * @auto_agg: enable agg. without check, default = true
106 * @disable_5ghz: disable 5GHz capability, default = false
107 */ 106 */
108struct iwl_mod_params { 107struct iwl_mod_params {
109 int sw_crypto; 108 int sw_crypto;
@@ -120,7 +119,6 @@ struct iwl_mod_params {
120 int ant_coupling; 119 int ant_coupling;
121 bool bt_ch_announce; 120 bool bt_ch_announce;
122 bool auto_agg; 121 bool auto_agg;
123 bool disable_5ghz;
124}; 122};
125 123
126#endif /* #__iwl_modparams_h__ */ 124#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c
index efff2986b5b4..5cfd55b86ed3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-test.c
+++ b/drivers/net/wireless/iwlwifi/iwl-test.c
@@ -272,7 +272,7 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
272 272
273 reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 273 reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
274 skb = iwl_test_alloc_reply(tst, reply_len + 20); 274 skb = iwl_test_alloc_reply(tst, reply_len + 20);
275 reply_buf = kmalloc(reply_len, GFP_KERNEL); 275 reply_buf = kmemdup(&pkt->hdr, reply_len, GFP_KERNEL);
276 if (!skb || !reply_buf) { 276 if (!skb || !reply_buf) {
277 kfree_skb(skb); 277 kfree_skb(skb);
278 kfree(reply_buf); 278 kfree(reply_buf);
@@ -280,7 +280,6 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
280 } 280 }
281 281
282 /* The reply is in a page, that we cannot send to user space. */ 282 /* The reply is in a page, that we cannot send to user space. */
283 memcpy(reply_buf, &(pkt->hdr), reply_len);
284 iwl_free_resp(&cmd); 283 iwl_free_resp(&cmd);
285 284
286 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, 285 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 47954deb6493..1700232aa166 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -125,15 +125,15 @@ enum iwl_bt_kill_msk {
125}; 125};
126 126
127static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = { 127static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {
128 0xffffffff, 128 [BT_KILL_MSK_DEFAULT] = 0xffff0000,
129 0xfffffc00, 129 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
130 0, 130 [BT_KILL_MSK_REDUCED_TXPOW] = 0,
131}; 131};
132 132
133static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = { 133static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = {
134 0xffffffff, 134 [BT_KILL_MSK_DEFAULT] = 0xffff0000,
135 0xfffffc00, 135 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
136 0, 136 [BT_KILL_MSK_REDUCED_TXPOW] = 0,
137}; 137};
138 138
139#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0) 139#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0)
@@ -188,6 +188,8 @@ static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = {
188 188
189/* BT Antenna Coupling Threshold (dB) */ 189/* BT Antenna Coupling Threshold (dB) */
190#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) 190#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
191#define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3)
192
191 193
192int iwl_send_bt_init_conf(struct iwl_mvm *mvm) 194int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
193{ 195{
@@ -201,8 +203,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
201 203
202 cmd.flags = iwlwifi_mod_params.bt_coex_active ? 204 cmd.flags = iwlwifi_mod_params.bt_coex_active ?
203 BT_COEX_NW : BT_COEX_DISABLE; 205 BT_COEX_NW : BT_COEX_DISABLE;
204 cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? 206 cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? BT_CH_PRIMARY_EN : 0;
205 BT_CH_PRIMARY_EN | BT_CH_SECONDARY_EN : 0;
206 cmd.flags |= BT_SYNC_2_BT_DISABLE; 207 cmd.flags |= BT_SYNC_2_BT_DISABLE;
207 208
208 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | 209 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE |
@@ -275,7 +276,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
275 if (data->notif->bt_status) 276 if (data->notif->bt_status)
276 smps_mode = IEEE80211_SMPS_DYNAMIC; 277 smps_mode = IEEE80211_SMPS_DYNAMIC;
277 278
278 if (data->notif->bt_traffic_load) 279 if (data->notif->bt_traffic_load >= IWL_BT_LOAD_FORCE_SISO_THRESHOLD)
279 smps_mode = IEEE80211_SMPS_STATIC; 280 smps_mode = IEEE80211_SMPS_STATIC;
280 281
281 IWL_DEBUG_COEX(data->mvm, 282 IWL_DEBUG_COEX(data->mvm,
@@ -327,7 +328,7 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
327 return 0; 328 return 0;
328 329
329 IWL_DEBUG_COEX(mvm, 330 IWL_DEBUG_COEX(mvm,
330 "Udpate kill_msk: %d\n\t SCO %sactive A2DP %sactive SNIFF %sactive\n", 331 "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n",
331 bt_kill_msk, 332 bt_kill_msk,
332 BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", 333 BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",
333 BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", 334 BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index d4578cefe445..bf087abe39f3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -866,17 +866,13 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
866 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH); 866 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
867 867
868 if (wowlan->rfkill_release) 868 if (wowlan->rfkill_release)
869 d3_cfg_cmd.wakeup_flags |= 869 wowlan_config_cmd.wakeup_filter |=
870 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); 870 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
871 871
872 if (wowlan->tcp) { 872 if (wowlan->tcp) {
873 /* 873 /*
874 * The firmware currently doesn't really look at these, only 874 * Set the "link change" (really "link lost") flag as well
875 * the IWL_WOWLAN_WAKEUP_LINK_CHANGE bit. We have to set that 875 * since that implies losing the TCP connection.
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 */ 876 */
881 wowlan_config_cmd.wakeup_filter |= 877 wowlan_config_cmd.wakeup_filter |=
882 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS | 878 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 6d53850c5448..007a93b25bd7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -537,6 +537,12 @@ struct iwl_mac_beacon_cmd {
537 struct ieee80211_hdr frame[0]; 537 struct ieee80211_hdr frame[0];
538} __packed; 538} __packed;
539 539
540struct iwl_beacon_notif {
541 struct iwl_mvm_tx_resp beacon_notify_hdr;
542 __le64 tsf;
543 __le32 ibss_mgr_status;
544} __packed;
545
540/** 546/**
541 * enum iwl_dump_control - dump (flush) control flags 547 * enum iwl_dump_control - dump (flush) control flags
542 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty 548 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index f8d7e88234e4..1073f2682221 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -151,6 +151,7 @@ enum {
151 151
152 SET_CALIB_DEFAULT_CMD = 0x8e, 152 SET_CALIB_DEFAULT_CMD = 0x8e,
153 153
154 BEACON_NOTIFICATION = 0x90,
154 BEACON_TEMPLATE_CMD = 0x91, 155 BEACON_TEMPLATE_CMD = 0x91,
155 TX_ANT_CONFIGURATION_CMD = 0x98, 156 TX_ANT_CONFIGURATION_CMD = 0x98,
156 BT_CONFIG = 0x9b, 157 BT_CONFIG = 0x9b,
@@ -278,38 +279,7 @@ enum {
278 NVM_ACCESS_TARGET_EEPROM = 2, 279 NVM_ACCESS_TARGET_EEPROM = 2,
279}; 280};
280 281
281/** 282/* Section types for NVM_ACCESS_CMD */
282 * struct iwl_nvm_access_cmd_ver1 - Request the device to send the NVM.
283 * @op_code: 0 - read, 1 - write.
284 * @target: NVM_ACCESS_TARGET_*. should be 0 for read.
285 * @cache_refresh: 0 - None, 1- NVM.
286 * @offset: offset in the nvm data.
287 * @length: of the chunk.
288 * @data: empty on read, the NVM chunk on write
289 */
290struct iwl_nvm_access_cmd_ver1 {
291 u8 op_code;
292 u8 target;
293 u8 cache_refresh;
294 u8 reserved;
295 __le16 offset;
296 __le16 length;
297 u8 data[];
298} __packed; /* NVM_ACCESS_CMD_API_S_VER_1 */
299
300/**
301 * struct iwl_nvm_access_resp_ver1 - response to NVM_ACCESS_CMD
302 * @offset: the offset in the nvm data
303 * @length: of the chunk
304 * @data: the nvm chunk on when NVM_ACCESS_CMD was read, nothing on write
305 */
306struct iwl_nvm_access_resp_ver1 {
307 __le16 offset;
308 __le16 length;
309 u8 data[];
310} __packed; /* NVM_ACCESS_CMD_RESP_API_S_VER_1 */
311
312/* Section types for NVM_ACCESS_CMD version 2 */
313enum { 283enum {
314 NVM_SECTION_TYPE_HW = 0, 284 NVM_SECTION_TYPE_HW = 0,
315 NVM_SECTION_TYPE_SW, 285 NVM_SECTION_TYPE_SW,
@@ -330,7 +300,7 @@ enum {
330 * @length: in bytes, to read/write 300 * @length: in bytes, to read/write
331 * @data: if write operation, the data to write. On read its empty 301 * @data: if write operation, the data to write. On read its empty
332 */ 302 */
333struct iwl_nvm_access_cmd_ver2 { 303struct iwl_nvm_access_cmd {
334 u8 op_code; 304 u8 op_code;
335 u8 target; 305 u8 target;
336 __le16 type; 306 __le16 type;
@@ -347,7 +317,7 @@ struct iwl_nvm_access_cmd_ver2 {
347 * @status: 0 for success, fail otherwise 317 * @status: 0 for success, fail otherwise
348 * @data: if read operation, the data returned. Empty on write. 318 * @data: if read operation, the data returned. Empty on write.
349 */ 319 */
350struct iwl_nvm_access_resp_ver2 { 320struct iwl_nvm_access_resp {
351 __le16 offset; 321 __le16 offset;
352 __le16 length; 322 __le16 length;
353 __le16 type; 323 __le16 type;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 1006b3204e7b..e18c92dd60ec 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -114,7 +114,7 @@ static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant)
114 .valid = cpu_to_le32(valid_tx_ant), 114 .valid = cpu_to_le32(valid_tx_ant),
115 }; 115 };
116 116
117 IWL_DEBUG_HC(mvm, "select valid tx ant: %u\n", valid_tx_ant); 117 IWL_DEBUG_FW(mvm, "select valid tx ant: %u\n", valid_tx_ant);
118 return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC, 118 return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC,
119 sizeof(tx_ant_cmd), &tx_ant_cmd); 119 sizeof(tx_ant_cmd), &tx_ant_cmd);
120} 120}
@@ -134,9 +134,10 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
134 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr); 134 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr);
135 135
136 alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK; 136 alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK;
137 IWL_DEBUG_FW(mvm, "Alive ucode status 0x%04x revision 0x%01X 0x%01X\n", 137 IWL_DEBUG_FW(mvm,
138 "Alive ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
138 le16_to_cpu(palive->status), palive->ver_type, 139 le16_to_cpu(palive->status), palive->ver_type,
139 palive->ver_subtype); 140 palive->ver_subtype, palive->flags);
140 141
141 return true; 142 return true;
142} 143}
@@ -326,16 +327,14 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
326 WARN_ON(ret); 327 WARN_ON(ret);
327 328
328 /* Send TX valid antennas before triggering calibrations */ 329 /* Send TX valid antennas before triggering calibrations */
329 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); 330 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
330 if (ret) 331 if (ret)
331 goto error; 332 goto error;
332 333
333 /* WkP doesn't have all calibrations, need to set default values */ 334 /* need to set default values */
334 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 335 ret = iwl_set_default_calibrations(mvm);
335 ret = iwl_set_default_calibrations(mvm); 336 if (ret)
336 if (ret) 337 goto error;
337 goto error;
338 }
339 338
340 /* 339 /*
341 * Send phy configurations command to init uCode 340 * Send phy configurations command to init uCode
@@ -414,7 +413,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
414 goto error; 413 goto error;
415 } 414 }
416 415
417 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); 416 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
418 if (ret) 417 if (ret)
419 goto error; 418 goto error;
420 419
@@ -468,7 +467,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
468 goto error; 467 goto error;
469 } 468 }
470 469
471 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); 470 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
472 if (ret) 471 if (ret)
473 goto error; 472 goto error;
474 473
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 2779235daa35..86e312a4f629 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -196,7 +196,7 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
196 u32 qmask, ac; 196 u32 qmask, ac;
197 197
198 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 198 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
199 return BIT(IWL_OFFCHANNEL_QUEUE); 199 return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
200 200
201 qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ? 201 qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ?
202 BIT(vif->cab_queue) : 0; 202 BIT(vif->cab_queue) : 0;
@@ -692,7 +692,12 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
692 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); 692 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
693 693
694 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 694 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
695 /* No other data to be filled */ 695
696 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC |
697 MAC_FILTER_IN_CONTROL_AND_MGMT |
698 MAC_FILTER_IN_BEACON |
699 MAC_FILTER_IN_PROBE_REQUEST);
700
696 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 701 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
697} 702}
698 703
@@ -798,7 +803,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
798 TX_CMD_FLG_TSF); 803 TX_CMD_FLG_TSF);
799 804
800 mvm->mgmt_last_antenna_idx = 805 mvm->mgmt_last_antenna_idx =
801 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, 806 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
802 mvm->mgmt_last_antenna_idx); 807 mvm->mgmt_last_antenna_idx);
803 808
804 beacon_cmd.tx.rate_n_flags = 809 beacon_cmd.tx.rate_n_flags =
@@ -1013,3 +1018,22 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1013 mvmvif->uploaded = false; 1018 mvmvif->uploaded = false;
1014 return 0; 1019 return 0;
1015} 1020}
1021
1022int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1023 struct iwl_rx_cmd_buffer *rxb,
1024 struct iwl_device_cmd *cmd)
1025{
1026 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1027 struct iwl_beacon_notif *beacon = (void *)pkt->data;
1028 u16 status __maybe_unused =
1029 le16_to_cpu(beacon->beacon_notify_hdr.status.status);
1030 u32 rate __maybe_unused =
1031 le32_to_cpu(beacon->beacon_notify_hdr.initial_rate);
1032
1033 IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX rate:%d\n",
1034 status & TX_STATUS_MSK,
1035 beacon->beacon_notify_hdr.failure_frame,
1036 le64_to_cpu(beacon->tsf),
1037 rate);
1038 return 0;
1039}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 14dd5ee9a01e..3d193f8c33b6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -143,8 +143,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
143 IEEE80211_HW_AMPDU_AGGREGATION | 143 IEEE80211_HW_AMPDU_AGGREGATION |
144 IEEE80211_HW_TIMING_BEACON_ONLY; 144 IEEE80211_HW_TIMING_BEACON_ONLY;
145 145
146 hw->queues = IWL_FIRST_AMPDU_QUEUE; 146 hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
147 hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE; 147 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
148 hw->rate_control_algorithm = "iwl-mvm-rs"; 148 hw->rate_control_algorithm = "iwl-mvm-rs";
149 149
150 /* 150 /*
@@ -174,7 +174,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
174 hw->wiphy->n_iface_combinations = 174 hw->wiphy->n_iface_combinations =
175 ARRAY_SIZE(iwl_mvm_iface_combinations); 175 ARRAY_SIZE(iwl_mvm_iface_combinations);
176 176
177 hw->wiphy->max_remain_on_channel_duration = 500; 177 hw->wiphy->max_remain_on_channel_duration = 10000;
178 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; 178 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
179 179
180 /* Extract MAC address */ 180 /* Extract MAC address */
@@ -257,7 +257,7 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
257 goto drop; 257 goto drop;
258 } 258 }
259 259
260 if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_OFFCHANNEL_QUEUE && 260 if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
261 !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) 261 !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
262 goto drop; 262 goto drop;
263 263
@@ -1087,6 +1087,13 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1087 1087
1088 switch (cmd) { 1088 switch (cmd) {
1089 case SET_KEY: 1089 case SET_KEY:
1090 if (vif->type == NL80211_IFTYPE_AP && !sta) {
1091 /* GTK on AP interface is a TX-only key, return 0 */
1092 ret = 0;
1093 key->hw_key_idx = STA_KEY_IDX_INVALID;
1094 break;
1095 }
1096
1090 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n"); 1097 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
1091 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false); 1098 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
1092 if (ret) { 1099 if (ret) {
@@ -1095,11 +1102,17 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1095 * can't add key for RX, but we don't need it 1102 * can't add key for RX, but we don't need it
1096 * in the device for TX so still return 0 1103 * in the device for TX so still return 0
1097 */ 1104 */
1105 key->hw_key_idx = STA_KEY_IDX_INVALID;
1098 ret = 0; 1106 ret = 0;
1099 } 1107 }
1100 1108
1101 break; 1109 break;
1102 case DISABLE_KEY: 1110 case DISABLE_KEY:
1111 if (key->hw_key_idx == STA_KEY_IDX_INVALID) {
1112 ret = 0;
1113 break;
1114 }
1115
1103 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n"); 1116 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
1104 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key); 1117 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
1105 break; 1118 break;
@@ -1148,7 +1161,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
1148 &chandef, 1, 1); 1161 &chandef, 1, 1);
1149 1162
1150 /* Schedule the time events */ 1163 /* Schedule the time events */
1151 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration); 1164 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
1152 1165
1153 mutex_unlock(&mvm->mutex); 1166 mutex_unlock(&mvm->mutex);
1154 IWL_DEBUG_MAC80211(mvm, "leave\n"); 1167 IWL_DEBUG_MAC80211(mvm, "leave\n");
@@ -1252,6 +1265,7 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1252 * will handle quota settings. 1265 * will handle quota settings.
1253 */ 1266 */
1254 if (vif->type == NL80211_IFTYPE_MONITOR) { 1267 if (vif->type == NL80211_IFTYPE_MONITOR) {
1268 mvmvif->monitor_active = true;
1255 ret = iwl_mvm_update_quotas(mvm, vif); 1269 ret = iwl_mvm_update_quotas(mvm, vif);
1256 if (ret) 1270 if (ret)
1257 goto out_remove_binding; 1271 goto out_remove_binding;
@@ -1282,15 +1296,16 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1282 if (vif->type == NL80211_IFTYPE_AP) 1296 if (vif->type == NL80211_IFTYPE_AP)
1283 goto out_unlock; 1297 goto out_unlock;
1284 1298
1285 iwl_mvm_binding_remove_vif(mvm, vif);
1286 switch (vif->type) { 1299 switch (vif->type) {
1287 case NL80211_IFTYPE_MONITOR: 1300 case NL80211_IFTYPE_MONITOR:
1288 iwl_mvm_update_quotas(mvm, vif); 1301 mvmvif->monitor_active = false;
1302 iwl_mvm_update_quotas(mvm, NULL);
1289 break; 1303 break;
1290 default: 1304 default:
1291 break; 1305 break;
1292 } 1306 }
1293 1307
1308 iwl_mvm_binding_remove_vif(mvm, vif);
1294out_unlock: 1309out_unlock:
1295 mvmvif->phy_ctxt = NULL; 1310 mvmvif->phy_ctxt = NULL;
1296 mutex_unlock(&mvm->mutex); 1311 mutex_unlock(&mvm->mutex);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 203eb85e03d3..53d58968e30a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -90,10 +90,6 @@ enum iwl_mvm_tx_fifo {
90 IWL_MVM_TX_FIFO_VO, 90 IWL_MVM_TX_FIFO_VO,
91}; 91};
92 92
93/* Placeholder */
94#define IWL_OFFCHANNEL_QUEUE 8
95#define IWL_FIRST_AMPDU_QUEUE 11
96
97extern struct ieee80211_ops iwl_mvm_hw_ops; 93extern struct ieee80211_ops iwl_mvm_hw_ops;
98/** 94/**
99 * struct iwl_mvm_mod_params - module parameters for iwlmvm 95 * struct iwl_mvm_mod_params - module parameters for iwlmvm
@@ -161,6 +157,8 @@ enum iwl_power_scheme {
161 * @uploaded: indicates the MAC context has been added to the device 157 * @uploaded: indicates the MAC context has been added to the device
162 * @ap_active: indicates that ap context is configured, and that the interface 158 * @ap_active: indicates that ap context is configured, and that the interface
163 * should get quota etc. 159 * should get quota etc.
160 * @monitor_active: indicates that monitor context is configured, and that the
161 * interface should get quota etc.
164 * @queue_params: QoS params for this MAC 162 * @queue_params: QoS params for this MAC
165 * @bcast_sta: station used for broadcast packets. Used by the following 163 * @bcast_sta: station used for broadcast packets. Used by the following
166 * vifs: P2P_DEVICE, GO and AP. 164 * vifs: P2P_DEVICE, GO and AP.
@@ -173,6 +171,7 @@ struct iwl_mvm_vif {
173 171
174 bool uploaded; 172 bool uploaded;
175 bool ap_active; 173 bool ap_active;
174 bool monitor_active;
176 175
177 u32 ap_beacon_time; 176 u32 ap_beacon_time;
178 177
@@ -281,10 +280,7 @@ struct iwl_mvm {
281 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES]; 280 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES];
282 281
283 struct iwl_nvm_data *nvm_data; 282 struct iwl_nvm_data *nvm_data;
284 /* eeprom blob for debugfs/testmode */ 283 /* NVM sections */
285 u8 *eeprom_blob;
286 size_t eeprom_blob_size;
287 /* NVM sections for 7000 family */
288 struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS]; 284 struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS];
289 285
290 /* EEPROM MAC addresses */ 286 /* EEPROM MAC addresses */
@@ -451,6 +447,9 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
451 struct ieee80211_vif *vif); 447 struct ieee80211_vif *vif);
452int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, 448int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
453 struct ieee80211_vif *vif); 449 struct ieee80211_vif *vif);
450int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
451 struct iwl_rx_cmd_buffer *rxb,
452 struct iwl_device_cmd *cmd);
454 453
455/* Bindings */ 454/* Bindings */
456int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 455int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 93e3d0f174cc..b8ec02f89acc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -77,26 +77,8 @@ static const int nvm_to_read[] = {
77/* Default NVM size to read */ 77/* Default NVM size to read */
78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024); 78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024);
79 79
80/* used to simplify the shared operations on NCM_ACCESS_CMD versions */ 80static inline void iwl_nvm_fill_read(struct iwl_nvm_access_cmd *cmd,
81union iwl_nvm_access_cmd { 81 u16 offset, u16 length, u16 section)
82 struct iwl_nvm_access_cmd_ver1 ver1;
83 struct iwl_nvm_access_cmd_ver2 ver2;
84};
85union iwl_nvm_access_resp {
86 struct iwl_nvm_access_resp_ver1 ver1;
87 struct iwl_nvm_access_resp_ver2 ver2;
88};
89
90static inline void iwl_nvm_fill_read_ver1(struct iwl_nvm_access_cmd_ver1 *cmd,
91 u16 offset, u16 length)
92{
93 cmd->offset = cpu_to_le16(offset);
94 cmd->length = cpu_to_le16(length);
95 cmd->cache_refresh = 1;
96}
97
98static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd,
99 u16 offset, u16 length, u16 section)
100{ 82{
101 cmd->offset = cpu_to_le16(offset); 83 cmd->offset = cpu_to_le16(offset);
102 cmd->length = cpu_to_le16(length); 84 cmd->length = cpu_to_le16(length);
@@ -106,8 +88,8 @@ static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd,
106static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, 88static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
107 u16 offset, u16 length, u8 *data) 89 u16 offset, u16 length, u8 *data)
108{ 90{
109 union iwl_nvm_access_cmd nvm_access_cmd; 91 struct iwl_nvm_access_cmd nvm_access_cmd = {};
110 union iwl_nvm_access_resp *nvm_resp; 92 struct iwl_nvm_access_resp *nvm_resp;
111 struct iwl_rx_packet *pkt; 93 struct iwl_rx_packet *pkt;
112 struct iwl_host_cmd cmd = { 94 struct iwl_host_cmd cmd = {
113 .id = NVM_ACCESS_CMD, 95 .id = NVM_ACCESS_CMD,
@@ -117,18 +99,8 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
117 int ret, bytes_read, offset_read; 99 int ret, bytes_read, offset_read;
118 u8 *resp_data; 100 u8 *resp_data;
119 101
120 memset(&nvm_access_cmd, 0, sizeof(nvm_access_cmd)); 102 iwl_nvm_fill_read(&nvm_access_cmd, offset, length, section);
121 103 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd);
122 /* TODO: not sure family should be the decider, maybe FW version? */
123 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
124 iwl_nvm_fill_read_ver2(&(nvm_access_cmd.ver2),
125 offset, length, section);
126 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver2);
127 } else {
128 iwl_nvm_fill_read_ver1(&(nvm_access_cmd.ver1),
129 offset, length);
130 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver1);
131 }
132 104
133 ret = iwl_mvm_send_cmd(mvm, &cmd); 105 ret = iwl_mvm_send_cmd(mvm, &cmd);
134 if (ret) 106 if (ret)
@@ -144,17 +116,10 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
144 116
145 /* Extract NVM response */ 117 /* Extract NVM response */
146 nvm_resp = (void *)pkt->data; 118 nvm_resp = (void *)pkt->data;
147 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 119 ret = le16_to_cpu(nvm_resp->status);
148 ret = le16_to_cpu(nvm_resp->ver2.status); 120 bytes_read = le16_to_cpu(nvm_resp->length);
149 bytes_read = le16_to_cpu(nvm_resp->ver2.length); 121 offset_read = le16_to_cpu(nvm_resp->offset);
150 offset_read = le16_to_cpu(nvm_resp->ver2.offset); 122 resp_data = nvm_resp->data;
151 resp_data = nvm_resp->ver2.data;
152 } else {
153 ret = le16_to_cpu(nvm_resp->ver1.length) <= 0;
154 bytes_read = le16_to_cpu(nvm_resp->ver1.length);
155 offset_read = le16_to_cpu(nvm_resp->ver1.offset);
156 resp_data = nvm_resp->ver1.data;
157 }
158 if (ret) { 123 if (ret) {
159 IWL_ERR(mvm, 124 IWL_ERR(mvm,
160 "NVM access command failed with status %d (device: %s)\n", 125 "NVM access command failed with status %d (device: %s)\n",
@@ -194,17 +159,10 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
194{ 159{
195 u16 length, offset = 0; 160 u16 length, offset = 0;
196 int ret; 161 int ret;
197 bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000;
198 162
199 /* Set nvm section read length */ 163 /* Set nvm section read length */
200 length = IWL_NVM_DEFAULT_CHUNK_SIZE; 164 length = IWL_NVM_DEFAULT_CHUNK_SIZE;
201 165
202 /*
203 * if length is greater than EEPROM size, truncate it because uCode
204 * doesn't check it by itself, and exit the loop when reached.
205 */
206 if (old_eeprom && length > mvm->cfg->base_params->eeprom_size)
207 length = mvm->cfg->base_params->eeprom_size;
208 ret = length; 166 ret = length;
209 167
210 /* Read the NVM until exhausted (reading less than requested) */ 168 /* Read the NVM until exhausted (reading less than requested) */
@@ -217,8 +175,6 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
217 return ret; 175 return ret;
218 } 176 }
219 offset += ret; 177 offset += ret;
220 if (old_eeprom && offset == mvm->cfg->base_params->eeprom_size)
221 break;
222 } 178 }
223 179
224 IWL_INFO(mvm, "NVM section %d read completed\n", section); 180 IWL_INFO(mvm, "NVM section %d read completed\n", section);
@@ -252,63 +208,31 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
252 int ret, i, section; 208 int ret, i, section;
253 u8 *nvm_buffer, *temp; 209 u8 *nvm_buffer, *temp;
254 210
255 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 211 /* TODO: find correct NVM max size for a section */
256 /* TODO: find correct NVM max size for a section */ 212 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
257 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, 213 GFP_KERNEL);
258 GFP_KERNEL); 214 if (!nvm_buffer)
259 if (!nvm_buffer) 215 return -ENOMEM;
260 return -ENOMEM; 216 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
261 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { 217 section = nvm_to_read[i];
262 section = nvm_to_read[i]; 218 /* we override the constness for initial read */
263 /* we override the constness for initial read */ 219 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
264 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
265 if (ret < 0)
266 break;
267 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
268 if (!temp) {
269 ret = -ENOMEM;
270 break;
271 }
272 mvm->nvm_sections[section].data = temp;
273 mvm->nvm_sections[section].length = ret;
274 }
275 kfree(nvm_buffer);
276 if (ret < 0) 220 if (ret < 0)
277 return ret; 221 break;
278 } else { 222 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
279 /* allocate eeprom */ 223 if (!temp) {
280 mvm->eeprom_blob_size = mvm->cfg->base_params->eeprom_size; 224 ret = -ENOMEM;
281 IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM size = %zd\n", 225 break;
282 mvm->eeprom_blob_size);
283 mvm->eeprom_blob = kzalloc(mvm->eeprom_blob_size, GFP_KERNEL);
284 if (!mvm->eeprom_blob)
285 return -ENOMEM;
286
287 ret = iwl_nvm_read_section(mvm, 0, mvm->eeprom_blob);
288 if (ret != mvm->eeprom_blob_size) {
289 IWL_ERR(mvm, "Read partial NVM %d/%zd\n",
290 ret, mvm->eeprom_blob_size);
291 kfree(mvm->eeprom_blob);
292 mvm->eeprom_blob = NULL;
293 return -EINVAL;
294 } 226 }
227 mvm->nvm_sections[section].data = temp;
228 mvm->nvm_sections[section].length = ret;
295 } 229 }
230 kfree(nvm_buffer);
231 if (ret < 0)
232 return ret;
296 233
297 ret = 0; 234 ret = 0;
298 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) 235 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
299 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
300 else
301 mvm->nvm_data =
302 iwl_parse_eeprom_data(mvm->trans->dev,
303 mvm->cfg,
304 mvm->eeprom_blob,
305 mvm->eeprom_blob_size);
306
307 if (!mvm->nvm_data) {
308 kfree(mvm->eeprom_blob);
309 mvm->eeprom_blob = NULL;
310 ret = -ENOMEM;
311 }
312 236
313 return ret; 237 return ret;
314} 238}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 828bdddd07e9..fe031d304d1e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -143,21 +143,12 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
143 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash; 143 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
144 u32 reg_val = 0; 144 u32 reg_val = 0;
145 145
146 /* 146 radio_cfg_type = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_TYPE) >>
147 * We can't upload the correct value to the INIT image 147 FW_PHY_CFG_RADIO_TYPE_POS;
148 * as we don't have nvm_data by that time. 148 radio_cfg_step = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_STEP) >>
149 * 149 FW_PHY_CFG_RADIO_STEP_POS;
150 * TODO: Figure out what we should do here 150 radio_cfg_dash = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_DASH) >>
151 */ 151 FW_PHY_CFG_RADIO_DASH_POS;
152 if (mvm->nvm_data) {
153 radio_cfg_type = mvm->nvm_data->radio_cfg_type;
154 radio_cfg_step = mvm->nvm_data->radio_cfg_step;
155 radio_cfg_dash = mvm->nvm_data->radio_cfg_dash;
156 } else {
157 radio_cfg_type = 0;
158 radio_cfg_step = 0;
159 radio_cfg_dash = 0;
160 }
161 152
162 /* SKU control */ 153 /* SKU control */
163 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) << 154 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
@@ -175,7 +166,6 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
175 166
176 /* silicon bits */ 167 /* silicon bits */
177 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI; 168 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
178 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_MAC_SI;
179 169
180 iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG, 170 iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
181 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | 171 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
@@ -231,6 +221,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
231 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), 221 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
232 222
233 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true), 223 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
224 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
234 225
235 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 226 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
236 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), 227 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
@@ -276,6 +267,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
276 CMD(WEP_KEY), 267 CMD(WEP_KEY),
277 CMD(REPLY_RX_PHY_CMD), 268 CMD(REPLY_RX_PHY_CMD),
278 CMD(REPLY_RX_MPDU_CMD), 269 CMD(REPLY_RX_MPDU_CMD),
270 CMD(BEACON_NOTIFICATION),
279 CMD(BEACON_TEMPLATE_CMD), 271 CMD(BEACON_TEMPLATE_CMD),
280 CMD(STATISTICS_NOTIFICATION), 272 CMD(STATISTICS_NOTIFICATION),
281 CMD(TX_ANT_CONFIGURATION_CMD), 273 CMD(TX_ANT_CONFIGURATION_CMD),
@@ -319,16 +311,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
319 }; 311 };
320 int err, scan_size; 312 int err, scan_size;
321 313
322 switch (cfg->device_family) {
323 case IWL_DEVICE_FAMILY_6030:
324 case IWL_DEVICE_FAMILY_6005:
325 case IWL_DEVICE_FAMILY_7000:
326 break;
327 default:
328 IWL_ERR(trans, "Trying to load mvm on an unsupported device\n");
329 return NULL;
330 }
331
332 /******************************** 314 /********************************
333 * 1. Allocating and configuring HW data 315 * 1. Allocating and configuring HW data
334 ********************************/ 316 ********************************/
@@ -444,7 +426,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
444 out_free: 426 out_free:
445 iwl_phy_db_free(mvm->phy_db); 427 iwl_phy_db_free(mvm->phy_db);
446 kfree(mvm->scan_cmd); 428 kfree(mvm->scan_cmd);
447 kfree(mvm->eeprom_blob);
448 iwl_trans_stop_hw(trans, true); 429 iwl_trans_stop_hw(trans, true);
449 ieee80211_free_hw(mvm->hw); 430 ieee80211_free_hw(mvm->hw);
450 return NULL; 431 return NULL;
@@ -466,7 +447,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
466 iwl_phy_db_free(mvm->phy_db); 447 iwl_phy_db_free(mvm->phy_db);
467 mvm->phy_db = NULL; 448 mvm->phy_db = NULL;
468 449
469 kfree(mvm->eeprom_blob);
470 iwl_free_nvm_data(mvm->nvm_data); 450 iwl_free_nvm_data(mvm->nvm_data);
471 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++) 451 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++)
472 kfree(mvm->nvm_sections[i].data); 452 kfree(mvm->nvm_sections[i].data);
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index 0d537e035ef0..0f0b44eabd93 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -142,7 +142,7 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
142 struct cfg80211_chan_def *chandef, 142 struct cfg80211_chan_def *chandef,
143 u8 chains_static, u8 chains_dynamic) 143 u8 chains_static, u8 chains_dynamic)
144{ 144{
145 u8 valid_rx_chains, active_cnt, idle_cnt; 145 u8 active_cnt, idle_cnt;
146 146
147 /* Set the channel info data */ 147 /* Set the channel info data */
148 cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ? 148 cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ?
@@ -158,17 +158,16 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
158 * Need to add on chain noise calibration limitations, and 158 * Need to add on chain noise calibration limitations, and
159 * BT coex considerations. 159 * BT coex considerations.
160 */ 160 */
161 valid_rx_chains = mvm->nvm_data->valid_rx_ant;
162 idle_cnt = chains_static; 161 idle_cnt = chains_static;
163 active_cnt = chains_dynamic; 162 active_cnt = chains_dynamic;
164 163
165 cmd->rxchain_info = cpu_to_le32(valid_rx_chains << 164 cmd->rxchain_info = cpu_to_le32(iwl_fw_valid_rx_ant(mvm->fw) <<
166 PHY_RX_CHAIN_VALID_POS); 165 PHY_RX_CHAIN_VALID_POS);
167 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); 166 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
168 cmd->rxchain_info |= cpu_to_le32(active_cnt << 167 cmd->rxchain_info |= cpu_to_le32(active_cnt <<
169 PHY_RX_CHAIN_MIMO_CNT_POS); 168 PHY_RX_CHAIN_MIMO_CNT_POS);
170 169
171 cmd->txchain_info = cpu_to_le32(mvm->nvm_data->valid_tx_ant); 170 cmd->txchain_info = cpu_to_le32(iwl_fw_valid_tx_ant(mvm->fw));
172} 171}
173 172
174/* 173/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index df85c49dc599..a1e3e923ea3e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -114,7 +114,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
114 data->n_interfaces[id]++; 114 data->n_interfaces[id]++;
115 break; 115 break;
116 case NL80211_IFTYPE_MONITOR: 116 case NL80211_IFTYPE_MONITOR:
117 data->n_interfaces[id]++; 117 if (mvmvif->monitor_active)
118 data->n_interfaces[id]++;
118 break; 119 break;
119 case NL80211_IFTYPE_P2P_DEVICE: 120 case NL80211_IFTYPE_P2P_DEVICE:
120 break; 121 break;
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 0d3c76b29242..2157b0f8ced5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -74,7 +74,7 @@
74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
75{ 75{
76 u16 rx_chain; 76 u16 rx_chain;
77 u8 rx_ant = mvm->nvm_data->valid_rx_ant; 77 u8 rx_ant = iwl_fw_valid_rx_ant(mvm->fw);
78 78
79 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS; 79 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
80 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS; 80 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
@@ -115,7 +115,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
115 u32 tx_ant; 115 u32 tx_ant;
116 116
117 mvm->scan_last_antenna_idx = 117 mvm->scan_last_antenna_idx =
118 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, 118 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
119 mvm->scan_last_antenna_idx); 119 mvm->scan_last_antenna_idx);
120 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS; 120 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
121 121
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index c2c7f5176027..4dc934bed055 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -76,14 +76,12 @@
76#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024)) 76#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024))
77#define MSEC_TO_TU(_msec) (_msec*1000/1024) 77#define MSEC_TO_TU(_msec) (_msec*1000/1024)
78 78
79/* For ROC use a TE type which has priority high enough to be scheduled when 79/*
80 * there is a concurrent BSS or GO/AP. Currently, use a TE type that has 80 * For the high priority TE use a time event type that has similar priority to
81 * priority similar to the TE priority used for action scans by the FW. 81 * the FW's action scan priority.
82 * TODO: This needs to be changed, based on the reason for the ROC, i.e., use
83 * TE_P2P_DEVICE_DISCOVERABLE for remain on channel without mgmt skb, and use
84 * TE_P2P_DEVICE_ACTION_SCAN
85 */ 82 */
86#define IWL_MVM_ROC_TE_TYPE TE_P2P_DEVICE_ACTION_SCAN 83#define IWL_MVM_ROC_TE_TYPE_NORMAL TE_P2P_DEVICE_DISCOVERABLE
84#define IWL_MVM_ROC_TE_TYPE_MGMT_TX TE_P2P_CLIENT_ASSOC
87 85
88void iwl_mvm_te_clear_data(struct iwl_mvm *mvm, 86void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
89 struct iwl_mvm_time_event_data *te_data) 87 struct iwl_mvm_time_event_data *te_data)
@@ -116,7 +114,7 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
116 * issue as it will have to complete before the next command is 114 * issue as it will have to complete before the next command is
117 * executed, and a new time event means a new command. 115 * executed, and a new time event means a new command.
118 */ 116 */
119 iwl_mvm_flush_tx_path(mvm, BIT(IWL_OFFCHANNEL_QUEUE), false); 117 iwl_mvm_flush_tx_path(mvm, BIT(IWL_MVM_OFFCHANNEL_QUEUE), false);
120} 118}
121 119
122static void iwl_mvm_roc_finished(struct iwl_mvm *mvm) 120static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
@@ -438,7 +436,7 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
438} 436}
439 437
440int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 438int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
441 int duration) 439 int duration, enum ieee80211_roc_type type)
442{ 440{
443 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 441 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
444 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 442 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
@@ -459,21 +457,29 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
459 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); 457 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
460 time_cmd.id_and_color = 458 time_cmd.id_and_color =
461 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); 459 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
462 time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE); 460
461 switch (type) {
462 case IEEE80211_ROC_TYPE_NORMAL:
463 time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_NORMAL);
464 break;
465 case IEEE80211_ROC_TYPE_MGMT_TX:
466 time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_MGMT_TX);
467 break;
468 default:
469 WARN_ONCE(1, "Got an invalid ROC type\n");
470 return -EINVAL;
471 }
463 472
464 time_cmd.apply_time = cpu_to_le32(0); 473 time_cmd.apply_time = cpu_to_le32(0);
465 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT); 474 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT);
466 time_cmd.is_present = cpu_to_le32(1); 475 time_cmd.is_present = cpu_to_le32(1);
467
468 time_cmd.interval = cpu_to_le32(1); 476 time_cmd.interval = cpu_to_le32(1);
469 477
470 /* 478 /*
471 * IWL_MVM_ROC_TE_TYPE can have lower priority than other events 479 * The P2P Device TEs can have lower priority than other events
472 * that are being scheduled by the driver/fw, and thus it might not be 480 * that are being scheduled by the driver/fw, and thus it might not be
473 * scheduled. To improve the chances of it being scheduled, allow it to 481 * scheduled. To improve the chances of it being scheduled, allow them
474 * be fragmented. 482 * to be fragmented, and in addition allow them to be delayed.
475 * In addition, for the same reasons, allow to delay the scheduling of
476 * the time event.
477 */ 483 */
478 time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20); 484 time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20);
479 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2)); 485 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2));
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index b36424eda361..f86c51065ed3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -162,6 +162,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
162 * that the vif type is NL80211_IFTYPE_P2P_DEVICE 162 * that the vif type is NL80211_IFTYPE_P2P_DEVICE
163 * @duration: the requested duration in millisecond for the fw to be on the 163 * @duration: the requested duration in millisecond for the fw to be on the
164 * channel that is bound to the vif. 164 * channel that is bound to the vif.
165 * @type: the remain on channel request type
165 * 166 *
166 * This function can be used to issue a remain on channel session, 167 * This function can be used to issue a remain on channel session,
167 * which means that the fw will stay in the channel for the request %duration 168 * which means that the fw will stay in the channel for the request %duration
@@ -172,7 +173,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
172 * another notification to the driver. 173 * another notification to the driver.
173 */ 174 */
174int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 175int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
175 int duration); 176 int duration, enum ieee80211_roc_type type);
176 177
177/** 178/**
178 * iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity 179 * iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 0556d5e16f4e..0acc0bff43c7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
417 spin_unlock(&mvmsta->lock); 417 spin_unlock(&mvmsta->lock);
418 418
419 if (mvmsta->vif->type == NL80211_IFTYPE_AP && 419 if (mvmsta->vif->type == NL80211_IFTYPE_AP &&
420 txq_id < IWL_FIRST_AMPDU_QUEUE) 420 txq_id < IWL_MVM_FIRST_AGG_QUEUE)
421 atomic_inc(&mvmsta->pending_frames); 421 atomic_inc(&mvmsta->pending_frames);
422 422
423 return 0; 423 return 0;
@@ -606,7 +606,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
606 info); 606 info);
607 607
608 /* Single frame failure in an AMPDU queue => send BAR */ 608 /* Single frame failure in an AMPDU queue => send BAR */
609 if (txq_id >= IWL_FIRST_AMPDU_QUEUE && 609 if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE &&
610 !(info->flags & IEEE80211_TX_STAT_ACK)) 610 !(info->flags & IEEE80211_TX_STAT_ACK))
611 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 611 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
612 612
@@ -619,7 +619,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
619 ieee80211_tx_status_ni(mvm->hw, skb); 619 ieee80211_tx_status_ni(mvm->hw, skb);
620 } 620 }
621 621
622 if (txq_id >= IWL_FIRST_AMPDU_QUEUE) { 622 if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE) {
623 /* If this is an aggregation queue, we use the ssn since: 623 /* If this is an aggregation queue, we use the ssn since:
624 * ssn = wifi seq_num % 256. 624 * ssn = wifi seq_num % 256.
625 * The seq_ctl is the sequence control of the packet to which 625 * The seq_ctl is the sequence control of the packet to which
@@ -681,7 +681,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
681 * If there are no pending frames for this STA, notify mac80211 that 681 * If there are no pending frames for this STA, notify mac80211 that
682 * this station can go to sleep in its STA table. 682 * this station can go to sleep in its STA table.
683 */ 683 */
684 if (txq_id < IWL_FIRST_AMPDU_QUEUE && mvmsta && 684 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta &&
685 !WARN_ON(skb_freed > 1) && 685 !WARN_ON(skb_freed > 1) &&
686 mvmsta->vif->type == NL80211_IFTYPE_AP && 686 mvmsta->vif->type == NL80211_IFTYPE_AP &&
687 atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) { 687 atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) {
@@ -750,7 +750,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
750 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 750 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
751 struct ieee80211_sta *sta; 751 struct ieee80211_sta *sta;
752 752
753 if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_FIRST_AMPDU_QUEUE)) 753 if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_MVM_FIRST_AGG_QUEUE))
754 return; 754 return;
755 755
756 if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS)) 756 if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS))
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 282a5cafa913..68466ca80770 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1564,8 +1564,11 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
1564 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) 1564 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
1565 return -EIO; 1565 return -EIO;
1566 1566
1567 if (test_bit(STATUS_RFKILL, &trans_pcie->status)) 1567 if (test_bit(STATUS_RFKILL, &trans_pcie->status)) {
1568 IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
1569 cmd->id);
1568 return -ERFKILL; 1570 return -ERFKILL;
1571 }
1569 1572
1570 if (cmd->flags & CMD_ASYNC) 1573 if (cmd->flags & CMD_ASYNC)
1571 return iwl_pcie_send_hcmd_async(trans, cmd); 1574 return iwl_pcie_send_hcmd_async(trans, cmd);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 7490c4fc7177..0064d38276bf 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -964,6 +964,12 @@ static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw,
964 newtype, vif->addr); 964 newtype, vif->addr);
965 hwsim_check_magic(vif); 965 hwsim_check_magic(vif);
966 966
967 /*
968 * interface may change from non-AP to AP in
969 * which case this needs to be set up again
970 */
971 vif->cab_queue = 0;
972
967 return 0; 973 return 0;
968} 974}
969 975
@@ -1389,7 +1395,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
1389 return 0; 1395 return 0;
1390} 1396}
1391 1397
1392static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop) 1398static void mac80211_hwsim_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1393{ 1399{
1394 /* Not implemented, queues only on kernel side */ 1400 /* Not implemented, queues only on kernel side */
1395} 1401}
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c
index cf43b3c29250..966a78f8e21a 100644
--- a/drivers/net/wireless/mwifiex/11ac.c
+++ b/drivers/net/wireless/mwifiex/11ac.c
@@ -259,3 +259,44 @@ int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
259 259
260 return ret_len; 260 return ret_len;
261} 261}
262
263int mwifiex_cmd_11ac_cfg(struct mwifiex_private *priv,
264 struct host_cmd_ds_command *cmd, u16 cmd_action,
265 struct mwifiex_11ac_vht_cfg *cfg)
266{
267 struct host_cmd_11ac_vht_cfg *vhtcfg = &cmd->params.vht_cfg;
268
269 cmd->command = cpu_to_le16(HostCmd_CMD_11AC_CFG);
270 cmd->size = cpu_to_le16(sizeof(struct host_cmd_11ac_vht_cfg) +
271 S_DS_GEN);
272 vhtcfg->action = cpu_to_le16(cmd_action);
273 vhtcfg->band_config = cfg->band_config;
274 vhtcfg->misc_config = cfg->misc_config;
275 vhtcfg->cap_info = cpu_to_le32(cfg->cap_info);
276 vhtcfg->mcs_tx_set = cpu_to_le32(cfg->mcs_tx_set);
277 vhtcfg->mcs_rx_set = cpu_to_le32(cfg->mcs_rx_set);
278
279 return 0;
280}
281
282/* This function initializes the BlockACK setup information for given
283 * mwifiex_private structure for 11ac enabled networks.
284 */
285void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv)
286{
287 priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT;
288
289 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
290 priv->add_ba_param.tx_win_size =
291 MWIFIEX_11AC_UAP_AMPDU_DEF_TXWINSIZE;
292 priv->add_ba_param.rx_win_size =
293 MWIFIEX_11AC_UAP_AMPDU_DEF_RXWINSIZE;
294 } else {
295 priv->add_ba_param.tx_win_size =
296 MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE;
297 priv->add_ba_param.rx_win_size =
298 MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE;
299 }
300
301 return;
302}
diff --git a/drivers/net/wireless/mwifiex/11ac.h b/drivers/net/wireless/mwifiex/11ac.h
index 80fd1ba46200..7c2c69b5b3eb 100644
--- a/drivers/net/wireless/mwifiex/11ac.h
+++ b/drivers/net/wireless/mwifiex/11ac.h
@@ -20,7 +20,24 @@
20#ifndef _MWIFIEX_11AC_H_ 20#ifndef _MWIFIEX_11AC_H_
21#define _MWIFIEX_11AC_H_ 21#define _MWIFIEX_11AC_H_
22 22
23#define VHT_CFG_2GHZ BIT(0)
24#define VHT_CFG_5GHZ BIT(1)
25
26enum vht_cfg_misc_config {
27 VHT_CAP_TX_OPERATION = 1,
28 VHT_CAP_ASSOCIATION,
29 VHT_CAP_UAP_ONLY
30};
31
32#define DEFAULT_VHT_MCS_SET 0xfffa
33#define DISABLE_VHT_MCS_SET 0xffff
34
35#define VHT_BW_80_160_80P80 BIT(2)
36
23int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv, 37int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
24 struct mwifiex_bssdescriptor *bss_desc, 38 struct mwifiex_bssdescriptor *bss_desc,
25 u8 **buffer); 39 u8 **buffer);
40int mwifiex_cmd_11ac_cfg(struct mwifiex_private *priv,
41 struct host_cmd_ds_command *cmd, u16 cmd_action,
42 struct mwifiex_11ac_vht_cfg *cfg);
26#endif /* _MWIFIEX_11AC_H_ */ 43#endif /* _MWIFIEX_11AC_H_ */
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 45f19716687e..41e9d25a2d8e 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -679,3 +679,25 @@ void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra)
679 679
680 return; 680 return;
681} 681}
682
683/* This function initializes the BlockACK setup information for given
684 * mwifiex_private structure.
685 */
686void mwifiex_set_ba_params(struct mwifiex_private *priv)
687{
688 priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT;
689
690 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
691 priv->add_ba_param.tx_win_size =
692 MWIFIEX_UAP_AMPDU_DEF_TXWINSIZE;
693 priv->add_ba_param.rx_win_size =
694 MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE;
695 } else {
696 priv->add_ba_param.tx_win_size =
697 MWIFIEX_STA_AMPDU_DEF_TXWINSIZE;
698 priv->add_ba_param.rx_win_size =
699 MWIFIEX_STA_AMPDU_DEF_RXWINSIZE;
700 }
701
702 return;
703}
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 78c2bb8d3726..47012947a447 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1374,6 +1374,18 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1374 } 1374 }
1375 1375
1376 mwifiex_set_ht_params(priv, bss_cfg, params); 1376 mwifiex_set_ht_params(priv, bss_cfg, params);
1377
1378 if (priv->adapter->is_hw_11ac_capable) {
1379 mwifiex_set_vht_params(priv, bss_cfg, params);
1380 mwifiex_set_vht_width(priv, params->chandef.width,
1381 priv->ap_11ac_enabled);
1382 }
1383
1384 if (priv->ap_11ac_enabled)
1385 mwifiex_set_11ac_ba_params(priv);
1386 else
1387 mwifiex_set_ba_params(priv);
1388
1377 mwifiex_set_wmm_params(priv, bss_cfg, params); 1389 mwifiex_set_wmm_params(priv, bss_cfg, params);
1378 1390
1379 if (params->inactivity_timeout > 0) { 1391 if (params->inactivity_timeout > 0) {
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 9a1302bd4c03..da469c336aa1 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -153,7 +153,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
153 " or cmd size is 0, not sending\n"); 153 " or cmd size is 0, not sending\n");
154 if (cmd_node->wait_q_enabled) 154 if (cmd_node->wait_q_enabled)
155 adapter->cmd_wait_q.status = -1; 155 adapter->cmd_wait_q.status = -1;
156 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 156 mwifiex_recycle_cmd_node(adapter, cmd_node);
157 return -1; 157 return -1;
158 } 158 }
159 159
@@ -167,7 +167,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
167 "DNLD_CMD: FW in reset state, ignore cmd %#x\n", 167 "DNLD_CMD: FW in reset state, ignore cmd %#x\n",
168 cmd_code); 168 cmd_code);
169 mwifiex_complete_cmd(adapter, cmd_node); 169 mwifiex_complete_cmd(adapter, cmd_node);
170 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 170 mwifiex_recycle_cmd_node(adapter, cmd_node);
171 return -1; 171 return -1;
172 } 172 }
173 173
@@ -228,7 +228,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
228 adapter->cmd_sent = false; 228 adapter->cmd_sent = false;
229 if (cmd_node->wait_q_enabled) 229 if (cmd_node->wait_q_enabled)
230 adapter->cmd_wait_q.status = -1; 230 adapter->cmd_wait_q.status = -1;
231 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); 231 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
232 232
233 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 233 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
234 adapter->curr_cmd = NULL; 234 adapter->curr_cmd = NULL;
@@ -632,6 +632,20 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
632 spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); 632 spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
633} 633}
634 634
635/* This function reuses a command node. */
636void mwifiex_recycle_cmd_node(struct mwifiex_adapter *adapter,
637 struct cmd_ctrl_node *cmd_node)
638{
639 struct host_cmd_ds_command *host_cmd = (void *)cmd_node->cmd_skb->data;
640
641 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
642
643 atomic_dec(&adapter->cmd_pending);
644 dev_dbg(adapter->dev, "cmd: FREE_CMD: cmd=%#x, cmd_pending=%d\n",
645 le16_to_cpu(host_cmd->command),
646 atomic_read(&adapter->cmd_pending));
647}
648
635/* 649/*
636 * This function queues a command to the command pending queue. 650 * This function queues a command to the command pending queue.
637 * 651 *
@@ -673,7 +687,9 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
673 list_add(&cmd_node->list, &adapter->cmd_pending_q); 687 list_add(&cmd_node->list, &adapter->cmd_pending_q);
674 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); 688 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
675 689
676 dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command); 690 atomic_inc(&adapter->cmd_pending);
691 dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x, cmd_pending=%d\n",
692 command, atomic_read(&adapter->cmd_pending));
677} 693}
678 694
679/* 695/*
@@ -783,7 +799,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
783 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { 799 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
784 dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n", 800 dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n",
785 le16_to_cpu(resp->command)); 801 le16_to_cpu(resp->command));
786 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); 802 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
787 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 803 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
788 adapter->curr_cmd = NULL; 804 adapter->curr_cmd = NULL;
789 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 805 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
@@ -833,7 +849,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
833 if (adapter->curr_cmd->wait_q_enabled) 849 if (adapter->curr_cmd->wait_q_enabled)
834 adapter->cmd_wait_q.status = -1; 850 adapter->cmd_wait_q.status = -1;
835 851
836 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); 852 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
837 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 853 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
838 adapter->curr_cmd = NULL; 854 adapter->curr_cmd = NULL;
839 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 855 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
@@ -865,8 +881,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
865 if (adapter->curr_cmd->wait_q_enabled) 881 if (adapter->curr_cmd->wait_q_enabled)
866 adapter->cmd_wait_q.status = ret; 882 adapter->cmd_wait_q.status = ret;
867 883
868 /* Clean up and put current command back to cmd_free_q */ 884 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
869 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
870 885
871 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 886 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
872 adapter->curr_cmd = NULL; 887 adapter->curr_cmd = NULL;
@@ -993,7 +1008,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
993 mwifiex_complete_cmd(adapter, cmd_node); 1008 mwifiex_complete_cmd(adapter, cmd_node);
994 cmd_node->wait_q_enabled = false; 1009 cmd_node->wait_q_enabled = false;
995 } 1010 }
996 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 1011 mwifiex_recycle_cmd_node(adapter, cmd_node);
997 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); 1012 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
998 } 1013 }
999 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); 1014 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
@@ -1040,7 +1055,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1040 cmd_node = adapter->curr_cmd; 1055 cmd_node = adapter->curr_cmd;
1041 cmd_node->wait_q_enabled = false; 1056 cmd_node->wait_q_enabled = false;
1042 cmd_node->cmd_flag |= CMD_F_CANCELED; 1057 cmd_node->cmd_flag |= CMD_F_CANCELED;
1043 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 1058 mwifiex_recycle_cmd_node(adapter, cmd_node);
1044 mwifiex_complete_cmd(adapter, adapter->curr_cmd); 1059 mwifiex_complete_cmd(adapter, adapter->curr_cmd);
1045 adapter->curr_cmd = NULL; 1060 adapter->curr_cmd = NULL;
1046 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); 1061 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index e8a569aaa2e8..94cc09d48444 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -41,8 +41,15 @@
41#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2 41#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2
42#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16 42#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16
43 43
44#define MWIFIEX_AMPDU_DEF_TXWINSIZE 32 44#define MWIFIEX_STA_AMPDU_DEF_TXWINSIZE 16
45#define MWIFIEX_AMPDU_DEF_RXWINSIZE 16 45#define MWIFIEX_STA_AMPDU_DEF_RXWINSIZE 32
46#define MWIFIEX_UAP_AMPDU_DEF_TXWINSIZE 32
47#define MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE 16
48#define MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE 32
49#define MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE 48
50#define MWIFIEX_11AC_UAP_AMPDU_DEF_TXWINSIZE 48
51#define MWIFIEX_11AC_UAP_AMPDU_DEF_RXWINSIZE 32
52
46#define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff 53#define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff
47 54
48#define MWIFIEX_RATE_BITMAP_MCS0 32 55#define MWIFIEX_RATE_BITMAP_MCS0 32
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 57c5defe1f9d..1f7578d553ec 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -295,6 +295,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
295#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa 295#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa
296#define HostCmd_CMD_MGMT_FRAME_REG 0x010c 296#define HostCmd_CMD_MGMT_FRAME_REG 0x010c
297#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d 297#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d
298#define HostCmd_CMD_11AC_CFG 0x0112
298 299
299#define PROTOCOL_NO_SECURITY 0x01 300#define PROTOCOL_NO_SECURITY 0x01
300#define PROTOCOL_STATIC_WEP 0x02 301#define PROTOCOL_STATIC_WEP 0x02
@@ -1363,6 +1364,15 @@ struct host_cmd_ds_sys_config {
1363 u8 tlv[0]; 1364 u8 tlv[0];
1364}; 1365};
1365 1366
1367struct host_cmd_11ac_vht_cfg {
1368 __le16 action;
1369 u8 band_config;
1370 u8 misc_config;
1371 __le32 cap_info;
1372 __le32 mcs_tx_set;
1373 __le32 mcs_rx_set;
1374} __packed;
1375
1366struct host_cmd_tlv_akmp { 1376struct host_cmd_tlv_akmp {
1367 struct host_cmd_tlv tlv; 1377 struct host_cmd_tlv tlv;
1368 __le16 key_mgmt; 1378 __le16 key_mgmt;
@@ -1620,6 +1630,7 @@ struct host_cmd_ds_command {
1620 struct host_cmd_ds_802_11_eeprom_access eeprom; 1630 struct host_cmd_ds_802_11_eeprom_access eeprom;
1621 struct host_cmd_ds_802_11_subsc_evt subsc_evt; 1631 struct host_cmd_ds_802_11_subsc_evt subsc_evt;
1622 struct host_cmd_ds_sys_config uap_sys_config; 1632 struct host_cmd_ds_sys_config uap_sys_config;
1633 struct host_cmd_11ac_vht_cfg vht_cfg;
1623 } params; 1634 } params;
1624} __packed; 1635} __packed;
1625 1636
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index daf8801cecd2..42d7f0adf9bd 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -533,10 +533,8 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
533 if (!adapter->priv[i]) 533 if (!adapter->priv[i])
534 continue; 534 continue;
535 priv = adapter->priv[i]; 535 priv = adapter->priv[i];
536 for (j = 0; j < MAX_NUM_TID; ++j) { 536 for (j = 0; j < MAX_NUM_TID; ++j)
537 INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list); 537 INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list);
538 spin_lock_init(&priv->wmm.tid_tbl_ptr[j].tid_tbl_lock);
539 }
540 INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr); 538 INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
541 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); 539 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
542 INIT_LIST_HEAD(&priv->sta_list); 540 INIT_LIST_HEAD(&priv->sta_list);
@@ -713,7 +711,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
713 if (adapter->curr_cmd) { 711 if (adapter->curr_cmd) {
714 dev_warn(adapter->dev, "curr_cmd is still in processing\n"); 712 dev_warn(adapter->dev, "curr_cmd is still in processing\n");
715 del_timer(&adapter->cmd_timer); 713 del_timer(&adapter->cmd_timer);
716 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); 714 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
717 adapter->curr_cmd = NULL; 715 adapter->curr_cmd = NULL;
718 } 716 }
719 717
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 91d522c746ed..7f27e45680b5 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -272,6 +272,14 @@ struct mwifiex_ds_pm_cfg {
272 } param; 272 } param;
273}; 273};
274 274
275struct mwifiex_11ac_vht_cfg {
276 u8 band_config;
277 u8 misc_config;
278 u32 cap_info;
279 u32 mcs_tx_set;
280 u32 mcs_rx_set;
281};
282
275struct mwifiex_ds_11n_tx_cfg { 283struct mwifiex_ds_11n_tx_cfg {
276 u16 tx_htcap; 284 u16 tx_htcap;
277 u16 tx_htinfo; 285 u16 tx_htinfo;
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 2fe0ceba4400..6bcb66e6e97c 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1295,6 +1295,14 @@ int mwifiex_associate(struct mwifiex_private *priv,
1295 (bss_desc->bss_mode != NL80211_IFTYPE_STATION)) 1295 (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
1296 return -1; 1296 return -1;
1297 1297
1298 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1299 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1300 (priv->adapter->config_bands & BAND_GAC ||
1301 priv->adapter->config_bands & BAND_AAC))
1302 mwifiex_set_11ac_ba_params(priv);
1303 else
1304 mwifiex_set_ba_params(priv);
1305
1298 memcpy(&current_bssid, 1306 memcpy(&current_bssid,
1299 &priv->curr_bss_params.bss_descriptor.mac_address, 1307 &priv->curr_bss_params.bss_descriptor.mac_address,
1300 sizeof(current_bssid)); 1308 sizeof(current_bssid));
@@ -1323,6 +1331,13 @@ mwifiex_adhoc_start(struct mwifiex_private *priv,
1323 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", 1331 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n",
1324 priv->curr_bss_params.band); 1332 priv->curr_bss_params.band);
1325 1333
1334 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1335 (priv->adapter->config_bands & BAND_GAC ||
1336 priv->adapter->config_bands & BAND_AAC))
1337 mwifiex_set_11ac_ba_params(priv);
1338 else
1339 mwifiex_set_ba_params(priv);
1340
1326 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, 1341 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START,
1327 HostCmd_ACT_GEN_SET, 0, adhoc_ssid); 1342 HostCmd_ACT_GEN_SET, 0, adhoc_ssid);
1328} 1343}
@@ -1356,6 +1371,14 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
1356 return -1; 1371 return -1;
1357 } 1372 }
1358 1373
1374 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1375 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1376 (priv->adapter->config_bands & BAND_GAC ||
1377 priv->adapter->config_bands & BAND_AAC))
1378 mwifiex_set_11ac_ba_params(priv);
1379 else
1380 mwifiex_set_ba_params(priv);
1381
1359 dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", 1382 dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
1360 priv->curr_bss_params.bss_descriptor.channel); 1383 priv->curr_bss_params.bss_descriptor.channel);
1361 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", 1384 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 7255289a48ac..b7484efc9443 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -213,15 +213,12 @@ struct mwifiex_ra_list_tbl {
213 213
214struct mwifiex_tid_tbl { 214struct mwifiex_tid_tbl {
215 struct list_head ra_list; 215 struct list_head ra_list;
216 /* spin lock for tid table */
217 spinlock_t tid_tbl_lock;
218 struct mwifiex_ra_list_tbl *ra_list_curr; 216 struct mwifiex_ra_list_tbl *ra_list_curr;
219}; 217};
220 218
221#define WMM_HIGHEST_PRIORITY 7 219#define WMM_HIGHEST_PRIORITY 7
222#define HIGH_PRIO_TID 7 220#define HIGH_PRIO_TID 7
223#define LOW_PRIO_TID 0 221#define LOW_PRIO_TID 0
224#define NO_PKT_PRIO_TID (-1)
225 222
226struct mwifiex_wmm_desc { 223struct mwifiex_wmm_desc {
227 struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID]; 224 struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID];
@@ -798,6 +795,8 @@ void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter);
798 795
799void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, 796void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
800 struct cmd_ctrl_node *cmd_node); 797 struct cmd_ctrl_node *cmd_node);
798void mwifiex_recycle_cmd_node(struct mwifiex_adapter *adapter,
799 struct cmd_ctrl_node *cmd_node);
801 800
802void mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, 801void mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
803 struct cmd_ctrl_node *cmd_node, 802 struct cmd_ctrl_node *cmd_node,
@@ -912,12 +911,20 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
912void mwifiex_set_ht_params(struct mwifiex_private *priv, 911void mwifiex_set_ht_params(struct mwifiex_private *priv,
913 struct mwifiex_uap_bss_param *bss_cfg, 912 struct mwifiex_uap_bss_param *bss_cfg,
914 struct cfg80211_ap_settings *params); 913 struct cfg80211_ap_settings *params);
914void mwifiex_set_vht_params(struct mwifiex_private *priv,
915 struct mwifiex_uap_bss_param *bss_cfg,
916 struct cfg80211_ap_settings *params);
915void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, 917void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
916 struct cfg80211_ap_settings *params); 918 struct cfg80211_ap_settings *params);
919void mwifiex_set_vht_width(struct mwifiex_private *priv,
920 enum nl80211_chan_width width,
921 bool ap_11ac_disable);
917void 922void
918mwifiex_set_wmm_params(struct mwifiex_private *priv, 923mwifiex_set_wmm_params(struct mwifiex_private *priv,
919 struct mwifiex_uap_bss_param *bss_cfg, 924 struct mwifiex_uap_bss_param *bss_cfg,
920 struct cfg80211_ap_settings *params); 925 struct cfg80211_ap_settings *params);
926void mwifiex_set_ba_params(struct mwifiex_private *priv);
927void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv);
921 928
922/* 929/*
923 * This function checks if the queuing is RA based or not. 930 * This function checks if the queuing is RA based or not.
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 8cd8cdc91a7e..856959b64bc7 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -287,18 +287,13 @@ static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
287} 287}
288 288
289/* 289/*
290 * This function wakes up the card. 290 * This function adds delay loop to ensure FW is awake before proceeding.
291 *
292 * A host power up command is written to the card configuration
293 * register to wake up the card.
294 */ 291 */
295static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) 292static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
296{ 293{
297 int i = 0; 294 int i = 0;
298 struct pcie_service_card *card = adapter->card;
299 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
300 295
301 while (reg->sleep_cookie && mwifiex_pcie_ok_to_access_hw(adapter)) { 296 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
302 i++; 297 i++;
303 usleep_range(10, 20); 298 usleep_range(10, 20);
304 /* 50ms max wait */ 299 /* 50ms max wait */
@@ -306,16 +301,32 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
306 break; 301 break;
307 } 302 }
308 303
304 return;
305}
306
307/* This function wakes up the card by reading fw_status register. */
308static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
309{
310 u32 fw_status;
311 struct pcie_service_card *card = adapter->card;
312 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
313
309 dev_dbg(adapter->dev, "event: Wakeup device...\n"); 314 dev_dbg(adapter->dev, "event: Wakeup device...\n");
310 315
311 /* Enable interrupts or any chip access will wakeup device */ 316 if (reg->sleep_cookie)
312 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK, HOST_INTR_MASK)) { 317 mwifiex_pcie_dev_wakeup_delay(adapter);
313 dev_warn(adapter->dev, "Enable host interrupt failed\n"); 318
319 /* Reading fw_status register will wakeup device */
320 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
321 dev_warn(adapter->dev, "Reading fw_status register failed\n");
314 return -1; 322 return -1;
315 } 323 }
316 324
317 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n"); 325 if (reg->sleep_cookie) {
318 adapter->ps_state = PS_STATE_AWAKE; 326 mwifiex_pcie_dev_wakeup_delay(adapter);
327 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
328 adapter->ps_state = PS_STATE_AWAKE;
329 }
319 330
320 return 0; 331 return 0;
321} 332}
@@ -1984,12 +1995,13 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1984 } 1995 }
1985 } 1996 }
1986 } else if (!adapter->pps_uapsd_mode && 1997 } else if (!adapter->pps_uapsd_mode &&
1987 adapter->ps_state == PS_STATE_SLEEP) { 1998 adapter->ps_state == PS_STATE_SLEEP &&
1999 mwifiex_pcie_ok_to_access_hw(adapter)) {
1988 /* Potentially for PCIe we could get other 2000 /* Potentially for PCIe we could get other
1989 * interrupts like shared. Don't change power 2001 * interrupts like shared. Don't change power
1990 * state until cookie is set */ 2002 * state until cookie is set */
1991 if (mwifiex_pcie_ok_to_access_hw(adapter)) 2003 adapter->ps_state = PS_STATE_AWAKE;
1992 adapter->ps_state = PS_STATE_AWAKE; 2004 adapter->pm_wakeup_fw_try = false;
1993 } 2005 }
1994 } 2006 }
1995} 2007}
@@ -2112,7 +2124,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2112 } 2124 }
2113 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", 2125 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
2114 adapter->cmd_sent, adapter->data_sent); 2126 adapter->cmd_sent, adapter->data_sent);
2115 mwifiex_pcie_enable_host_int(adapter); 2127 if (adapter->ps_state != PS_STATE_SLEEP)
2128 mwifiex_pcie_enable_host_int(adapter);
2116 2129
2117 return 0; 2130 return 0;
2118} 2131}
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index d215b4d3c51b..e7f6deaf715e 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1393,8 +1393,10 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
1393 queue_work(adapter->workqueue, &adapter->main_work); 1393 queue_work(adapter->workqueue, &adapter->main_work);
1394 1394
1395 /* Perform internal scan synchronously */ 1395 /* Perform internal scan synchronously */
1396 if (!priv->scan_request) 1396 if (!priv->scan_request) {
1397 dev_dbg(adapter->dev, "wait internal scan\n");
1397 mwifiex_wait_queue_complete(adapter, cmd_node); 1398 mwifiex_wait_queue_complete(adapter, cmd_node);
1399 }
1398 } else { 1400 } else {
1399 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1401 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1400 flags); 1402 flags);
@@ -1793,7 +1795,12 @@ check_next_scan:
1793 /* Need to indicate IOCTL complete */ 1795 /* Need to indicate IOCTL complete */
1794 if (adapter->curr_cmd->wait_q_enabled) { 1796 if (adapter->curr_cmd->wait_q_enabled) {
1795 adapter->cmd_wait_q.status = 0; 1797 adapter->cmd_wait_q.status = 0;
1796 mwifiex_complete_cmd(adapter, adapter->curr_cmd); 1798 if (!priv->scan_request) {
1799 dev_dbg(adapter->dev,
1800 "complete internal scan\n");
1801 mwifiex_complete_cmd(adapter,
1802 adapter->curr_cmd);
1803 }
1797 } 1804 }
1798 if (priv->report_scan_result) 1805 if (priv->report_scan_result)
1799 priv->report_scan_result = false; 1806 priv->report_scan_result = false;
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index a2ae690a0a67..b193e25977d2 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -24,6 +24,7 @@
24#include "main.h" 24#include "main.h"
25#include "wmm.h" 25#include "wmm.h"
26#include "11n.h" 26#include "11n.h"
27#include "11ac.h"
27 28
28/* 29/*
29 * This function prepares command to set/get RSSI information. 30 * This function prepares command to set/get RSSI information.
@@ -1258,6 +1259,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1258 cpu_to_le16(sizeof(struct host_cmd_ds_remain_on_chan) + 1259 cpu_to_le16(sizeof(struct host_cmd_ds_remain_on_chan) +
1259 S_DS_GEN); 1260 S_DS_GEN);
1260 break; 1261 break;
1262 case HostCmd_CMD_11AC_CFG:
1263 ret = mwifiex_cmd_11ac_cfg(priv, cmd_ptr, cmd_action, data_buf);
1264 break;
1261 case HostCmd_CMD_P2P_MODE_CFG: 1265 case HostCmd_CMD_P2P_MODE_CFG:
1262 cmd_ptr->command = cpu_to_le16(cmd_no); 1266 cmd_ptr->command = cpu_to_le16(cmd_no);
1263 cmd_ptr->params.mode_cfg.action = cpu_to_le16(cmd_action); 1267 cmd_ptr->params.mode_cfg.action = cpu_to_le16(cmd_action);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 80b9f2238001..9f990e14966e 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -95,7 +95,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
95 break; 95 break;
96 } 96 }
97 /* Handling errors here */ 97 /* Handling errors here */
98 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); 98 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
99 99
100 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 100 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
101 adapter->curr_cmd = NULL; 101 adapter->curr_cmd = NULL;
@@ -907,6 +907,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
907 case HostCmd_CMD_REMAIN_ON_CHAN: 907 case HostCmd_CMD_REMAIN_ON_CHAN:
908 ret = mwifiex_ret_remain_on_chan(priv, resp, data_buf); 908 ret = mwifiex_ret_remain_on_chan(priv, resp, data_buf);
909 break; 909 break;
910 case HostCmd_CMD_11AC_CFG:
911 break;
910 case HostCmd_CMD_P2P_MODE_CFG: 912 case HostCmd_CMD_P2P_MODE_CFG:
911 ret = mwifiex_ret_p2p_mode_cfg(priv, resp, data_buf); 913 ret = mwifiex_ret_p2p_mode_cfg(priv, resp, data_buf);
912 break; 914 break;
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 8c943b6ebf45..e6c9b2ae22ed 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -59,9 +59,6 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
59{ 59{
60 int status; 60 int status;
61 61
62 dev_dbg(adapter->dev, "cmd pending\n");
63 atomic_inc(&adapter->cmd_pending);
64
65 /* Wait for completion */ 62 /* Wait for completion */
66 status = wait_event_interruptible(adapter->cmd_wait_q.wait, 63 status = wait_event_interruptible(adapter->cmd_wait_q.wait,
67 *(cmd_queued->condition)); 64 *(cmd_queued->condition));
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 6e76a15a8950..b04b1db29100 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include "main.h" 20#include "main.h"
21#include "11ac.h"
21 22
22/* This function parses security related parameters from cfg80211_ap_settings 23/* This function parses security related parameters from cfg80211_ap_settings
23 * and sets into FW understandable bss_config structure. 24 * and sets into FW understandable bss_config structure.
@@ -177,6 +178,60 @@ mwifiex_set_ht_params(struct mwifiex_private *priv,
177 return; 178 return;
178} 179}
179 180
181/* This function updates 11ac related parameters from IE
182 * and sets them into bss_config structure.
183 */
184void mwifiex_set_vht_params(struct mwifiex_private *priv,
185 struct mwifiex_uap_bss_param *bss_cfg,
186 struct cfg80211_ap_settings *params)
187{
188 const u8 *vht_ie;
189
190 vht_ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, params->beacon.tail,
191 params->beacon.tail_len);
192 if (vht_ie) {
193 memcpy(&bss_cfg->vht_cap, vht_ie + 2,
194 sizeof(struct ieee80211_vht_cap));
195 priv->ap_11ac_enabled = 1;
196 } else {
197 priv->ap_11ac_enabled = 0;
198 }
199
200 return;
201}
202
203/* Enable VHT only when cfg80211_ap_settings has VHT IE.
204 * Otherwise disable VHT.
205 */
206void mwifiex_set_vht_width(struct mwifiex_private *priv,
207 enum nl80211_chan_width width,
208 bool ap_11ac_enable)
209{
210 struct mwifiex_adapter *adapter = priv->adapter;
211 struct mwifiex_11ac_vht_cfg vht_cfg;
212
213 vht_cfg.band_config = VHT_CFG_5GHZ;
214 vht_cfg.cap_info = adapter->hw_dot_11ac_dev_cap;
215
216 if (!ap_11ac_enable) {
217 vht_cfg.mcs_tx_set = DISABLE_VHT_MCS_SET;
218 vht_cfg.mcs_rx_set = DISABLE_VHT_MCS_SET;
219 } else {
220 vht_cfg.mcs_tx_set = DEFAULT_VHT_MCS_SET;
221 vht_cfg.mcs_rx_set = DEFAULT_VHT_MCS_SET;
222 }
223
224 vht_cfg.misc_config = VHT_CAP_UAP_ONLY;
225
226 if (ap_11ac_enable && width >= NL80211_CHAN_WIDTH_80)
227 vht_cfg.misc_config |= VHT_BW_80_160_80P80;
228
229 mwifiex_send_cmd_sync(priv, HostCmd_CMD_11AC_CFG,
230 HostCmd_ACT_GEN_SET, 0, &vht_cfg);
231
232 return;
233}
234
180/* This function finds supported rates IE from beacon parameter and sets 235/* This function finds supported rates IE from beacon parameter and sets
181 * these rates into bss_config structure. 236 * these rates into bss_config structure.
182 */ 237 */
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 54667e65ca47..e57ac0dd3ab5 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -239,7 +239,6 @@ int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb)
239int mwifiex_complete_cmd(struct mwifiex_adapter *adapter, 239int mwifiex_complete_cmd(struct mwifiex_adapter *adapter,
240 struct cmd_ctrl_node *cmd_node) 240 struct cmd_ctrl_node *cmd_node)
241{ 241{
242 atomic_dec(&adapter->cmd_pending);
243 dev_dbg(adapter->dev, "cmd completed: status=%d\n", 242 dev_dbg(adapter->dev, "cmd completed: status=%d\n",
244 adapter->cmd_wait_q.status); 243 adapter->cmd_wait_q.status);
245 244
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 32adc878041d..2cc81ba590e3 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -436,10 +436,7 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
436 = priv->aggr_prio_tbl[7].ampdu_user 436 = priv->aggr_prio_tbl[7].ampdu_user
437 = BA_STREAM_NOT_ALLOWED; 437 = BA_STREAM_NOT_ALLOWED;
438 438
439 priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; 439 mwifiex_set_ba_params(priv);
440 priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE;
441 priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE;
442
443 mwifiex_reset_11n_rx_seq_num(priv); 440 mwifiex_reset_11n_rx_seq_num(priv);
444 441
445 atomic_set(&priv->wmm.tx_pkts_queued, 0); 442 atomic_set(&priv->wmm.tx_pkts_queued, 0);
@@ -688,13 +685,13 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
688 ra_list->total_pkts_size += skb->len; 685 ra_list->total_pkts_size += skb->len;
689 ra_list->pkt_count++; 686 ra_list->pkt_count++;
690 687
691 atomic_inc(&priv->wmm.tx_pkts_queued);
692
693 if (atomic_read(&priv->wmm.highest_queued_prio) < 688 if (atomic_read(&priv->wmm.highest_queued_prio) <
694 tos_to_tid_inv[tid_down]) 689 tos_to_tid_inv[tid_down])
695 atomic_set(&priv->wmm.highest_queued_prio, 690 atomic_set(&priv->wmm.highest_queued_prio,
696 tos_to_tid_inv[tid_down]); 691 tos_to_tid_inv[tid_down]);
697 692
693 atomic_inc(&priv->wmm.tx_pkts_queued);
694
698 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); 695 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
699} 696}
700 697
@@ -890,19 +887,15 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
890 struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; 887 struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head;
891 struct mwifiex_tid_tbl *tid_ptr; 888 struct mwifiex_tid_tbl *tid_ptr;
892 atomic_t *hqp; 889 atomic_t *hqp;
893 int is_list_empty; 890 unsigned long flags_bss, flags_ra;
894 unsigned long flags;
895 int i, j; 891 int i, j;
896 892
897 for (j = adapter->priv_num - 1; j >= 0; --j) { 893 for (j = adapter->priv_num - 1; j >= 0; --j) {
898 spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, 894 spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock,
899 flags); 895 flags_bss);
900 is_list_empty = list_empty(&adapter->bss_prio_tbl[j] 896
901 .bss_prio_head); 897 if (list_empty(&adapter->bss_prio_tbl[j].bss_prio_head))
902 spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, 898 goto skip_prio_tbl;
903 flags);
904 if (is_list_empty)
905 continue;
906 899
907 if (adapter->bss_prio_tbl[j].bss_prio_cur == 900 if (adapter->bss_prio_tbl[j].bss_prio_cur ==
908 (struct mwifiex_bss_prio_node *) 901 (struct mwifiex_bss_prio_node *)
@@ -919,26 +912,26 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
919 912
920 do { 913 do {
921 priv_tmp = bssprio_node->priv; 914 priv_tmp = bssprio_node->priv;
922 hqp = &priv_tmp->wmm.highest_queued_prio;
923 915
916 if (atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0)
917 goto skip_bss;
918
919 /* iterate over the WMM queues of the BSS */
920 hqp = &priv_tmp->wmm.highest_queued_prio;
924 for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) { 921 for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) {
925 922
923 spin_lock_irqsave(&priv_tmp->wmm.
924 ra_list_spinlock, flags_ra);
925
926 tid_ptr = &(priv_tmp)->wmm. 926 tid_ptr = &(priv_tmp)->wmm.
927 tid_tbl_ptr[tos_to_tid[i]]; 927 tid_tbl_ptr[tos_to_tid[i]];
928 928
929 /* For non-STA ra_list_curr may be NULL */ 929 /* For non-STA ra_list_curr may be NULL */
930 if (!tid_ptr->ra_list_curr) 930 if (!tid_ptr->ra_list_curr)
931 continue; 931 goto skip_wmm_queue;
932 932
933 spin_lock_irqsave(&tid_ptr->tid_tbl_lock, 933 if (list_empty(&tid_ptr->ra_list))
934 flags); 934 goto skip_wmm_queue;
935 is_list_empty =
936 list_empty(&adapter->bss_prio_tbl[j]
937 .bss_prio_head);
938 spin_unlock_irqrestore(&tid_ptr->tid_tbl_lock,
939 flags);
940 if (is_list_empty)
941 continue;
942 935
943 /* 936 /*
944 * Always choose the next ra we transmitted 937 * Always choose the next ra we transmitted
@@ -960,10 +953,8 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
960 } 953 }
961 954
962 do { 955 do {
963 is_list_empty = 956 if (!skb_queue_empty(&ptr->skb_head))
964 skb_queue_empty(&ptr->skb_head); 957 /* holds both locks */
965
966 if (!is_list_empty)
967 goto found; 958 goto found;
968 959
969 /* Get next ra */ 960 /* Get next ra */
@@ -978,14 +969,14 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
978 struct mwifiex_ra_list_tbl, 969 struct mwifiex_ra_list_tbl,
979 list); 970 list);
980 } while (ptr != head); 971 } while (ptr != head);
981 }
982 972
983 /* No packet at any TID for this priv. Mark as such 973skip_wmm_queue:
984 * to skip checking TIDs for this priv (until pkt is 974 spin_unlock_irqrestore(&priv_tmp->wmm.
985 * added). 975 ra_list_spinlock,
986 */ 976 flags_ra);
987 atomic_set(hqp, NO_PKT_PRIO_TID); 977 }
988 978
979skip_bss:
989 /* Get next bss priority node */ 980 /* Get next bss priority node */
990 bssprio_node = list_first_entry(&bssprio_node->list, 981 bssprio_node = list_first_entry(&bssprio_node->list,
991 struct mwifiex_bss_prio_node, 982 struct mwifiex_bss_prio_node,
@@ -1000,14 +991,21 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
1000 struct mwifiex_bss_prio_node, 991 struct mwifiex_bss_prio_node,
1001 list); 992 list);
1002 } while (bssprio_node != bssprio_head); 993 } while (bssprio_node != bssprio_head);
994
995skip_prio_tbl:
996 spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
997 flags_bss);
1003 } 998 }
999
1004 return NULL; 1000 return NULL;
1005 1001
1006found: 1002found:
1007 spin_lock_irqsave(&priv_tmp->wmm.ra_list_spinlock, flags); 1003 /* holds bss_prio_lock / ra_list_spinlock */
1008 if (atomic_read(hqp) > i) 1004 if (atomic_read(hqp) > i)
1009 atomic_set(hqp, i); 1005 atomic_set(hqp, i);
1010 spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags); 1006 spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags_ra);
1007 spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
1008 flags_bss);
1011 1009
1012 *priv = priv_tmp; 1010 *priv = priv_tmp;
1013 *tid = tos_to_tid[i]; 1011 *tid = tos_to_tid[i];
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 0640e7d7f0c2..956c1084ebf1 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -4807,16 +4807,14 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
4807 struct mwl8k_priv *priv = hw->priv; 4807 struct mwl8k_priv *priv = hw->priv;
4808 int rc; 4808 int rc;
4809 4809
4810 if (conf->flags & IEEE80211_CONF_IDLE) {
4811 mwl8k_cmd_radio_disable(hw);
4812 return 0;
4813 }
4814
4815 rc = mwl8k_fw_lock(hw); 4810 rc = mwl8k_fw_lock(hw);
4816 if (rc) 4811 if (rc)
4817 return rc; 4812 return rc;
4818 4813
4819 rc = mwl8k_cmd_radio_enable(hw); 4814 if (conf->flags & IEEE80211_CONF_IDLE)
4815 rc = mwl8k_cmd_radio_disable(hw);
4816 else
4817 rc = mwl8k_cmd_radio_enable(hw);
4820 if (rc) 4818 if (rc)
4821 goto out; 4819 goto out;
4822 4820
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index aadda99989c0..ee654a691f38 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -670,7 +670,7 @@ static unsigned int p54_flush_count(struct p54_common *priv)
670 return total; 670 return total;
671} 671}
672 672
673static void p54_flush(struct ieee80211_hw *dev, bool drop) 673static void p54_flush(struct ieee80211_hw *dev, u32 queues, bool drop)
674{ 674{
675 struct p54_common *priv = dev->priv; 675 struct p54_common *priv = dev->priv;
676 unsigned int total, i; 676 unsigned int total, i;
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index ffe61d53e3fe..9b915d3a44be 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -20,6 +20,7 @@ if RT2X00
20config RT2400PCI 20config RT2400PCI
21 tristate "Ralink rt2400 (PCI/PCMCIA) support" 21 tristate "Ralink rt2400 (PCI/PCMCIA) support"
22 depends on PCI 22 depends on PCI
23 select RT2X00_LIB_MMIO
23 select RT2X00_LIB_PCI 24 select RT2X00_LIB_PCI
24 select EEPROM_93CX6 25 select EEPROM_93CX6
25 ---help--- 26 ---help---
@@ -31,6 +32,7 @@ config RT2400PCI
31config RT2500PCI 32config RT2500PCI
32 tristate "Ralink rt2500 (PCI/PCMCIA) support" 33 tristate "Ralink rt2500 (PCI/PCMCIA) support"
33 depends on PCI 34 depends on PCI
35 select RT2X00_LIB_MMIO
34 select RT2X00_LIB_PCI 36 select RT2X00_LIB_PCI
35 select EEPROM_93CX6 37 select EEPROM_93CX6
36 ---help--- 38 ---help---
@@ -43,6 +45,7 @@ config RT61PCI
43 tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support" 45 tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support"
44 depends on PCI 46 depends on PCI
45 select RT2X00_LIB_PCI 47 select RT2X00_LIB_PCI
48 select RT2X00_LIB_MMIO
46 select RT2X00_LIB_FIRMWARE 49 select RT2X00_LIB_FIRMWARE
47 select RT2X00_LIB_CRYPTO 50 select RT2X00_LIB_CRYPTO
48 select CRC_ITU_T 51 select CRC_ITU_T
@@ -57,6 +60,7 @@ config RT2800PCI
57 tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" 60 tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
58 depends on PCI || SOC_RT288X || SOC_RT305X 61 depends on PCI || SOC_RT288X || SOC_RT305X
59 select RT2800_LIB 62 select RT2800_LIB
63 select RT2X00_LIB_MMIO
60 select RT2X00_LIB_PCI if PCI 64 select RT2X00_LIB_PCI if PCI
61 select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X 65 select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
62 select RT2X00_LIB_FIRMWARE 66 select RT2X00_LIB_FIRMWARE
@@ -192,6 +196,9 @@ endif
192config RT2800_LIB 196config RT2800_LIB
193 tristate 197 tristate
194 198
199config RT2X00_LIB_MMIO
200 tristate
201
195config RT2X00_LIB_PCI 202config RT2X00_LIB_PCI
196 tristate 203 tristate
197 select RT2X00_LIB 204 select RT2X00_LIB
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index 349d5b8284a4..f069d8bc5b67 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -9,6 +9,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
9rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o 9rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o
10 10
11obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o 11obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o
12obj-$(CONFIG_RT2X00_LIB_MMIO) += rt2x00mmio.o
12obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o 13obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
13obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o 14obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o
14obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o 15obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 221beaaa83f1..dcfb54e0c516 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -34,6 +34,7 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35 35
36#include "rt2x00.h" 36#include "rt2x00.h"
37#include "rt2x00mmio.h"
37#include "rt2x00pci.h" 38#include "rt2x00pci.h"
38#include "rt2400pci.h" 39#include "rt2400pci.h"
39 40
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 39edc59e8d03..e1d2dc9ed28a 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -34,6 +34,7 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35 35
36#include "rt2x00.h" 36#include "rt2x00.h"
37#include "rt2x00mmio.h"
37#include "rt2x00pci.h" 38#include "rt2x00pci.h"
38#include "rt2500pci.h" 39#include "rt2500pci.h"
39 40
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index f08a0424fe4d..7deac4d2459f 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -5431,9 +5431,9 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
5431 5431
5432static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) 5432static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
5433{ 5433{
5434 u32 reg;
5435 u16 value; 5434 u16 value;
5436 u16 eeprom; 5435 u16 eeprom;
5436 u16 rf;
5437 5437
5438 /* 5438 /*
5439 * Read EEPROM word for configuration. 5439 * Read EEPROM word for configuration.
@@ -5445,42 +5445,14 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
5445 * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field 5445 * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field
5446 * RT53xx: defined in "EEPROM_CHIP_ID" field 5446 * RT53xx: defined in "EEPROM_CHIP_ID" field
5447 */ 5447 */
5448 if (rt2x00_rt(rt2x00dev, RT3290)) 5448 if (rt2x00_rt(rt2x00dev, RT3290) ||
5449 rt2800_register_read(rt2x00dev, MAC_CSR0_3290, &reg); 5449 rt2x00_rt(rt2x00dev, RT5390) ||
5450 else 5450 rt2x00_rt(rt2x00dev, RT5392))
5451 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg); 5451 rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
5452
5453 if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT3290 ||
5454 rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 ||
5455 rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392)
5456 rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value);
5457 else 5452 else
5458 value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); 5453 rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
5459 5454
5460 rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), 5455 switch (rf) {
5461 value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
5462
5463 switch (rt2x00dev->chip.rt) {
5464 case RT2860:
5465 case RT2872:
5466 case RT2883:
5467 case RT3070:
5468 case RT3071:
5469 case RT3090:
5470 case RT3290:
5471 case RT3352:
5472 case RT3390:
5473 case RT3572:
5474 case RT5390:
5475 case RT5392:
5476 case RT5592:
5477 break;
5478 default:
5479 ERROR(rt2x00dev, "Invalid RT chipset 0x%04x detected.\n", rt2x00dev->chip.rt);
5480 return -ENODEV;
5481 }
5482
5483 switch (rt2x00dev->chip.rf) {
5484 case RF2820: 5456 case RF2820:
5485 case RF2850: 5457 case RF2850:
5486 case RF2720: 5458 case RF2720:
@@ -5501,11 +5473,12 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
5501 case RF5592: 5473 case RF5592:
5502 break; 5474 break;
5503 default: 5475 default:
5504 ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", 5476 ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", rf);
5505 rt2x00dev->chip.rf);
5506 return -ENODEV; 5477 return -ENODEV;
5507 } 5478 }
5508 5479
5480 rt2x00_set_rf(rt2x00dev, rf);
5481
5509 /* 5482 /*
5510 * Identify default antenna configuration. 5483 * Identify default antenna configuration.
5511 */ 5484 */
@@ -6059,11 +6032,56 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
6059 return 0; 6032 return 0;
6060} 6033}
6061 6034
6035static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev)
6036{
6037 u32 reg;
6038 u32 rt;
6039 u32 rev;
6040
6041 if (rt2x00_rt(rt2x00dev, RT3290))
6042 rt2800_register_read(rt2x00dev, MAC_CSR0_3290, &reg);
6043 else
6044 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
6045
6046 rt = rt2x00_get_field32(reg, MAC_CSR0_CHIPSET);
6047 rev = rt2x00_get_field32(reg, MAC_CSR0_REVISION);
6048
6049 switch (rt) {
6050 case RT2860:
6051 case RT2872:
6052 case RT2883:
6053 case RT3070:
6054 case RT3071:
6055 case RT3090:
6056 case RT3290:
6057 case RT3352:
6058 case RT3390:
6059 case RT3572:
6060 case RT5390:
6061 case RT5392:
6062 case RT5592:
6063 break;
6064 default:
6065 ERROR(rt2x00dev,
6066 "Invalid RT chipset 0x%04x, rev %04x detected.\n",
6067 rt, rev);
6068 return -ENODEV;
6069 }
6070
6071 rt2x00_set_rt(rt2x00dev, rt, rev);
6072
6073 return 0;
6074}
6075
6062int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev) 6076int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
6063{ 6077{
6064 int retval; 6078 int retval;
6065 u32 reg; 6079 u32 reg;
6066 6080
6081 retval = rt2800_probe_rt(rt2x00dev);
6082 if (retval)
6083 return retval;
6084
6067 /* 6085 /*
6068 * Allocate eeprom data. 6086 * Allocate eeprom data.
6069 */ 6087 */
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index f732ded8f1ba..565a80d0e564 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -41,6 +41,7 @@
41#include <linux/eeprom_93cx6.h> 41#include <linux/eeprom_93cx6.h>
42 42
43#include "rt2x00.h" 43#include "rt2x00.h"
44#include "rt2x00mmio.h"
44#include "rt2x00pci.h" 45#include "rt2x00pci.h"
45#include "rt2x00soc.h" 46#include "rt2x00soc.h"
46#include "rt2800lib.h" 47#include "rt2800lib.h"
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 51922cc179de..0d02d16ca166 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1106,6 +1106,23 @@ static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev,
1106 rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev); 1106 rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev);
1107} 1107}
1108 1108
1109static inline void rt2x00_set_rt(struct rt2x00_dev *rt2x00dev,
1110 const u16 rt, const u16 rev)
1111{
1112 rt2x00dev->chip.rt = rt;
1113 rt2x00dev->chip.rev = rev;
1114
1115 INFO(rt2x00dev, "RT chipset %04x, rev %04x detected\n",
1116 rt2x00dev->chip.rt, rt2x00dev->chip.rev);
1117}
1118
1119static inline void rt2x00_set_rf(struct rt2x00_dev *rt2x00dev, const u16 rf)
1120{
1121 rt2x00dev->chip.rf = rf;
1122
1123 INFO(rt2x00dev, "RF chipset %04x detected\n", rt2x00dev->chip.rf);
1124}
1125
1109static inline bool rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt) 1126static inline bool rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt)
1110{ 1127{
1111 return (rt2x00dev->chip.rt == rt); 1128 return (rt2x00dev->chip.rt == rt);
@@ -1366,7 +1383,7 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw,
1366 struct ieee80211_vif *vif, u16 queue, 1383 struct ieee80211_vif *vif, u16 queue,
1367 const struct ieee80211_tx_queue_params *params); 1384 const struct ieee80211_tx_queue_params *params);
1368void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); 1385void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
1369void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); 1386void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
1370int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); 1387int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
1371int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 1388int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
1372void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, 1389void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 20c6eccce5aa..9161c02d8ff9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -748,7 +748,7 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
748} 748}
749EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); 749EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
750 750
751void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) 751void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
752{ 752{
753 struct rt2x00_dev *rt2x00dev = hw->priv; 753 struct rt2x00_dev *rt2x00dev = hw->priv;
754 struct data_queue *queue; 754 struct data_queue *queue;
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.c b/drivers/net/wireless/rt2x00/rt2x00mmio.c
new file mode 100644
index 000000000000..d84a680ba0c9
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00mmio.c
@@ -0,0 +1,216 @@
1/*
2 Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
3 <http://rt2x00.serialmonkey.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*
22 Module: rt2x00mmio
23 Abstract: rt2x00 generic mmio device routines.
24 */
25
26#include <linux/dma-mapping.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/slab.h>
30
31#include "rt2x00.h"
32#include "rt2x00mmio.h"
33
34/*
35 * Register access.
36 */
37int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
38 const unsigned int offset,
39 const struct rt2x00_field32 field,
40 u32 *reg)
41{
42 unsigned int i;
43
44 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
45 return 0;
46
47 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
48 rt2x00pci_register_read(rt2x00dev, offset, reg);
49 if (!rt2x00_get_field32(*reg, field))
50 return 1;
51 udelay(REGISTER_BUSY_DELAY);
52 }
53
54 printk_once(KERN_ERR "%s() Indirect register access failed: "
55 "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg);
56 *reg = ~0;
57
58 return 0;
59}
60EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
61
62bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
63{
64 struct data_queue *queue = rt2x00dev->rx;
65 struct queue_entry *entry;
66 struct queue_entry_priv_pci *entry_priv;
67 struct skb_frame_desc *skbdesc;
68 int max_rx = 16;
69
70 while (--max_rx) {
71 entry = rt2x00queue_get_entry(queue, Q_INDEX);
72 entry_priv = entry->priv_data;
73
74 if (rt2x00dev->ops->lib->get_entry_state(entry))
75 break;
76
77 /*
78 * Fill in desc fields of the skb descriptor
79 */
80 skbdesc = get_skb_frame_desc(entry->skb);
81 skbdesc->desc = entry_priv->desc;
82 skbdesc->desc_len = entry->queue->desc_size;
83
84 /*
85 * DMA is already done, notify rt2x00lib that
86 * it finished successfully.
87 */
88 rt2x00lib_dmastart(entry);
89 rt2x00lib_dmadone(entry);
90
91 /*
92 * Send the frame to rt2x00lib for further processing.
93 */
94 rt2x00lib_rxdone(entry, GFP_ATOMIC);
95 }
96
97 return !max_rx;
98}
99EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
100
101void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
102{
103 unsigned int i;
104
105 for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
106 msleep(10);
107}
108EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
109
110/*
111 * Device initialization handlers.
112 */
113static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
114 struct data_queue *queue)
115{
116 struct queue_entry_priv_pci *entry_priv;
117 void *addr;
118 dma_addr_t dma;
119 unsigned int i;
120
121 /*
122 * Allocate DMA memory for descriptor and buffer.
123 */
124 addr = dma_alloc_coherent(rt2x00dev->dev,
125 queue->limit * queue->desc_size,
126 &dma, GFP_KERNEL);
127 if (!addr)
128 return -ENOMEM;
129
130 memset(addr, 0, queue->limit * queue->desc_size);
131
132 /*
133 * Initialize all queue entries to contain valid addresses.
134 */
135 for (i = 0; i < queue->limit; i++) {
136 entry_priv = queue->entries[i].priv_data;
137 entry_priv->desc = addr + i * queue->desc_size;
138 entry_priv->desc_dma = dma + i * queue->desc_size;
139 }
140
141 return 0;
142}
143
144static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
145 struct data_queue *queue)
146{
147 struct queue_entry_priv_pci *entry_priv =
148 queue->entries[0].priv_data;
149
150 if (entry_priv->desc)
151 dma_free_coherent(rt2x00dev->dev,
152 queue->limit * queue->desc_size,
153 entry_priv->desc, entry_priv->desc_dma);
154 entry_priv->desc = NULL;
155}
156
157int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
158{
159 struct data_queue *queue;
160 int status;
161
162 /*
163 * Allocate DMA
164 */
165 queue_for_each(rt2x00dev, queue) {
166 status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue);
167 if (status)
168 goto exit;
169 }
170
171 /*
172 * Register interrupt handler.
173 */
174 status = request_irq(rt2x00dev->irq,
175 rt2x00dev->ops->lib->irq_handler,
176 IRQF_SHARED, rt2x00dev->name, rt2x00dev);
177 if (status) {
178 ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
179 rt2x00dev->irq, status);
180 goto exit;
181 }
182
183 return 0;
184
185exit:
186 queue_for_each(rt2x00dev, queue)
187 rt2x00pci_free_queue_dma(rt2x00dev, queue);
188
189 return status;
190}
191EXPORT_SYMBOL_GPL(rt2x00pci_initialize);
192
193void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
194{
195 struct data_queue *queue;
196
197 /*
198 * Free irq line.
199 */
200 free_irq(rt2x00dev->irq, rt2x00dev);
201
202 /*
203 * Free DMA
204 */
205 queue_for_each(rt2x00dev, queue)
206 rt2x00pci_free_queue_dma(rt2x00dev, queue);
207}
208EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
209
210/*
211 * rt2x00mmio module information.
212 */
213MODULE_AUTHOR(DRV_PROJECT);
214MODULE_VERSION(DRV_VERSION);
215MODULE_DESCRIPTION("rt2x00 mmio library");
216MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.h b/drivers/net/wireless/rt2x00/rt2x00mmio.h
new file mode 100644
index 000000000000..4ecaf60175bf
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00mmio.h
@@ -0,0 +1,119 @@
1/*
2 Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
3 <http://rt2x00.serialmonkey.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*
22 Module: rt2x00mmio
23 Abstract: Data structures for the rt2x00mmio module.
24 */
25
26#ifndef RT2X00MMIO_H
27#define RT2X00MMIO_H
28
29#include <linux/io.h>
30
31/*
32 * Register access.
33 */
34static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
35 const unsigned int offset,
36 u32 *value)
37{
38 *value = readl(rt2x00dev->csr.base + offset);
39}
40
41static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
42 const unsigned int offset,
43 void *value, const u32 length)
44{
45 memcpy_fromio(value, rt2x00dev->csr.base + offset, length);
46}
47
48static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
49 const unsigned int offset,
50 u32 value)
51{
52 writel(value, rt2x00dev->csr.base + offset);
53}
54
55static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
56 const unsigned int offset,
57 const void *value,
58 const u32 length)
59{
60 __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
61}
62
63/**
64 * rt2x00pci_regbusy_read - Read from register with busy check
65 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
66 * @offset: Register offset
67 * @field: Field to check if register is busy
68 * @reg: Pointer to where register contents should be stored
69 *
70 * This function will read the given register, and checks if the
71 * register is busy. If it is, it will sleep for a couple of
72 * microseconds before reading the register again. If the register
73 * is not read after a certain timeout, this function will return
74 * FALSE.
75 */
76int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
77 const unsigned int offset,
78 const struct rt2x00_field32 field,
79 u32 *reg);
80
81/**
82 * struct queue_entry_priv_pci: Per entry PCI specific information
83 *
84 * @desc: Pointer to device descriptor
85 * @desc_dma: DMA pointer to &desc.
86 * @data: Pointer to device's entry memory.
87 * @data_dma: DMA pointer to &data.
88 */
89struct queue_entry_priv_pci {
90 __le32 *desc;
91 dma_addr_t desc_dma;
92};
93
94/**
95 * rt2x00pci_rxdone - Handle RX done events
96 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
97 *
98 * Returns true if there are still rx frames pending and false if all
99 * pending rx frames were processed.
100 */
101bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
102
103/**
104 * rt2x00pci_flush_queue - Flush data queue
105 * @queue: Data queue to stop
106 * @drop: True to drop all pending frames.
107 *
108 * This will wait for a maximum of 100ms, waiting for the queues
109 * to become empty.
110 */
111void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
112
113/*
114 * Device initialization handlers.
115 */
116int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev);
117void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev);
118
119#endif /* RT2X00MMIO_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index c4009eaeb697..e87865e33113 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -33,180 +33,6 @@
33#include "rt2x00pci.h" 33#include "rt2x00pci.h"
34 34
35/* 35/*
36 * Register access.
37 */
38int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
39 const unsigned int offset,
40 const struct rt2x00_field32 field,
41 u32 *reg)
42{
43 unsigned int i;
44
45 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
46 return 0;
47
48 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
49 rt2x00pci_register_read(rt2x00dev, offset, reg);
50 if (!rt2x00_get_field32(*reg, field))
51 return 1;
52 udelay(REGISTER_BUSY_DELAY);
53 }
54
55 printk_once(KERN_ERR "%s() Indirect register access failed: "
56 "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg);
57 *reg = ~0;
58
59 return 0;
60}
61EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
62
63bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
64{
65 struct data_queue *queue = rt2x00dev->rx;
66 struct queue_entry *entry;
67 struct queue_entry_priv_pci *entry_priv;
68 struct skb_frame_desc *skbdesc;
69 int max_rx = 16;
70
71 while (--max_rx) {
72 entry = rt2x00queue_get_entry(queue, Q_INDEX);
73 entry_priv = entry->priv_data;
74
75 if (rt2x00dev->ops->lib->get_entry_state(entry))
76 break;
77
78 /*
79 * Fill in desc fields of the skb descriptor
80 */
81 skbdesc = get_skb_frame_desc(entry->skb);
82 skbdesc->desc = entry_priv->desc;
83 skbdesc->desc_len = entry->queue->desc_size;
84
85 /*
86 * DMA is already done, notify rt2x00lib that
87 * it finished successfully.
88 */
89 rt2x00lib_dmastart(entry);
90 rt2x00lib_dmadone(entry);
91
92 /*
93 * Send the frame to rt2x00lib for further processing.
94 */
95 rt2x00lib_rxdone(entry, GFP_ATOMIC);
96 }
97
98 return !max_rx;
99}
100EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
101
102void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
103{
104 unsigned int i;
105
106 for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
107 msleep(10);
108}
109EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
110
111/*
112 * Device initialization handlers.
113 */
114static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
115 struct data_queue *queue)
116{
117 struct queue_entry_priv_pci *entry_priv;
118 void *addr;
119 dma_addr_t dma;
120 unsigned int i;
121
122 /*
123 * Allocate DMA memory for descriptor and buffer.
124 */
125 addr = dma_alloc_coherent(rt2x00dev->dev,
126 queue->limit * queue->desc_size,
127 &dma, GFP_KERNEL | __GFP_ZERO);
128 if (!addr)
129 return -ENOMEM;
130
131 /*
132 * Initialize all queue entries to contain valid addresses.
133 */
134 for (i = 0; i < queue->limit; i++) {
135 entry_priv = queue->entries[i].priv_data;
136 entry_priv->desc = addr + i * queue->desc_size;
137 entry_priv->desc_dma = dma + i * queue->desc_size;
138 }
139
140 return 0;
141}
142
143static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
144 struct data_queue *queue)
145{
146 struct queue_entry_priv_pci *entry_priv =
147 queue->entries[0].priv_data;
148
149 if (entry_priv->desc)
150 dma_free_coherent(rt2x00dev->dev,
151 queue->limit * queue->desc_size,
152 entry_priv->desc, entry_priv->desc_dma);
153 entry_priv->desc = NULL;
154}
155
156int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
157{
158 struct data_queue *queue;
159 int status;
160
161 /*
162 * Allocate DMA
163 */
164 queue_for_each(rt2x00dev, queue) {
165 status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue);
166 if (status)
167 goto exit;
168 }
169
170 /*
171 * Register interrupt handler.
172 */
173 status = request_irq(rt2x00dev->irq,
174 rt2x00dev->ops->lib->irq_handler,
175 IRQF_SHARED, rt2x00dev->name, rt2x00dev);
176 if (status) {
177 ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
178 rt2x00dev->irq, status);
179 goto exit;
180 }
181
182 return 0;
183
184exit:
185 queue_for_each(rt2x00dev, queue)
186 rt2x00pci_free_queue_dma(rt2x00dev, queue);
187
188 return status;
189}
190EXPORT_SYMBOL_GPL(rt2x00pci_initialize);
191
192void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
193{
194 struct data_queue *queue;
195
196 /*
197 * Free irq line.
198 */
199 free_irq(rt2x00dev->irq, rt2x00dev);
200
201 /*
202 * Free DMA
203 */
204 queue_for_each(rt2x00dev, queue)
205 rt2x00pci_free_queue_dma(rt2x00dev, queue);
206}
207EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
208
209/*
210 * PCI driver handlers. 36 * PCI driver handlers.
211 */ 37 */
212static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) 38static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index e2c99f2b9a14..60d90b20f8b9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -36,94 +36,6 @@
36#define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops) 36#define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops)
37 37
38/* 38/*
39 * Register access.
40 */
41static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
42 const unsigned int offset,
43 u32 *value)
44{
45 *value = readl(rt2x00dev->csr.base + offset);
46}
47
48static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
49 const unsigned int offset,
50 void *value, const u32 length)
51{
52 memcpy_fromio(value, rt2x00dev->csr.base + offset, length);
53}
54
55static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
56 const unsigned int offset,
57 u32 value)
58{
59 writel(value, rt2x00dev->csr.base + offset);
60}
61
62static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
63 const unsigned int offset,
64 const void *value,
65 const u32 length)
66{
67 __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
68}
69
70/**
71 * rt2x00pci_regbusy_read - Read from register with busy check
72 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
73 * @offset: Register offset
74 * @field: Field to check if register is busy
75 * @reg: Pointer to where register contents should be stored
76 *
77 * This function will read the given register, and checks if the
78 * register is busy. If it is, it will sleep for a couple of
79 * microseconds before reading the register again. If the register
80 * is not read after a certain timeout, this function will return
81 * FALSE.
82 */
83int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
84 const unsigned int offset,
85 const struct rt2x00_field32 field,
86 u32 *reg);
87
88/**
89 * struct queue_entry_priv_pci: Per entry PCI specific information
90 *
91 * @desc: Pointer to device descriptor
92 * @desc_dma: DMA pointer to &desc.
93 * @data: Pointer to device's entry memory.
94 * @data_dma: DMA pointer to &data.
95 */
96struct queue_entry_priv_pci {
97 __le32 *desc;
98 dma_addr_t desc_dma;
99};
100
101/**
102 * rt2x00pci_rxdone - Handle RX done events
103 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
104 *
105 * Returns true if there are still rx frames pending and false if all
106 * pending rx frames were processed.
107 */
108bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
109
110/**
111 * rt2x00pci_flush_queue - Flush data queue
112 * @queue: Data queue to stop
113 * @drop: True to drop all pending frames.
114 *
115 * This will wait for a maximum of 100ms, waiting for the queues
116 * to become empty.
117 */
118void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
119
120/*
121 * Device initialization handlers.
122 */
123int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev);
124void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev);
125
126/*
127 * PCI driver handlers. 39 * PCI driver handlers.
128 */ 40 */
129int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops); 41int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index f95792cfcf89..9e3c8ff53e3f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -35,6 +35,7 @@
35#include <linux/eeprom_93cx6.h> 35#include <linux/eeprom_93cx6.h>
36 36
37#include "rt2x00.h" 37#include "rt2x00.h"
38#include "rt2x00mmio.h"
38#include "rt2x00pci.h" 39#include "rt2x00pci.h"
39#include "rt61pci.h" 40#include "rt61pci.h"
40 41
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig
index b6aa0c40658f..7253de3d8c66 100644
--- a/drivers/net/wireless/rtlwifi/Kconfig
+++ b/drivers/net/wireless/rtlwifi/Kconfig
@@ -55,6 +55,15 @@ config RTL8723AE
55 55
56 If you choose to build it as a module, it will be called rtl8723ae 56 If you choose to build it as a module, it will be called rtl8723ae
57 57
58config RTL8188EE
59 tristate "Realtek RTL8188EE Wireless Network Adapter"
60 depends on RTLWIFI && PCI
61 ---help---
62 This is the driver for Realtek RTL8188EE 802.11n PCIe
63 wireless network adapters.
64
65 If you choose to build it as a module, it will be called rtl8188ee
66
58config RTL8192CU 67config RTL8192CU
59 tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" 68 tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
60 depends on RTLWIFI && USB 69 depends on RTLWIFI && USB
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile
index 3b1cbac741e3..ff02b874f8d8 100644
--- a/drivers/net/wireless/rtlwifi/Makefile
+++ b/drivers/net/wireless/rtlwifi/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_RTL8192CU) += rtl8192cu/
26obj-$(CONFIG_RTL8192SE) += rtl8192se/ 26obj-$(CONFIG_RTL8192SE) += rtl8192se/
27obj-$(CONFIG_RTL8192DE) += rtl8192de/ 27obj-$(CONFIG_RTL8192DE) += rtl8192de/
28obj-$(CONFIG_RTL8723AE) += rtl8723ae/ 28obj-$(CONFIG_RTL8723AE) += rtl8723ae/
29obj-$(CONFIG_RTL8188EE) += rtl8188ee/
29 30
30ccflags-y += -D__CHECK_ENDIAN__ 31ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 99c5cea3fe21..cac1fa912e8c 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -54,7 +54,8 @@
54 *5) frame process functions 54 *5) frame process functions
55 *6) IOT functions 55 *6) IOT functions
56 *7) sysfs functions 56 *7) sysfs functions
57 *8) ... 57 *8) vif functions
58 *9) ...
58 */ 59 */
59 60
60/********************************************************* 61/*********************************************************
@@ -198,34 +199,46 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
198 199
199 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 200 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
200 201
201 /* 202 /*hw->wiphy->bands[IEEE80211_BAND_2GHZ]
202 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
203 *base on ant_num 203 *base on ant_num
204 *rx_mask: RX mask 204 *rx_mask: RX mask
205 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7 205 *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7
206 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15 206 *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15
207 *if rx_ant >=3 rx_mask[2]=0xff; 207 *if rx_ant >= 3 rx_mask[2]= 0xff;
208 *if BW_40 rx_mask[4]=0x01; 208 *if BW_40 rx_mask[4]= 0x01;
209 *highest supported RX rate 209 *highest supported RX rate
210 */ 210 */
211 if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) { 211 if (rtlpriv->dm.supp_phymode_switch) {
212 212
213 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T2R or 2T2R\n"); 213 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
214 "Support phy mode switch\n");
214 215
215 ht_cap->mcs.rx_mask[0] = 0xFF; 216 ht_cap->mcs.rx_mask[0] = 0xFF;
216 ht_cap->mcs.rx_mask[1] = 0xFF; 217 ht_cap->mcs.rx_mask[1] = 0xFF;
217 ht_cap->mcs.rx_mask[4] = 0x01; 218 ht_cap->mcs.rx_mask[4] = 0x01;
218 219
219 ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); 220 ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
220 } else if (get_rf_type(rtlphy) == RF_1T1R) { 221 } else {
221 222 if (get_rf_type(rtlphy) == RF_1T2R ||
222 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); 223 get_rf_type(rtlphy) == RF_2T2R) {
223 224 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
224 ht_cap->mcs.rx_mask[0] = 0xFF; 225 "1T2R or 2T2R\n");
225 ht_cap->mcs.rx_mask[1] = 0x00; 226 ht_cap->mcs.rx_mask[0] = 0xFF;
226 ht_cap->mcs.rx_mask[4] = 0x01; 227 ht_cap->mcs.rx_mask[1] = 0xFF;
227 228 ht_cap->mcs.rx_mask[4] = 0x01;
228 ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7); 229
230 ht_cap->mcs.rx_highest =
231 cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
232 } else if (get_rf_type(rtlphy) == RF_1T1R) {
233 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n");
234
235 ht_cap->mcs.rx_mask[0] = 0xFF;
236 ht_cap->mcs.rx_mask[1] = 0x00;
237 ht_cap->mcs.rx_mask[4] = 0x01;
238
239 ht_cap->mcs.rx_highest =
240 cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7);
241 }
229 } 242 }
230} 243}
231 244
@@ -311,6 +324,8 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
311 IEEE80211_HW_AMPDU_AGGREGATION | 324 IEEE80211_HW_AMPDU_AGGREGATION |
312 IEEE80211_HW_CONNECTION_MONITOR | 325 IEEE80211_HW_CONNECTION_MONITOR |
313 /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */ 326 /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */
327 IEEE80211_HW_CONNECTION_MONITOR |
328 IEEE80211_HW_MFP_CAPABLE |
314 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0; 329 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;
315 330
316 /* swlps or hwlps has been set in diff chip in init_sw_vars */ 331 /* swlps or hwlps has been set in diff chip in init_sw_vars */
@@ -323,8 +338,12 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
323 hw->wiphy->interface_modes = 338 hw->wiphy->interface_modes =
324 BIT(NL80211_IFTYPE_AP) | 339 BIT(NL80211_IFTYPE_AP) |
325 BIT(NL80211_IFTYPE_STATION) | 340 BIT(NL80211_IFTYPE_STATION) |
326 BIT(NL80211_IFTYPE_ADHOC); 341 BIT(NL80211_IFTYPE_ADHOC) |
342 BIT(NL80211_IFTYPE_MESH_POINT) |
343 BIT(NL80211_IFTYPE_P2P_CLIENT) |
344 BIT(NL80211_IFTYPE_P2P_GO);
327 345
346 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
328 hw->wiphy->rts_threshold = 2347; 347 hw->wiphy->rts_threshold = 2347;
329 348
330 hw->queues = AC_MAX; 349 hw->queues = AC_MAX;
@@ -354,9 +373,10 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
354 struct rtl_priv *rtlpriv = rtl_priv(hw); 373 struct rtl_priv *rtlpriv = rtl_priv(hw);
355 374
356 /* <1> timer */ 375 /* <1> timer */
357 init_timer(&rtlpriv->works.watchdog_timer);
358 setup_timer(&rtlpriv->works.watchdog_timer, 376 setup_timer(&rtlpriv->works.watchdog_timer,
359 rtl_watch_dog_timer_callback, (unsigned long)hw); 377 rtl_watch_dog_timer_callback, (unsigned long)hw);
378 setup_timer(&rtlpriv->works.dualmac_easyconcurrent_retrytimer,
379 rtl_easy_concurrent_retrytimer_callback, (unsigned long)hw);
360 380
361 /* <2> work queue */ 381 /* <2> work queue */
362 rtlpriv->works.hw = hw; 382 rtlpriv->works.hw = hw;
@@ -369,6 +389,8 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
369 (void *)rtl_swlps_wq_callback); 389 (void *)rtl_swlps_wq_callback);
370 INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq, 390 INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq,
371 (void *)rtl_swlps_rfon_wq_callback); 391 (void *)rtl_swlps_rfon_wq_callback);
392 INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq,
393 (void *)rtl_fwevt_wq_callback);
372 394
373} 395}
374 396
@@ -382,6 +404,7 @@ void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
382 cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); 404 cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
383 cancel_delayed_work(&rtlpriv->works.ps_work); 405 cancel_delayed_work(&rtlpriv->works.ps_work);
384 cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); 406 cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
407 cancel_delayed_work(&rtlpriv->works.fwevt_wq);
385} 408}
386 409
387void rtl_init_rfkill(struct ieee80211_hw *hw) 410void rtl_init_rfkill(struct ieee80211_hw *hw)
@@ -436,12 +459,6 @@ int rtl_init_core(struct ieee80211_hw *hw)
436 if (rtl_regd_init(hw, rtl_reg_notifier)) { 459 if (rtl_regd_init(hw, rtl_reg_notifier)) {
437 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "REGD init failed\n"); 460 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "REGD init failed\n");
438 return 1; 461 return 1;
439 } else {
440 /* CRDA regd hint must after init CRDA */
441 if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) {
442 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
443 "regulatory_hint fail\n");
444 }
445 } 462 }
446 463
447 /* <4> locks */ 464 /* <4> locks */
@@ -449,15 +466,25 @@ int rtl_init_core(struct ieee80211_hw *hw)
449 mutex_init(&rtlpriv->locks.ps_mutex); 466 mutex_init(&rtlpriv->locks.ps_mutex);
450 spin_lock_init(&rtlpriv->locks.ips_lock); 467 spin_lock_init(&rtlpriv->locks.ips_lock);
451 spin_lock_init(&rtlpriv->locks.irq_th_lock); 468 spin_lock_init(&rtlpriv->locks.irq_th_lock);
469 spin_lock_init(&rtlpriv->locks.irq_pci_lock);
470 spin_lock_init(&rtlpriv->locks.tx_lock);
452 spin_lock_init(&rtlpriv->locks.h2c_lock); 471 spin_lock_init(&rtlpriv->locks.h2c_lock);
453 spin_lock_init(&rtlpriv->locks.rf_ps_lock); 472 spin_lock_init(&rtlpriv->locks.rf_ps_lock);
454 spin_lock_init(&rtlpriv->locks.rf_lock); 473 spin_lock_init(&rtlpriv->locks.rf_lock);
455 spin_lock_init(&rtlpriv->locks.waitq_lock); 474 spin_lock_init(&rtlpriv->locks.waitq_lock);
475 spin_lock_init(&rtlpriv->locks.entry_list_lock);
476 spin_lock_init(&rtlpriv->locks.fw_ps_lock);
456 spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); 477 spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);
478 spin_lock_init(&rtlpriv->locks.check_sendpkt_lock);
479 spin_lock_init(&rtlpriv->locks.fw_ps_lock);
480 spin_lock_init(&rtlpriv->locks.lps_lock);
481
482 /* <5> init list */
483 INIT_LIST_HEAD(&rtlpriv->entry_list);
457 484
458 rtlmac->link_state = MAC80211_NOLINK; 485 rtlmac->link_state = MAC80211_NOLINK;
459 486
460 /* <5> init deferred work */ 487 /* <6> init deferred work */
461 _rtl_init_deferred_work(hw); 488 _rtl_init_deferred_work(hw);
462 489
463 return 0; 490 return 0;
@@ -523,7 +550,8 @@ static void _rtl_query_shortgi(struct ieee80211_hw *hw,
523 if (mac->opmode == NL80211_IFTYPE_STATION) 550 if (mac->opmode == NL80211_IFTYPE_STATION)
524 bw_40 = mac->bw_40; 551 bw_40 = mac->bw_40;
525 else if (mac->opmode == NL80211_IFTYPE_AP || 552 else if (mac->opmode == NL80211_IFTYPE_AP ||
526 mac->opmode == NL80211_IFTYPE_ADHOC) 553 mac->opmode == NL80211_IFTYPE_ADHOC ||
554 mac->opmode == NL80211_IFTYPE_MESH_POINT)
527 bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40; 555 bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
528 556
529 if (bw_40 && sgi_40) 557 if (bw_40 && sgi_40)
@@ -578,23 +606,26 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
578 if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) { 606 if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) {
579 if (mac->opmode == NL80211_IFTYPE_STATION) { 607 if (mac->opmode == NL80211_IFTYPE_STATION) {
580 tcb_desc->ratr_index = 0; 608 tcb_desc->ratr_index = 0;
581 } else if (mac->opmode == NL80211_IFTYPE_ADHOC) { 609 } else if (mac->opmode == NL80211_IFTYPE_ADHOC ||
610 mac->opmode == NL80211_IFTYPE_MESH_POINT) {
582 if (tcb_desc->multicast || tcb_desc->broadcast) { 611 if (tcb_desc->multicast || tcb_desc->broadcast) {
583 tcb_desc->hw_rate = 612 tcb_desc->hw_rate =
584 rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; 613 rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
585 tcb_desc->use_driver_rate = 1; 614 tcb_desc->use_driver_rate = 1;
615 tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;
586 } else { 616 } else {
587 /* TODO */ 617 tcb_desc->ratr_index = ratr_index;
588 } 618 }
589 tcb_desc->ratr_index = ratr_index;
590 } else if (mac->opmode == NL80211_IFTYPE_AP) { 619 } else if (mac->opmode == NL80211_IFTYPE_AP) {
591 tcb_desc->ratr_index = ratr_index; 620 tcb_desc->ratr_index = ratr_index;
592 } 621 }
593 } 622 }
594 623
595 if (rtlpriv->dm.useramask) { 624 if (rtlpriv->dm.useramask) {
596 /* TODO we will differentiate adhoc and station futrue */ 625 tcb_desc->ratr_index = ratr_index;
597 if (mac->opmode == NL80211_IFTYPE_STATION) { 626 /* TODO we will differentiate adhoc and station future */
627 if (mac->opmode == NL80211_IFTYPE_STATION ||
628 mac->opmode == NL80211_IFTYPE_MESH_POINT) {
598 tcb_desc->mac_id = 0; 629 tcb_desc->mac_id = 0;
599 630
600 if (mac->mode == WIRELESS_MODE_N_24G) 631 if (mac->mode == WIRELESS_MODE_N_24G)
@@ -608,7 +639,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
608 else if (mac->mode & WIRELESS_MODE_A) 639 else if (mac->mode & WIRELESS_MODE_A)
609 tcb_desc->ratr_index = RATR_INX_WIRELESS_G; 640 tcb_desc->ratr_index = RATR_INX_WIRELESS_G;
610 } else if (mac->opmode == NL80211_IFTYPE_AP || 641 } else if (mac->opmode == NL80211_IFTYPE_AP ||
611 mac->opmode == NL80211_IFTYPE_ADHOC) { 642 mac->opmode == NL80211_IFTYPE_ADHOC) {
612 if (NULL != sta) { 643 if (NULL != sta) {
613 if (sta->aid > 0) 644 if (sta->aid > 0)
614 tcb_desc->mac_id = sta->aid + 1; 645 tcb_desc->mac_id = sta->aid + 1;
@@ -619,7 +650,6 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
619 } 650 }
620 } 651 }
621 } 652 }
622
623} 653}
624 654
625static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, 655static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
@@ -633,7 +663,8 @@ static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
633 if (!sta) 663 if (!sta)
634 return; 664 return;
635 if (mac->opmode == NL80211_IFTYPE_AP || 665 if (mac->opmode == NL80211_IFTYPE_AP ||
636 mac->opmode == NL80211_IFTYPE_ADHOC) { 666 mac->opmode == NL80211_IFTYPE_ADHOC ||
667 mac->opmode == NL80211_IFTYPE_MESH_POINT) {
637 if (sta->bandwidth == IEEE80211_STA_RX_BW_20) 668 if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
638 return; 669 return;
639 } else if (mac->opmode == NL80211_IFTYPE_STATION) { 670 } else if (mac->opmode == NL80211_IFTYPE_STATION) {
@@ -834,8 +865,8 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
834 if (rtlpriv->dm.supp_phymode_switch && 865 if (rtlpriv->dm.supp_phymode_switch &&
835 mac->link_state < MAC80211_LINKED && 866 mac->link_state < MAC80211_LINKED &&
836 (ieee80211_is_auth(fc) || ieee80211_is_probe_req(fc))) { 867 (ieee80211_is_auth(fc) || ieee80211_is_probe_req(fc))) {
837 if (rtlpriv->cfg->ops->check_switch_to_dmdp) 868 if (rtlpriv->cfg->ops->chk_switch_dmdp)
838 rtlpriv->cfg->ops->check_switch_to_dmdp(hw); 869 rtlpriv->cfg->ops->chk_switch_dmdp(hw);
839 } 870 }
840 if (ieee80211_is_auth(fc)) { 871 if (ieee80211_is_auth(fc)) {
841 RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); 872 RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
@@ -924,6 +955,56 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
924} 955}
925EXPORT_SYMBOL(rtl_get_tcb_desc); 956EXPORT_SYMBOL(rtl_get_tcb_desc);
926 957
958static bool addbareq_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
959{
960 struct rtl_priv *rtlpriv = rtl_priv(hw);
961 struct ieee80211_sta *sta = NULL;
962 struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
963 struct rtl_sta_info *sta_entry = NULL;
964 struct ieee80211_mgmt *mgmt = (void *)skb->data;
965 u16 capab = 0, tid = 0;
966 struct rtl_tid_data *tid_data;
967 struct sk_buff *skb_delba = NULL;
968 struct ieee80211_rx_status rx_status = { 0 };
969
970 rcu_read_lock();
971 sta = rtl_find_sta(hw, hdr->addr3);
972 if (sta == NULL) {
973 RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_EMERG,
974 "sta is NULL\n");
975 rcu_read_unlock();
976 return true;
977 }
978
979 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
980 if (!sta_entry) {
981 rcu_read_unlock();
982 return true;
983 }
984 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
985 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
986 tid_data = &sta_entry->tids[tid];
987 if (tid_data->agg.rx_agg_state == RTL_RX_AGG_START) {
988 skb_delba = rtl_make_del_ba(hw, hdr->addr2, hdr->addr3, tid);
989 if (skb_delba) {
990 rx_status.freq = hw->conf.channel->center_freq;
991 rx_status.band = hw->conf.channel->band;
992 rx_status.flag |= RX_FLAG_DECRYPTED;
993 rx_status.flag |= RX_FLAG_MACTIME_END;
994 rx_status.rate_idx = 0;
995 rx_status.signal = 50 + 10;
996 memcpy(IEEE80211_SKB_RXCB(skb_delba), &rx_status,
997 sizeof(rx_status));
998 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG,
999 "fake del\n", skb_delba->data,
1000 skb_delba->len);
1001 ieee80211_rx_irqsafe(hw, skb_delba);
1002 }
1003 }
1004 rcu_read_unlock();
1005 return false;
1006}
1007
927bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) 1008bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
928{ 1009{
929 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 1010 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -948,6 +1029,11 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
948 RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, 1029 RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
949 "%s ACT_ADDBAREQ From :%pM\n", 1030 "%s ACT_ADDBAREQ From :%pM\n",
950 is_tx ? "Tx" : "Rx", hdr->addr2); 1031 is_tx ? "Tx" : "Rx", hdr->addr2);
1032 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "req\n",
1033 skb->data, skb->len);
1034 if (!is_tx)
1035 if (addbareq_rx(hw, skb))
1036 return true;
951 break; 1037 break;
952 case ACT_ADDBARSP: 1038 case ACT_ADDBARSP:
953 RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, 1039 RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
@@ -1003,8 +1089,9 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
1003 is_tx ? "Tx" : "Rx"); 1089 is_tx ? "Tx" : "Rx");
1004 1090
1005 if (is_tx) { 1091 if (is_tx) {
1092 rtlpriv->enter_ps = false;
1006 schedule_work(&rtlpriv-> 1093 schedule_work(&rtlpriv->
1007 works.lps_leave_work); 1094 works.lps_change_work);
1008 ppsc->last_delaylps_stamp_jiffies = 1095 ppsc->last_delaylps_stamp_jiffies =
1009 jiffies; 1096 jiffies;
1010 } 1097 }
@@ -1014,7 +1101,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
1014 } 1101 }
1015 } else if (ETH_P_ARP == ether_type) { 1102 } else if (ETH_P_ARP == ether_type) {
1016 if (is_tx) { 1103 if (is_tx) {
1017 schedule_work(&rtlpriv->works.lps_leave_work); 1104 rtlpriv->enter_ps = false;
1105 schedule_work(&rtlpriv->works.lps_change_work);
1018 ppsc->last_delaylps_stamp_jiffies = jiffies; 1106 ppsc->last_delaylps_stamp_jiffies = jiffies;
1019 } 1107 }
1020 1108
@@ -1024,7 +1112,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
1024 "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); 1112 "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx");
1025 1113
1026 if (is_tx) { 1114 if (is_tx) {
1027 schedule_work(&rtlpriv->works.lps_leave_work); 1115 rtlpriv->enter_ps = false;
1116 schedule_work(&rtlpriv->works.lps_change_work);
1028 ppsc->last_delaylps_stamp_jiffies = jiffies; 1117 ppsc->last_delaylps_stamp_jiffies = jiffies;
1029 } 1118 }
1030 1119
@@ -1101,6 +1190,58 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw,
1101 return 0; 1190 return 0;
1102} 1191}
1103 1192
1193int rtl_rx_agg_start(struct ieee80211_hw *hw,
1194 struct ieee80211_sta *sta, u16 tid)
1195{
1196 struct rtl_priv *rtlpriv = rtl_priv(hw);
1197 struct rtl_tid_data *tid_data;
1198 struct rtl_sta_info *sta_entry = NULL;
1199
1200 if (sta == NULL)
1201 return -EINVAL;
1202
1203 if (unlikely(tid >= MAX_TID_COUNT))
1204 return -EINVAL;
1205
1206 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
1207 if (!sta_entry)
1208 return -ENXIO;
1209 tid_data = &sta_entry->tids[tid];
1210
1211 RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG,
1212 "on ra = %pM tid = %d seq:%d\n", sta->addr, tid,
1213 tid_data->seq_number);
1214
1215 tid_data->agg.rx_agg_state = RTL_RX_AGG_START;
1216 return 0;
1217}
1218
1219int rtl_rx_agg_stop(struct ieee80211_hw *hw,
1220 struct ieee80211_sta *sta, u16 tid)
1221{
1222 struct rtl_priv *rtlpriv = rtl_priv(hw);
1223 struct rtl_sta_info *sta_entry = NULL;
1224
1225 if (sta == NULL)
1226 return -EINVAL;
1227
1228 if (!sta->addr) {
1229 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n");
1230 return -EINVAL;
1231 }
1232
1233 RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
1234 "on ra = %pM tid = %d\n", sta->addr, tid);
1235
1236 if (unlikely(tid >= MAX_TID_COUNT))
1237 return -EINVAL;
1238
1239 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
1240 sta_entry->tids[tid].agg.rx_agg_state = RTL_RX_AGG_STOP;
1241
1242 return 0;
1243}
1244
1104int rtl_tx_agg_oper(struct ieee80211_hw *hw, 1245int rtl_tx_agg_oper(struct ieee80211_hw *hw,
1105 struct ieee80211_sta *sta, u16 tid) 1246 struct ieee80211_sta *sta, u16 tid)
1106{ 1247{
@@ -1132,6 +1273,34 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw,
1132 * wq & timer callback functions 1273 * wq & timer callback functions
1133 * 1274 *
1134 *********************************************************/ 1275 *********************************************************/
1276/* this function is used for roaming */
1277void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb)
1278{
1279 struct rtl_priv *rtlpriv = rtl_priv(hw);
1280 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1281
1282 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
1283 return;
1284
1285 if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
1286 return;
1287
1288 /* check if this really is a beacon */
1289 if (!ieee80211_is_beacon(hdr->frame_control) &&
1290 !ieee80211_is_probe_resp(hdr->frame_control))
1291 return;
1292
1293 /* min. beacon length + FCS_LEN */
1294 if (skb->len <= 40 + FCS_LEN)
1295 return;
1296
1297 /* and only beacons from the associated BSSID, please */
1298 if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
1299 return;
1300
1301 rtlpriv->link_info.bcn_rx_inperiod++;
1302}
1303
1135void rtl_watchdog_wq_callback(void *data) 1304void rtl_watchdog_wq_callback(void *data)
1136{ 1305{
1137 struct rtl_works *rtlworks = container_of_dwork_rtl(data, 1306 struct rtl_works *rtlworks = container_of_dwork_rtl(data,
@@ -1142,6 +1311,8 @@ void rtl_watchdog_wq_callback(void *data)
1142 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1311 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1143 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 1312 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1144 bool busytraffic = false; 1313 bool busytraffic = false;
1314 bool tx_busy_traffic = false;
1315 bool rx_busy_traffic = false;
1145 bool higher_busytraffic = false; 1316 bool higher_busytraffic = false;
1146 bool higher_busyrxtraffic = false; 1317 bool higher_busyrxtraffic = false;
1147 u8 idx, tid; 1318 u8 idx, tid;
@@ -1151,7 +1322,6 @@ void rtl_watchdog_wq_callback(void *data)
1151 u32 aver_tx_cnt_inperiod = 0; 1322 u32 aver_tx_cnt_inperiod = 0;
1152 u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0}; 1323 u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0};
1153 u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0}; 1324 u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0};
1154 bool enter_ps = false;
1155 1325
1156 if (is_hal_stop(rtlhal)) 1326 if (is_hal_stop(rtlhal))
1157 return; 1327 return;
@@ -1191,8 +1361,13 @@ void rtl_watchdog_wq_callback(void *data)
1191 aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4; 1361 aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4;
1192 1362
1193 /* (2) check traffic busy */ 1363 /* (2) check traffic busy */
1194 if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100) 1364 if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100) {
1195 busytraffic = true; 1365 busytraffic = true;
1366 if (aver_rx_cnt_inperiod > aver_tx_cnt_inperiod)
1367 rx_busy_traffic = true;
1368 else
1369 tx_busy_traffic = false;
1370 }
1196 1371
1197 /* Higher Tx/Rx data. */ 1372 /* Higher Tx/Rx data. */
1198 if (aver_rx_cnt_inperiod > 4000 || 1373 if (aver_rx_cnt_inperiod > 4000 ||
@@ -1228,15 +1403,12 @@ void rtl_watchdog_wq_callback(void *data)
1228 if (((rtlpriv->link_info.num_rx_inperiod + 1403 if (((rtlpriv->link_info.num_rx_inperiod +
1229 rtlpriv->link_info.num_tx_inperiod) > 8) || 1404 rtlpriv->link_info.num_tx_inperiod) > 8) ||
1230 (rtlpriv->link_info.num_rx_inperiod > 2)) 1405 (rtlpriv->link_info.num_rx_inperiod > 2))
1231 enter_ps = false; 1406 rtlpriv->enter_ps = true;
1232 else 1407 else
1233 enter_ps = true; 1408 rtlpriv->enter_ps = false;
1234 1409
1235 /* LeisurePS only work in infra mode. */ 1410 /* LeisurePS only work in infra mode. */
1236 if (enter_ps) 1411 schedule_work(&rtlpriv->works.lps_change_work);
1237 rtl_lps_enter(hw);
1238 else
1239 rtl_lps_leave(hw);
1240 } 1412 }
1241 1413
1242 rtlpriv->link_info.num_rx_inperiod = 0; 1414 rtlpriv->link_info.num_rx_inperiod = 0;
@@ -1246,10 +1418,37 @@ void rtl_watchdog_wq_callback(void *data)
1246 1418
1247 rtlpriv->link_info.busytraffic = busytraffic; 1419 rtlpriv->link_info.busytraffic = busytraffic;
1248 rtlpriv->link_info.higher_busytraffic = higher_busytraffic; 1420 rtlpriv->link_info.higher_busytraffic = higher_busytraffic;
1421 rtlpriv->link_info.rx_busy_traffic = rx_busy_traffic;
1422 rtlpriv->link_info.tx_busy_traffic = tx_busy_traffic;
1249 rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic; 1423 rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic;
1250 1424
1251 /* <3> DM */ 1425 /* <3> DM */
1252 rtlpriv->cfg->ops->dm_watchdog(hw); 1426 rtlpriv->cfg->ops->dm_watchdog(hw);
1427
1428 /* <4> roaming */
1429 if (mac->link_state == MAC80211_LINKED &&
1430 mac->opmode == NL80211_IFTYPE_STATION) {
1431 if ((rtlpriv->link_info.bcn_rx_inperiod +
1432 rtlpriv->link_info.num_rx_inperiod) == 0) {
1433 rtlpriv->link_info.roam_times++;
1434 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
1435 "AP off for %d s\n",
1436 (rtlpriv->link_info.roam_times * 2));
1437
1438 /* if we can't recv beacon for 6s, we should
1439 * reconnect this AP
1440 */
1441 if (rtlpriv->link_info.roam_times >= 3) {
1442 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1443 "AP off, try to reconnect now\n");
1444 rtlpriv->link_info.roam_times = 0;
1445 ieee80211_connection_loss(rtlpriv->mac80211.vif);
1446 }
1447 } else {
1448 rtlpriv->link_info.roam_times = 0;
1449 }
1450 }
1451 rtlpriv->link_info.bcn_rx_inperiod = 0;
1253} 1452}
1254 1453
1255void rtl_watch_dog_timer_callback(unsigned long data) 1454void rtl_watch_dog_timer_callback(unsigned long data)
@@ -1264,6 +1463,28 @@ void rtl_watch_dog_timer_callback(unsigned long data)
1264 jiffies + MSECS(RTL_WATCH_DOG_TIME)); 1463 jiffies + MSECS(RTL_WATCH_DOG_TIME));
1265} 1464}
1266 1465
1466void rtl_fwevt_wq_callback(void *data)
1467{
1468 struct rtl_works *rtlworks =
1469 container_of_dwork_rtl(data, struct rtl_works, fwevt_wq);
1470 struct ieee80211_hw *hw = rtlworks->hw;
1471 struct rtl_priv *rtlpriv = rtl_priv(hw);
1472
1473 rtlpriv->cfg->ops->c2h_command_handle(hw);
1474}
1475
1476void rtl_easy_concurrent_retrytimer_callback(unsigned long data)
1477{
1478 struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
1479 struct rtl_priv *rtlpriv = rtl_priv(hw);
1480 struct rtl_priv *buddy_priv = rtlpriv->buddy_priv;
1481
1482 if (buddy_priv == NULL)
1483 return;
1484
1485 rtlpriv->cfg->ops->dualmac_easy_concurrent(hw);
1486}
1487
1267/********************************************************* 1488/*********************************************************
1268 * 1489 *
1269 * frame process functions 1490 * frame process functions
@@ -1334,14 +1555,16 @@ static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw,
1334} 1555}
1335 1556
1336int rtl_send_smps_action(struct ieee80211_hw *hw, 1557int rtl_send_smps_action(struct ieee80211_hw *hw,
1337 struct ieee80211_sta *sta, u8 *da, u8 *bssid, 1558 struct ieee80211_sta *sta,
1338 enum ieee80211_smps_mode smps) 1559 enum ieee80211_smps_mode smps)
1339{ 1560{
1340 struct rtl_priv *rtlpriv = rtl_priv(hw); 1561 struct rtl_priv *rtlpriv = rtl_priv(hw);
1341 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1562 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1342 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 1563 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1343 struct sk_buff *skb = rtl_make_smps_action(hw, smps, da, bssid); 1564 struct sk_buff *skb = NULL;
1344 struct rtl_tcb_desc tcb_desc; 1565 struct rtl_tcb_desc tcb_desc;
1566 u8 bssid[ETH_ALEN] = {0};
1567
1345 memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); 1568 memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
1346 1569
1347 if (rtlpriv->mac80211.act_scanning) 1570 if (rtlpriv->mac80211.act_scanning)
@@ -1356,21 +1579,67 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,
1356 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) 1579 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
1357 goto err_free; 1580 goto err_free;
1358 1581
1582 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP)
1583 memcpy(bssid, rtlpriv->efuse.dev_addr, ETH_ALEN);
1584 else
1585 memcpy(bssid, rtlpriv->mac80211.bssid, ETH_ALEN);
1586
1587 skb = rtl_make_smps_action(hw, smps, sta->addr, bssid);
1359 /* this is a type = mgmt * stype = action frame */ 1588 /* this is a type = mgmt * stype = action frame */
1360 if (skb) { 1589 if (skb) {
1361 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1590 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1362 struct rtl_sta_info *sta_entry = 1591 struct rtl_sta_info *sta_entry =
1363 (struct rtl_sta_info *) sta->drv_priv; 1592 (struct rtl_sta_info *) sta->drv_priv;
1364 sta_entry->mimo_ps = smps; 1593 sta_entry->mimo_ps = smps;
1365 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
1366 1594
1367 info->control.rates[0].idx = 0; 1595 info->control.rates[0].idx = 0;
1368 info->band = hw->conf.channel->band; 1596 info->band = hw->conf.channel->band;
1369 rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc); 1597 rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc);
1370 } 1598 }
1599 return 1;
1600
1371err_free: 1601err_free:
1372 return 0; 1602 return 0;
1373} 1603}
1604EXPORT_SYMBOL(rtl_send_smps_action);
1605
1606/* There seem to be issues in mac80211 regarding when del ba frames can be
1607 * received. As a work around, we make a fake del_ba if we receive a ba_req;
1608 * however, rx_agg was opened to let mac80211 release some ba related
1609 * resources. This del_ba is for tx only.
1610 */
1611struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw,
1612 u8 *sa, u8 *bssid, u16 tid)
1613{
1614 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1615 struct sk_buff *skb;
1616 struct ieee80211_mgmt *action_frame;
1617 u16 params;
1618
1619 /* 27 = header + category + action + smps mode */
1620 skb = dev_alloc_skb(34 + hw->extra_tx_headroom);
1621 if (!skb)
1622 return NULL;
1623
1624 skb_reserve(skb, hw->extra_tx_headroom);
1625 action_frame = (void *)skb_put(skb, 34);
1626 memset(action_frame, 0, 34);
1627 memcpy(action_frame->sa, sa, ETH_ALEN);
1628 memcpy(action_frame->da, rtlefuse->dev_addr, ETH_ALEN);
1629 memcpy(action_frame->bssid, bssid, ETH_ALEN);
1630 action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1631 IEEE80211_STYPE_ACTION);
1632 action_frame->u.action.category = WLAN_CATEGORY_BACK;
1633 action_frame->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
1634 params = (u16)(1 << 11); /* bit 11 initiator */
1635 params |= (u16)(tid << 12); /* bit 15:12 TID number */
1636
1637 action_frame->u.action.u.delba.params = cpu_to_le16(params);
1638 action_frame->u.action.u.delba.reason_code =
1639 cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
1640
1641 return skb;
1642}
1374 1643
1375/********************************************************* 1644/*********************************************************
1376 * 1645 *
@@ -1587,11 +1856,17 @@ MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
1587MODULE_LICENSE("GPL"); 1856MODULE_LICENSE("GPL");
1588MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); 1857MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
1589 1858
1859struct rtl_global_var global_var = {};
1860
1590static int __init rtl_core_module_init(void) 1861static int __init rtl_core_module_init(void)
1591{ 1862{
1592 if (rtl_rate_control_register()) 1863 if (rtl_rate_control_register())
1593 pr_err("Unable to register rtl_rc, use default RC !!\n"); 1864 pr_err("Unable to register rtl_rc, use default RC !!\n");
1594 1865
1866 /* init some global vars */
1867 INIT_LIST_HEAD(&global_var.glb_priv_list);
1868 spin_lock_init(&global_var.glb_list_lock);
1869
1595 return 0; 1870 return 0;
1596} 1871}
1597 1872
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index 5a8c80e259f7..8576bc34b032 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -113,6 +113,7 @@ void rtl_init_rx_config(struct ieee80211_hw *hw);
113void rtl_init_rfkill(struct ieee80211_hw *hw); 113void rtl_init_rfkill(struct ieee80211_hw *hw);
114void rtl_deinit_rfkill(struct ieee80211_hw *hw); 114void rtl_deinit_rfkill(struct ieee80211_hw *hw);
115 115
116void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb);
116void rtl_watch_dog_timer_callback(unsigned long data); 117void rtl_watch_dog_timer_callback(unsigned long data);
117void rtl_deinit_deferred_work(struct ieee80211_hw *hw); 118void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
118 119
@@ -126,7 +127,12 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
126 u16 tid); 127 u16 tid);
127int rtl_tx_agg_oper(struct ieee80211_hw *hw, struct ieee80211_sta *sta, 128int rtl_tx_agg_oper(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
128 u16 tid); 129 u16 tid);
130int rtl_rx_agg_start(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
131 u16 tid);
132int rtl_rx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
133 u16 tid);
129void rtl_watchdog_wq_callback(void *data); 134void rtl_watchdog_wq_callback(void *data);
135void rtl_fwevt_wq_callback(void *data);
130 136
131void rtl_get_tcb_desc(struct ieee80211_hw *hw, 137void rtl_get_tcb_desc(struct ieee80211_hw *hw,
132 struct ieee80211_tx_info *info, 138 struct ieee80211_tx_info *info,
@@ -134,14 +140,18 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
134 struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc); 140 struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc);
135 141
136int rtl_send_smps_action(struct ieee80211_hw *hw, 142int rtl_send_smps_action(struct ieee80211_hw *hw,
137 struct ieee80211_sta *sta, u8 *da, u8 *bssid, 143 struct ieee80211_sta *sta,
138 enum ieee80211_smps_mode smps); 144 enum ieee80211_smps_mode smps);
139u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); 145u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
140void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); 146void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
141u8 rtl_tid_to_ac(u8 tid); 147u8 rtl_tid_to_ac(u8 tid);
142extern struct attribute_group rtl_attribute_group; 148extern struct attribute_group rtl_attribute_group;
149void rtl_easy_concurrent_retrytimer_callback(unsigned long data);
150extern struct rtl_global_var global_var;
143int rtlwifi_rate_mapping(struct ieee80211_hw *hw, 151int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
144 bool isht, u8 desc_rate, bool first_ampdu); 152 bool isht, u8 desc_rate, bool first_ampdu);
145bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); 153bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
154struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw,
155 u8 *sa, u8 *bssid, u16 tid);
146 156
147#endif 157#endif
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index d3ce9fbef00e..2201b5cee08f 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -104,9 +104,12 @@ static void rtl_op_stop(struct ieee80211_hw *hw)
104 if (is_hal_stop(rtlhal)) 104 if (is_hal_stop(rtlhal))
105 return; 105 return;
106 106
107 /* here is must, because adhoc do stop and start,
108 * but stop with RFOFF may cause something wrong,
109 * like adhoc TP
110 */
107 if (unlikely(ppsc->rfpwr_state == ERFOFF)) { 111 if (unlikely(ppsc->rfpwr_state == ERFOFF)) {
108 rtl_ips_nic_on(hw); 112 rtl_ips_nic_on(hw);
109 mdelay(1);
110 } 113 }
111 114
112 mutex_lock(&rtlpriv->locks.conf_mutex); 115 mutex_lock(&rtlpriv->locks.conf_mutex);
@@ -167,7 +170,11 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
167 rtl_ips_nic_on(hw); 170 rtl_ips_nic_on(hw);
168 171
169 mutex_lock(&rtlpriv->locks.conf_mutex); 172 mutex_lock(&rtlpriv->locks.conf_mutex);
170 switch (vif->type) { 173
174 switch (ieee80211_vif_type_p2p(vif)) {
175 case NL80211_IFTYPE_P2P_CLIENT:
176 mac->p2p = P2P_ROLE_CLIENT;
177 /*fall through*/
171 case NL80211_IFTYPE_STATION: 178 case NL80211_IFTYPE_STATION:
172 if (mac->beacon_enabled == 1) { 179 if (mac->beacon_enabled == 1) {
173 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 180 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
@@ -192,6 +199,9 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
192 (u8 *) (&mac->basic_rates)); 199 (u8 *) (&mac->basic_rates));
193 200
194 break; 201 break;
202 case NL80211_IFTYPE_P2P_GO:
203 mac->p2p = P2P_ROLE_GO;
204 /*fall through*/
195 case NL80211_IFTYPE_AP: 205 case NL80211_IFTYPE_AP:
196 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 206 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
197 "NL80211_IFTYPE_AP\n"); 207 "NL80211_IFTYPE_AP\n");
@@ -205,6 +215,19 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
205 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, 215 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
206 (u8 *) (&mac->basic_rates)); 216 (u8 *) (&mac->basic_rates));
207 break; 217 break;
218 case NL80211_IFTYPE_MESH_POINT:
219 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
220 "NL80211_IFTYPE_MESH_POINT\n");
221
222 mac->link_state = MAC80211_LINKED;
223 rtlpriv->cfg->ops->set_bcn_reg(hw);
224 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
225 mac->basic_rates = 0xfff;
226 else
227 mac->basic_rates = 0xff0;
228 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
229 (u8 *)(&mac->basic_rates));
230 break;
208 default: 231 default:
209 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 232 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
210 "operation mode %d is not supported!\n", vif->type); 233 "operation mode %d is not supported!\n", vif->type);
@@ -212,6 +235,13 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
212 goto out; 235 goto out;
213 } 236 }
214 237
238 if (mac->p2p) {
239 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
240 "p2p role %x\n", vif->type);
241 mac->basic_rates = 0xff0;/*disable cck rate for p2p*/
242 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
243 (u8 *)(&mac->basic_rates));
244 }
215 mac->vif = vif; 245 mac->vif = vif;
216 mac->opmode = vif->type; 246 mac->opmode = vif->type;
217 rtlpriv->cfg->ops->set_network_type(hw, vif->type); 247 rtlpriv->cfg->ops->set_network_type(hw, vif->type);
@@ -232,9 +262,9 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw,
232 mutex_lock(&rtlpriv->locks.conf_mutex); 262 mutex_lock(&rtlpriv->locks.conf_mutex);
233 263
234 /* Free beacon resources */ 264 /* Free beacon resources */
235 if ((mac->opmode == NL80211_IFTYPE_AP) || 265 if ((vif->type == NL80211_IFTYPE_AP) ||
236 (mac->opmode == NL80211_IFTYPE_ADHOC) || 266 (vif->type == NL80211_IFTYPE_ADHOC) ||
237 (mac->opmode == NL80211_IFTYPE_MESH_POINT)) { 267 (vif->type == NL80211_IFTYPE_MESH_POINT)) {
238 if (mac->beacon_enabled == 1) { 268 if (mac->beacon_enabled == 1) {
239 mac->beacon_enabled = 0; 269 mac->beacon_enabled = 0;
240 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, 270 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
@@ -247,6 +277,7 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw,
247 *Note: We assume NL80211_IFTYPE_UNSPECIFIED as 277 *Note: We assume NL80211_IFTYPE_UNSPECIFIED as
248 *NO LINK for our hardware. 278 *NO LINK for our hardware.
249 */ 279 */
280 mac->p2p = 0;
250 mac->vif = NULL; 281 mac->vif = NULL;
251 mac->link_state = MAC80211_NOLINK; 282 mac->link_state = MAC80211_NOLINK;
252 memset(mac->bssid, 0, 6); 283 memset(mac->bssid, 0, 6);
@@ -256,6 +287,22 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw,
256 mutex_unlock(&rtlpriv->locks.conf_mutex); 287 mutex_unlock(&rtlpriv->locks.conf_mutex);
257} 288}
258 289
290static int rtl_op_change_interface(struct ieee80211_hw *hw,
291 struct ieee80211_vif *vif,
292 enum nl80211_iftype new_type, bool p2p)
293{
294 struct rtl_priv *rtlpriv = rtl_priv(hw);
295 int ret;
296 rtl_op_remove_interface(hw, vif);
297
298 vif->type = new_type;
299 vif->p2p = p2p;
300 ret = rtl_op_add_interface(hw, vif);
301 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
302 "p2p %x\n", p2p);
303 return ret;
304}
305
259static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) 306static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
260{ 307{
261 struct rtl_priv *rtlpriv = rtl_priv(hw); 308 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -264,6 +311,9 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
264 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 311 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
265 struct ieee80211_conf *conf = &hw->conf; 312 struct ieee80211_conf *conf = &hw->conf;
266 313
314 if (mac->skip_scan)
315 return 1;
316
267 mutex_lock(&rtlpriv->locks.conf_mutex); 317 mutex_lock(&rtlpriv->locks.conf_mutex);
268 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /*BIT(2)*/ 318 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /*BIT(2)*/
269 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 319 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
@@ -323,6 +373,16 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
323 struct ieee80211_channel *channel = hw->conf.channel; 373 struct ieee80211_channel *channel = hw->conf.channel;
324 u8 wide_chan = (u8) channel->hw_value; 374 u8 wide_chan = (u8) channel->hw_value;
325 375
376 if (mac->act_scanning)
377 mac->n_channels++;
378
379 if (rtlpriv->dm.supp_phymode_switch &&
380 mac->link_state < MAC80211_LINKED &&
381 !mac->act_scanning) {
382 if (rtlpriv->cfg->ops->chk_switch_dmdp)
383 rtlpriv->cfg->ops->chk_switch_dmdp(hw);
384 }
385
326 /* 386 /*
327 *because we should back channel to 387 *because we should back channel to
328 *current_network.chan in in scanning, 388 *current_network.chan in in scanning,
@@ -373,13 +433,13 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
373 if (wide_chan <= 0) 433 if (wide_chan <= 0)
374 wide_chan = 1; 434 wide_chan = 1;
375 435
376 /* In scanning, before we go offchannel we may send a ps=1 null 436 /* In scanning, before we go offchannel we may send a ps = 1
377 * to AP, and then we may send a ps = 0 null to AP quickly, but 437 * null to AP, and then we may send a ps = 0 null to AP quickly,
378 * first null may have caused AP to put lots of packet to hw tx 438 * but first null may have caused AP to put lots of packet to
379 * buffer. These packets must be tx'd before we go off channel 439 * hw tx buffer. These packets must be tx'd before we go off
380 * so we must delay more time to let AP flush these packets 440 * channel so we must delay more time to let AP flush these
381 * before going offchannel, or dis-association or delete BA will 441 * packets before going offchannel, or dis-association or
382 * happen by AP 442 * delete BA will be caused by AP
383 */ 443 */
384 if (rtlpriv->mac80211.offchan_delay) { 444 if (rtlpriv->mac80211.offchan_delay) {
385 rtlpriv->mac80211.offchan_delay = false; 445 rtlpriv->mac80211.offchan_delay = false;
@@ -441,7 +501,8 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
441 * and nolink check bssid is set in set network_type */ 501 * and nolink check bssid is set in set network_type */
442 if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) && 502 if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
443 (mac->link_state >= MAC80211_LINKED)) { 503 (mac->link_state >= MAC80211_LINKED)) {
444 if (mac->opmode != NL80211_IFTYPE_AP) { 504 if (mac->opmode != NL80211_IFTYPE_AP &&
505 mac->opmode != NL80211_IFTYPE_MESH_POINT) {
445 if (*new_flags & FIF_BCN_PRBRESP_PROMISC) { 506 if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
446 rtlpriv->cfg->ops->set_chk_bssid(hw, false); 507 rtlpriv->cfg->ops->set_chk_bssid(hw, false);
447 } else { 508 } else {
@@ -481,32 +542,43 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw,
481{ 542{
482 struct rtl_priv *rtlpriv = rtl_priv(hw); 543 struct rtl_priv *rtlpriv = rtl_priv(hw);
483 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 544 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
545 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
484 struct rtl_sta_info *sta_entry; 546 struct rtl_sta_info *sta_entry;
485 547
486 if (sta) { 548 if (sta) {
487 sta_entry = (struct rtl_sta_info *) sta->drv_priv; 549 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
550 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
551 list_add_tail(&sta_entry->list, &rtlpriv->entry_list);
552 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
488 if (rtlhal->current_bandtype == BAND_ON_2_4G) { 553 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
489 sta_entry->wireless_mode = WIRELESS_MODE_G; 554 sta_entry->wireless_mode = WIRELESS_MODE_G;
490 if (sta->supp_rates[0] <= 0xf) 555 if (sta->supp_rates[0] <= 0xf)
491 sta_entry->wireless_mode = WIRELESS_MODE_B; 556 sta_entry->wireless_mode = WIRELESS_MODE_B;
492 if (sta->ht_cap.ht_supported) 557 if (sta->ht_cap.ht_supported == true)
493 sta_entry->wireless_mode = WIRELESS_MODE_N_24G; 558 sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
559
560 if (vif->type == NL80211_IFTYPE_ADHOC)
561 sta_entry->wireless_mode = WIRELESS_MODE_G;
494 } else if (rtlhal->current_bandtype == BAND_ON_5G) { 562 } else if (rtlhal->current_bandtype == BAND_ON_5G) {
495 sta_entry->wireless_mode = WIRELESS_MODE_A; 563 sta_entry->wireless_mode = WIRELESS_MODE_A;
496 if (sta->ht_cap.ht_supported) 564 if (sta->ht_cap.ht_supported == true)
497 sta_entry->wireless_mode = WIRELESS_MODE_N_24G; 565 sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
498 }
499 566
500 /* I found some times mac80211 give wrong supp_rates for adhoc*/ 567 if (vif->type == NL80211_IFTYPE_ADHOC)
501 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) 568 sta_entry->wireless_mode = WIRELESS_MODE_A;
502 sta_entry->wireless_mode = WIRELESS_MODE_G; 569 }
570 /*disable cck rate for p2p*/
571 if (mac->p2p)
572 sta->supp_rates[0] &= 0xfffffff0;
503 573
574 memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN);
504 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, 575 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
505 "Add sta addr is %pM\n", sta->addr); 576 "Add sta addr is %pM\n", sta->addr);
506 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); 577 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
507 } 578 }
508 return 0; 579 return 0;
509} 580}
581
510static int rtl_op_sta_remove(struct ieee80211_hw *hw, 582static int rtl_op_sta_remove(struct ieee80211_hw *hw,
511 struct ieee80211_vif *vif, 583 struct ieee80211_vif *vif,
512 struct ieee80211_sta *sta) 584 struct ieee80211_sta *sta)
@@ -519,9 +591,14 @@ static int rtl_op_sta_remove(struct ieee80211_hw *hw,
519 sta_entry = (struct rtl_sta_info *) sta->drv_priv; 591 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
520 sta_entry->wireless_mode = 0; 592 sta_entry->wireless_mode = 0;
521 sta_entry->ratr_index = 0; 593 sta_entry->ratr_index = 0;
594
595 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
596 list_del(&sta_entry->list);
597 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
522 } 598 }
523 return 0; 599 return 0;
524} 600}
601
525static int _rtl_get_hal_qnum(u16 queue) 602static int _rtl_get_hal_qnum(u16 queue)
526{ 603{
527 int qnum; 604 int qnum;
@@ -547,8 +624,8 @@ static int _rtl_get_hal_qnum(u16 queue)
547} 624}
548 625
549/* 626/*
550 *for mac80211 VO=0, VI=1, BE=2, BK=3 627 *for mac80211 VO = 0, VI = 1, BE = 2, BK = 3
551 *for rtl819x BE=0, BK=1, VI=2, VO=3 628 *for rtl819x BE = 0, BK = 1, VI = 2, VO = 3
552 */ 629 */
553static int rtl_op_conf_tx(struct ieee80211_hw *hw, 630static int rtl_op_conf_tx(struct ieee80211_hw *hw,
554 struct ieee80211_vif *vif, u16 queue, 631 struct ieee80211_vif *vif, u16 queue,
@@ -630,6 +707,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
630 /*TODO: reference to enum ieee80211_bss_change */ 707 /*TODO: reference to enum ieee80211_bss_change */
631 if (changed & BSS_CHANGED_ASSOC) { 708 if (changed & BSS_CHANGED_ASSOC) {
632 if (bss_conf->assoc) { 709 if (bss_conf->assoc) {
710 struct ieee80211_sta *sta = NULL;
633 /* we should reset all sec info & cam 711 /* we should reset all sec info & cam
634 * before set cam after linked, we should not 712 * before set cam after linked, we should not
635 * reset in disassoc, that will cause tkip->wep 713 * reset in disassoc, that will cause tkip->wep
@@ -647,23 +725,39 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
647 725
648 if (rtlpriv->cfg->ops->linked_set_reg) 726 if (rtlpriv->cfg->ops->linked_set_reg)
649 rtlpriv->cfg->ops->linked_set_reg(hw); 727 rtlpriv->cfg->ops->linked_set_reg(hw);
650 if (mac->opmode == NL80211_IFTYPE_STATION && sta) 728 rcu_read_lock();
729 sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid);
730
731 if (vif->type == NL80211_IFTYPE_STATION && sta)
651 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); 732 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
733 RT_TRACE(rtlpriv, COMP_EASY_CONCURRENT, DBG_LOUD,
734 "send PS STATIC frame\n");
735 if (rtlpriv->dm.supp_phymode_switch) {
736 if (sta->ht_cap.ht_supported)
737 rtl_send_smps_action(hw, sta,
738 IEEE80211_SMPS_STATIC);
739 }
740 rcu_read_unlock();
741
652 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, 742 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
653 "BSS_CHANGED_ASSOC\n"); 743 "BSS_CHANGED_ASSOC\n");
654 } else { 744 } else {
655 if (mac->link_state == MAC80211_LINKED) 745 if (mac->link_state == MAC80211_LINKED) {
656 rtl_lps_leave(hw); 746 rtlpriv->enter_ps = false;
747 schedule_work(&rtlpriv->works.lps_change_work);
748 }
657 749
750 if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE)
751 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
658 mac->link_state = MAC80211_NOLINK; 752 mac->link_state = MAC80211_NOLINK;
659 memset(mac->bssid, 0, 6); 753 memset(mac->bssid, 0, 6);
660
661 /* reset sec info */
662 rtl_cam_reset_sec_info(hw);
663
664 rtl_cam_reset_all_entry(hw);
665 mac->vendor = PEER_UNKNOWN; 754 mac->vendor = PEER_UNKNOWN;
666 755
756 if (rtlpriv->dm.supp_phymode_switch) {
757 if (rtlpriv->cfg->ops->chk_switch_dmdp)
758 rtlpriv->cfg->ops->chk_switch_dmdp(hw);
759 }
760
667 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, 761 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
668 "BSS_CHANGED_UN_ASSOC\n"); 762 "BSS_CHANGED_UN_ASSOC\n");
669 } 763 }
@@ -778,7 +872,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
778 } 872 }
779 873
780 if (changed & BSS_CHANGED_BASIC_RATES) { 874 if (changed & BSS_CHANGED_BASIC_RATES) {
781 /* for 5G must << RATE_6M_INDEX=4, 875 /* for 5G must << RATE_6M_INDEX = 4,
782 * because 5G have no cck rate*/ 876 * because 5G have no cck rate*/
783 if (rtlhal->current_bandtype == BAND_ON_5G) 877 if (rtlhal->current_bandtype == BAND_ON_5G)
784 basic_rates = sta->supp_rates[1] << 4; 878 basic_rates = sta->supp_rates[1] << 4;
@@ -815,6 +909,9 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
815 ppsc->report_linked = false; 909 ppsc->report_linked = false;
816 } 910 }
817 } 911 }
912 if (rtlpriv->cfg->ops->bt_wifi_media_status_notify)
913 rtlpriv->cfg->ops->bt_wifi_media_status_notify(hw,
914 ppsc->report_linked);
818 } 915 }
819 916
820out: 917out:
@@ -885,7 +982,6 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
885 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 982 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
886 "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); 983 "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid);
887 return rtl_tx_agg_stop(hw, sta, tid); 984 return rtl_tx_agg_stop(hw, sta, tid);
888 break;
889 case IEEE80211_AMPDU_TX_OPERATIONAL: 985 case IEEE80211_AMPDU_TX_OPERATIONAL:
890 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 986 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
891 "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid); 987 "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid);
@@ -894,11 +990,11 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
894 case IEEE80211_AMPDU_RX_START: 990 case IEEE80211_AMPDU_RX_START:
895 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 991 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
896 "IEEE80211_AMPDU_RX_START:TID:%d\n", tid); 992 "IEEE80211_AMPDU_RX_START:TID:%d\n", tid);
897 break; 993 return rtl_rx_agg_start(hw, sta, tid);
898 case IEEE80211_AMPDU_RX_STOP: 994 case IEEE80211_AMPDU_RX_STOP:
899 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 995 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
900 "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid); 996 "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid);
901 break; 997 return rtl_rx_agg_stop(hw, sta, tid);
902 default: 998 default:
903 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 999 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
904 "IEEE80211_AMPDU_ERR!!!!:\n"); 1000 "IEEE80211_AMPDU_ERR!!!!:\n");
@@ -912,12 +1008,20 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
912 struct rtl_priv *rtlpriv = rtl_priv(hw); 1008 struct rtl_priv *rtlpriv = rtl_priv(hw);
913 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 1009 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
914 1010
915 mac->act_scanning = true;
916
917 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); 1011 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
1012 mac->act_scanning = true;
1013 if (rtlpriv->link_info.higher_busytraffic) {
1014 mac->skip_scan = true;
1015 return;
1016 }
918 1017
1018 if (rtlpriv->dm.supp_phymode_switch) {
1019 if (rtlpriv->cfg->ops->chk_switch_dmdp)
1020 rtlpriv->cfg->ops->chk_switch_dmdp(hw);
1021 }
919 if (mac->link_state == MAC80211_LINKED) { 1022 if (mac->link_state == MAC80211_LINKED) {
920 rtl_lps_leave(hw); 1023 rtlpriv->enter_ps = false;
1024 schedule_work(&rtlpriv->works.lps_change_work);
921 mac->link_state = MAC80211_LINKED_SCANNING; 1025 mac->link_state = MAC80211_LINKED_SCANNING;
922 } else { 1026 } else {
923 rtl_ips_nic_on(hw); 1027 rtl_ips_nic_on(hw);
@@ -937,6 +1041,16 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
937 1041
938 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); 1042 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
939 mac->act_scanning = false; 1043 mac->act_scanning = false;
1044 mac->skip_scan = false;
1045 if (rtlpriv->link_info.higher_busytraffic)
1046 return;
1047
1048 /*p2p will use 1/6/11 to scan */
1049 if (mac->n_channels == 3)
1050 mac->p2p_in_use = true;
1051 else
1052 mac->p2p_in_use = false;
1053 mac->n_channels = 0;
940 /* Dual mac */ 1054 /* Dual mac */
941 rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; 1055 rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
942 1056
@@ -970,6 +1084,11 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
970 "not open hw encryption\n"); 1084 "not open hw encryption\n");
971 return -ENOSPC; /*User disabled HW-crypto */ 1085 return -ENOSPC; /*User disabled HW-crypto */
972 } 1086 }
1087 /* To support IBSS, use sw-crypto for GTK */
1088 if (((vif->type == NL80211_IFTYPE_ADHOC) ||
1089 (vif->type == NL80211_IFTYPE_MESH_POINT)) &&
1090 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1091 return -ENOSPC;
973 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 1092 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
974 "%s hardware based encryption for keyidx: %d, mac: %pM\n", 1093 "%s hardware based encryption for keyidx: %d, mac: %pM\n",
975 cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, 1094 cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
@@ -996,6 +1115,14 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
996 key_type = AESCCMP_ENCRYPTION; 1115 key_type = AESCCMP_ENCRYPTION;
997 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n"); 1116 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n");
998 break; 1117 break;
1118 case WLAN_CIPHER_SUITE_AES_CMAC:
1119 /*HW doesn't support CMAC encryption, use software CMAC */
1120 key_type = AESCMAC_ENCRYPTION;
1121 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CMAC\n");
1122 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1123 "HW don't support CMAC encryption, use software CMAC\n");
1124 err = -EOPNOTSUPP;
1125 goto out_unlock;
999 default: 1126 default:
1000 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "alg_err:%x!!!!\n", 1127 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "alg_err:%x!!!!\n",
1001 key->cipher); 1128 key->cipher);
@@ -1017,13 +1144,14 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1017 * 1) wep only: is just for wep enc, in this condition 1144 * 1) wep only: is just for wep enc, in this condition
1018 * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION 1145 * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION
1019 * will be true & enable_hw_sec will be set when wep 1146 * will be true & enable_hw_sec will be set when wep
1020 * ke setting. 1147 * key setting.
1021 * 2) wep(group) + AES(pairwise): some AP like cisco 1148 * 2) wep(group) + AES(pairwise): some AP like cisco
1022 * may use it, in this condition enable_hw_sec will not 1149 * may use it, in this condition enable_hw_sec will not
1023 * be set when wep key setting */ 1150 * be set when wep key setting */
1024 /* we must reset sec_info after lingked before set key, 1151 /* we must reset sec_info after lingked before set key,
1025 * or some flag will be wrong*/ 1152 * or some flag will be wrong*/
1026 if (mac->opmode == NL80211_IFTYPE_AP) { 1153 if (vif->type == NL80211_IFTYPE_AP ||
1154 vif->type == NL80211_IFTYPE_MESH_POINT) {
1027 if (!group_key || key_type == WEP40_ENCRYPTION || 1155 if (!group_key || key_type == WEP40_ENCRYPTION ||
1028 key_type == WEP104_ENCRYPTION) { 1156 key_type == WEP104_ENCRYPTION) {
1029 if (group_key) 1157 if (group_key)
@@ -1098,12 +1226,16 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1098 key->hw_key_idx = key_idx; 1226 key->hw_key_idx = key_idx;
1099 if (key_type == TKIP_ENCRYPTION) 1227 if (key_type == TKIP_ENCRYPTION)
1100 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; 1228 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1229 /*use software CCMP encryption for management frames (MFP) */
1230 if (key_type == AESCCMP_ENCRYPTION)
1231 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
1101 break; 1232 break;
1102 case DISABLE_KEY: 1233 case DISABLE_KEY:
1103 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 1234 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1104 "disable key delete one entry\n"); 1235 "disable key delete one entry\n");
1105 /*set local buf about wep key. */ 1236 /*set local buf about wep key. */
1106 if (mac->opmode == NL80211_IFTYPE_AP) { 1237 if (vif->type == NL80211_IFTYPE_AP ||
1238 vif->type == NL80211_IFTYPE_MESH_POINT) {
1107 if (sta) 1239 if (sta)
1108 rtl_cam_del_entry(hw, sta->addr); 1240 rtl_cam_del_entry(hw, sta->addr);
1109 } 1241 }
@@ -1163,10 +1295,10 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
1163} 1295}
1164 1296
1165/* this function is called by mac80211 to flush tx buffer 1297/* this function is called by mac80211 to flush tx buffer
1166 * before switch channle or power save, or tx buffer packet 1298 * before switch channel or power save, or tx buffer packet
1167 * maybe send after offchannel or rf sleep, this may cause 1299 * maybe send after offchannel or rf sleep, this may cause
1168 * dis-association by AP */ 1300 * dis-association by AP */
1169static void rtl_op_flush(struct ieee80211_hw *hw, bool drop) 1301static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1170{ 1302{
1171 struct rtl_priv *rtlpriv = rtl_priv(hw); 1303 struct rtl_priv *rtlpriv = rtl_priv(hw);
1172 1304
@@ -1180,6 +1312,7 @@ const struct ieee80211_ops rtl_ops = {
1180 .tx = rtl_op_tx, 1312 .tx = rtl_op_tx,
1181 .add_interface = rtl_op_add_interface, 1313 .add_interface = rtl_op_add_interface,
1182 .remove_interface = rtl_op_remove_interface, 1314 .remove_interface = rtl_op_remove_interface,
1315 .change_interface = rtl_op_change_interface,
1183 .config = rtl_op_config, 1316 .config = rtl_op_config,
1184 .configure_filter = rtl_op_configure_filter, 1317 .configure_filter = rtl_op_configure_filter,
1185 .sta_add = rtl_op_sta_add, 1318 .sta_add = rtl_op_sta_add,
diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c
index bdda9b2fffe1..7d52d3d7769f 100644
--- a/drivers/net/wireless/rtlwifi/debug.c
+++ b/drivers/net/wireless/rtlwifi/debug.c
@@ -41,7 +41,10 @@ void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
41 COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC | 41 COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC |
42 COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS | 42 COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS |
43 COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD | 43 COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD |
44 COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN; 44 COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN |
45 COMP_EASY_CONCURRENT | COMP_EFUSE | COMP_QOS | COMP_MAC80211 |
46 COMP_REGD | COMP_CHAN | COMP_BT_COEXIST;
47
45 48
46 for (i = 0; i < DBGP_TYPE_MAX; i++) 49 for (i = 0; i < DBGP_TYPE_MAX; i++)
47 rtlpriv->dbg.dbgp_type[i] = 0; 50 rtlpriv->dbg.dbgp_type[i] = 0;
diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h
index fd3269f47685..6d669364e3d9 100644
--- a/drivers/net/wireless/rtlwifi/debug.h
+++ b/drivers/net/wireless/rtlwifi/debug.h
@@ -115,11 +115,11 @@
115/* Define EEPROM and EFUSE check module bit*/ 115/* Define EEPROM and EFUSE check module bit*/
116#define EEPROM_W BIT(0) 116#define EEPROM_W BIT(0)
117#define EFUSE_PG BIT(1) 117#define EFUSE_PG BIT(1)
118#define EFUSE_READ_ALL BIT(2) 118#define EFUSE_READ_ALL BIT(2)
119 119
120/* Define init check for module bit*/ 120/* Define init check for module bit*/
121#define INIT_EEPROM BIT(0) 121#define INIT_EEPROM BIT(0)
122#define INIT_TxPower BIT(1) 122#define INIT_TXPOWER BIT(1)
123#define INIT_IQK BIT(2) 123#define INIT_IQK BIT(2)
124#define INIT_RF BIT(3) 124#define INIT_RF BIT(3)
125 125
@@ -135,6 +135,15 @@
135#define PHY_TXPWR BIT(8) 135#define PHY_TXPWR BIT(8)
136#define PHY_PWRDIFF BIT(9) 136#define PHY_PWRDIFF BIT(9)
137 137
138/* Define Dynamic Mechanism check module bit --> FDM */
139#define WA_IOT BIT(0)
140#define DM_PWDB BIT(1)
141#define DM_MONITOR BIT(2)
142#define DM_DIG BIT(3)
143#define DM_EDCA_TURBO BIT(4)
144
145#define DM_PWDB BIT(1)
146
138enum dbgp_flag_e { 147enum dbgp_flag_e {
139 FQOS = 0, 148 FQOS = 0,
140 FTX = 1, 149 FTX = 1,
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c
index 8e2f9afb125a..9e3894178e77 100644
--- a/drivers/net/wireless/rtlwifi/efuse.c
+++ b/drivers/net/wireless/rtlwifi/efuse.c
@@ -35,8 +35,6 @@ static const u8 MAX_PGPKT_SIZE = 9;
35static const u8 PGPKT_DATA_SIZE = 8; 35static const u8 PGPKT_DATA_SIZE = 8;
36static const int EFUSE_MAX_SIZE = 512; 36static const int EFUSE_MAX_SIZE = 512;
37 37
38static const u8 EFUSE_OOB_PROTECT_BYTES = 15;
39
40static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = { 38static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
41 {0, 0, 0, 2}, 39 {0, 0, 0, 2},
42 {0, 1, 0, 2}, 40 {0, 1, 0, 2},
@@ -240,6 +238,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
240 u8 rtemp8[1]; 238 u8 rtemp8[1];
241 u16 efuse_addr = 0; 239 u16 efuse_addr = 0;
242 u8 offset, wren; 240 u8 offset, wren;
241 u8 u1temp = 0;
243 u16 i; 242 u16 i;
244 u16 j; 243 u16 j;
245 const u16 efuse_max_section = 244 const u16 efuse_max_section =
@@ -285,10 +284,31 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
285 } 284 }
286 285
287 while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_len)) { 286 while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_len)) {
288 offset = ((*rtemp8 >> 4) & 0x0f); 287 /* Check PG header for section num. */
288 if ((*rtemp8 & 0x1F) == 0x0F) {/* extended header */
289 u1temp = ((*rtemp8 & 0xE0) >> 5);
290 read_efuse_byte(hw, efuse_addr, rtemp8);
289 291
290 if (offset < efuse_max_section) { 292 if ((*rtemp8 & 0x0F) == 0x0F) {
293 efuse_addr++;
294 read_efuse_byte(hw, efuse_addr, rtemp8);
295
296 if (*rtemp8 != 0xFF &&
297 (efuse_addr < efuse_len)) {
298 efuse_addr++;
299 }
300 continue;
301 } else {
302 offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
303 wren = (*rtemp8 & 0x0F);
304 efuse_addr++;
305 }
306 } else {
307 offset = ((*rtemp8 >> 4) & 0x0f);
291 wren = (*rtemp8 & 0x0f); 308 wren = (*rtemp8 & 0x0f);
309 }
310
311 if (offset < efuse_max_section) {
292 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, 312 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
293 "offset-%d Worden=%x\n", offset, wren); 313 "offset-%d Worden=%x\n", offset, wren);
294 314
@@ -391,7 +411,8 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
391 efuse_used = rtlefuse->efuse_usedbytes; 411 efuse_used = rtlefuse->efuse_usedbytes;
392 412
393 if ((totalbytes + efuse_used) >= 413 if ((totalbytes + efuse_used) >=
394 (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) 414 (EFUSE_MAX_SIZE -
415 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))
395 result = false; 416 result = false;
396 417
397 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, 418 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
@@ -932,8 +953,8 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
932 u8 badworden = 0x0F; 953 u8 badworden = 0x0F;
933 static int repeat_times; 954 static int repeat_times;
934 955
935 if (efuse_get_current_size(hw) >= 956 if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE -
936 (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) { 957 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
937 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, 958 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
938 "efuse_pg_packet_write error\n"); 959 "efuse_pg_packet_write error\n");
939 return false; 960 return false;
@@ -949,8 +970,8 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
949 970
950 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n"); 971 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n");
951 972
952 while (continual && (efuse_addr < 973 while (continual && (efuse_addr < (EFUSE_MAX_SIZE -
953 (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) { 974 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) {
954 975
955 if (write_state == PG_STATE_HEADER) { 976 if (write_state == PG_STATE_HEADER) {
956 badworden = 0x0F; 977 badworden = 0x0F;
@@ -1003,7 +1024,8 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
1003 } 1024 }
1004 } 1025 }
1005 1026
1006 if (efuse_addr >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) { 1027 if (efuse_addr >= (EFUSE_MAX_SIZE -
1028 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
1007 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, 1029 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
1008 "efuse_addr(%#x) Out of size!!\n", efuse_addr); 1030 "efuse_addr(%#x) Out of size!!\n", efuse_addr);
1009 } 1031 }
@@ -1102,8 +1124,11 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)
1102 u8 tempval; 1124 u8 tempval;
1103 u16 tmpV16; 1125 u16 tmpV16;
1104 1126
1105 if (pwrstate && (rtlhal->hw_type != 1127 if (pwrstate && (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)) {
1106 HARDWARE_TYPE_RTL8192SE)) { 1128 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE)
1129 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS],
1130 0x69);
1131
1107 tmpV16 = rtl_read_word(rtlpriv, 1132 tmpV16 = rtl_read_word(rtlpriv,
1108 rtlpriv->cfg->maps[SYS_ISO_CTRL]); 1133 rtlpriv->cfg->maps[SYS_ISO_CTRL]);
1109 if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { 1134 if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
@@ -1153,6 +1178,10 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)
1153 } 1178 }
1154 1179
1155 } else { 1180 } else {
1181 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE)
1182 rtl_write_byte(rtlpriv,
1183 rtlpriv->cfg->maps[EFUSE_ACCESS], 0);
1184
1156 if (write) { 1185 if (write) {
1157 tempval = rtl_read_byte(rtlpriv, 1186 tempval = rtl_read_byte(rtlpriv,
1158 rtlpriv->cfg->maps[EFUSE_TEST] + 1187 rtlpriv->cfg->maps[EFUSE_TEST] +
diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h
index 2bdea9a8699e..395a326acfb4 100644
--- a/drivers/net/wireless/rtlwifi/efuse.h
+++ b/drivers/net/wireless/rtlwifi/efuse.h
@@ -32,7 +32,6 @@
32 32
33#define EFUSE_IC_ID_OFFSET 506 33#define EFUSE_IC_ID_OFFSET 506
34 34
35#define EFUSE_REAL_CONTENT_LEN 512
36#define EFUSE_MAP_LEN 128 35#define EFUSE_MAP_LEN 128
37#define EFUSE_MAX_WORD_UNIT 4 36#define EFUSE_MAX_WORD_UNIT 4
38 37
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 4261e8ecc4c3..999ffc12578b 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -59,7 +59,7 @@ static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw,
59 59
60 if (unlikely(ieee80211_is_beacon(fc))) 60 if (unlikely(ieee80211_is_beacon(fc)))
61 return BEACON_QUEUE; 61 return BEACON_QUEUE;
62 if (ieee80211_is_mgmt(fc)) 62 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
63 return MGNT_QUEUE; 63 return MGNT_QUEUE;
64 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) 64 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
65 if (ieee80211_is_nullfunc(fc)) 65 if (ieee80211_is_nullfunc(fc))
@@ -271,9 +271,6 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
271 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 271 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
272 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 272 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
273 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 273 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
274 u8 pcibridge_busnum = pcipriv->ndis_adapter.pcibridge_busnum;
275 u8 pcibridge_devnum = pcipriv->ndis_adapter.pcibridge_devnum;
276 u8 pcibridge_funcnum = pcipriv->ndis_adapter.pcibridge_funcnum;
277 u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; 274 u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
278 u8 num4bytes = pcipriv->ndis_adapter.num4bytes; 275 u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
279 u16 aspmlevel; 276 u16 aspmlevel;
@@ -302,8 +299,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
302 u_pcibridge_aspmsetting); 299 u_pcibridge_aspmsetting);
303 300
304 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 301 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
305 "PlatformEnableASPM():PciBridge busnumber[%x], DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", 302 "PlatformEnableASPM(): Write reg[%x] = %x\n",
306 pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum,
307 (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), 303 (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
308 u_pcibridge_aspmsetting); 304 u_pcibridge_aspmsetting);
309 305
@@ -349,6 +345,49 @@ static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
349 return status; 345 return status;
350} 346}
351 347
348static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw,
349 struct rtl_priv **buddy_priv)
350{
351 struct rtl_priv *rtlpriv = rtl_priv(hw);
352 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
353 bool find_buddy_priv = false;
354 struct rtl_priv *tpriv = NULL;
355 struct rtl_pci_priv *tpcipriv = NULL;
356
357 if (!list_empty(&rtlpriv->glb_var->glb_priv_list)) {
358 list_for_each_entry(tpriv, &rtlpriv->glb_var->glb_priv_list,
359 list) {
360 if (tpriv) {
361 tpcipriv = (struct rtl_pci_priv *)tpriv->priv;
362 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
363 "pcipriv->ndis_adapter.funcnumber %x\n",
364 pcipriv->ndis_adapter.funcnumber);
365 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
366 "tpcipriv->ndis_adapter.funcnumber %x\n",
367 tpcipriv->ndis_adapter.funcnumber);
368
369 if ((pcipriv->ndis_adapter.busnumber ==
370 tpcipriv->ndis_adapter.busnumber) &&
371 (pcipriv->ndis_adapter.devnumber ==
372 tpcipriv->ndis_adapter.devnumber) &&
373 (pcipriv->ndis_adapter.funcnumber !=
374 tpcipriv->ndis_adapter.funcnumber)) {
375 find_buddy_priv = true;
376 break;
377 }
378 }
379 }
380 }
381
382 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
383 "find_buddy_priv %d\n", find_buddy_priv);
384
385 if (find_buddy_priv)
386 *buddy_priv = tpriv;
387
388 return find_buddy_priv;
389}
390
352static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) 391static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)
353{ 392{
354 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 393 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
@@ -420,17 +459,14 @@ static void _rtl_pci_io_handler_init(struct device *dev,
420 459
421} 460}
422 461
423static void _rtl_pci_io_handler_release(struct ieee80211_hw *hw)
424{
425}
426
427static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw, 462static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw,
428 struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc, u8 tid) 463 struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc, u8 tid)
429{ 464{
430 struct rtl_priv *rtlpriv = rtl_priv(hw); 465 struct rtl_priv *rtlpriv = rtl_priv(hw);
431 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 466 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
432 u8 additionlen = FCS_LEN; 467 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
433 struct sk_buff *next_skb; 468 struct sk_buff *next_skb;
469 u8 additionlen = FCS_LEN;
434 470
435 /* here open is 4, wep/tkip is 8, aes is 12*/ 471 /* here open is 4, wep/tkip is 8, aes is 12*/
436 if (info->control.hw_key) 472 if (info->control.hw_key)
@@ -455,7 +491,7 @@ static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw,
455 next_skb)) 491 next_skb))
456 break; 492 break;
457 493
458 if (tcb_desc->empkt_num >= 5) 494 if (tcb_desc->empkt_num >= rtlhal->max_earlymode_num)
459 break; 495 break;
460 } 496 }
461 spin_unlock_bh(&rtlpriv->locks.waitq_lock); 497 spin_unlock_bh(&rtlpriv->locks.waitq_lock);
@@ -471,11 +507,17 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
471 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 507 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
472 struct sk_buff *skb = NULL; 508 struct sk_buff *skb = NULL;
473 struct ieee80211_tx_info *info = NULL; 509 struct ieee80211_tx_info *info = NULL;
510 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
474 int tid; 511 int tid;
475 512
476 if (!rtlpriv->rtlhal.earlymode_enable) 513 if (!rtlpriv->rtlhal.earlymode_enable)
477 return; 514 return;
478 515
516 if (rtlpriv->dm.supp_phymode_switch &&
517 (rtlpriv->easy_concurrent_ctl.switch_in_process ||
518 (rtlpriv->buddy_priv &&
519 rtlpriv->buddy_priv->easy_concurrent_ctl.switch_in_process)))
520 return;
479 /* we juse use em for BE/BK/VI/VO */ 521 /* we juse use em for BE/BK/VI/VO */
480 for (tid = 7; tid >= 0; tid--) { 522 for (tid = 7; tid >= 0; tid--) {
481 u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)]; 523 u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)];
@@ -487,7 +529,8 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
487 529
488 spin_lock_bh(&rtlpriv->locks.waitq_lock); 530 spin_lock_bh(&rtlpriv->locks.waitq_lock);
489 if (!skb_queue_empty(&mac->skb_waitq[tid]) && 531 if (!skb_queue_empty(&mac->skb_waitq[tid]) &&
490 (ring->entries - skb_queue_len(&ring->queue) > 5)) { 532 (ring->entries - skb_queue_len(&ring->queue) >
533 rtlhal->max_earlymode_num)) {
491 skb = skb_dequeue(&mac->skb_waitq[tid]); 534 skb = skb_dequeue(&mac->skb_waitq[tid]);
492 } else { 535 } else {
493 spin_unlock_bh(&rtlpriv->locks.waitq_lock); 536 spin_unlock_bh(&rtlpriv->locks.waitq_lock);
@@ -525,9 +568,8 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
525 u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true, 568 u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true,
526 HW_DESC_OWN); 569 HW_DESC_OWN);
527 570
528 /* 571 /*beacon packet will only use the first
529 *beacon packet will only use the first 572 *descriptor by defaut, and the own may not
530 *descriptor defautly,and the own may not
531 *be cleared by the hardware 573 *be cleared by the hardware
532 */ 574 */
533 if (own) 575 if (own)
@@ -558,8 +600,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
558 } 600 }
559 601
560 /* for sw LPS, just after NULL skb send out, we can 602 /* for sw LPS, just after NULL skb send out, we can
561 * sure AP kown we are sleeped, our we should not let 603 * sure AP knows we are sleeping, we should not let
562 * rf to sleep*/ 604 * rf sleep
605 */
563 fc = rtl_get_fc(skb); 606 fc = rtl_get_fc(skb);
564 if (ieee80211_is_nullfunc(fc)) { 607 if (ieee80211_is_nullfunc(fc)) {
565 if (ieee80211_has_pm(fc)) { 608 if (ieee80211_has_pm(fc)) {
@@ -569,6 +612,15 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
569 rtlpriv->psc.state_inap = false; 612 rtlpriv->psc.state_inap = false;
570 } 613 }
571 } 614 }
615 if (ieee80211_is_action(fc)) {
616 struct ieee80211_mgmt *action_frame =
617 (struct ieee80211_mgmt *)skb->data;
618 if (action_frame->u.action.u.ht_smps.action ==
619 WLAN_HT_ACTION_SMPS) {
620 dev_kfree_skb(skb);
621 goto tx_status_ok;
622 }
623 }
572 624
573 /* update tid tx pkt num */ 625 /* update tid tx pkt num */
574 tid = rtl_get_tid(skb); 626 tid = rtl_get_tid(skb);
@@ -602,7 +654,8 @@ tx_status_ok:
602 if (((rtlpriv->link_info.num_rx_inperiod + 654 if (((rtlpriv->link_info.num_rx_inperiod +
603 rtlpriv->link_info.num_tx_inperiod) > 8) || 655 rtlpriv->link_info.num_tx_inperiod) > 8) ||
604 (rtlpriv->link_info.num_rx_inperiod > 2)) { 656 (rtlpriv->link_info.num_rx_inperiod > 2)) {
605 schedule_work(&rtlpriv->works.lps_leave_work); 657 rtlpriv->enter_ps = false;
658 schedule_work(&rtlpriv->works.lps_change_work);
606 } 659 }
607} 660}
608 661
@@ -637,6 +690,10 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb,
637 rtlpriv->link_info.num_rx_inperiod++; 690 rtlpriv->link_info.num_rx_inperiod++;
638 } 691 }
639 692
693 /* static bcn for roaming */
694 rtl_beacon_statistic(hw, skb);
695 rtl_p2p_info(hw, (void *)skb->data, skb->len);
696
640 /* for sw lps */ 697 /* for sw lps */
641 rtl_swlps_beacon(hw, (void *)skb->data, skb->len); 698 rtl_swlps_beacon(hw, (void *)skb->data, skb->len);
642 rtl_recognize_peer(hw, (void *)skb->data, skb->len); 699 rtl_recognize_peer(hw, (void *)skb->data, skb->len);
@@ -727,9 +784,10 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
727 _rtl_receive_one(hw, skb, rx_status); 784 _rtl_receive_one(hw, skb, rx_status);
728 785
729 if (((rtlpriv->link_info.num_rx_inperiod + 786 if (((rtlpriv->link_info.num_rx_inperiod +
730 rtlpriv->link_info.num_tx_inperiod) > 8) || 787 rtlpriv->link_info.num_tx_inperiod) > 8) ||
731 (rtlpriv->link_info.num_rx_inperiod > 2)) { 788 (rtlpriv->link_info.num_rx_inperiod > 2)) {
732 schedule_work(&rtlpriv->works.lps_leave_work); 789 rtlpriv->enter_ps = false;
790 schedule_work(&rtlpriv->works.lps_change_work);
733 } 791 }
734 792
735 dev_kfree_skb_any(skb); 793 dev_kfree_skb_any(skb);
@@ -803,7 +861,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
803 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); 861 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n");
804 } 862 }
805 863
806 if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) { 864 if (inta & rtlpriv->cfg->maps[RTL_IMR_BCNINT]) {
807 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, 865 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
808 "prepare beacon for interrupt!\n"); 866 "prepare beacon for interrupt!\n");
809 tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet); 867 tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet);
@@ -884,6 +942,16 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
884 _rtl_pci_rx_interrupt(hw); 942 _rtl_pci_rx_interrupt(hw);
885 } 943 }
886 944
945 /*fw related*/
946 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723AE) {
947 if (inta & rtlpriv->cfg->maps[RTL_IMR_C2HCMD]) {
948 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
949 "firmware interrupt!\n");
950 queue_delayed_work(rtlpriv->works.rtl_wq,
951 &rtlpriv->works.fwevt_wq, 0);
952 }
953 }
954
887 if (rtlpriv->rtlhal.earlymode_enable) 955 if (rtlpriv->rtlhal.earlymode_enable)
888 tasklet_schedule(&rtlpriv->works.irq_tasklet); 956 tasklet_schedule(&rtlpriv->works.irq_tasklet);
889 957
@@ -939,13 +1007,17 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
939 return; 1007 return;
940} 1008}
941 1009
942static void rtl_lps_leave_work_callback(struct work_struct *work) 1010static void rtl_lps_change_work_callback(struct work_struct *work)
943{ 1011{
944 struct rtl_works *rtlworks = 1012 struct rtl_works *rtlworks =
945 container_of(work, struct rtl_works, lps_leave_work); 1013 container_of(work, struct rtl_works, lps_change_work);
946 struct ieee80211_hw *hw = rtlworks->hw; 1014 struct ieee80211_hw *hw = rtlworks->hw;
1015 struct rtl_priv *rtlpriv = rtl_priv(hw);
947 1016
948 rtl_lps_leave(hw); 1017 if (rtlpriv->enter_ps)
1018 rtl_lps_enter(hw);
1019 else
1020 rtl_lps_leave(hw);
949} 1021}
950 1022
951static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw) 1023static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw)
@@ -1009,7 +1081,8 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
1009 tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet, 1081 tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
1010 (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet, 1082 (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
1011 (unsigned long)hw); 1083 (unsigned long)hw);
1012 INIT_WORK(&rtlpriv->works.lps_leave_work, rtl_lps_leave_work_callback); 1084 INIT_WORK(&rtlpriv->works.lps_change_work,
1085 rtl_lps_change_work_callback);
1013} 1086}
1014 1087
1015static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, 1088static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
@@ -1458,10 +1531,14 @@ static void rtl_pci_flush(struct ieee80211_hw *hw, bool drop)
1458 struct rtl_priv *rtlpriv = rtl_priv(hw); 1531 struct rtl_priv *rtlpriv = rtl_priv(hw);
1459 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 1532 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1460 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1533 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1534 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1461 u16 i = 0; 1535 u16 i = 0;
1462 int queue_id; 1536 int queue_id;
1463 struct rtl8192_tx_ring *ring; 1537 struct rtl8192_tx_ring *ring;
1464 1538
1539 if (mac->skip_scan)
1540 return;
1541
1465 for (queue_id = RTL_PCI_MAX_TX_QUEUE_COUNT - 1; queue_id >= 0;) { 1542 for (queue_id = RTL_PCI_MAX_TX_QUEUE_COUNT - 1; queue_id >= 0;) {
1466 u32 queue_len; 1543 u32 queue_len;
1467 ring = &pcipriv->dev.tx_ring[queue_id]; 1544 ring = &pcipriv->dev.tx_ring[queue_id];
@@ -1491,7 +1568,7 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw)
1491 1568
1492 synchronize_irq(rtlpci->pdev->irq); 1569 synchronize_irq(rtlpci->pdev->irq);
1493 tasklet_kill(&rtlpriv->works.irq_tasklet); 1570 tasklet_kill(&rtlpriv->works.irq_tasklet);
1494 cancel_work_sync(&rtlpriv->works.lps_leave_work); 1571 cancel_work_sync(&rtlpriv->works.lps_change_work);
1495 1572
1496 flush_workqueue(rtlpriv->works.rtl_wq); 1573 flush_workqueue(rtlpriv->works.rtl_wq);
1497 destroy_workqueue(rtlpriv->works.rtl_wq); 1574 destroy_workqueue(rtlpriv->works.rtl_wq);
@@ -1566,7 +1643,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)
1566 set_hal_stop(rtlhal); 1643 set_hal_stop(rtlhal);
1567 1644
1568 rtlpriv->cfg->ops->disable_interrupt(hw); 1645 rtlpriv->cfg->ops->disable_interrupt(hw);
1569 cancel_work_sync(&rtlpriv->works.lps_leave_work); 1646 cancel_work_sync(&rtlpriv->works.lps_change_work);
1570 1647
1571 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); 1648 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
1572 while (ppsc->rfchange_inprogress) { 1649 while (ppsc->rfchange_inprogress) {
@@ -1673,6 +1750,10 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
1673 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, 1750 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1674 "8192D PCI-E is found - vid/did=%x/%x\n", 1751 "8192D PCI-E is found - vid/did=%x/%x\n",
1675 venderid, deviceid); 1752 venderid, deviceid);
1753 } else if (deviceid == RTL_PCI_8188EE_DID) {
1754 rtlhal->hw_type = HARDWARE_TYPE_RTL8188EE;
1755 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1756 "Find adapter, Hardware type is 8188EE\n");
1676 } else { 1757 } else {
1677 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 1758 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1678 "Err: Unknown device - vid/did=%x/%x\n", 1759 "Err: Unknown device - vid/did=%x/%x\n",
@@ -1704,6 +1785,9 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
1704 pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); 1785 pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);
1705 pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); 1786 pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn);
1706 1787
1788 /* some ARM have no bridge_pdev and will crash here
1789 * so we should check if bridge_pdev is NULL
1790 */
1707 if (bridge_pdev) { 1791 if (bridge_pdev) {
1708 /*find bridge info if available */ 1792 /*find bridge info if available */
1709 pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; 1793 pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor;
@@ -1758,6 +1842,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
1758 pcipriv->ndis_adapter.amd_l1_patch); 1842 pcipriv->ndis_adapter.amd_l1_patch);
1759 1843
1760 rtl_pci_parse_configuration(pdev, hw); 1844 rtl_pci_parse_configuration(pdev, hw);
1845 list_add_tail(&rtlpriv->list, &rtlpriv->glb_var->glb_priv_list);
1761 1846
1762 return true; 1847 return true;
1763} 1848}
@@ -1804,6 +1889,7 @@ int rtl_pci_probe(struct pci_dev *pdev,
1804 pci_set_drvdata(pdev, hw); 1889 pci_set_drvdata(pdev, hw);
1805 1890
1806 rtlpriv = hw->priv; 1891 rtlpriv = hw->priv;
1892 rtlpriv->hw = hw;
1807 pcipriv = (void *)rtlpriv->priv; 1893 pcipriv = (void *)rtlpriv->priv;
1808 pcipriv->dev.pdev = pdev; 1894 pcipriv->dev.pdev = pdev;
1809 init_completion(&rtlpriv->firmware_loading_complete); 1895 init_completion(&rtlpriv->firmware_loading_complete);
@@ -1812,6 +1898,7 @@ int rtl_pci_probe(struct pci_dev *pdev,
1812 rtlpriv->rtlhal.interface = INTF_PCI; 1898 rtlpriv->rtlhal.interface = INTF_PCI;
1813 rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); 1899 rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
1814 rtlpriv->intf_ops = &rtl_pci_ops; 1900 rtlpriv->intf_ops = &rtl_pci_ops;
1901 rtlpriv->glb_var = &global_var;
1815 1902
1816 /* 1903 /*
1817 *init dbgp flags before all 1904 *init dbgp flags before all
@@ -1916,7 +2003,6 @@ int rtl_pci_probe(struct pci_dev *pdev,
1916 2003
1917fail3: 2004fail3:
1918 rtl_deinit_core(hw); 2005 rtl_deinit_core(hw);
1919 _rtl_pci_io_handler_release(hw);
1920 2006
1921 if (rtlpriv->io.pci_mem_start != 0) 2007 if (rtlpriv->io.pci_mem_start != 0)
1922 pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); 2008 pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
@@ -1965,14 +2051,15 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
1965 2051
1966 rtl_pci_deinit(hw); 2052 rtl_pci_deinit(hw);
1967 rtl_deinit_core(hw); 2053 rtl_deinit_core(hw);
1968 _rtl_pci_io_handler_release(hw);
1969 rtlpriv->cfg->ops->deinit_sw_vars(hw); 2054 rtlpriv->cfg->ops->deinit_sw_vars(hw);
1970 2055
1971 if (rtlpci->irq_alloc) { 2056 if (rtlpci->irq_alloc) {
2057 synchronize_irq(rtlpci->pdev->irq);
1972 free_irq(rtlpci->pdev->irq, hw); 2058 free_irq(rtlpci->pdev->irq, hw);
1973 rtlpci->irq_alloc = 0; 2059 rtlpci->irq_alloc = 0;
1974 } 2060 }
1975 2061
2062 list_del(&rtlpriv->list);
1976 if (rtlpriv->io.pci_mem_start != 0) { 2063 if (rtlpriv->io.pci_mem_start != 0) {
1977 pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); 2064 pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
1978 pci_release_regions(pdev); 2065 pci_release_regions(pdev);
@@ -2034,6 +2121,7 @@ struct rtl_intf_ops rtl_pci_ops = {
2034 .read_efuse_byte = read_efuse_byte, 2121 .read_efuse_byte = read_efuse_byte,
2035 .adapter_start = rtl_pci_start, 2122 .adapter_start = rtl_pci_start,
2036 .adapter_stop = rtl_pci_stop, 2123 .adapter_stop = rtl_pci_stop,
2124 .check_buddy_priv = rtl_pci_check_buddy_priv,
2037 .adapter_tx = rtl_pci_tx, 2125 .adapter_tx = rtl_pci_tx,
2038 .flush = rtl_pci_flush, 2126 .flush = rtl_pci_flush,
2039 .reset_trx_ring = rtl_pci_reset_trx_ring, 2127 .reset_trx_ring = rtl_pci_reset_trx_ring,
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index 65b08f50022e..d3262ec45d23 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -94,6 +94,7 @@
94#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */ 94#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */
95#define RTL_PCI_8192DE_DID 0x8193 /*8192de */ 95#define RTL_PCI_8192DE_DID 0x8193 /*8192de */
96#define RTL_PCI_8192DE_DID2 0x002B /*92DE*/ 96#define RTL_PCI_8192DE_DID2 0x002B /*92DE*/
97#define RTL_PCI_8188EE_DID 0x8179 /*8188ee*/
97 98
98/*8192 support 16 pages of IO registers*/ 99/*8192 support 16 pages of IO registers*/
99#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000 100#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000
@@ -175,6 +176,7 @@ struct rtl_pci {
175 /*irq */ 176 /*irq */
176 u8 irq_alloc; 177 u8 irq_alloc;
177 u32 irq_mask[2]; 178 u32 irq_mask[2];
179 u32 sys_irq_mask;
178 180
179 /*Bcn control register setting */ 181 /*Bcn control register setting */
180 u32 reg_bcn_ctrl_val; 182 u32 reg_bcn_ctrl_val;
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index 13ad33e85577..884bceae38a9 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -180,6 +180,9 @@ void rtl_ips_nic_off_wq_callback(void *data)
180 return; 180 return;
181 } 181 }
182 182
183 if (mac->p2p_in_use)
184 return;
185
183 if (mac->link_state > MAC80211_NOLINK) 186 if (mac->link_state > MAC80211_NOLINK)
184 return; 187 return;
185 188
@@ -189,6 +192,9 @@ void rtl_ips_nic_off_wq_callback(void *data)
189 if (rtlpriv->sec.being_setkey) 192 if (rtlpriv->sec.being_setkey)
190 return; 193 return;
191 194
195 if (rtlpriv->cfg->ops->bt_coex_off_before_lps)
196 rtlpriv->cfg->ops->bt_coex_off_before_lps(hw);
197
192 if (ppsc->inactiveps) { 198 if (ppsc->inactiveps) {
193 rtstate = ppsc->rfpwr_state; 199 rtstate = ppsc->rfpwr_state;
194 200
@@ -231,6 +237,9 @@ void rtl_ips_nic_off(struct ieee80211_hw *hw)
231 &rtlpriv->works.ips_nic_off_wq, MSECS(100)); 237 &rtlpriv->works.ips_nic_off_wq, MSECS(100));
232} 238}
233 239
240/* NOTICE: any opmode should exc nic_on, or disable without
241 * nic_on may something wrong, like adhoc TP
242 */
234void rtl_ips_nic_on(struct ieee80211_hw *hw) 243void rtl_ips_nic_on(struct ieee80211_hw *hw)
235{ 244{
236 struct rtl_priv *rtlpriv = rtl_priv(hw); 245 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -299,7 +308,7 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
299 struct rtl_priv *rtlpriv = rtl_priv(hw); 308 struct rtl_priv *rtlpriv = rtl_priv(hw);
300 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 309 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
301 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 310 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
302 u8 rpwm_val, fw_pwrmode; 311 bool enter_fwlps;
303 312
304 if (mac->opmode == NL80211_IFTYPE_ADHOC) 313 if (mac->opmode == NL80211_IFTYPE_ADHOC)
305 return; 314 return;
@@ -324,43 +333,31 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
324 */ 333 */
325 334
326 if ((ppsc->fwctrl_lps) && ppsc->report_linked) { 335 if ((ppsc->fwctrl_lps) && ppsc->report_linked) {
327 bool fw_current_inps;
328 if (ppsc->dot11_psmode == EACTIVE) { 336 if (ppsc->dot11_psmode == EACTIVE) {
329 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, 337 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
330 "FW LPS leave ps_mode:%x\n", 338 "FW LPS leave ps_mode:%x\n",
331 FW_PS_ACTIVE_MODE); 339 FW_PS_ACTIVE_MODE);
332 340 enter_fwlps = false;
333 rpwm_val = 0x0C; /* RF on */ 341 ppsc->pwr_mode = FW_PS_ACTIVE_MODE;
334 fw_pwrmode = FW_PS_ACTIVE_MODE; 342 ppsc->smart_ps = 0;
335 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
336 &rpwm_val);
337 rtlpriv->cfg->ops->set_hw_reg(hw, 343 rtlpriv->cfg->ops->set_hw_reg(hw,
338 HW_VAR_H2C_FW_PWRMODE, 344 HW_VAR_FW_LPS_ACTION,
339 &fw_pwrmode); 345 (u8 *)(&enter_fwlps));
340 fw_current_inps = false; 346 if (ppsc->p2p_ps_info.opp_ps)
341 347 rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
342 rtlpriv->cfg->ops->set_hw_reg(hw,
343 HW_VAR_FW_PSMODE_STATUS,
344 (u8 *) (&fw_current_inps));
345 348
346 } else { 349 } else {
347 if (rtl_get_fwlps_doze(hw)) { 350 if (rtl_get_fwlps_doze(hw)) {
348 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, 351 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
349 "FW LPS enter ps_mode:%x\n", 352 "FW LPS enter ps_mode:%x\n",
350 ppsc->fwctrl_psmode); 353 ppsc->fwctrl_psmode);
351 354 enter_fwlps = true;
352 rpwm_val = 0x02; /* RF off */ 355 ppsc->pwr_mode = ppsc->fwctrl_psmode;
353 fw_current_inps = true; 356 ppsc->smart_ps = 2;
354 rtlpriv->cfg->ops->set_hw_reg(hw, 357 rtlpriv->cfg->ops->set_hw_reg(hw,
355 HW_VAR_FW_PSMODE_STATUS, 358 HW_VAR_FW_LPS_ACTION,
356 (u8 *) (&fw_current_inps)); 359 (u8 *)(&enter_fwlps));
357 rtlpriv->cfg->ops->set_hw_reg(hw,
358 HW_VAR_H2C_FW_PWRMODE,
359 &ppsc->fwctrl_psmode);
360 360
361 rtlpriv->cfg->ops->set_hw_reg(hw,
362 HW_VAR_SET_RPWM,
363 &rpwm_val);
364 } else { 361 } else {
365 /* Reset the power save related parameters. */ 362 /* Reset the power save related parameters. */
366 ppsc->dot11_psmode = EACTIVE; 363 ppsc->dot11_psmode = EACTIVE;
@@ -642,3 +639,286 @@ void rtl_swlps_wq_callback(void *data)
642 rtlpriv->psc.state = ps; 639 rtlpriv->psc.state = ps;
643 } 640 }
644} 641}
642
643static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data,
644 unsigned int len)
645{
646 struct rtl_priv *rtlpriv = rtl_priv(hw);
647 struct ieee80211_mgmt *mgmt = (void *)data;
648 struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
649 u8 *pos, *end, *ie;
650 u16 noa_len;
651 static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09};
652 u8 noa_num, index, i, noa_index = 0;
653 bool find_p2p_ie = false , find_p2p_ps_ie = false;
654 pos = (u8 *)mgmt->u.beacon.variable;
655 end = data + len;
656 ie = NULL;
657
658 while (pos + 1 < end) {
659 if (pos + 2 + pos[1] > end)
660 return;
661
662 if (pos[0] == 221 && pos[1] > 4) {
663 if (memcmp(&pos[2], p2p_oui_ie_type, 4) == 0) {
664 ie = pos + 2+4;
665 break;
666 }
667 }
668 pos += 2 + pos[1];
669 }
670
671 if (ie == NULL)
672 return;
673 find_p2p_ie = true;
674 /*to find noa ie*/
675 while (ie + 1 < end) {
676 noa_len = READEF2BYTE(&ie[1]);
677 if (ie + 3 + ie[1] > end)
678 return;
679
680 if (ie[0] == 12) {
681 find_p2p_ps_ie = true;
682 if ((noa_len - 2) % 13 != 0) {
683 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
684 "P2P notice of absence: invalid length.%d\n",
685 noa_len);
686 return;
687 } else {
688 noa_num = (noa_len - 2) / 13;
689 }
690 noa_index = ie[3];
691 if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode ==
692 P2P_PS_NONE || noa_index != p2pinfo->noa_index) {
693 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
694 "update NOA ie.\n");
695 p2pinfo->noa_index = noa_index;
696 p2pinfo->opp_ps = (ie[4] >> 7);
697 p2pinfo->ctwindow = ie[4] & 0x7F;
698 p2pinfo->noa_num = noa_num;
699 index = 5;
700 for (i = 0; i < noa_num; i++) {
701 p2pinfo->noa_count_type[i] =
702 READEF1BYTE(ie+index);
703 index += 1;
704 p2pinfo->noa_duration[i] =
705 READEF4BYTE(ie+index);
706 index += 4;
707 p2pinfo->noa_interval[i] =
708 READEF4BYTE(ie+index);
709 index += 4;
710 p2pinfo->noa_start_time[i] =
711 READEF4BYTE(ie+index);
712 index += 4;
713 }
714
715 if (p2pinfo->opp_ps == 1) {
716 p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
717 /* Driver should wait LPS entering
718 * CTWindow
719 */
720 if (rtlpriv->psc.fw_current_inpsmode)
721 rtl_p2p_ps_cmd(hw,
722 P2P_PS_ENABLE);
723 } else if (p2pinfo->noa_num > 0) {
724 p2pinfo->p2p_ps_mode = P2P_PS_NOA;
725 rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
726 } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
727 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
728 }
729 }
730 break;
731 }
732 ie += 3 + noa_len;
733 }
734
735 if (find_p2p_ie == true) {
736 if ((p2pinfo->p2p_ps_mode > P2P_PS_NONE) &&
737 (find_p2p_ps_ie == false))
738 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
739 }
740}
741
742static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data,
743 unsigned int len)
744{
745 struct rtl_priv *rtlpriv = rtl_priv(hw);
746 struct ieee80211_mgmt *mgmt = (void *)data;
747 struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
748 u8 noa_num, index, i, noa_index = 0;
749 u8 *pos, *end, *ie;
750 u16 noa_len;
751 static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09};
752
753 pos = (u8 *)&mgmt->u.action.category;
754 end = data + len;
755 ie = NULL;
756
757 if (pos[0] == 0x7f) {
758 if (memcmp(&pos[1], p2p_oui_ie_type, 4) == 0)
759 ie = pos + 3+4;
760 }
761
762 if (ie == NULL)
763 return;
764
765 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n");
766 /*to find noa ie*/
767 while (ie + 1 < end) {
768 noa_len = READEF2BYTE(&ie[1]);
769 if (ie + 3 + ie[1] > end)
770 return;
771
772 if (ie[0] == 12) {
773 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n");
774 RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, "noa ie ",
775 ie, noa_len);
776 if ((noa_len - 2) % 13 != 0) {
777 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
778 "P2P notice of absence: invalid length.%d\n",
779 noa_len);
780 return;
781 } else {
782 noa_num = (noa_len - 2) / 13;
783 }
784 noa_index = ie[3];
785 if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode ==
786 P2P_PS_NONE || noa_index != p2pinfo->noa_index) {
787 p2pinfo->noa_index = noa_index;
788 p2pinfo->opp_ps = (ie[4] >> 7);
789 p2pinfo->ctwindow = ie[4] & 0x7F;
790 p2pinfo->noa_num = noa_num;
791 index = 5;
792 for (i = 0; i < noa_num; i++) {
793 p2pinfo->noa_count_type[i] =
794 READEF1BYTE(ie+index);
795 index += 1;
796 p2pinfo->noa_duration[i] =
797 READEF4BYTE(ie+index);
798 index += 4;
799 p2pinfo->noa_interval[i] =
800 READEF4BYTE(ie+index);
801 index += 4;
802 p2pinfo->noa_start_time[i] =
803 READEF4BYTE(ie+index);
804 index += 4;
805 }
806
807 if (p2pinfo->opp_ps == 1) {
808 p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
809 /* Driver should wait LPS entering
810 * CTWindow
811 */
812 if (rtlpriv->psc.fw_current_inpsmode)
813 rtl_p2p_ps_cmd(hw,
814 P2P_PS_ENABLE);
815 } else if (p2pinfo->noa_num > 0) {
816 p2pinfo->p2p_ps_mode = P2P_PS_NOA;
817 rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
818 } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
819 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
820 }
821 }
822 break;
823 }
824 ie += 3 + noa_len;
825 }
826}
827
828void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
829{
830 struct rtl_priv *rtlpriv = rtl_priv(hw);
831 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
832 struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
833
834 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, " p2p state %x\n", p2p_ps_state);
835 switch (p2p_ps_state) {
836 case P2P_PS_DISABLE:
837 p2pinfo->p2p_ps_state = p2p_ps_state;
838 rtlpriv->cfg->ops->set_hw_reg(hw,
839 HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
840 (u8 *)(&p2p_ps_state));
841
842 p2pinfo->noa_index = 0;
843 p2pinfo->ctwindow = 0;
844 p2pinfo->opp_ps = 0;
845 p2pinfo->noa_num = 0;
846 p2pinfo->p2p_ps_mode = P2P_PS_NONE;
847 if (rtlps->fw_current_inpsmode == true) {
848 if (rtlps->smart_ps == 0) {
849 rtlps->smart_ps = 2;
850 rtlpriv->cfg->ops->set_hw_reg(hw,
851 HW_VAR_H2C_FW_PWRMODE,
852 (u8 *)(&rtlps->pwr_mode));
853 }
854 }
855 break;
856 case P2P_PS_ENABLE:
857 if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
858 p2pinfo->p2p_ps_state = p2p_ps_state;
859
860 if (p2pinfo->ctwindow > 0) {
861 if (rtlps->smart_ps != 0) {
862 rtlps->smart_ps = 0;
863 rtlpriv->cfg->ops->set_hw_reg(hw,
864 HW_VAR_H2C_FW_PWRMODE,
865 (u8 *)(&rtlps->pwr_mode));
866 }
867 }
868 rtlpriv->cfg->ops->set_hw_reg(hw,
869 HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
870 (u8 *)(&p2p_ps_state));
871 }
872 break;
873 case P2P_PS_SCAN:
874 case P2P_PS_SCAN_DONE:
875 case P2P_PS_ALLSTASLEEP:
876 if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
877 p2pinfo->p2p_ps_state = p2p_ps_state;
878 rtlpriv->cfg->ops->set_hw_reg(hw,
879 HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
880 (u8 *)(&p2p_ps_state));
881 }
882 break;
883 default:
884 break;
885 }
886 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
887 "ctwindow %x oppps %x\n", p2pinfo->ctwindow, p2pinfo->opp_ps);
888 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
889 "count %x duration %x index %x interval %x start time %x noa num %x\n",
890 p2pinfo->noa_count_type[0], p2pinfo->noa_duration[0],
891 p2pinfo->noa_index, p2pinfo->noa_interval[0],
892 p2pinfo->noa_start_time[0], p2pinfo->noa_num);
893 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "end\n");
894}
895
896void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)
897{
898 struct rtl_priv *rtlpriv = rtl_priv(hw);
899 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
900 struct ieee80211_hdr *hdr = (void *)data;
901
902 if (!mac->p2p)
903 return;
904 if (mac->link_state != MAC80211_LINKED)
905 return;
906 /* min. beacon length + FCS_LEN */
907 if (len <= 40 + FCS_LEN)
908 return;
909
910 /* and only beacons from the associated BSSID, please */
911 if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
912 return;
913
914 /* check if this really is a beacon */
915 if (!(ieee80211_is_beacon(hdr->frame_control) ||
916 ieee80211_is_probe_resp(hdr->frame_control) ||
917 ieee80211_is_action(hdr->frame_control)))
918 return;
919
920 if (ieee80211_is_action(hdr->frame_control))
921 rtl_p2p_action_ie(hw, data, len - FCS_LEN);
922 else
923 rtl_p2p_noa_ie(hw, data, len - FCS_LEN);
924}
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h
index 1357856998c2..4d682b753f50 100644
--- a/drivers/net/wireless/rtlwifi/ps.h
+++ b/drivers/net/wireless/rtlwifi/ps.h
@@ -47,5 +47,7 @@ void rtl_swlps_wq_callback(void *data);
47void rtl_swlps_rfon_wq_callback(void *data); 47void rtl_swlps_rfon_wq_callback(void *data);
48void rtl_swlps_rf_awake(struct ieee80211_hw *hw); 48void rtl_swlps_rf_awake(struct ieee80211_hw *hw);
49void rtl_swlps_rf_sleep(struct ieee80211_hw *hw); 49void rtl_swlps_rf_sleep(struct ieee80211_hw *hw);
50void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
51void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len);
50 52
51#endif 53#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile b/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile
new file mode 100644
index 000000000000..5b194e97f4b3
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile
@@ -0,0 +1,16 @@
1rtl8188ee-objs := \
2 dm.o \
3 fw.o \
4 hw.o \
5 led.o \
6 phy.o \
7 pwrseq.o \
8 pwrseqcmd.o \
9 rf.o \
10 sw.o \
11 table.o \
12 trx.o
13
14obj-$(CONFIG_RTL8188EE) += rtl8188ee.o
15
16ccflags-y += -Idrivers/net/wireless/rtlwifi -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/def.h b/drivers/net/wireless/rtlwifi/rtl8188ee/def.h
new file mode 100644
index 000000000000..c764fff9ebe6
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/def.h
@@ -0,0 +1,324 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C_DEF_H__
31#define __RTL92C_DEF_H__
32
33#define HAL_RETRY_LIMIT_INFRA 48
34#define HAL_RETRY_LIMIT_AP_ADHOC 7
35
36#define RESET_DELAY_8185 20
37
38#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
39#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
40
41#define NUM_OF_FIRMWARE_QUEUE 10
42#define NUM_OF_PAGES_IN_FW 0x100
43#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
44#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
45#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
46#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
47#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
48#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
49#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
50#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
51#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
52#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
53
54#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
55#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
56#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
57#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
58#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
59
60#define MAX_LINES_HWCONFIG_TXT 1000
61#define MAX_BYTES_LINE_HWCONFIG_TXT 256
62
63#define SW_THREE_WIRE 0
64#define HW_THREE_WIRE 2
65
66#define BT_DEMO_BOARD 0
67#define BT_QA_BOARD 1
68#define BT_FPGA 2
69
70#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
71#define HAL_PRIME_CHNL_OFFSET_LOWER 1
72#define HAL_PRIME_CHNL_OFFSET_UPPER 2
73
74#define MAX_H2C_QUEUE_NUM 10
75
76#define RX_MPDU_QUEUE 0
77#define RX_CMD_QUEUE 1
78#define RX_MAX_QUEUE 2
79#define AC2QUEUEID(_AC) (_AC)
80
81#define C2H_RX_CMD_HDR_LEN 8
82#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
83 LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
84#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
85 LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
86#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
87 LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
88#define GET_C2H_CMD_CONTINUE(__prxhdr) \
89 LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
90#define GET_C2H_CMD_CONTENT(__prxhdr) \
91 ((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
92
93#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
94 LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
95#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
96 LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
97#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
98 LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
99#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
100 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
101#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
102 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
103#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
104 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
105#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
106 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
107#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
108 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
109#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
110 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
111
112#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)
113
114
115/* [15:12] IC version(CUT): A-cut=0, B-cut=1, C-cut=2, D-cut=3
116 * [7] Manufacturer: TSMC=0, UMC=1
117 * [6:4] RF type: 1T1R=0, 1T2R=1, 2T2R=2
118 * [3] Chip type: TEST=0, NORMAL=1
119 * [2:0] IC type: 81xxC=0, 8723=1, 92D=2
120 */
121#define CHIP_8723 BIT(0)
122#define CHIP_92D BIT(1)
123#define NORMAL_CHIP BIT(3)
124#define RF_TYPE_1T1R (~(BIT(4)|BIT(5)|BIT(6)))
125#define RF_TYPE_1T2R BIT(4)
126#define RF_TYPE_2T2R BIT(5)
127#define CHIP_VENDOR_UMC BIT(7)
128#define B_CUT_VERSION BIT(12)
129#define C_CUT_VERSION BIT(13)
130#define D_CUT_VERSION ((BIT(12)|BIT(13)))
131#define E_CUT_VERSION BIT(14)
132
133
134/* MASK */
135#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2))
136#define CHIP_TYPE_MASK BIT(3)
137#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6))
138#define MANUFACTUER_MASK BIT(7)
139#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8))
140#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12))
141
142/* Get element */
143#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK)
144#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK)
145#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK)
146#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK)
147#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK)
148#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK)
149
150
151#define IS_81XXC(version) \
152 ((GET_CVID_IC_TYPE(version) == 0) ? true : false)
153#define IS_8723_SERIES(version) \
154 ((GET_CVID_IC_TYPE(version) == CHIP_8723) ? true : false)
155#define IS_92D(version) \
156 ((GET_CVID_IC_TYPE(version) == CHIP_92D) ? true : false)
157
158#define IS_NORMAL_CHIP(version) \
159 ((GET_CVID_CHIP_TYPE(version)) ? true : false)
160#define IS_NORMAL_CHIP92D(version) \
161 ((GET_CVID_CHIP_TYPE(version)) ? true : false)
162
163#define IS_1T1R(version) \
164 ((GET_CVID_RF_TYPE(version)) ? false : true)
165#define IS_1T2R(version) \
166 ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R) ? true : false)
167#define IS_2T2R(version) \
168 ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R) ? true : false)
169#define IS_CHIP_VENDOR_UMC(version) \
170 ((GET_CVID_MANUFACTUER(version)) ? true : false)
171
172#define IS_92C_SERIAL(version) \
173 ((IS_81XXC(version) && IS_2T2R(version)) ? true : false)
174#define IS_81xxC_VENDOR_UMC_A_CUT(version) \
175 (IS_81XXC(version) ? ((IS_CHIP_VENDOR_UMC(version)) ? \
176 ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) : false)
177#define IS_81xxC_VENDOR_UMC_B_CUT(version) \
178 (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \
179 ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? true \
180 : false) : false) : false)
181
182enum version_8188e {
183 VERSION_TEST_CHIP_88E = 0x00,
184 VERSION_NORMAL_CHIP_88E = 0x01,
185 VERSION_UNKNOWN = 0xFF,
186};
187
188enum rx_packet_type {
189 NORMAL_RX,
190 TX_REPORT1,
191 TX_REPORT2,
192 HIS_REPORT,
193};
194
195enum rtl819x_loopback_e {
196 RTL819X_NO_LOOPBACK = 0,
197 RTL819X_MAC_LOOPBACK = 1,
198 RTL819X_DMA_LOOPBACK = 2,
199 RTL819X_CCK_LOOPBACK = 3,
200};
201
202enum rf_optype {
203 RF_OP_BY_SW_3WIRE = 0,
204 RF_OP_BY_FW,
205 RF_OP_MAX
206};
207
208enum rf_power_state {
209 RF_ON,
210 RF_OFF,
211 RF_SLEEP,
212 RF_SHUT_DOWN,
213};
214
215enum power_save_mode {
216 POWER_SAVE_MODE_ACTIVE,
217 POWER_SAVE_MODE_SAVE,
218};
219
220enum power_polocy_config {
221 POWERCFG_MAX_POWER_SAVINGS,
222 POWERCFG_GLOBAL_POWER_SAVINGS,
223 POWERCFG_LOCAL_POWER_SAVINGS,
224 POWERCFG_LENOVO,
225};
226
227enum interface_select_pci {
228 INTF_SEL1_MINICARD,
229 INTF_SEL0_PCIE,
230 INTF_SEL2_RSV,
231 INTF_SEL3_RSV,
232};
233
234enum hal_fw_c2h_cmd_id {
235 HAL_FW_C2H_CMD_Read_MACREG,
236 HAL_FW_C2H_CMD_Read_BBREG,
237 HAL_FW_C2H_CMD_Read_RFREG,
238 HAL_FW_C2H_CMD_Read_EEPROM,
239 HAL_FW_C2H_CMD_Read_EFUSE,
240 HAL_FW_C2H_CMD_Read_CAM,
241 HAL_FW_C2H_CMD_Get_BasicRate,
242 HAL_FW_C2H_CMD_Get_DataRate,
243 HAL_FW_C2H_CMD_Survey,
244 HAL_FW_C2H_CMD_SurveyDone,
245 HAL_FW_C2H_CMD_JoinBss,
246 HAL_FW_C2H_CMD_AddSTA,
247 HAL_FW_C2H_CMD_DelSTA,
248 HAL_FW_C2H_CMD_AtimDone,
249 HAL_FW_C2H_CMD_TX_Report,
250 HAL_FW_C2H_CMD_CCX_Report,
251 HAL_FW_C2H_CMD_DTM_Report,
252 HAL_FW_C2H_CMD_TX_Rate_Statistics,
253 HAL_FW_C2H_CMD_C2HLBK,
254 HAL_FW_C2H_CMD_C2HDBG,
255 HAL_FW_C2H_CMD_C2HFEEDBACK,
256 HAL_FW_C2H_CMD_MAX
257};
258
259enum wake_on_wlan_mode {
260 ewowlandisable,
261 ewakeonmagicpacketonly,
262 ewakeonpatternmatchonly,
263 ewakeonbothtypepacket
264};
265
266enum rtl_desc_qsel {
267 QSLT_BK = 0x2,
268 QSLT_BE = 0x0,
269 QSLT_VI = 0x5,
270 QSLT_VO = 0x7,
271 QSLT_BEACON = 0x10,
272 QSLT_HIGH = 0x11,
273 QSLT_MGNT = 0x12,
274 QSLT_CMD = 0x13,
275};
276
277enum rtl_desc92c_rate {
278 DESC92C_RATE1M = 0x00,
279 DESC92C_RATE2M = 0x01,
280 DESC92C_RATE5_5M = 0x02,
281 DESC92C_RATE11M = 0x03,
282
283 DESC92C_RATE6M = 0x04,
284 DESC92C_RATE9M = 0x05,
285 DESC92C_RATE12M = 0x06,
286 DESC92C_RATE18M = 0x07,
287 DESC92C_RATE24M = 0x08,
288 DESC92C_RATE36M = 0x09,
289 DESC92C_RATE48M = 0x0a,
290 DESC92C_RATE54M = 0x0b,
291
292 DESC92C_RATEMCS0 = 0x0c,
293 DESC92C_RATEMCS1 = 0x0d,
294 DESC92C_RATEMCS2 = 0x0e,
295 DESC92C_RATEMCS3 = 0x0f,
296 DESC92C_RATEMCS4 = 0x10,
297 DESC92C_RATEMCS5 = 0x11,
298 DESC92C_RATEMCS6 = 0x12,
299 DESC92C_RATEMCS7 = 0x13,
300 DESC92C_RATEMCS8 = 0x14,
301 DESC92C_RATEMCS9 = 0x15,
302 DESC92C_RATEMCS10 = 0x16,
303 DESC92C_RATEMCS11 = 0x17,
304 DESC92C_RATEMCS12 = 0x18,
305 DESC92C_RATEMCS13 = 0x19,
306 DESC92C_RATEMCS14 = 0x1a,
307 DESC92C_RATEMCS15 = 0x1b,
308 DESC92C_RATEMCS15_SG = 0x1c,
309 DESC92C_RATEMCS32 = 0x20,
310};
311
312struct phy_sts_cck_8192s_t {
313 u8 adc_pwdb_X[4];
314 u8 sq_rpt;
315 u8 cck_agc_rpt;
316};
317
318struct h2c_cmd_8192c {
319 u8 element_id;
320 u32 cmd_len;
321 u8 *p_cmdbuffer;
322};
323
324#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
new file mode 100644
index 000000000000..21a5cf060677
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
@@ -0,0 +1,1794 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../base.h"
32#include "../pci.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "dm.h"
37#include "fw.h"
38#include "trx.h"
39
40static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
41 0x7f8001fe, /* 0, +6.0dB */
42 0x788001e2, /* 1, +5.5dB */
43 0x71c001c7, /* 2, +5.0dB */
44 0x6b8001ae, /* 3, +4.5dB */
45 0x65400195, /* 4, +4.0dB */
46 0x5fc0017f, /* 5, +3.5dB */
47 0x5a400169, /* 6, +3.0dB */
48 0x55400155, /* 7, +2.5dB */
49 0x50800142, /* 8, +2.0dB */
50 0x4c000130, /* 9, +1.5dB */
51 0x47c0011f, /* 10, +1.0dB */
52 0x43c0010f, /* 11, +0.5dB */
53 0x40000100, /* 12, +0dB */
54 0x3c8000f2, /* 13, -0.5dB */
55 0x390000e4, /* 14, -1.0dB */
56 0x35c000d7, /* 15, -1.5dB */
57 0x32c000cb, /* 16, -2.0dB */
58 0x300000c0, /* 17, -2.5dB */
59 0x2d4000b5, /* 18, -3.0dB */
60 0x2ac000ab, /* 19, -3.5dB */
61 0x288000a2, /* 20, -4.0dB */
62 0x26000098, /* 21, -4.5dB */
63 0x24000090, /* 22, -5.0dB */
64 0x22000088, /* 23, -5.5dB */
65 0x20000080, /* 24, -6.0dB */
66 0x1e400079, /* 25, -6.5dB */
67 0x1c800072, /* 26, -7.0dB */
68 0x1b00006c, /* 27. -7.5dB */
69 0x19800066, /* 28, -8.0dB */
70 0x18000060, /* 29, -8.5dB */
71 0x16c0005b, /* 30, -9.0dB */
72 0x15800056, /* 31, -9.5dB */
73 0x14400051, /* 32, -10.0dB */
74 0x1300004c, /* 33, -10.5dB */
75 0x12000048, /* 34, -11.0dB */
76 0x11000044, /* 35, -11.5dB */
77 0x10000040, /* 36, -12.0dB */
78 0x0f00003c, /* 37, -12.5dB */
79 0x0e400039, /* 38, -13.0dB */
80 0x0d800036, /* 39, -13.5dB */
81 0x0cc00033, /* 40, -14.0dB */
82 0x0c000030, /* 41, -14.5dB */
83 0x0b40002d, /* 42, -15.0dB */
84};
85
86static const u8 cck_tbl_ch1_13[CCK_TABLE_SIZE][8] = {
87 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */
88 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */
89 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */
90 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */
91 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */
92 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */
93 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */
94 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */
95 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */
96 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */
97 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */
98 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */
99 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */
100 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */
101 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */
102 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */
103 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
104 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */
105 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */
106 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */
107 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/
108 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/
109 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/
110 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/
111 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/
112 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/
113 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/
114 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/
115 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/
116 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/
117 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/
118 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/
119 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/
120};
121
122static const u8 cck_tbl_ch14[CCK_TABLE_SIZE][8] = {
123 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */
124 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */
125 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */
126 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */
127 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */
128 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */
129 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */
130 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */
131 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */
132 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */
133 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */
134 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */
135 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */
136 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */
137 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */
138 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */
139 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
140 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */
141 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */
142 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */
143 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/
144 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/
145 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/
146 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/
147 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/
148 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/
149 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/
150 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/
151 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/
152 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/
153 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/
154 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/
155 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/
156};
157
158#define CAL_SWING_OFF(_off, _dir, _size, _del) \
159 do { \
160 for (_off = 0; _off < _size; _off++) { \
161 if (_del < thermal_threshold[_dir][_off]) { \
162 if (_off != 0) \
163 _off--; \
164 break; \
165 } \
166 } \
167 if (_off >= _size) \
168 _off = _size - 1; \
169 } while (0)
170
171static void rtl88e_set_iqk_matrix(struct ieee80211_hw *hw,
172 u8 ofdm_index, u8 rfpath,
173 long iqk_result_x, long iqk_result_y)
174{
175 long ele_a = 0, ele_d, ele_c = 0, value32;
176
177 ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000)>>22;
178
179 if (iqk_result_x != 0) {
180 if ((iqk_result_x & 0x00000200) != 0)
181 iqk_result_x = iqk_result_x | 0xFFFFFC00;
182 ele_a = ((iqk_result_x * ele_d)>>8)&0x000003FF;
183
184 if ((iqk_result_y & 0x00000200) != 0)
185 iqk_result_y = iqk_result_y | 0xFFFFFC00;
186 ele_c = ((iqk_result_y * ele_d)>>8)&0x000003FF;
187
188 switch (rfpath) {
189 case RF90_PATH_A:
190 value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
191 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBAL, MASKDWORD,
192 value32);
193 value32 = (ele_c & 0x000003C0) >> 6;
194 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32);
195 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
196 rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(24), value32);
197 break;
198 case RF90_PATH_B:
199 value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
200 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBAL,
201 MASKDWORD, value32);
202 value32 = (ele_c & 0x000003C0) >> 6;
203 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, value32);
204 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
205 rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(28), value32);
206 break;
207 default:
208 break;
209 }
210 } else {
211 switch (rfpath) {
212 case RF90_PATH_A:
213 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBAL, MASKDWORD,
214 ofdmswing_table[ofdm_index]);
215 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00);
216 rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(24), 0x00);
217 break;
218 case RF90_PATH_B:
219 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBAL, MASKDWORD,
220 ofdmswing_table[ofdm_index]);
221 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, 0x00);
222 rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(28), 0x00);
223 break;
224 default:
225 break;
226 }
227 }
228}
229
230void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw,
231 u8 type, u8 *pdirection, u32 *poutwrite_val)
232{
233 struct rtl_priv *rtlpriv = rtl_priv(hw);
234 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
235 u8 pwr_val = 0;
236 u8 cck_base = rtldm->swing_idx_cck_base;
237 u8 cck_val = rtldm->swing_idx_cck;
238 u8 ofdm_base = rtldm->swing_idx_ofdm_base;
239 u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
240
241 if (type == 0) {
242 if (ofdm_val <= ofdm_base) {
243 *pdirection = 1;
244 pwr_val = ofdm_base - ofdm_val;
245 } else {
246 *pdirection = 2;
247 pwr_val = ofdm_val - ofdm_base;
248 }
249 } else if (type == 1) {
250 if (cck_val <= cck_base) {
251 *pdirection = 1;
252 pwr_val = cck_base - cck_val;
253 } else {
254 *pdirection = 2;
255 pwr_val = cck_val - cck_base;
256 }
257 }
258
259 if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
260 pwr_val = TXPWRTRACK_MAX_IDX;
261
262 *poutwrite_val = pwr_val | (pwr_val << 8) | (pwr_val << 16) |
263 (pwr_val << 24);
264}
265
266
267static void rtl88e_chk_tx_track(struct ieee80211_hw *hw,
268 enum pwr_track_control_method method,
269 u8 rfpath, u8 index)
270{
271 struct rtl_priv *rtlpriv = rtl_priv(hw);
272 struct rtl_phy *rtlphy = &(rtlpriv->phy);
273 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
274 int jj = rtldm->swing_idx_cck;
275 int i;
276
277 if (method == TXAGC) {
278 if (rtldm->swing_flag_ofdm == true ||
279 rtldm->swing_flag_cck == true) {
280 u8 chan = rtlphy->current_channel;
281 rtl88e_phy_set_txpower_level(hw, chan);
282 rtldm->swing_flag_ofdm = false;
283 rtldm->swing_flag_cck = false;
284 }
285 } else if (method == BBSWING) {
286 if (!rtldm->cck_inch14) {
287 for (i = 0; i < 8; i++)
288 rtl_write_byte(rtlpriv, 0xa22 + i,
289 cck_tbl_ch1_13[jj][i]);
290 } else {
291 for (i = 0; i < 8; i++)
292 rtl_write_byte(rtlpriv, 0xa22 + i,
293 cck_tbl_ch14[jj][i]);
294 }
295
296 if (rfpath == RF90_PATH_A) {
297 long x = rtlphy->iqk_matrix[index].value[0][0];
298 long y = rtlphy->iqk_matrix[index].value[0][1];
299 u8 indx = rtldm->swing_idx_ofdm[rfpath];
300 rtl88e_set_iqk_matrix(hw, indx, rfpath, x, y);
301 } else if (rfpath == RF90_PATH_B) {
302 u8 indx = rtldm->swing_idx_ofdm[rfpath];
303 long x = rtlphy->iqk_matrix[indx].value[0][4];
304 long y = rtlphy->iqk_matrix[indx].value[0][5];
305 rtl88e_set_iqk_matrix(hw, indx, rfpath, x, y);
306 }
307 } else {
308 return;
309 }
310}
311
312static void rtl88e_dm_diginit(struct ieee80211_hw *hw)
313{
314 struct rtl_priv *rtlpriv = rtl_priv(hw);
315 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
316
317 dm_dig->dig_enable_flag = true;
318 dm_dig->cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
319 dm_dig->pre_igvalue = 0;
320 dm_dig->cursta_cstate = DIG_STA_DISCONNECT;
321 dm_dig->presta_cstate = DIG_STA_DISCONNECT;
322 dm_dig->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
323 dm_dig->rssi_lowthresh = DM_DIG_THRESH_LOW;
324 dm_dig->rssi_highthresh = DM_DIG_THRESH_HIGH;
325 dm_dig->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
326 dm_dig->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
327 dm_dig->rx_gain_max = DM_DIG_MAX;
328 dm_dig->rx_gain_min = DM_DIG_MIN;
329 dm_dig->back_val = DM_DIG_BACKOFF_DEFAULT;
330 dm_dig->back_range_max = DM_DIG_BACKOFF_MAX;
331 dm_dig->back_range_min = DM_DIG_BACKOFF_MIN;
332 dm_dig->pre_cck_cca_thres = 0xff;
333 dm_dig->cur_cck_cca_thres = 0x83;
334 dm_dig->forbidden_igi = DM_DIG_MIN;
335 dm_dig->large_fa_hit = 0;
336 dm_dig->recover_cnt = 0;
337 dm_dig->dig_min_0 = 0x25;
338 dm_dig->dig_min_1 = 0x25;
339 dm_dig->media_connect_0 = false;
340 dm_dig->media_connect_1 = false;
341 rtlpriv->dm.dm_initialgain_enable = true;
342}
343
344static u8 rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
345{
346 struct rtl_priv *rtlpriv = rtl_priv(hw);
347 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
348 long rssi_val_min = 0;
349
350 if ((dm_dig->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
351 (dm_dig->cursta_cstate == DIG_STA_CONNECT)) {
352 if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
353 rssi_val_min =
354 (rtlpriv->dm.entry_min_undec_sm_pwdb >
355 rtlpriv->dm.undec_sm_pwdb) ?
356 rtlpriv->dm.undec_sm_pwdb :
357 rtlpriv->dm.entry_min_undec_sm_pwdb;
358 else
359 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
360 } else if (dm_dig->cursta_cstate == DIG_STA_CONNECT ||
361 dm_dig->cursta_cstate == DIG_STA_BEFORE_CONNECT) {
362 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
363 } else if (dm_dig->curmultista_cstate ==
364 DIG_MULTISTA_CONNECT) {
365 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
366 }
367 return (u8)rssi_val_min;
368}
369
370static void rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
371{
372 u32 ret_value;
373 struct rtl_priv *rtlpriv = rtl_priv(hw);
374 struct false_alarm_statistics *alm_cnt = &(rtlpriv->falsealm_cnt);
375
376 rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1);
377 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1);
378
379 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
380 alm_cnt->cnt_fast_fsync_fail = (ret_value&0xffff);
381 alm_cnt->cnt_sb_search_fail = ((ret_value&0xffff0000)>>16);
382
383 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
384 alm_cnt->cnt_ofdm_cca = (ret_value&0xffff);
385 alm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
386
387 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
388 alm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
389 alm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
390
391 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
392 alm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
393 alm_cnt->cnt_ofdm_fail = alm_cnt->cnt_parity_fail +
394 alm_cnt->cnt_rate_illegal +
395 alm_cnt->cnt_crc8_fail +
396 alm_cnt->cnt_mcs_fail +
397 alm_cnt->cnt_fast_fsync_fail +
398 alm_cnt->cnt_sb_search_fail;
399
400 ret_value = rtl_get_bbreg(hw, REG_SC_CNT, MASKDWORD);
401 alm_cnt->cnt_bw_lsc = (ret_value & 0xffff);
402 alm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);
403
404 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(12), 1);
405 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
406
407 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
408 alm_cnt->cnt_cck_fail = ret_value;
409
410 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
411 alm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
412
413 ret_value = rtl_get_bbreg(hw, RCCK0_CCA_CNT, MASKDWORD);
414 alm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
415 ((ret_value&0xFF00)>>8);
416
417 alm_cnt->cnt_all = alm_cnt->cnt_fast_fsync_fail +
418 alm_cnt->cnt_sb_search_fail +
419 alm_cnt->cnt_parity_fail +
420 alm_cnt->cnt_rate_illegal +
421 alm_cnt->cnt_crc8_fail +
422 alm_cnt->cnt_mcs_fail +
423 alm_cnt->cnt_cck_fail;
424 alm_cnt->cnt_cca_all = alm_cnt->cnt_ofdm_cca + alm_cnt->cnt_cck_cca;
425
426 rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 1);
427 rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 0);
428 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 1);
429 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 0);
430 rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0);
431 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0);
432 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 0);
433 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 2);
434 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 0);
435 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 2);
436
437 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
438 "cnt_parity_fail = %d, cnt_rate_illegal = %d, "
439 "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
440 alm_cnt->cnt_parity_fail,
441 alm_cnt->cnt_rate_illegal,
442 alm_cnt->cnt_crc8_fail, alm_cnt->cnt_mcs_fail);
443
444 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
445 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
446 alm_cnt->cnt_ofdm_fail,
447 alm_cnt->cnt_cck_fail, alm_cnt->cnt_all);
448}
449
450static void rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
451{
452 struct rtl_priv *rtlpriv = rtl_priv(hw);
453 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
454 u8 cur_cck_cca_thresh;
455
456 if (dm_dig->cursta_cstate == DIG_STA_CONNECT) {
457 dm_dig->rssi_val_min = rtl88e_dm_initial_gain_min_pwdb(hw);
458 if (dm_dig->rssi_val_min > 25) {
459 cur_cck_cca_thresh = 0xcd;
460 } else if ((dm_dig->rssi_val_min <= 25) &&
461 (dm_dig->rssi_val_min > 10)) {
462 cur_cck_cca_thresh = 0x83;
463 } else {
464 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
465 cur_cck_cca_thresh = 0x83;
466 else
467 cur_cck_cca_thresh = 0x40;
468 }
469
470 } else {
471 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
472 cur_cck_cca_thresh = 0x83;
473 else
474 cur_cck_cca_thresh = 0x40;
475 }
476
477 if (dm_dig->cur_cck_cca_thres != cur_cck_cca_thresh)
478 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
479
480 dm_dig->cur_cck_cca_thres = cur_cck_cca_thresh;
481 dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres;
482 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
483 "CCK cca thresh hold =%x\n", dm_dig->cur_cck_cca_thres);
484}
485
486static void rtl88e_dm_dig(struct ieee80211_hw *hw)
487{
488 struct rtl_priv *rtlpriv = rtl_priv(hw);
489 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
490 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
491 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
492 u8 dig_min, dig_maxofmin;
493 bool bfirstconnect;
494 u8 dm_dig_max, dm_dig_min;
495 u8 current_igi = dm_dig->cur_igvalue;
496
497 if (rtlpriv->dm.dm_initialgain_enable == false)
498 return;
499 if (dm_dig->dig_enable_flag == false)
500 return;
501 if (mac->act_scanning == true)
502 return;
503
504 if (mac->link_state >= MAC80211_LINKED)
505 dm_dig->cursta_cstate = DIG_STA_CONNECT;
506 else
507 dm_dig->cursta_cstate = DIG_STA_DISCONNECT;
508 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
509 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
510 dm_dig->cursta_cstate = DIG_STA_DISCONNECT;
511
512 dm_dig_max = DM_DIG_MAX;
513 dm_dig_min = DM_DIG_MIN;
514 dig_maxofmin = DM_DIG_MAX_AP;
515 dig_min = dm_dig->dig_min_0;
516 bfirstconnect = ((mac->link_state >= MAC80211_LINKED) ? true : false) &&
517 (dm_dig->media_connect_0 == false);
518
519 dm_dig->rssi_val_min =
520 rtl88e_dm_initial_gain_min_pwdb(hw);
521
522 if (mac->link_state >= MAC80211_LINKED) {
523 if ((dm_dig->rssi_val_min + 20) > dm_dig_max)
524 dm_dig->rx_gain_max = dm_dig_max;
525 else if ((dm_dig->rssi_val_min + 20) < dm_dig_min)
526 dm_dig->rx_gain_max = dm_dig_min;
527 else
528 dm_dig->rx_gain_max = dm_dig->rssi_val_min + 20;
529
530 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
531 dig_min = dm_dig->antdiv_rssi_max;
532 } else {
533 if (dm_dig->rssi_val_min < dm_dig_min)
534 dig_min = dm_dig_min;
535 else if (dm_dig->rssi_val_min < dig_maxofmin)
536 dig_min = dig_maxofmin;
537 else
538 dig_min = dm_dig->rssi_val_min;
539 }
540 } else {
541 dm_dig->rx_gain_max = dm_dig_max;
542 dig_min = dm_dig_min;
543 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
544 }
545
546 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
547 dm_dig->large_fa_hit++;
548 if (dm_dig->forbidden_igi < current_igi) {
549 dm_dig->forbidden_igi = current_igi;
550 dm_dig->large_fa_hit = 1;
551 }
552
553 if (dm_dig->large_fa_hit >= 3) {
554 if ((dm_dig->forbidden_igi + 1) > dm_dig->rx_gain_max)
555 dm_dig->rx_gain_min = dm_dig->rx_gain_max;
556 else
557 dm_dig->rx_gain_min = dm_dig->forbidden_igi + 1;
558 dm_dig->recover_cnt = 3600;
559 }
560 } else {
561 if (dm_dig->recover_cnt != 0) {
562 dm_dig->recover_cnt--;
563 } else {
564 if (dm_dig->large_fa_hit == 0) {
565 if ((dm_dig->forbidden_igi - 1) < dig_min) {
566 dm_dig->forbidden_igi = dig_min;
567 dm_dig->rx_gain_min = dig_min;
568 } else {
569 dm_dig->forbidden_igi--;
570 dm_dig->rx_gain_min =
571 dm_dig->forbidden_igi + 1;
572 }
573 } else if (dm_dig->large_fa_hit == 3) {
574 dm_dig->large_fa_hit = 0;
575 }
576 }
577 }
578
579 if (dm_dig->cursta_cstate == DIG_STA_CONNECT) {
580 if (bfirstconnect) {
581 current_igi = dm_dig->rssi_val_min;
582 } else {
583 if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
584 current_igi += 2;
585 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
586 current_igi++;
587 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
588 current_igi--;
589 }
590 } else {
591 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
592 current_igi += 2;
593 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
594 current_igi++;
595 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
596 current_igi--;
597 }
598
599 if (current_igi > DM_DIG_FA_UPPER)
600 current_igi = DM_DIG_FA_UPPER;
601 else if (current_igi < DM_DIG_FA_LOWER)
602 current_igi = DM_DIG_FA_LOWER;
603
604 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
605 current_igi = DM_DIG_FA_UPPER;
606
607 dm_dig->cur_igvalue = current_igi;
608 rtl88e_dm_write_dig(hw);
609 dm_dig->media_connect_0 = ((mac->link_state >= MAC80211_LINKED) ?
610 true : false);
611 dm_dig->dig_min_0 = dig_min;
612
613 rtl88e_dm_cck_packet_detection_thresh(hw);
614}
615
616static void rtl88e_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
617{
618 struct rtl_priv *rtlpriv = rtl_priv(hw);
619
620 rtlpriv->dm.dynamic_txpower_enable = false;
621
622 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
623 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
624}
625
626static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
627{
628 struct rtl_priv *rtlpriv = rtl_priv(hw);
629 struct rtl_phy *rtlphy = &(rtlpriv->phy);
630 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
631 long undec_sm_pwdb;
632
633 if (!rtlpriv->dm.dynamic_txpower_enable)
634 return;
635
636 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
637 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
638 return;
639 }
640
641 if ((mac->link_state < MAC80211_LINKED) &&
642 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
643 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
644 "Not connected\n");
645
646 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
647
648 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
649 return;
650 }
651
652 if (mac->link_state >= MAC80211_LINKED) {
653 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
654 undec_sm_pwdb =
655 rtlpriv->dm.entry_min_undec_sm_pwdb;
656 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
657 "AP Client PWDB = 0x%lx\n",
658 undec_sm_pwdb);
659 } else {
660 undec_sm_pwdb =
661 rtlpriv->dm.undec_sm_pwdb;
662 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
663 "STA Default Port PWDB = 0x%lx\n",
664 undec_sm_pwdb);
665 }
666 } else {
667 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
668
669 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
670 "AP Ext Port PWDB = 0x%lx\n", undec_sm_pwdb);
671 }
672
673 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
674 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
675 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
676 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x0)\n");
677 } else if ((undec_sm_pwdb <
678 (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
679 (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
680 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
681 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
682 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x10)\n");
683 } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
684 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
685 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
686 "TXHIGHPWRLEVEL_NORMAL\n");
687 }
688
689 if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
690 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
691 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
692 rtlphy->current_channel);
693 rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel);
694 }
695
696 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
697}
698
699void rtl88e_dm_write_dig(struct ieee80211_hw *hw)
700{
701 struct rtl_priv *rtlpriv = rtl_priv(hw);
702 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
703
704 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
705 "cur_igvalue = 0x%x, "
706 "pre_igvalue = 0x%x, back_val = %d\n",
707 dm_dig->cur_igvalue, dm_dig->pre_igvalue,
708 dm_dig->back_val);
709
710 if (dm_dig->cur_igvalue > 0x3f)
711 dm_dig->cur_igvalue = 0x3f;
712 if (dm_dig->pre_igvalue != dm_dig->cur_igvalue) {
713 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
714 dm_dig->cur_igvalue);
715
716 dm_dig->pre_igvalue = dm_dig->cur_igvalue;
717 }
718}
719
720static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw *hw)
721{
722 struct rtl_priv *rtlpriv = rtl_priv(hw);
723 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
724 struct rtl_sta_info *drv_priv;
725 static u64 last_txok;
726 static u64 last_rx;
727 long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
728
729 if (rtlhal->oem_id == RT_CID_819x_HP) {
730 u64 cur_txok_cnt = 0;
731 u64 cur_rxok_cnt = 0;
732 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok;
733 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rx;
734 last_txok = cur_txok_cnt;
735 last_rx = cur_rxok_cnt;
736
737 if (cur_rxok_cnt > (cur_txok_cnt * 6))
738 rtl_write_dword(rtlpriv, REG_ARFR0, 0x8f015);
739 else
740 rtl_write_dword(rtlpriv, REG_ARFR0, 0xff015);
741 }
742
743 /* AP & ADHOC & MESH */
744 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
745 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
746 if (drv_priv->rssi_stat.undec_sm_pwdb < tmp_entry_min_pwdb)
747 tmp_entry_min_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
748 if (drv_priv->rssi_stat.undec_sm_pwdb > tmp_entry_max_pwdb)
749 tmp_entry_max_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
750 }
751 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
752
753 /* If associated entry is found */
754 if (tmp_entry_max_pwdb != 0) {
755 rtlpriv->dm.entry_max_undec_sm_pwdb = tmp_entry_max_pwdb;
756 RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMaxPWDB = 0x%lx(%ld)\n",
757 tmp_entry_max_pwdb, tmp_entry_max_pwdb);
758 } else {
759 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
760 }
761 /* If associated entry is found */
762 if (tmp_entry_min_pwdb != 0xff) {
763 rtlpriv->dm.entry_min_undec_sm_pwdb = tmp_entry_min_pwdb;
764 RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMinPWDB = 0x%lx(%ld)\n",
765 tmp_entry_min_pwdb, tmp_entry_min_pwdb);
766 } else {
767 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
768 }
769 /* Indicate Rx signal strength to FW. */
770 if (!rtlpriv->dm.useramask)
771 rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);
772}
773
774void rtl88e_dm_init_edca_turbo(struct ieee80211_hw *hw)
775{
776 struct rtl_priv *rtlpriv = rtl_priv(hw);
777
778 rtlpriv->dm.current_turbo_edca = false;
779 rtlpriv->dm.is_any_nonbepkts = false;
780 rtlpriv->dm.is_cur_rdlstate = false;
781}
782
783static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)
784{
785 struct rtl_priv *rtlpriv = rtl_priv(hw);
786 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
787 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
788 static u64 last_txok_cnt;
789 static u64 last_rxok_cnt;
790 static u32 last_bt_edca_ul;
791 static u32 last_bt_edca_dl;
792 u64 cur_txok_cnt = 0;
793 u64 cur_rxok_cnt = 0;
794 u32 edca_be_ul = 0x5ea42b;
795 u32 edca_be_dl = 0x5ea42b;
796 bool change_edca = false;
797
798 if ((last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) ||
799 (last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) {
800 rtlpriv->dm.current_turbo_edca = false;
801 last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
802 last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl;
803 }
804
805 if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) {
806 edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
807 change_edca = true;
808 }
809
810 if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) {
811 edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl;
812 change_edca = true;
813 }
814
815 if (mac->link_state != MAC80211_LINKED) {
816 rtlpriv->dm.current_turbo_edca = false;
817 return;
818 }
819
820 if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) {
821 if (!(edca_be_ul & 0xffff0000))
822 edca_be_ul |= 0x005e0000;
823
824 if (!(edca_be_dl & 0xffff0000))
825 edca_be_dl |= 0x005e0000;
826 }
827
828 if ((change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
829 (!rtlpriv->dm.disable_framebursting))) {
830 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
831 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
832
833 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
834 if (!rtlpriv->dm.is_cur_rdlstate ||
835 !rtlpriv->dm.current_turbo_edca) {
836 rtl_write_dword(rtlpriv,
837 REG_EDCA_BE_PARAM,
838 edca_be_dl);
839 rtlpriv->dm.is_cur_rdlstate = true;
840 }
841 } else {
842 if (rtlpriv->dm.is_cur_rdlstate ||
843 !rtlpriv->dm.current_turbo_edca) {
844 rtl_write_dword(rtlpriv,
845 REG_EDCA_BE_PARAM,
846 edca_be_ul);
847 rtlpriv->dm.is_cur_rdlstate = false;
848 }
849 }
850 rtlpriv->dm.current_turbo_edca = true;
851 } else {
852 if (rtlpriv->dm.current_turbo_edca) {
853 u8 tmp = AC0_BE;
854 rtlpriv->cfg->ops->set_hw_reg(hw,
855 HW_VAR_AC_PARAM,
856 (u8 *)(&tmp));
857 rtlpriv->dm.current_turbo_edca = false;
858 }
859 }
860
861 rtlpriv->dm.is_any_nonbepkts = false;
862 last_txok_cnt = rtlpriv->stats.txbytesunicast;
863 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
864}
865
866static void rtl88e_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
867 *hw)
868{
869 struct rtl_priv *rtlpriv = rtl_priv(hw);
870 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
871 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
872 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
873 u8 thermalvalue = 0, delta, delta_lck, delta_iqk, off;
874 u8 th_avg_cnt = 0;
875 u32 thermalvalue_avg = 0;
876 long ele_d, temp_cck;
877 char ofdm_index[2], cck_index = 0, ofdm_old[2] = {0, 0}, cck_old = 0;
878 int i = 0;
879 bool is2t = false;
880
881 u8 ofdm_min_index = 6, rf = (is2t) ? 2 : 1;
882 u8 index_for_channel;
883 enum _dec_inc {dec, power_inc};
884
885 /* 0.1 the following TWO tables decide the final index of
886 * OFDM/CCK swing table
887 */
888 char del_tbl_idx[2][15] = {
889 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
890 {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}
891 };
892 u8 thermal_threshold[2][15] = {
893 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
894 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
895 };
896
897 /*Initilization (7 steps in total) */
898 rtlpriv->dm.txpower_trackinginit = true;
899 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
900 "rtl88e_dm_txpower_tracking_callback_thermalmeter\n");
901
902 thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xfc00);
903 if (!thermalvalue)
904 return;
905 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
906 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
907 thermalvalue, rtlpriv->dm.thermalvalue,
908 rtlefuse->eeprom_thermalmeter);
909
910 /*1. Query OFDM Default Setting: Path A*/
911 ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBAL, MASKDWORD) & MASKOFDM_D;
912 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
913 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
914 ofdm_old[0] = (u8) i;
915 rtldm->swing_idx_ofdm_base = (u8)i;
916 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
917 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",
918 ROFDM0_XATXIQIMBAL,
919 ele_d, ofdm_old[0]);
920 break;
921 }
922 }
923
924 if (is2t) {
925 ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBAL,
926 MASKDWORD) & MASKOFDM_D;
927 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
928 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
929 ofdm_old[1] = (u8)i;
930
931 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
932 DBG_LOUD,
933 "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",
934 ROFDM0_XBTXIQIMBAL, ele_d,
935 ofdm_old[1]);
936 break;
937 }
938 }
939 }
940 /*2.Query CCK default setting From 0xa24*/
941 temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
942 for (i = 0; i < CCK_TABLE_LENGTH; i++) {
943 if (rtlpriv->dm.cck_inch14) {
944 if (memcmp(&temp_cck, &cck_tbl_ch14[i][2], 4) == 0) {
945 cck_old = (u8)i;
946 rtldm->swing_idx_cck_base = (u8)i;
947 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
948 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch 14 %d\n",
949 RCCK0_TXFILTER2, temp_cck, cck_old,
950 rtlpriv->dm.cck_inch14);
951 break;
952 }
953 } else {
954 if (memcmp(&temp_cck, &cck_tbl_ch1_13[i][2], 4) == 0) {
955 cck_old = (u8)i;
956 rtldm->swing_idx_cck_base = (u8)i;
957 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
958 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
959 RCCK0_TXFILTER2, temp_cck, cck_old,
960 rtlpriv->dm.cck_inch14);
961 break;
962 }
963 }
964 }
965
966 /*3 Initialize ThermalValues of RFCalibrateInfo*/
967 if (!rtldm->thermalvalue) {
968 rtlpriv->dm.thermalvalue = rtlefuse->eeprom_thermalmeter;
969 rtlpriv->dm.thermalvalue_lck = thermalvalue;
970 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
971 for (i = 0; i < rf; i++)
972 rtlpriv->dm.ofdm_index[i] = ofdm_old[i];
973 rtlpriv->dm.cck_index = cck_old;
974 }
975
976 /*4 Calculate average thermal meter*/
977 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
978 rtldm->thermalvalue_avg_index++;
979 if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_88E)
980 rtldm->thermalvalue_avg_index = 0;
981
982 for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
983 if (rtldm->thermalvalue_avg[i]) {
984 thermalvalue_avg += rtldm->thermalvalue_avg[i];
985 th_avg_cnt++;
986 }
987 }
988
989 if (th_avg_cnt)
990 thermalvalue = (u8)(thermalvalue_avg / th_avg_cnt);
991
992 /* 5 Calculate delta, delta_LCK, delta_IQK.*/
993 if (rtlhal->reloadtxpowerindex) {
994 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
995 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
996 (rtlefuse->eeprom_thermalmeter - thermalvalue);
997 rtlhal->reloadtxpowerindex = false;
998 rtlpriv->dm.done_txpower = false;
999 } else if (rtlpriv->dm.done_txpower) {
1000 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
1001 (thermalvalue - rtlpriv->dm.thermalvalue) :
1002 (rtlpriv->dm.thermalvalue - thermalvalue);
1003 } else {
1004 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
1005 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
1006 (rtlefuse->eeprom_thermalmeter - thermalvalue);
1007 }
1008 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
1009 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
1010 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
1011 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
1012 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
1013 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
1014
1015 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1016 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
1017 "eeprom_thermalmeter 0x%x delta 0x%x "
1018 "delta_lck 0x%x delta_iqk 0x%x\n",
1019 thermalvalue, rtlpriv->dm.thermalvalue,
1020 rtlefuse->eeprom_thermalmeter, delta, delta_lck,
1021 delta_iqk);
1022 /* 6 If necessary, do LCK.*/
1023 if (delta_lck >= 8) {
1024 rtlpriv->dm.thermalvalue_lck = thermalvalue;
1025 rtl88e_phy_lc_calibrate(hw);
1026 }
1027
1028 /* 7 If necessary, move the index of swing table to adjust Tx power. */
1029 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
1030 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
1031 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
1032 (rtlefuse->eeprom_thermalmeter - thermalvalue);
1033
1034 /* 7.1 Get the final CCK_index and OFDM_index for each
1035 * swing table.
1036 */
1037 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
1038 CAL_SWING_OFF(off, power_inc, IDX_MAP, delta);
1039 for (i = 0; i < rf; i++)
1040 ofdm_index[i] = rtldm->ofdm_index[i] +
1041 del_tbl_idx[power_inc][off];
1042 cck_index = rtldm->cck_index +
1043 del_tbl_idx[power_inc][off];
1044 } else {
1045 CAL_SWING_OFF(off, dec, IDX_MAP, delta);
1046 for (i = 0; i < rf; i++)
1047 ofdm_index[i] = rtldm->ofdm_index[i] +
1048 del_tbl_idx[dec][off];
1049 cck_index = rtldm->cck_index + del_tbl_idx[dec][off];
1050 }
1051
1052 /* 7.2 Handle boundary conditions of index.*/
1053 for (i = 0; i < rf; i++) {
1054 if (ofdm_index[i] > OFDM_TABLE_SIZE-1)
1055 ofdm_index[i] = OFDM_TABLE_SIZE-1;
1056 else if (rtldm->ofdm_index[i] < ofdm_min_index)
1057 ofdm_index[i] = ofdm_min_index;
1058 }
1059
1060 if (cck_index > CCK_TABLE_SIZE - 1)
1061 cck_index = CCK_TABLE_SIZE - 1;
1062 else if (cck_index < 0)
1063 cck_index = 0;
1064
1065 /*7.3Configure the Swing Table to adjust Tx Power.*/
1066 if (rtlpriv->dm.txpower_track_control) {
1067 rtldm->done_txpower = true;
1068 rtldm->swing_idx_ofdm[RF90_PATH_A] =
1069 (u8)ofdm_index[RF90_PATH_A];
1070 if (is2t)
1071 rtldm->swing_idx_ofdm[RF90_PATH_B] =
1072 (u8)ofdm_index[RF90_PATH_B];
1073 rtldm->swing_idx_cck = cck_index;
1074 if (rtldm->swing_idx_ofdm_cur !=
1075 rtldm->swing_idx_ofdm[0]) {
1076 rtldm->swing_idx_ofdm_cur =
1077 rtldm->swing_idx_ofdm[0];
1078 rtldm->swing_flag_ofdm = true;
1079 }
1080
1081 if (rtldm->swing_idx_cck != rtldm->swing_idx_cck) {
1082 rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;
1083 rtldm->swing_flag_cck = true;
1084 }
1085
1086 rtl88e_chk_tx_track(hw, TXAGC, 0, 0);
1087
1088 if (is2t)
1089 rtl88e_chk_tx_track(hw, BBSWING,
1090 RF90_PATH_B,
1091 index_for_channel);
1092 }
1093 }
1094
1095 if (delta_iqk >= 8) {
1096 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1097 rtl88e_phy_iq_calibrate(hw, false);
1098 }
1099
1100 if (rtldm->txpower_track_control)
1101 rtldm->thermalvalue = thermalvalue;
1102 rtldm->txpowercount = 0;
1103 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
1104}
1105
1106static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw *hw)
1107{
1108 struct rtl_priv *rtlpriv = rtl_priv(hw);
1109
1110 rtlpriv->dm.txpower_tracking = true;
1111 rtlpriv->dm.txpower_trackinginit = false;
1112 rtlpriv->dm.txpowercount = 0;
1113 rtlpriv->dm.txpower_track_control = true;
1114
1115 rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] = 12;
1116 rtlpriv->dm.swing_idx_ofdm_cur = 12;
1117 rtlpriv->dm.swing_flag_ofdm = false;
1118 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1119 " rtlpriv->dm.txpower_tracking = %d\n",
1120 rtlpriv->dm.txpower_tracking);
1121}
1122
1123void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1124{
1125 struct rtl_priv *rtlpriv = rtl_priv(hw);
1126 static u8 tm_trigger;
1127
1128 if (!rtlpriv->dm.txpower_tracking)
1129 return;
1130
1131 if (!tm_trigger) {
1132 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17)|BIT(16),
1133 0x03);
1134 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1135 "Trigger 88E Thermal Meter!!\n");
1136 tm_trigger = 1;
1137 return;
1138 } else {
1139 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1140 "Schedule TxPowerTracking !!\n");
1141 rtl88e_dm_txpower_tracking_callback_thermalmeter(hw);
1142 tm_trigger = 0;
1143 }
1144}
1145
1146void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1147{
1148 struct rtl_priv *rtlpriv = rtl_priv(hw);
1149 struct rate_adaptive *p_ra = &(rtlpriv->ra);
1150
1151 p_ra->ratr_state = DM_RATR_STA_INIT;
1152 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
1153
1154 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1155 rtlpriv->dm.useramask = true;
1156 else
1157 rtlpriv->dm.useramask = false;
1158}
1159
1160static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
1161{
1162 struct rtl_priv *rtlpriv = rtl_priv(hw);
1163 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1164 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1165 struct rate_adaptive *p_ra = &(rtlpriv->ra);
1166 struct ieee80211_sta *sta = NULL;
1167 u32 low_rssi, hi_rssi;
1168
1169 if (is_hal_stop(rtlhal)) {
1170 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1171 "driver is going to unload\n");
1172 return;
1173 }
1174
1175 if (!rtlpriv->dm.useramask) {
1176 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1177 "driver does not control rate adaptive mask\n");
1178 return;
1179 }
1180
1181 if (mac->link_state == MAC80211_LINKED &&
1182 mac->opmode == NL80211_IFTYPE_STATION) {
1183 switch (p_ra->pre_ratr_state) {
1184 case DM_RATR_STA_HIGH:
1185 hi_rssi = 50;
1186 low_rssi = 20;
1187 break;
1188 case DM_RATR_STA_MIDDLE:
1189 hi_rssi = 55;
1190 low_rssi = 20;
1191 break;
1192 case DM_RATR_STA_LOW:
1193 hi_rssi = 50;
1194 low_rssi = 25;
1195 break;
1196 default:
1197 hi_rssi = 50;
1198 low_rssi = 20;
1199 break;
1200 }
1201
1202 if (rtlpriv->dm.undec_sm_pwdb > (long)hi_rssi)
1203 p_ra->ratr_state = DM_RATR_STA_HIGH;
1204 else if (rtlpriv->dm.undec_sm_pwdb > (long)low_rssi)
1205 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
1206 else
1207 p_ra->ratr_state = DM_RATR_STA_LOW;
1208
1209 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
1210 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1211 "RSSI = %ld\n",
1212 rtlpriv->dm.undec_sm_pwdb);
1213 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1214 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
1215 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1216 "PreState = %d, CurState = %d\n",
1217 p_ra->pre_ratr_state, p_ra->ratr_state);
1218
1219 rcu_read_lock();
1220 sta = rtl_find_sta(hw, mac->bssid);
1221 if (sta)
1222 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1223 p_ra->ratr_state);
1224 rcu_read_unlock();
1225
1226 p_ra->pre_ratr_state = p_ra->ratr_state;
1227 }
1228 }
1229}
1230
1231static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1232{
1233 struct rtl_priv *rtlpriv = rtl_priv(hw);
1234 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1235
1236 dm_pstable->pre_ccastate = CCA_MAX;
1237 dm_pstable->cur_ccasate = CCA_MAX;
1238 dm_pstable->pre_rfstate = RF_MAX;
1239 dm_pstable->cur_rfstate = RF_MAX;
1240 dm_pstable->rssi_val_min = 0;
1241}
1242
1243static void rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw *hw, u8 ant)
1244{
1245 struct rtl_priv *rtlpriv = rtl_priv(hw);
1246 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1247 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1248 struct fast_ant_training *fat_tbl = &(rtldm->fat_table);
1249 u32 def_ant, opt_ant;
1250
1251 if (fat_tbl->rx_idle_ant != ant) {
1252 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1253 "need to update rx idle ant\n");
1254 if (ant == MAIN_ANT) {
1255 def_ant = (fat_tbl->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1256 MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
1257 opt_ant = (fat_tbl->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1258 AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
1259 } else {
1260 def_ant = (fat_tbl->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1261 AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
1262 opt_ant = (fat_tbl->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1263 MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
1264 }
1265
1266 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
1267 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(5) |
1268 BIT(4) | BIT(3), def_ant);
1269 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(8) |
1270 BIT(7) | BIT(6), opt_ant);
1271 rtl_set_bbreg(hw, DM_REG_ANTSEL_CTRL_11N, BIT(14) |
1272 BIT(13) | BIT(12), def_ant);
1273 rtl_set_bbreg(hw, DM_REG_RESP_TX_11N, BIT(6) | BIT(7),
1274 def_ant);
1275 } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {
1276 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(5) |
1277 BIT(4) | BIT(3), def_ant);
1278 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(8) |
1279 BIT(7) | BIT(6), opt_ant);
1280 }
1281 }
1282 fat_tbl->rx_idle_ant = ant;
1283 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RxIdleAnt %s\n",
1284 ((ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT")));
1285}
1286
1287static void rtl88e_dm_update_tx_ant(struct ieee80211_hw *hw,
1288 u8 ant, u32 mac_id)
1289{
1290 struct rtl_priv *rtlpriv = rtl_priv(hw);
1291 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1292 struct fast_ant_training *fat_tbl = &(rtldm->fat_table);
1293 u8 target_ant;
1294
1295 if (ant == MAIN_ANT)
1296 target_ant = MAIN_ANT_CG_TRX;
1297 else
1298 target_ant = AUX_ANT_CG_TRX;
1299
1300 fat_tbl->antsel_a[mac_id] = target_ant & BIT(0);
1301 fat_tbl->antsel_b[mac_id] = (target_ant & BIT(1)) >> 1;
1302 fat_tbl->antsel_c[mac_id] = (target_ant & BIT(2)) >> 2;
1303 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "txfrominfo target ant %s\n",
1304 ((ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT")));
1305 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "antsel_tr_mux = 3'b%d%d%d\n",
1306 fat_tbl->antsel_c[mac_id],
1307 fat_tbl->antsel_b[mac_id], fat_tbl->antsel_a[mac_id]);
1308}
1309
1310static void rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw *hw)
1311{
1312 u32 value32;
1313 /*MAC Setting*/
1314 value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1315 rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD, value32 |
1316 (BIT(23) | BIT(25)));
1317 /*Pin Setting*/
1318 rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1319 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1320 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 1);
1321 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1322 /*OFDM Setting*/
1323 rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1324 /*CCK Setting*/
1325 rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);
1326 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);
1327 rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);
1328 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);
1329}
1330
1331static void rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw *hw)
1332{
1333 u32 value32;
1334
1335 /*MAC Setting*/
1336 value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1337 rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD, value32 |
1338 (BIT(23) | BIT(25)));
1339 /*Pin Setting*/
1340 rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1341 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1342 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);
1343 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1344 /*OFDM Setting*/
1345 rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1346 /*CCK Setting*/
1347 rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);
1348 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);
1349 /*TX Setting*/
1350 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 0);
1351 rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);
1352 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);
1353}
1354
1355static void rtl88e_dm_fast_training_init(struct ieee80211_hw *hw)
1356{
1357 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1358 struct fast_ant_training *fat_tbl = &(rtldm->fat_table);
1359 u32 ant_combo = 2;
1360 u32 value32, i;
1361
1362 for (i = 0; i < 6; i++) {
1363 fat_tbl->bssid[i] = 0;
1364 fat_tbl->ant_sum[i] = 0;
1365 fat_tbl->ant_cnt[i] = 0;
1366 fat_tbl->ant_ave[i] = 0;
1367 }
1368 fat_tbl->train_idx = 0;
1369 fat_tbl->fat_state = FAT_NORMAL_STATE;
1370
1371 /*MAC Setting*/
1372 value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1373 rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD, value32 | (BIT(23) |
1374 BIT(25)));
1375 value32 = rtl_get_bbreg(hw, DM_REG_ANT_TRAIN_2, MASKDWORD);
1376 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_2, MASKDWORD, value32 | (BIT(16) |
1377 BIT(17)));
1378 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_2, MASKLWORD, 0);
1379 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_1, MASKDWORD, 0);
1380
1381 /*Pin Setting*/
1382 rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1383 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1384 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);
1385 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1386
1387 /*OFDM Setting*/
1388 rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1389 /*antenna mapping table*/
1390 if (ant_combo == 2) {
1391 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE0, 1);
1392 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE1, 2);
1393 } else if (ant_combo == 7) {
1394 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE0, 1);
1395 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE1, 2);
1396 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE2, 2);
1397 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE3, 3);
1398 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING2_11N, MASKBYTE0, 4);
1399 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING2_11N, MASKBYTE1, 5);
1400 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING2_11N, MASKBYTE2, 6);
1401 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING2_11N, MASKBYTE3, 7);
1402 }
1403
1404 /*TX Setting*/
1405 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 1);
1406 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), 0);
1407 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(8) | BIT(7) | BIT(6), 1);
1408 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(2) | BIT(1) | BIT(0),
1409 (ant_combo - 1));
1410
1411 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1412}
1413
1414static void rtl88e_dm_antenna_div_init(struct ieee80211_hw *hw)
1415{
1416 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1417
1418 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1419 rtl88e_dm_rx_hw_antena_div_init(hw);
1420 else if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1421 rtl88e_dm_trx_hw_antenna_div_init(hw);
1422 else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)
1423 rtl88e_dm_fast_training_init(hw);
1424}
1425
1426void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
1427 u8 *pdesc, u32 mac_id)
1428{
1429 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1430 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1431 struct fast_ant_training *fat_tbl = &(rtldm->fat_table);
1432
1433 if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
1434 (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)) {
1435 SET_TX_DESC_ANTSEL_A(pdesc, fat_tbl->antsel_a[mac_id]);
1436 SET_TX_DESC_ANTSEL_B(pdesc, fat_tbl->antsel_b[mac_id]);
1437 SET_TX_DESC_ANTSEL_C(pdesc, fat_tbl->antsel_c[mac_id]);
1438 }
1439}
1440
1441void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw *hw,
1442 u8 antsel_tr_mux, u32 mac_id, u32 rx_pwdb_all)
1443{
1444 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1445 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1446 struct fast_ant_training *fat_tbl = &(rtldm->fat_table);
1447
1448 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
1449 if (antsel_tr_mux == MAIN_ANT_CG_TRX) {
1450 fat_tbl->main_ant_sum[mac_id] += rx_pwdb_all;
1451 fat_tbl->main_ant_cnt[mac_id]++;
1452 } else {
1453 fat_tbl->aux_ant_sum[mac_id] += rx_pwdb_all;
1454 fat_tbl->aux_ant_cnt[mac_id]++;
1455 }
1456 } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {
1457 if (antsel_tr_mux == MAIN_ANT_CGCS_RX) {
1458 fat_tbl->main_ant_sum[mac_id] += rx_pwdb_all;
1459 fat_tbl->main_ant_cnt[mac_id]++;
1460 } else {
1461 fat_tbl->aux_ant_sum[mac_id] += rx_pwdb_all;
1462 fat_tbl->aux_ant_cnt[mac_id]++;
1463 }
1464 }
1465}
1466
1467static void rtl88e_dm_hw_ant_div(struct ieee80211_hw *hw)
1468{
1469 struct rtl_priv *rtlpriv = rtl_priv(hw);
1470 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
1471 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1472 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1473 struct rtl_sta_info *drv_priv;
1474 struct fast_ant_training *fat_tbl = &(rtldm->fat_table);
1475 u32 i, min_rssi = 0xff, ant_div_max_rssi = 0, max_rssi = 0;
1476 u32 local_min_rssi, local_max_rssi;
1477 u32 main_rssi, aux_rssi;
1478 u8 rx_idle_ant = 0, target_ant = 7;
1479
1480 i = 0;
1481 main_rssi = (fat_tbl->main_ant_cnt[i] != 0) ?
1482 (fat_tbl->main_ant_sum[i] /
1483 fat_tbl->main_ant_cnt[i]) : 0;
1484 aux_rssi = (fat_tbl->aux_ant_cnt[i] != 0) ?
1485 (fat_tbl->aux_ant_sum[i] / fat_tbl->aux_ant_cnt[i]) : 0;
1486 target_ant = (main_rssi == aux_rssi) ?
1487 fat_tbl->rx_idle_ant : ((main_rssi >= aux_rssi) ?
1488 MAIN_ANT : AUX_ANT);
1489 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1490 "main_ant_sum %d main_ant_cnt %d\n",
1491 fat_tbl->main_ant_sum[i], fat_tbl->main_ant_cnt[i]);
1492 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1493 "aux_ant_sum %d aux_ant_cnt %d\n",
1494 fat_tbl->aux_ant_sum[i],
1495 fat_tbl->aux_ant_cnt[i]);
1496 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1497 "main_rssi %d aux_rssi%d\n", main_rssi, aux_rssi);
1498 local_max_rssi = (main_rssi > aux_rssi) ? main_rssi : aux_rssi;
1499 if ((local_max_rssi > ant_div_max_rssi) && (local_max_rssi < 40))
1500 ant_div_max_rssi = local_max_rssi;
1501 if (local_max_rssi > max_rssi)
1502 max_rssi = local_max_rssi;
1503
1504 if ((fat_tbl->rx_idle_ant == MAIN_ANT) && (main_rssi == 0))
1505 main_rssi = aux_rssi;
1506 else if ((fat_tbl->rx_idle_ant == AUX_ANT) && (aux_rssi == 0))
1507 aux_rssi = main_rssi;
1508
1509 local_min_rssi = (main_rssi > aux_rssi) ? aux_rssi : main_rssi;
1510 if (local_min_rssi < min_rssi) {
1511 min_rssi = local_min_rssi;
1512 rx_idle_ant = target_ant;
1513 }
1514 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1515 rtl88e_dm_update_tx_ant(hw, target_ant, i);
1516
1517 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1518 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) {
1519 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1520 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1521 i++;
1522 main_rssi = (fat_tbl->main_ant_cnt[i] != 0) ?
1523 (fat_tbl->main_ant_sum[i] /
1524 fat_tbl->main_ant_cnt[i]) : 0;
1525 aux_rssi = (fat_tbl->aux_ant_cnt[i] != 0) ?
1526 (fat_tbl->aux_ant_sum[i] /
1527 fat_tbl->aux_ant_cnt[i]) : 0;
1528 target_ant = (main_rssi == aux_rssi) ?
1529 fat_tbl->rx_idle_ant : ((main_rssi >=
1530 aux_rssi) ? MAIN_ANT : AUX_ANT);
1531
1532
1533 local_max_rssi = max_t(u32, main_rssi, aux_rssi);
1534 if ((local_max_rssi > ant_div_max_rssi) &&
1535 (local_max_rssi < 40))
1536 ant_div_max_rssi = local_max_rssi;
1537 if (local_max_rssi > max_rssi)
1538 max_rssi = local_max_rssi;
1539
1540 if ((fat_tbl->rx_idle_ant == MAIN_ANT) && !main_rssi)
1541 main_rssi = aux_rssi;
1542 else if ((fat_tbl->rx_idle_ant == AUX_ANT) &&
1543 (aux_rssi == 0))
1544 aux_rssi = main_rssi;
1545
1546 local_min_rssi = (main_rssi > aux_rssi) ?
1547 aux_rssi : main_rssi;
1548 if (local_min_rssi < min_rssi) {
1549 min_rssi = local_min_rssi;
1550 rx_idle_ant = target_ant;
1551 }
1552 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1553 rtl88e_dm_update_tx_ant(hw, target_ant, i);
1554 }
1555 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1556 }
1557
1558 for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {
1559 fat_tbl->main_ant_sum[i] = 0;
1560 fat_tbl->aux_ant_sum[i] = 0;
1561 fat_tbl->main_ant_cnt[i] = 0;
1562 fat_tbl->aux_ant_cnt[i] = 0;
1563 }
1564
1565 rtl88e_dm_update_rx_idle_ant(hw, rx_idle_ant);
1566
1567 dm_dig->antdiv_rssi_max = ant_div_max_rssi;
1568 dm_dig->rssi_max = max_rssi;
1569}
1570
1571static void rtl88e_set_next_mac_address_target(struct ieee80211_hw *hw)
1572{
1573 struct rtl_priv *rtlpriv = rtl_priv(hw);
1574 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1575 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1576 struct rtl_sta_info *drv_priv;
1577 struct fast_ant_training *fat_tbl = &(rtldm->fat_table);
1578 u32 value32, i, j = 0;
1579
1580 if (mac->link_state >= MAC80211_LINKED) {
1581 for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {
1582 if ((fat_tbl->train_idx + 1) == ASSOCIATE_ENTRY_NUM)
1583 fat_tbl->train_idx = 0;
1584 else
1585 fat_tbl->train_idx++;
1586
1587 if (fat_tbl->train_idx == 0) {
1588 value32 = (mac->mac_addr[5] << 8) |
1589 mac->mac_addr[4];
1590 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_2,
1591 MASKLWORD, value32);
1592
1593 value32 = (mac->mac_addr[3] << 24) |
1594 (mac->mac_addr[2] << 16) |
1595 (mac->mac_addr[1] << 8) |
1596 mac->mac_addr[0];
1597 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_1,
1598 MASKDWORD, value32);
1599 break;
1600 }
1601
1602 if (rtlpriv->mac80211.opmode !=
1603 NL80211_IFTYPE_STATION) {
1604 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1605 list_for_each_entry(drv_priv,
1606 &rtlpriv->entry_list,
1607 list) {
1608 j++;
1609 if (j != fat_tbl->train_idx)
1610 continue;
1611
1612 value32 = (drv_priv->mac_addr[5] << 8) |
1613 drv_priv->mac_addr[4];
1614 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_2,
1615 MASKLWORD, value32);
1616
1617 value32 = (drv_priv->mac_addr[3]<<24) |
1618 (drv_priv->mac_addr[2]<<16) |
1619 (drv_priv->mac_addr[1]<<8) |
1620 drv_priv->mac_addr[0];
1621 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_1,
1622 MASKDWORD, value32);
1623 break;
1624 }
1625 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1626 /*find entry, break*/
1627 if (j == fat_tbl->train_idx)
1628 break;
1629 }
1630 }
1631 }
1632}
1633
1634static void rtl88e_dm_fast_ant_training(struct ieee80211_hw *hw)
1635{
1636 struct rtl_priv *rtlpriv = rtl_priv(hw);
1637 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1638 struct fast_ant_training *fat_tbl = &(rtldm->fat_table);
1639 u32 i, max_rssi = 0;
1640 u8 target_ant = 2;
1641 bool bpkt_filter_match = false;
1642
1643 if (fat_tbl->fat_state == FAT_TRAINING_STATE) {
1644 for (i = 0; i < 7; i++) {
1645 if (fat_tbl->ant_cnt[i] == 0) {
1646 fat_tbl->ant_ave[i] = 0;
1647 } else {
1648 fat_tbl->ant_ave[i] = fat_tbl->ant_sum[i] /
1649 fat_tbl->ant_cnt[i];
1650 bpkt_filter_match = true;
1651 }
1652
1653 if (fat_tbl->ant_ave[i] > max_rssi) {
1654 max_rssi = fat_tbl->ant_ave[i];
1655 target_ant = (u8) i;
1656 }
1657 }
1658
1659 if (bpkt_filter_match == false) {
1660 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,
1661 BIT(16), 0);
1662 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1663 } else {
1664 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,
1665 BIT(16), 0);
1666 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(8) |
1667 BIT(7) | BIT(6), target_ant);
1668 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 1);
1669
1670 fat_tbl->antsel_a[fat_tbl->train_idx] =
1671 target_ant & BIT(0);
1672 fat_tbl->antsel_b[fat_tbl->train_idx] =
1673 (target_ant & BIT(1)) >> 1;
1674 fat_tbl->antsel_c[fat_tbl->train_idx] =
1675 (target_ant & BIT(2)) >> 2;
1676
1677 if (target_ant == 0)
1678 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1679 }
1680
1681 for (i = 0; i < 7; i++) {
1682 fat_tbl->ant_sum[i] = 0;
1683 fat_tbl->ant_cnt[i] = 0;
1684 }
1685
1686 fat_tbl->fat_state = FAT_NORMAL_STATE;
1687 return;
1688 }
1689
1690 if (fat_tbl->fat_state == FAT_NORMAL_STATE) {
1691 rtl88e_set_next_mac_address_target(hw);
1692
1693 fat_tbl->fat_state = FAT_TRAINING_STATE;
1694 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N, BIT(16), 1);
1695 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1696
1697 mod_timer(&rtlpriv->works.fast_antenna_training_timer,
1698 jiffies + MSECS(RTL_WATCH_DOG_TIME));
1699 }
1700}
1701
1702void rtl88e_dm_fast_antenna_training_callback(unsigned long data)
1703{
1704 struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
1705
1706 rtl88e_dm_fast_ant_training(hw);
1707}
1708
1709static void rtl88e_dm_antenna_diversity(struct ieee80211_hw *hw)
1710{
1711 struct rtl_priv *rtlpriv = rtl_priv(hw);
1712 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1713 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1714 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1715 struct fast_ant_training *fat_tbl = &(rtldm->fat_table);
1716
1717 if (mac->link_state < MAC80211_LINKED) {
1718 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n");
1719 if (fat_tbl->becomelinked == true) {
1720 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
1721 "need to turn off HW AntDiv\n");
1722 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1723 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,
1724 BIT(15), 0);
1725 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1726 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1727 BIT(21), 0);
1728 fat_tbl->becomelinked =
1729 (mac->link_state == MAC80211_LINKED) ? true : false;
1730 }
1731 return;
1732 } else {
1733 if (fat_tbl->becomelinked == false) {
1734 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
1735 "Need to turn on HW AntDiv\n");
1736 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1737 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,
1738 BIT(15), 1);
1739 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1740 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1741 BIT(21), 1);
1742 fat_tbl->becomelinked =
1743 (mac->link_state >= MAC80211_LINKED) ? true : false;
1744 }
1745 }
1746
1747 if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
1748 (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV))
1749 rtl88e_dm_hw_ant_div(hw);
1750 else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)
1751 rtl88e_dm_fast_ant_training(hw);
1752}
1753
1754void rtl88e_dm_init(struct ieee80211_hw *hw)
1755{
1756 struct rtl_priv *rtlpriv = rtl_priv(hw);
1757
1758 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1759 rtl88e_dm_diginit(hw);
1760 rtl88e_dm_init_dynamic_txpower(hw);
1761 rtl88e_dm_init_edca_turbo(hw);
1762 rtl88e_dm_init_rate_adaptive_mask(hw);
1763 rtl88e_dm_init_txpower_tracking(hw);
1764 rtl92c_dm_init_dynamic_bb_powersaving(hw);
1765 rtl88e_dm_antenna_div_init(hw);
1766}
1767
1768void rtl88e_dm_watchdog(struct ieee80211_hw *hw)
1769{
1770 struct rtl_priv *rtlpriv = rtl_priv(hw);
1771 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1772 bool fw_current_inpsmode = false;
1773 bool fw_ps_awake = true;
1774
1775 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1776 (u8 *)(&fw_current_inpsmode));
1777 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1778 (u8 *)(&fw_ps_awake));
1779 if (ppsc->p2p_ps_info.p2p_ps_mode)
1780 fw_ps_awake = false;
1781
1782 if ((ppsc->rfpwr_state == ERFON) &&
1783 ((!fw_current_inpsmode) && fw_ps_awake) &&
1784 (!ppsc->rfchange_inprogress)) {
1785 rtl88e_dm_pwdb_monitor(hw);
1786 rtl88e_dm_dig(hw);
1787 rtl88e_dm_false_alarm_counter_statistics(hw);
1788 rtl92c_dm_dynamic_txpower(hw);
1789 rtl88e_dm_check_txpower_tracking(hw);
1790 rtl88e_dm_refresh_rate_adaptive_mask(hw);
1791 rtl88e_dm_check_edca_turbo(hw);
1792 rtl88e_dm_antenna_diversity(hw);
1793 }
1794}
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.h b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.h
new file mode 100644
index 000000000000..0e07f72ea158
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.h
@@ -0,0 +1,326 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL88E_DM_H__
31#define __RTL88E_DM_H__
32
33#define MAIN_ANT 0
34#define AUX_ANT 1
35#define MAIN_ANT_CG_TRX 1
36#define AUX_ANT_CG_TRX 0
37#define MAIN_ANT_CGCS_RX 0
38#define AUX_ANT_CGCS_RX 1
39
40/*RF REG LIST*/
41#define DM_REG_RF_MODE_11N 0x00
42#define DM_REG_RF_0B_11N 0x0B
43#define DM_REG_CHNBW_11N 0x18
44#define DM_REG_T_METER_11N 0x24
45#define DM_REG_RF_25_11N 0x25
46#define DM_REG_RF_26_11N 0x26
47#define DM_REG_RF_27_11N 0x27
48#define DM_REG_RF_2B_11N 0x2B
49#define DM_REG_RF_2C_11N 0x2C
50#define DM_REG_RXRF_A3_11N 0x3C
51#define DM_REG_T_METER_92D_11N 0x42
52#define DM_REG_T_METER_88E_11N 0x42
53
54/*BB REG LIST*/
55/*PAGE 8 */
56#define DM_REG_BB_CTRL_11N 0x800
57#define DM_REG_RF_PIN_11N 0x804
58#define DM_REG_PSD_CTRL_11N 0x808
59#define DM_REG_TX_ANT_CTRL_11N 0x80C
60#define DM_REG_BB_PWR_SAV5_11N 0x818
61#define DM_REG_CCK_RPT_FORMAT_11N 0x824
62#define DM_REG_RX_DEFAULT_A_11N 0x858
63#define DM_REG_RX_DEFAULT_B_11N 0x85A
64#define DM_REG_BB_PWR_SAV3_11N 0x85C
65#define DM_REG_ANTSEL_CTRL_11N 0x860
66#define DM_REG_RX_ANT_CTRL_11N 0x864
67#define DM_REG_PIN_CTRL_11N 0x870
68#define DM_REG_BB_PWR_SAV1_11N 0x874
69#define DM_REG_ANTSEL_PATH_11N 0x878
70#define DM_REG_BB_3WIRE_11N 0x88C
71#define DM_REG_SC_CNT_11N 0x8C4
72#define DM_REG_PSD_DATA_11N 0x8B4
73/*PAGE 9*/
74#define DM_REG_ANT_MAPPING1_11N 0x914
75#define DM_REG_ANT_MAPPING2_11N 0x918
76/*PAGE A*/
77#define DM_REG_CCK_ANTDIV_PARA1_11N 0xA00
78#define DM_REG_CCK_CCA_11N 0xA0A
79#define DM_REG_CCK_ANTDIV_PARA2_11N 0xA0C
80#define DM_REG_CCK_ANTDIV_PARA3_11N 0xA10
81#define DM_REG_CCK_ANTDIV_PARA4_11N 0xA14
82#define DM_REG_CCK_FILTER_PARA1_11N 0xA22
83#define DM_REG_CCK_FILTER_PARA2_11N 0xA23
84#define DM_REG_CCK_FILTER_PARA3_11N 0xA24
85#define DM_REG_CCK_FILTER_PARA4_11N 0xA25
86#define DM_REG_CCK_FILTER_PARA5_11N 0xA26
87#define DM_REG_CCK_FILTER_PARA6_11N 0xA27
88#define DM_REG_CCK_FILTER_PARA7_11N 0xA28
89#define DM_REG_CCK_FILTER_PARA8_11N 0xA29
90#define DM_REG_CCK_FA_RST_11N 0xA2C
91#define DM_REG_CCK_FA_MSB_11N 0xA58
92#define DM_REG_CCK_FA_LSB_11N 0xA5C
93#define DM_REG_CCK_CCA_CNT_11N 0xA60
94#define DM_REG_BB_PWR_SAV4_11N 0xA74
95/*PAGE B */
96#define DM_REG_LNA_SWITCH_11N 0xB2C
97#define DM_REG_PATH_SWITCH_11N 0xB30
98#define DM_REG_RSSI_CTRL_11N 0xB38
99#define DM_REG_CONFIG_ANTA_11N 0xB68
100#define DM_REG_RSSI_BT_11N 0xB9C
101/*PAGE C */
102#define DM_REG_OFDM_FA_HOLDC_11N 0xC00
103#define DM_REG_RX_PATH_11N 0xC04
104#define DM_REG_TRMUX_11N 0xC08
105#define DM_REG_OFDM_FA_RSTC_11N 0xC0C
106#define DM_REG_RXIQI_MATRIX_11N 0xC14
107#define DM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C
108#define DM_REG_IGI_A_11N 0xC50
109#define DM_REG_ANTDIV_PARA2_11N 0xC54
110#define DM_REG_IGI_B_11N 0xC58
111#define DM_REG_ANTDIV_PARA3_11N 0xC5C
112#define DM_REG_BB_PWR_SAV2_11N 0xC70
113#define DM_REG_RX_OFF_11N 0xC7C
114#define DM_REG_TXIQK_MATRIXA_11N 0xC80
115#define DM_REG_TXIQK_MATRIXB_11N 0xC88
116#define DM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94
117#define DM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C
118#define DM_REG_RXIQK_MATRIX_LSB_11N 0xCA0
119#define DM_REG_ANTDIV_PARA1_11N 0xCA4
120#define DM_REG_OFDM_FA_TYPE1_11N 0xCF0
121/*PAGE D */
122#define DM_REG_OFDM_FA_RSTD_11N 0xD00
123#define DM_REG_OFDM_FA_TYPE2_11N 0xDA0
124#define DM_REG_OFDM_FA_TYPE3_11N 0xDA4
125#define DM_REG_OFDM_FA_TYPE4_11N 0xDA8
126/*PAGE E */
127#define DM_REG_TXAGC_A_6_18_11N 0xE00
128#define DM_REG_TXAGC_A_24_54_11N 0xE04
129#define DM_REG_TXAGC_A_1_MCS32_11N 0xE08
130#define DM_REG_TXAGC_A_MCS0_3_11N 0xE10
131#define DM_REG_TXAGC_A_MCS4_7_11N 0xE14
132#define DM_REG_TXAGC_A_MCS8_11_11N 0xE18
133#define DM_REG_TXAGC_A_MCS12_15_11N 0xE1C
134#define DM_REG_FPGA0_IQK_11N 0xE28
135#define DM_REG_TXIQK_TONE_A_11N 0xE30
136#define DM_REG_RXIQK_TONE_A_11N 0xE34
137#define DM_REG_TXIQK_PI_A_11N 0xE38
138#define DM_REG_RXIQK_PI_A_11N 0xE3C
139#define DM_REG_TXIQK_11N 0xE40
140#define DM_REG_RXIQK_11N 0xE44
141#define DM_REG_IQK_AGC_PTS_11N 0xE48
142#define DM_REG_IQK_AGC_RSP_11N 0xE4C
143#define DM_REG_BLUETOOTH_11N 0xE6C
144#define DM_REG_RX_WAIT_CCA_11N 0xE70
145#define DM_REG_TX_CCK_RFON_11N 0xE74
146#define DM_REG_TX_CCK_BBON_11N 0xE78
147#define DM_REG_OFDM_RFON_11N 0xE7C
148#define DM_REG_OFDM_BBON_11N 0xE80
149#define DM_REG_TX2RX_11N 0xE84
150#define DM_REG_TX2TX_11N 0xE88
151#define DM_REG_RX_CCK_11N 0xE8C
152#define DM_REG_RX_OFDM_11N 0xED0
153#define DM_REG_RX_WAIT_RIFS_11N 0xED4
154#define DM_REG_RX2RX_11N 0xED8
155#define DM_REG_STANDBY_11N 0xEDC
156#define DM_REG_SLEEP_11N 0xEE0
157#define DM_REG_PMPD_ANAEN_11N 0xEEC
158
159
160/*MAC REG LIST*/
161#define DM_REG_BB_RST_11N 0x02
162#define DM_REG_ANTSEL_PIN_11N 0x4C
163#define DM_REG_EARLY_MODE_11N 0x4D0
164#define DM_REG_RSSI_MONITOR_11N 0x4FE
165#define DM_REG_EDCA_VO_11N 0x500
166#define DM_REG_EDCA_VI_11N 0x504
167#define DM_REG_EDCA_BE_11N 0x508
168#define DM_REG_EDCA_BK_11N 0x50C
169#define DM_REG_TXPAUSE_11N 0x522
170#define DM_REG_RESP_TX_11N 0x6D8
171#define DM_REG_ANT_TRAIN_1 0x7b0
172#define DM_REG_ANT_TRAIN_2 0x7b4
173
174/*DIG Related*/
175#define DM_BIT_IGI_11N 0x0000007F
176
177#define HAL_DM_DIG_DISABLE BIT(0)
178#define HAL_DM_HIPWR_DISABLE BIT(1)
179
180#define OFDM_TABLE_LENGTH 43
181#define CCK_TABLE_LENGTH 33
182
183#define OFDM_TABLE_SIZE 43
184#define CCK_TABLE_SIZE 33
185
186#define BW_AUTO_SWITCH_HIGH_LOW 25
187#define BW_AUTO_SWITCH_LOW_HIGH 30
188
189#define DM_DIG_THRESH_HIGH 40
190#define DM_DIG_THRESH_LOW 35
191
192#define DM_FALSEALARM_THRESH_LOW 400
193#define DM_FALSEALARM_THRESH_HIGH 1000
194
195#define DM_DIG_MAX 0x3e
196#define DM_DIG_MIN 0x1e
197
198#define DM_DIG_MAX_AP 0x32
199#define DM_DIG_MIN_AP 0x20
200
201#define DM_DIG_FA_UPPER 0x3e
202#define DM_DIG_FA_LOWER 0x1e
203#define DM_DIG_FA_TH0 0x200
204#define DM_DIG_FA_TH1 0x300
205#define DM_DIG_FA_TH2 0x400
206
207#define DM_DIG_BACKOFF_MAX 12
208#define DM_DIG_BACKOFF_MIN -4
209#define DM_DIG_BACKOFF_DEFAULT 10
210
211#define RXPATHSELECTION_SS_TH_LOW 30
212#define RXPATHSELECTION_DIFF_TH 18
213
214#define DM_RATR_STA_INIT 0
215#define DM_RATR_STA_HIGH 1
216#define DM_RATR_STA_MIDDLE 2
217#define DM_RATR_STA_LOW 3
218
219#define CTS2SELF_THVAL 30
220#define REGC38_TH 20
221
222#define WAIOTTHVAL 25
223
224#define TXHIGHPWRLEVEL_NORMAL 0
225#define TXHIGHPWRLEVEL_LEVEL1 1
226#define TXHIGHPWRLEVEL_LEVEL2 2
227#define TXHIGHPWRLEVEL_BT1 3
228#define TXHIGHPWRLEVEL_BT2 4
229
230#define DM_TYPE_BYFW 0
231#define DM_TYPE_BYDRIVER 1
232
233#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
234#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
235#define TXPWRTRACK_MAX_IDX 6
236
237struct swat_t {
238 u8 failure_cnt;
239 u8 try_flag;
240 u8 stop_trying;
241 long pre_rssi;
242 long trying_threshold;
243 u8 cur_antenna;
244 u8 pre_antenna;
245};
246
247enum FAT_STATE {
248 FAT_NORMAL_STATE = 0,
249 FAT_TRAINING_STATE = 1,
250};
251
252enum tag_dynamic_init_gain_operation_type_definition {
253 DIG_TYPE_THRESH_HIGH = 0,
254 DIG_TYPE_THRESH_LOW = 1,
255 DIG_TYPE_BACKOFF = 2,
256 DIG_TYPE_RX_GAIN_MIN = 3,
257 DIG_TYPE_RX_GAIN_MAX = 4,
258 DIG_TYPE_ENABLE = 5,
259 DIG_TYPE_DISABLE = 6,
260 DIG_OP_TYPE_MAX
261};
262
263enum tag_cck_packet_detection_threshold_type_definition {
264 CCK_PD_STAGE_LOWRSSI = 0,
265 CCK_PD_STAGE_HIGHRSSI = 1,
266 CCK_FA_STAGE_LOW = 2,
267 CCK_FA_STAGE_HIGH = 3,
268 CCK_PD_STAGE_MAX = 4,
269};
270
271enum dm_1r_cca_e {
272 CCA_1R = 0,
273 CCA_2R = 1,
274 CCA_MAX = 2,
275};
276
277enum dm_rf_e {
278 RF_SAVE = 0,
279 RF_NORMAL = 1,
280 RF_MAX = 2,
281};
282
283enum dm_sw_ant_switch_e {
284 ANS_ANTENNA_B = 1,
285 ANS_ANTENNA_A = 2,
286 ANS_ANTENNA_MAX = 3,
287};
288
289enum dm_dig_ext_port_alg_e {
290 DIG_EXT_PORT_STAGE_0 = 0,
291 DIG_EXT_PORT_STAGE_1 = 1,
292 DIG_EXT_PORT_STAGE_2 = 2,
293 DIG_EXT_PORT_STAGE_3 = 3,
294 DIG_EXT_PORT_STAGE_MAX = 4,
295};
296
297enum dm_dig_connect_e {
298 DIG_STA_DISCONNECT = 0,
299 DIG_STA_CONNECT = 1,
300 DIG_STA_BEFORE_CONNECT = 2,
301 DIG_MULTISTA_DISCONNECT = 3,
302 DIG_MULTISTA_CONNECT = 4,
303 DIG_CONNECT_MAX
304};
305
306enum pwr_track_control_method {
307 BBSWING,
308 TXAGC
309};
310
311void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
312 u8 *pdesc, u32 mac_id);
313void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw *hw, u8 antsel_tr_mux,
314 u32 mac_id, u32 rx_pwdb_all);
315void rtl88e_dm_fast_antenna_training_callback(unsigned long data);
316void rtl88e_dm_init(struct ieee80211_hw *hw);
317void rtl88e_dm_watchdog(struct ieee80211_hw *hw);
318void rtl88e_dm_write_dig(struct ieee80211_hw *hw);
319void rtl88e_dm_init_edca_turbo(struct ieee80211_hw *hw);
320void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw);
321void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
322void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw,
323 u8 type, u8 *pdirection,
324 u32 *poutwrite_val);
325
326#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c
new file mode 100644
index 000000000000..57e4cc5833a9
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c
@@ -0,0 +1,830 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../base.h"
33#include "reg.h"
34#include "def.h"
35#include "fw.h"
36
37#include <linux/kmemleak.h>
38
39static void _rtl88e_enable_fw_download(struct ieee80211_hw *hw, bool enable)
40{
41 struct rtl_priv *rtlpriv = rtl_priv(hw);
42 u8 tmp;
43
44 if (enable) {
45 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
46 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
47
48 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
49 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
50
51 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
52 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
53 } else {
54 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
55 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
56
57 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
58 }
59}
60
61static void _rtl88e_fw_block_write(struct ieee80211_hw *hw,
62 const u8 *buffer, u32 size)
63{
64 struct rtl_priv *rtlpriv = rtl_priv(hw);
65 u32 blk_sz = sizeof(u32);
66 u8 *buf_ptr = (u8 *)buffer;
67 u32 *pu4BytePtr = (u32 *)buffer;
68 u32 i, offset, blk_cnt, remain;
69
70 blk_cnt = size / blk_sz;
71 remain = size % blk_sz;
72
73 for (i = 0; i < blk_cnt; i++) {
74 offset = i * blk_sz;
75 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
76 *(pu4BytePtr + i));
77 }
78
79 if (remain) {
80 offset = blk_cnt * blk_sz;
81 buf_ptr += offset;
82 for (i = 0; i < remain; i++) {
83 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
84 offset + i), *(buf_ptr + i));
85 }
86 }
87}
88
89static void _rtl88e_fw_page_write(struct ieee80211_hw *hw,
90 u32 page, const u8 *buffer, u32 size)
91{
92 struct rtl_priv *rtlpriv = rtl_priv(hw);
93 u8 value8;
94 u8 u8page = (u8) (page & 0x07);
95
96 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
97
98 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
99 _rtl88e_fw_block_write(hw, buffer, size);
100}
101
102static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
103{
104 u32 fwlen = *pfwlen;
105 u8 remain = (u8) (fwlen % 4);
106
107 remain = (remain == 0) ? 0 : (4 - remain);
108
109 while (remain > 0) {
110 pfwbuf[fwlen] = 0;
111 fwlen++;
112 remain--;
113 }
114
115 *pfwlen = fwlen;
116}
117
118static void _rtl88e_write_fw(struct ieee80211_hw *hw,
119 enum version_8188e version, u8 *buffer, u32 size)
120{
121 struct rtl_priv *rtlpriv = rtl_priv(hw);
122 u8 *buf_ptr = (u8 *)buffer;
123 u32 page_no, remain;
124 u32 page, offset;
125
126 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
127
128 _rtl88e_fill_dummy(buf_ptr, &size);
129
130 page_no = size / FW_8192C_PAGE_SIZE;
131 remain = size % FW_8192C_PAGE_SIZE;
132
133 if (page_no > 8) {
134 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
135 "Page numbers should not greater then 8\n");
136 }
137
138 for (page = 0; page < page_no; page++) {
139 offset = page * FW_8192C_PAGE_SIZE;
140 _rtl88e_fw_page_write(hw, page, (buf_ptr + offset),
141 FW_8192C_PAGE_SIZE);
142 }
143
144 if (remain) {
145 offset = page_no * FW_8192C_PAGE_SIZE;
146 page = page_no;
147 _rtl88e_fw_page_write(hw, page, (buf_ptr + offset), remain);
148 }
149}
150
151static int _rtl88e_fw_free_to_go(struct ieee80211_hw *hw)
152{
153 struct rtl_priv *rtlpriv = rtl_priv(hw);
154 int err = -EIO;
155 u32 counter = 0;
156 u32 value32;
157
158 do {
159 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
160 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
161 (!(value32 & FWDL_CHKSUM_RPT)));
162
163 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
164 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
165 "chksum report faill ! REG_MCUFWDL:0x%08x .\n",
166 value32);
167 goto exit;
168 }
169
170 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
171 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);
172
173 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
174 value32 |= MCUFWDL_RDY;
175 value32 &= ~WINTINI_RDY;
176 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
177
178 rtl88e_firmware_selfreset(hw);
179 counter = 0;
180
181 do {
182 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
183 if (value32 & WINTINI_RDY) {
184 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
185 "Polling FW ready success!! REG_MCUFWDL:0x%08x.\n",
186 value32);
187 err = 0;
188 goto exit;
189 }
190
191 udelay(FW_8192C_POLLING_DELAY);
192
193 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
194
195 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
196 "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32);
197
198exit:
199 return err;
200}
201
202int rtl88e_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)
203{
204 struct rtl_priv *rtlpriv = rtl_priv(hw);
205 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
206 struct rtl92c_firmware_header *pfwheader;
207 u8 *pfwdata;
208 u32 fwsize;
209 int err;
210 enum version_8188e version = rtlhal->version;
211
212 if (!rtlhal->pfirmware)
213 return 1;
214
215 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
216 pfwdata = (u8 *)rtlhal->pfirmware;
217 fwsize = rtlhal->fwsize;
218 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
219 "normal Firmware SIZE %d\n", fwsize);
220
221 if (IS_FW_HEADER_EXIST(pfwheader)) {
222 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
223 "Firmware Version(%d), Signature(%#x), Size(%d)\n",
224 pfwheader->version, pfwheader->signature,
225 (int)sizeof(struct rtl92c_firmware_header));
226
227 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
228 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
229 }
230
231 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
232 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
233 rtl88e_firmware_selfreset(hw);
234 }
235 _rtl88e_enable_fw_download(hw, true);
236 _rtl88e_write_fw(hw, version, pfwdata, fwsize);
237 _rtl88e_enable_fw_download(hw, false);
238
239 err = _rtl88e_fw_free_to_go(hw);
240
241 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
242 "Firmware is%s ready to run!\n", err ? " not" : "");
243 return 0;
244}
245
246static bool _rtl88e_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
247{
248 struct rtl_priv *rtlpriv = rtl_priv(hw);
249 u8 val_hmetfr;
250
251 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
252 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
253 return true;
254 return false;
255}
256
257static void _rtl88e_fill_h2c_command(struct ieee80211_hw *hw,
258 u8 element_id, u32 cmd_len,
259 u8 *cmd_b)
260{
261 struct rtl_priv *rtlpriv = rtl_priv(hw);
262 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
263 u8 boxnum;
264 u16 box_reg = 0, box_extreg = 0;
265 u8 u1b_tmp;
266 bool isfw_read = false;
267 u8 buf_index = 0;
268 bool write_sucess = false;
269 u8 wait_h2c_limit = 100;
270 u8 wait_writeh2c_limit = 100;
271 u8 boxc[4], boxext[2];
272 u32 h2c_waitcounter = 0;
273 unsigned long flag;
274 u8 idx;
275
276 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
277
278 while (true) {
279 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
280 if (rtlhal->h2c_setinprogress) {
281 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
282 "H2C set in progress! Wait to set..element_id(%d).\n",
283 element_id);
284
285 while (rtlhal->h2c_setinprogress) {
286 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
287 flag);
288 h2c_waitcounter++;
289 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
290 "Wait 100 us (%d times)...\n",
291 h2c_waitcounter);
292 udelay(100);
293
294 if (h2c_waitcounter > 1000)
295 return;
296 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
297 flag);
298 }
299 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
300 } else {
301 rtlhal->h2c_setinprogress = true;
302 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
303 break;
304 }
305 }
306
307 while (!write_sucess) {
308 wait_writeh2c_limit--;
309 if (wait_writeh2c_limit == 0) {
310 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
311 "Write H2C fail because no trigger for FW INT!\n");
312 break;
313 }
314
315 boxnum = rtlhal->last_hmeboxnum;
316 switch (boxnum) {
317 case 0:
318 box_reg = REG_HMEBOX_0;
319 box_extreg = REG_HMEBOX_EXT_0;
320 break;
321 case 1:
322 box_reg = REG_HMEBOX_1;
323 box_extreg = REG_HMEBOX_EXT_1;
324 break;
325 case 2:
326 box_reg = REG_HMEBOX_2;
327 box_extreg = REG_HMEBOX_EXT_2;
328 break;
329 case 3:
330 box_reg = REG_HMEBOX_3;
331 box_extreg = REG_HMEBOX_EXT_3;
332 break;
333 default:
334 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
335 "switch case not processed\n");
336 break;
337 }
338
339 isfw_read = _rtl88e_check_fw_read_last_h2c(hw, boxnum);
340 while (!isfw_read) {
341 wait_h2c_limit--;
342 if (wait_h2c_limit == 0) {
343 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
344 "Wating too long for FW read "
345 "clear HMEBox(%d)!\n", boxnum);
346 break;
347 }
348
349 udelay(10);
350
351 isfw_read = _rtl88e_check_fw_read_last_h2c(hw, boxnum);
352 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
353 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
354 "Wating for FW read clear HMEBox(%d)!!! "
355 "0x130 = %2x\n", boxnum, u1b_tmp);
356 }
357
358 if (!isfw_read) {
359 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
360 "Write H2C register BOX[%d] fail!!!!! "
361 "Fw do not read.\n", boxnum);
362 break;
363 }
364
365 memset(boxc, 0, sizeof(boxc));
366 memset(boxext, 0, sizeof(boxext));
367 boxc[0] = element_id;
368 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
369 "Write element_id box_reg(%4x) = %2x\n",
370 box_reg, element_id);
371
372 switch (cmd_len) {
373 case 1:
374 case 2:
375 case 3:
376 /*boxc[0] &= ~(BIT(7));*/
377 memcpy((u8 *)(boxc) + 1, cmd_b + buf_index, cmd_len);
378
379 for (idx = 0; idx < 4; idx++)
380 rtl_write_byte(rtlpriv, box_reg+idx, boxc[idx]);
381 break;
382 case 4:
383 case 5:
384 case 6:
385 case 7:
386 /*boxc[0] |= (BIT(7));*/
387 memcpy((u8 *)(boxext), cmd_b + buf_index+3, cmd_len-3);
388 memcpy((u8 *)(boxc) + 1, cmd_b + buf_index, 3);
389
390 for (idx = 0; idx < 2; idx++) {
391 rtl_write_byte(rtlpriv, box_extreg + idx,
392 boxext[idx]);
393 }
394
395 for (idx = 0; idx < 4; idx++) {
396 rtl_write_byte(rtlpriv, box_reg + idx,
397 boxc[idx]);
398 }
399 break;
400 default:
401 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
402 "switch case not processed\n");
403 break;
404 }
405
406 write_sucess = true;
407
408 rtlhal->last_hmeboxnum = boxnum + 1;
409 if (rtlhal->last_hmeboxnum == 4)
410 rtlhal->last_hmeboxnum = 0;
411
412 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
413 "pHalData->last_hmeboxnum = %d\n",
414 rtlhal->last_hmeboxnum);
415 }
416
417 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
418 rtlhal->h2c_setinprogress = false;
419 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
420
421 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
422}
423
424void rtl88e_fill_h2c_cmd(struct ieee80211_hw *hw,
425 u8 element_id, u32 cmd_len, u8 *cmd_b)
426{
427 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
428 u32 tmp_cmdbuf[2];
429
430 if (rtlhal->fw_ready == false) {
431 RT_ASSERT(false, "fail H2C cmd - Fw download fail!!!\n");
432 return;
433 }
434
435 memset(tmp_cmdbuf, 0, 8);
436 memcpy(tmp_cmdbuf, cmd_b, cmd_len);
437 _rtl88e_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
438
439 return;
440}
441
442void rtl88e_firmware_selfreset(struct ieee80211_hw *hw)
443{
444 u8 u1b_tmp;
445 struct rtl_priv *rtlpriv = rtl_priv(hw);
446
447 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
448 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2))));
449 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp | BIT(2)));
450 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
451 "8051Reset88E(): 8051 reset success.\n");
452}
453
454void rtl88e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
455{
456 struct rtl_priv *rtlpriv = rtl_priv(hw);
457 u8 u1_h2c_set_pwrmode[H2C_88E_PWEMODE_LENGTH] = { 0 };
458 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
459 u8 power_state = 0;
460
461 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
462 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
463 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, 0);
464 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
465 (rtlpriv->mac80211.p2p) ?
466 ppsc->smart_ps : 1);
467 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
468 ppsc->reg_max_lps_awakeintvl);
469 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
470 if (mode == FW_PS_ACTIVE_MODE)
471 power_state |= FW_PWR_STATE_ACTIVE;
472 else
473 power_state |= FW_PWR_STATE_RF_OFF;
474 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
475
476 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
477 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
478 u1_h2c_set_pwrmode, H2C_88E_PWEMODE_LENGTH);
479 rtl88e_fill_h2c_cmd(hw, H2C_88E_SETPWRMODE, H2C_88E_PWEMODE_LENGTH,
480 u1_h2c_set_pwrmode);
481}
482
483void rtl88e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
484{
485 u8 u1_joinbssrpt_parm[1] = { 0 };
486
487 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
488
489 rtl88e_fill_h2c_cmd(hw, H2C_88E_JOINBSSRPT, 1, u1_joinbssrpt_parm);
490}
491
492void rtl88e_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,
493 u8 ap_offload_enable)
494{
495 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
496 u8 u1_apoffload_parm[H2C_88E_AP_OFFLOAD_LENGTH] = { 0 };
497
498 SET_H2CCMD_AP_OFFLOAD_ON(u1_apoffload_parm, ap_offload_enable);
499 SET_H2CCMD_AP_OFFLOAD_HIDDEN(u1_apoffload_parm, mac->hiddenssid);
500 SET_H2CCMD_AP_OFFLOAD_DENYANY(u1_apoffload_parm, 0);
501
502 rtl88e_fill_h2c_cmd(hw, H2C_88E_AP_OFFLOAD, H2C_88E_AP_OFFLOAD_LENGTH,
503 u1_apoffload_parm);
504}
505
506static bool _rtl88e_cmd_send_packet(struct ieee80211_hw *hw,
507 struct sk_buff *skb)
508{
509 struct rtl_priv *rtlpriv = rtl_priv(hw);
510 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
511 struct rtl8192_tx_ring *ring;
512 struct rtl_tx_desc *pdesc;
513 struct sk_buff *pskb = NULL;
514 unsigned long flags;
515
516 ring = &rtlpci->tx_ring[BEACON_QUEUE];
517
518 pskb = __skb_dequeue(&ring->queue);
519 if (pskb)
520 kfree_skb(pskb);
521
522 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
523
524 pdesc = &ring->desc[0];
525
526 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
527
528 __skb_queue_tail(&ring->queue, skb);
529
530 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
531
532 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
533
534 return true;
535}
536
537#define BEACON_PG 0 /* ->1 */
538#define PSPOLL_PG 2
539#define NULL_PG 3
540#define PROBERSP_PG 4 /* ->5 */
541
542#define TOTAL_RESERVED_PKT_LEN 768
543
544static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
545 /* page 0 beacon */
546 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
547 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
548 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
549 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
551 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
552 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
553 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
554 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
555 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
556 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
560 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562
563 /* page 1 beacon */
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580
581 /* page 2 ps-poll */
582 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
583 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
596 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598
599 /* page 3 null */
600 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
601 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
602 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
614 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616
617 /* page 4 probe_resp */
618 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
619 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
620 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
621 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
622 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
623 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
624 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
625 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
626 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
627 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
628 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
632 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634
635 /* page 5 probe_resp */
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652};
653
654void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
655{
656 struct rtl_priv *rtlpriv = rtl_priv(hw);
657 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
658 struct sk_buff *skb = NULL;
659
660 u32 totalpacketlen;
661 u8 u1RsvdPageLoc[5] = { 0 };
662
663 u8 *beacon;
664 u8 *pspoll;
665 u8 *nullfunc;
666 u8 *probersp;
667 /*---------------------------------------------------------
668 * (1) beacon
669 *---------------------------------------------------------
670 */
671 beacon = &reserved_page_packet[BEACON_PG * 128];
672 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
673 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
674
675 /*-------------------------------------------------------
676 * (2) ps-poll
677 *--------------------------------------------------------
678 */
679 pspoll = &reserved_page_packet[PSPOLL_PG * 128];
680 SET_80211_PS_POLL_AID(pspoll, (mac->assoc_id | 0xc000));
681 SET_80211_PS_POLL_BSSID(pspoll, mac->bssid);
682 SET_80211_PS_POLL_TA(pspoll, mac->mac_addr);
683
684 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
685
686 /*--------------------------------------------------------
687 * (3) null data
688 *---------------------------------------------------------
689 */
690 nullfunc = &reserved_page_packet[NULL_PG * 128];
691 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
692 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
693 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
694
695 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
696
697 /*---------------------------------------------------------
698 * (4) probe response
699 *----------------------------------------------------------
700 */
701 probersp = &reserved_page_packet[PROBERSP_PG * 128];
702 SET_80211_HDR_ADDRESS1(probersp, mac->bssid);
703 SET_80211_HDR_ADDRESS2(probersp, mac->mac_addr);
704 SET_80211_HDR_ADDRESS3(probersp, mac->bssid);
705
706 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
707
708 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
709
710 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
711 "rtl88e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
712 &reserved_page_packet[0], totalpacketlen);
713 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
714 "rtl88e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
715 u1RsvdPageLoc, 3);
716
717 skb = dev_alloc_skb(totalpacketlen);
718 if (!skb)
719 return;
720 kmemleak_not_leak(skb);
721 memcpy(skb_put(skb, totalpacketlen),
722 &reserved_page_packet, totalpacketlen);
723
724 if (_rtl88e_cmd_send_packet(hw, skb)) {
725 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
726 "Set RSVD page location to Fw.\n");
727 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
728 "H2C_RSVDPAGE:\n", u1RsvdPageLoc, 3);
729 rtl88e_fill_h2c_cmd(hw, H2C_88E_RSVDPAGE,
730 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
731 } else
732 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
733 "Set RSVD page location to Fw FAIL!!!!!!.\n");
734}
735
736/*Shoud check FW support p2p or not.*/
737static void rtl88e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
738{
739 u8 u1_ctwindow_period[1] = {ctwindow};
740
741 rtl88e_fill_h2c_cmd(hw, H2C_88E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
742}
743
744void rtl88e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
745{
746 struct rtl_priv *rtlpriv = rtl_priv(hw);
747 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
748 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
749 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
750 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
751 u8 i;
752 u16 ctwindow;
753 u32 start_time, tsf_low;
754
755 switch (p2p_ps_state) {
756 case P2P_PS_DISABLE:
757 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
758 memset(p2p_ps_offload, 0, sizeof(struct p2p_ps_offload_t));
759 break;
760 case P2P_PS_ENABLE:
761 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
762 /* update CTWindow value. */
763 if (p2pinfo->ctwindow > 0) {
764 p2p_ps_offload->ctwindow_en = 1;
765 ctwindow = p2pinfo->ctwindow;
766 rtl88e_set_p2p_ctw_period_cmd(hw, ctwindow);
767 }
768 /* hw only support 2 set of NoA */
769 for (i = 0; i < p2pinfo->noa_num; i++) {
770 /* To control the register setting for which NOA*/
771 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
772 if (i == 0)
773 p2p_ps_offload->noa0_en = 1;
774 else
775 p2p_ps_offload->noa1_en = 1;
776
777 /* config P2P NoA Descriptor Register */
778 rtl_write_dword(rtlpriv, 0x5E0,
779 p2pinfo->noa_duration[i]);
780 rtl_write_dword(rtlpriv, 0x5E4,
781 p2pinfo->noa_interval[i]);
782
783 /*Get Current TSF value */
784 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
785
786 start_time = p2pinfo->noa_start_time[i];
787 if (p2pinfo->noa_count_type[i] != 1) {
788 while (start_time <= (tsf_low + (50 * 1024))) {
789 start_time += p2pinfo->noa_interval[i];
790 if (p2pinfo->noa_count_type[i] != 255)
791 p2pinfo->noa_count_type[i]--;
792 }
793 }
794 rtl_write_dword(rtlpriv, 0x5E8, start_time);
795 rtl_write_dword(rtlpriv, 0x5EC,
796 p2pinfo->noa_count_type[i]);
797 }
798
799 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
800 /* rst p2p circuit */
801 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
802
803 p2p_ps_offload->offload_en = 1;
804
805 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
806 p2p_ps_offload->role = 1;
807 p2p_ps_offload->allstasleep = 0;
808 } else {
809 p2p_ps_offload->role = 0;
810 }
811
812 p2p_ps_offload->discovery = 0;
813 }
814 break;
815 case P2P_PS_SCAN:
816 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
817 p2p_ps_offload->discovery = 1;
818 break;
819 case P2P_PS_SCAN_DONE:
820 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
821 p2p_ps_offload->discovery = 0;
822 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
823 break;
824 default:
825 break;
826 }
827
828 rtl88e_fill_h2c_cmd(hw, H2C_88E_P2P_PS_OFFLOAD, 1,
829 (u8 *)p2p_ps_offload);
830}
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.h b/drivers/net/wireless/rtlwifi/rtl8188ee/fw.h
new file mode 100644
index 000000000000..854a9875cd5f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/fw.h
@@ -0,0 +1,301 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 * Larry Finger <Larry.Finger@lwfinger.net>
26 *
27 *****************************************************************************/
28
29#ifndef __RTL92C__FW__H__
30#define __RTL92C__FW__H__
31
32#define FW_8192C_SIZE 0x8000
33#define FW_8192C_START_ADDRESS 0x1000
34#define FW_8192C_END_ADDRESS 0x5FFF
35#define FW_8192C_PAGE_SIZE 4096
36#define FW_8192C_POLLING_DELAY 5
37#define FW_8192C_POLLING_TIMEOUT_COUNT 3000
38
39#define IS_FW_HEADER_EXIST(_pfwhdr) \
40 ((_pfwhdr->signature&0xFFFF) == 0x88E1)
41#define USE_OLD_WOWLAN_DEBUG_FW 0
42
43#define H2C_88E_RSVDPAGE_LOC_LEN 5
44#define H2C_88E_PWEMODE_LENGTH 5
45#define H2C_88E_JOINBSSRPT_LENGTH 1
46#define H2C_88E_AP_OFFLOAD_LENGTH 3
47#define H2C_88E_WOWLAN_LENGTH 3
48#define H2C_88E_KEEP_ALIVE_CTRL_LENGTH 3
49#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
50#define H2C_88E_REMOTE_WAKE_CTRL_LEN 1
51#else
52#define H2C_88E_REMOTE_WAKE_CTRL_LEN 3
53#endif
54#define H2C_88E_AOAC_GLOBAL_INFO_LEN 2
55#define H2C_88E_AOAC_RSVDPAGE_LOC_LEN 7
56
57/* Fw PS state for RPWM.
58 * BIT[2:0] = HW state
59 * BIT[3] = Protocol PS state, 1: register active state, 0: register sleep state
60 * BIT[4] = sub-state
61 */
62#define FW_PS_GO_ON BIT(0)
63#define FW_PS_TX_NULL BIT(1)
64#define FW_PS_RF_ON BIT(2)
65#define FW_PS_REGISTER_ACTIVE BIT(3)
66
67#define FW_PS_DPS BIT(0)
68#define FW_PS_LCLK (FW_PS_DPS)
69#define FW_PS_RF_OFF BIT(1)
70#define FW_PS_ALL_ON BIT(2)
71#define FW_PS_ST_ACTIVE BIT(3)
72#define FW_PS_ISR_ENABLE BIT(4)
73#define FW_PS_IMR_ENABLE BIT(5)
74
75
76#define FW_PS_ACK BIT(6)
77#define FW_PS_TOGGLE BIT(7)
78
79 /* 88E RPWM value*/
80 /* BIT[0] = 1: 32k, 0: 40M*/
81#define FW_PS_CLOCK_OFF BIT(0) /* 32k*/
82#define FW_PS_CLOCK_ON 0 /*40M*/
83
84#define FW_PS_STATE_MASK (0x0F)
85#define FW_PS_STATE_HW_MASK (0x07)
86/*ISR_ENABLE, IMR_ENABLE, and PS mode should be inherited.*/
87#define FW_PS_STATE_INT_MASK (0x3F)
88
89#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x))
90#define FW_PS_STATE_HW(x) (FW_PS_STATE_HW_MASK & (x))
91#define FW_PS_STATE_INT(x) (FW_PS_STATE_INT_MASK & (x))
92#define FW_PS_ISR_VAL(x) ((x) & 0x70)
93#define FW_PS_IMR_MASK(x) ((x) & 0xDF)
94#define FW_PS_KEEP_IMR(x) ((x) & 0x20)
95
96#define FW_PS_STATE_S0 (FW_PS_DPS)
97#define FW_PS_STATE_S1 (FW_PS_LCLK)
98#define FW_PS_STATE_S2 (FW_PS_RF_OFF)
99#define FW_PS_STATE_S3 (FW_PS_ALL_ON)
100#define FW_PS_STATE_S4 ((FW_PS_ST_ACTIVE) | (FW_PS_ALL_ON))
101
102#define FW_PS_STATE_ALL_ON_88E (FW_PS_CLOCK_ON)
103#define FW_PS_STATE_RF_ON_88E (FW_PS_CLOCK_ON)
104#define FW_PS_STATE_RF_OFF_88E (FW_PS_CLOCK_ON)
105#define FW_PS_STATE_RF_OFF_LOW_PWR_88E (FW_PS_CLOCK_OFF)
106
107#define FW_PS_STATE_ALL_ON_92C (FW_PS_STATE_S4)
108#define FW_PS_STATE_RF_ON_92C (FW_PS_STATE_S3)
109#define FW_PS_STATE_RF_OFF_92C (FW_PS_STATE_S2)
110#define FW_PS_STATE_RF_OFF_LOW_PWR_92C (FW_PS_STATE_S1)
111
112/* For 88E H2C PwrMode Cmd ID 5.*/
113#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
114#define FW_PWR_STATE_RF_OFF 0
115
116#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK)
117#define FW_PS_IS_CLK_ON(x) ((x) & (FW_PS_RF_OFF | FW_PS_ALL_ON))
118#define FW_PS_IS_RF_ON(x) ((x) & (FW_PS_ALL_ON))
119#define FW_PS_IS_ACTIVE(x) ((x) & (FW_PS_ST_ACTIVE))
120#define FW_PS_IS_CPWM_INT(x) ((x) & 0x40)
121
122#define FW_CLR_PS_STATE(x) ((x) = ((x) & (0xF0)))
123
124#define IS_IN_LOW_POWER_STATE_88E(fwpsstate) \
125 (FW_PS_STATE(fwpsstate) == FW_PS_CLOCK_OFF)
126
127#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
128#define FW_PWR_STATE_RF_OFF 0
129
130struct rtl92c_firmware_header {
131 u16 signature;
132 u8 category;
133 u8 function;
134 u16 version;
135 u8 subversion;
136 u8 rsvd1;
137 u8 month;
138 u8 date;
139 u8 hour;
140 u8 minute;
141 u16 ramcodesize;
142 u16 rsvd2;
143 u32 svnindex;
144 u32 rsvd3;
145 u32 rsvd4;
146 u32 rsvd5;
147};
148
149enum rtl8192c_h2c_cmd {
150 H2C_88E_RSVDPAGE = 0,
151 H2C_88E_JOINBSSRPT = 1,
152 H2C_88E_SCAN = 2,
153 H2C_88E_KEEP_ALIVE_CTRL = 3,
154 H2C_88E_DISCONNECT_DECISION = 4,
155#if (USE_OLD_WOWLAN_DEBUG_FW == 1)
156 H2C_88E_WO_WLAN = 5,
157#endif
158 H2C_88E_INIT_OFFLOAD = 6,
159#if (USE_OLD_WOWLAN_DEBUG_FW == 1)
160 H2C_88E_REMOTE_WAKE_CTRL = 7,
161#endif
162 H2C_88E_AP_OFFLOAD = 8,
163 H2C_88E_BCN_RSVDPAGE = 9,
164 H2C_88E_PROBERSP_RSVDPAGE = 10,
165
166 H2C_88E_SETPWRMODE = 0x20,
167 H2C_88E_PS_TUNING_PARA = 0x21,
168 H2C_88E_PS_TUNING_PARA2 = 0x22,
169 H2C_88E_PS_LPS_PARA = 0x23,
170 H2C_88E_P2P_PS_OFFLOAD = 024,
171
172#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
173 H2C_88E_WO_WLAN = 0x80,
174 H2C_88E_REMOTE_WAKE_CTRL = 0x81,
175 H2C_88E_AOAC_GLOBAL_INFO = 0x82,
176 H2C_88E_AOAC_RSVDPAGE = 0x83,
177#endif
178 /* Not defined in new 88E H2C CMD Format */
179 H2C_88E_RA_MASK,
180 H2C_88E_SELECTIVE_SUSPEND_ROF_CMD,
181 H2C_88E_P2P_PS_MODE,
182 H2C_88E_PSD_RESULT,
183 /*Not defined CTW CMD for P2P yet*/
184 H2C_88E_P2P_PS_CTW_CMD,
185 MAX_88E_H2CCMD
186};
187
188#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0))
189
190#define SET_88E_H2CCMD_WOWLAN_FUNC_ENABLE(__cmd, __value) \
191 SET_BITS_TO_LE_1BYTE(__cmd, 0, 1, __value)
192#define SET_88E_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__cmd, __value) \
193 SET_BITS_TO_LE_1BYTE(__cmd, 1, 1, __value)
194#define SET_88E_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__cmd, __value) \
195 SET_BITS_TO_LE_1BYTE(__cmd, 2, 1, __value)
196#define SET_88E_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__cmd, __value) \
197 SET_BITS_TO_LE_1BYTE(__cmd, 3, 1, __value)
198#define SET_88E_H2CCMD_WOWLAN_ALL_PKT_DROP(__cmd, __value) \
199 SET_BITS_TO_LE_1BYTE(__cmd, 4, 1, __value)
200#define SET_88E_H2CCMD_WOWLAN_GPIO_ACTIVE(__cmd, __value) \
201 SET_BITS_TO_LE_1BYTE(__cmd, 5, 1, __value)
202#define SET_88E_H2CCMD_WOWLAN_REKEY_WAKE_UP(__cmd, __value) \
203 SET_BITS_TO_LE_1BYTE(__cmd, 6, 1, __value)
204#define SET_88E_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__cmd, __value) \
205 SET_BITS_TO_LE_1BYTE(__cmd, 7, 1, __value)
206#define SET_88E_H2CCMD_WOWLAN_GPIONUM(__cmd, __value) \
207 SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
208#define SET_88E_H2CCMD_WOWLAN_GPIO_DURATION(__cmd, __value) \
209 SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value)
210
211
212#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
213 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
214#define SET_H2CCMD_PWRMODE_PARM_RLBM(__cmd, __value) \
215 SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 4, __value)
216#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__cmd, __value) \
217 SET_BITS_TO_LE_1BYTE((__cmd)+1, 4, 4, __value)
218#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__cmd, __value) \
219 SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value)
220#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__cmd, __value) \
221 SET_BITS_TO_LE_1BYTE((__cmd)+3, 0, 8, __value)
222#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__cmd, __value) \
223 SET_BITS_TO_LE_1BYTE((__cmd)+4, 0, 8, __value)
224#define GET_88E_H2CCMD_PWRMODE_PARM_MODE(__cmd) \
225 LE_BITS_TO_1BYTE(__cmd, 0, 8)
226
227#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
228 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
229#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
230 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
231#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
232 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
233#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
234 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
235
236/* AP_OFFLOAD */
237#define SET_H2CCMD_AP_OFFLOAD_ON(__cmd, __value) \
238 SET_BITS_TO_LE_1BYTE(__cmd, 0, 8, __value)
239#define SET_H2CCMD_AP_OFFLOAD_HIDDEN(__cmd, __value) \
240 SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
241#define SET_H2CCMD_AP_OFFLOAD_DENYANY(__cmd, __value) \
242 SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value)
243#define SET_H2CCMD_AP_OFFLOAD_WAKEUP_EVT_RPT(__cmd, __value) \
244 SET_BITS_TO_LE_1BYTE((__cmd)+3, 0, 8, __value)
245
246/* Keep Alive Control*/
247#define SET_88E_H2CCMD_KEEP_ALIVE_ENABLE(__cmd, __value) \
248 SET_BITS_TO_LE_1BYTE(__cmd, 0, 1, __value)
249#define SET_88E_H2CCMD_KEEP_ALIVE_ACCPEPT_USER_DEFINED(__cmd, __value) \
250 SET_BITS_TO_LE_1BYTE(__cmd, 1, 1, __value)
251#define SET_88E_H2CCMD_KEEP_ALIVE_PERIOD(__cmd, __value) \
252 SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
253
254/*REMOTE_WAKE_CTRL */
255#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_EN(__cmd, __value) \
256 SET_BITS_TO_LE_1BYTE(__cmd, 0, 1, __value)
257#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
258#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(__cmd, __value) \
259 SET_BITS_TO_LE_1BYTE(__cmd, 1, 1, __value)
260#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(__cmd, __value) \
261 SET_BITS_TO_LE_1BYTE(__cmd, 2, 1, __value)
262#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(__cmd, __value) \
263 SET_BITS_TO_LE_1BYTE(__cmd, 3, 1, __value)
264#else
265#define SET_88E_H2_REM_WAKE_ENC_ALG(__cmd, __value) \
266 SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
267#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_GROUP_ENC_ALG(__cmd, __value) \
268 SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value)
269#endif
270
271/* GTK_OFFLOAD */
272#define SET_88E_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(__cmd, __value) \
273 SET_BITS_TO_LE_1BYTE(__cmd, 0, 8, __value)
274#define SET_88E_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(__cmd, __value) \
275 SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
276
277/* AOAC_RSVDPAGE_LOC */
278#define SET_88E_H2CCMD_AOAC_RSVD_LOC_REM_WAKE_CTRL_INFO(__cmd, __value) \
279 SET_BITS_TO_LE_1BYTE((__cmd), 0, 8, __value)
280#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(__cmd, __value) \
281 SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
282#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(__cmd, __value) \
283 SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value)
284#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(__cmd, __value) \
285 SET_BITS_TO_LE_1BYTE((__cmd)+3, 0, 8, __value)
286#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(__cmd, __value) \
287 SET_BITS_TO_LE_1BYTE((__cmd)+4, 0, 8, __value)
288
289int rtl88e_download_fw(struct ieee80211_hw *hw,
290 bool buse_wake_on_wlan_fw);
291void rtl88e_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
292 u32 cmd_len, u8 *p_cmdbuffer);
293void rtl88e_firmware_selfreset(struct ieee80211_hw *hw);
294void rtl88e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
295void rtl88e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw,
296 u8 mstatus);
297void rtl88e_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw, u8 enable);
298void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
299void rtl88e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
300
301#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
new file mode 100644
index 000000000000..bcff49730a4e
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
@@ -0,0 +1,2530 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../efuse.h"
32#include "../base.h"
33#include "../regd.h"
34#include "../cam.h"
35#include "../ps.h"
36#include "../pci.h"
37#include "reg.h"
38#include "def.h"
39#include "phy.h"
40#include "dm.h"
41#include "fw.h"
42#include "led.h"
43#include "hw.h"
44#include "pwrseqcmd.h"
45#include "pwrseq.h"
46
47#define LLT_CONFIG 5
48
49static void _rtl88ee_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
50 u8 set_bits, u8 clear_bits)
51{
52 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
53 struct rtl_priv *rtlpriv = rtl_priv(hw);
54
55 rtlpci->reg_bcn_ctrl_val |= set_bits;
56 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
57
58 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
59}
60
61static void _rtl88ee_stop_tx_beacon(struct ieee80211_hw *hw)
62{
63 struct rtl_priv *rtlpriv = rtl_priv(hw);
64 u8 tmp1byte;
65
66 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
67 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
68 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
69 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
70 tmp1byte &= ~(BIT(0));
71 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
72}
73
74static void _rtl88ee_resume_tx_beacon(struct ieee80211_hw *hw)
75{
76 struct rtl_priv *rtlpriv = rtl_priv(hw);
77 u8 tmp1byte;
78
79 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
80 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
81 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
82 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
83 tmp1byte |= BIT(0);
84 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
85}
86
87static void _rtl88ee_enable_bcn_sub_func(struct ieee80211_hw *hw)
88{
89 _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(1));
90}
91
92static void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw)
93{
94 struct rtl_priv *rtlpriv = rtl_priv(hw);
95 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
96 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
97
98 while (skb_queue_len(&ring->queue)) {
99 struct rtl_tx_desc *entry = &ring->desc[ring->idx];
100 struct sk_buff *skb = __skb_dequeue(&ring->queue);
101
102 pci_unmap_single(rtlpci->pdev,
103 rtlpriv->cfg->ops->get_desc(
104 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
105 skb->len, PCI_DMA_TODEVICE);
106 kfree_skb(skb);
107 ring->idx = (ring->idx + 1) % ring->entries;
108 }
109}
110
111static void _rtl88ee_disable_bcn_sub_func(struct ieee80211_hw *hw)
112{
113 _rtl88ee_set_bcn_ctrl_reg(hw, BIT(1), 0);
114}
115
116static void _rtl88ee_set_fw_clock_on(struct ieee80211_hw *hw,
117 u8 rpwm_val, bool need_turn_off_ckk)
118{
119 struct rtl_priv *rtlpriv = rtl_priv(hw);
120 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
121 bool support_remote_wake_up;
122 u32 count = 0, isr_regaddr, content;
123 bool schedule_timer = need_turn_off_ckk;
124
125 rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
126 (u8 *)(&support_remote_wake_up));
127 if (!rtlhal->fw_ready)
128 return;
129 if (!rtlpriv->psc.fw_current_inpsmode)
130 return;
131
132 while (1) {
133 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
134 if (rtlhal->fw_clk_change_in_progress) {
135 while (rtlhal->fw_clk_change_in_progress) {
136 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
137 udelay(100);
138 if (++count > 1000)
139 return;
140 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
141 }
142 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
143 } else {
144 rtlhal->fw_clk_change_in_progress = false;
145 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
146 }
147 }
148
149 if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
150 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
151 (u8 *)(&rpwm_val));
152 if (FW_PS_IS_ACK(rpwm_val)) {
153 isr_regaddr = REG_HISR;
154 content = rtl_read_dword(rtlpriv, isr_regaddr);
155 while (!(content & IMR_CPWM) && (count < 500)) {
156 udelay(50);
157 count++;
158 content = rtl_read_dword(rtlpriv, isr_regaddr);
159 }
160
161 if (content & IMR_CPWM) {
162 rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
163 rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_88E;
164 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
165 "Receive CPWM INT!!! Set pHalData->FwPSState = %X\n",
166 rtlhal->fw_ps_state);
167 }
168 }
169
170 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
171 rtlhal->fw_clk_change_in_progress = false;
172 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
173 if (schedule_timer) {
174 mod_timer(&rtlpriv->works.fw_clockoff_timer,
175 jiffies + MSECS(10));
176 }
177 } else {
178 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
179 rtlhal->fw_clk_change_in_progress = false;
180 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
181 }
182}
183
184static void _rtl88ee_set_fw_clock_off(struct ieee80211_hw *hw,
185 u8 rpwm_val)
186{
187 struct rtl_priv *rtlpriv = rtl_priv(hw);
188 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
189 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
190 struct rtl8192_tx_ring *ring;
191 enum rf_pwrstate rtstate;
192 bool schedule_timer = false;
193 u8 queue;
194
195 if (!rtlhal->fw_ready)
196 return;
197 if (!rtlpriv->psc.fw_current_inpsmode)
198 return;
199 if (!rtlhal->allow_sw_to_change_hwclc)
200 return;
201 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
202 if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
203 return;
204
205 for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
206 ring = &rtlpci->tx_ring[queue];
207 if (skb_queue_len(&ring->queue)) {
208 schedule_timer = true;
209 break;
210 }
211 }
212
213 if (schedule_timer) {
214 mod_timer(&rtlpriv->works.fw_clockoff_timer,
215 jiffies + MSECS(10));
216 return;
217 }
218
219 if (FW_PS_STATE(rtlhal->fw_ps_state) !=
220 FW_PS_STATE_RF_OFF_LOW_PWR_88E) {
221 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
222 if (!rtlhal->fw_clk_change_in_progress) {
223 rtlhal->fw_clk_change_in_progress = true;
224 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
225 rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
226 rtl_write_word(rtlpriv, REG_HISR, 0x0100);
227 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
228 (u8 *)(&rpwm_val));
229 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
230 rtlhal->fw_clk_change_in_progress = false;
231 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
232 } else {
233 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
234 mod_timer(&rtlpriv->works.fw_clockoff_timer,
235 jiffies + MSECS(10));
236 }
237 }
238}
239
240static void _rtl88ee_set_fw_ps_rf_on(struct ieee80211_hw *hw)
241{
242 u8 rpwm_val = 0;
243
244 rpwm_val |= (FW_PS_STATE_RF_OFF_88E | FW_PS_ACK);
245 _rtl88ee_set_fw_clock_on(hw, rpwm_val, true);
246}
247
248static void _rtl88ee_set_fw_ps_rf_off_low_power(struct ieee80211_hw *hw)
249{
250 u8 rpwm_val = 0;
251
252 rpwm_val |= FW_PS_STATE_RF_OFF_LOW_PWR_88E;
253 _rtl88ee_set_fw_clock_off(hw, rpwm_val);
254}
255
256void rtl88ee_fw_clk_off_timer_callback(unsigned long data)
257{
258 struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
259
260 _rtl88ee_set_fw_ps_rf_off_low_power(hw);
261}
262
263static void _rtl88ee_fwlps_leave(struct ieee80211_hw *hw)
264{
265 struct rtl_priv *rtlpriv = rtl_priv(hw);
266 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
267 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
268 bool fw_current_inps = false;
269 u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
270
271 if (ppsc->low_power_enable) {
272 rpwm_val = (FW_PS_STATE_ALL_ON_88E|FW_PS_ACK);/* RF on */
273 _rtl88ee_set_fw_clock_on(hw, rpwm_val, false);
274 rtlhal->allow_sw_to_change_hwclc = false;
275 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
276 (u8 *)(&fw_pwrmode));
277 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
278 (u8 *)(&fw_current_inps));
279 } else {
280 rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */
281 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
282 (u8 *)(&rpwm_val));
283 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
284 (u8 *)(&fw_pwrmode));
285 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
286 (u8 *)(&fw_current_inps));
287 }
288}
289
290static void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw)
291{
292 struct rtl_priv *rtlpriv = rtl_priv(hw);
293 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
294 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
295 bool fw_current_inps = true;
296 u8 rpwm_val;
297
298 if (ppsc->low_power_enable) {
299 rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR_88E; /* RF off */
300 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
301 (u8 *)(&fw_current_inps));
302 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
303 (u8 *)(&ppsc->fwctrl_psmode));
304 rtlhal->allow_sw_to_change_hwclc = true;
305 _rtl88ee_set_fw_clock_off(hw, rpwm_val);
306 } else {
307 rpwm_val = FW_PS_STATE_RF_OFF_88E; /* RF off */
308 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
309 (u8 *)(&fw_current_inps));
310 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
311 (u8 *)(&ppsc->fwctrl_psmode));
312 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
313 (u8 *)(&rpwm_val));
314 }
315}
316
317void rtl88ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
318{
319 struct rtl_priv *rtlpriv = rtl_priv(hw);
320 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
321 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
322
323 switch (variable) {
324 case HW_VAR_RCR:
325 *((u32 *)(val)) = rtlpci->receive_config;
326 break;
327 case HW_VAR_RF_STATE:
328 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
329 break;
330 case HW_VAR_FWLPS_RF_ON:{
331 enum rf_pwrstate rfstate;
332 u32 val_rcr;
333
334 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
335 (u8 *)(&rfstate));
336 if (rfstate == ERFOFF) {
337 *((bool *)(val)) = true;
338 } else {
339 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
340 val_rcr &= 0x00070000;
341 if (val_rcr)
342 *((bool *)(val)) = false;
343 else
344 *((bool *)(val)) = true;
345 }
346 break;
347 }
348 case HW_VAR_FW_PSMODE_STATUS:
349 *((bool *)(val)) = ppsc->fw_current_inpsmode;
350 break;
351 case HW_VAR_CORRECT_TSF:{
352 u64 tsf;
353 u32 *ptsf_low = (u32 *)&tsf;
354 u32 *ptsf_high = ((u32 *)&tsf) + 1;
355
356 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
357 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
358
359 *((u64 *)(val)) = tsf;
360 break; }
361 default:
362 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
363 "switch case not process %x\n", variable);
364 break;
365 }
366}
367
368void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
369{
370 struct rtl_priv *rtlpriv = rtl_priv(hw);
371 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
372 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
373 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
374 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
375 u8 idx;
376
377 switch (variable) {
378 case HW_VAR_ETHER_ADDR:
379 for (idx = 0; idx < ETH_ALEN; idx++)
380 rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
381 break;
382 case HW_VAR_BASIC_RATE:{
383 u16 rate_cfg = ((u16 *)val)[0];
384 u8 rate_index = 0;
385 rate_cfg = rate_cfg & 0x15f;
386 rate_cfg |= 0x01;
387 rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
388 rtl_write_byte(rtlpriv, REG_RRSR + 1, (rate_cfg >> 8) & 0xff);
389 while (rate_cfg > 0x1) {
390 rate_cfg = (rate_cfg >> 1);
391 rate_index++;
392 }
393 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
394 break; }
395 case HW_VAR_BSSID:
396 for (idx = 0; idx < ETH_ALEN; idx++)
397 rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
398 break;
399 case HW_VAR_SIFS:
400 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
401 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
402
403 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
404 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
405
406 if (!mac->ht_enable)
407 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
408 else
409 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
410 *((u16 *)val));
411 break;
412 case HW_VAR_SLOT_TIME:{
413 u8 e_aci;
414
415 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
416 "HW_VAR_SLOT_TIME %x\n", val[0]);
417
418 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
419
420 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
421 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
422 (u8 *)(&e_aci));
423 }
424 break; }
425 case HW_VAR_ACK_PREAMBLE:{
426 u8 reg_tmp;
427 u8 short_preamble = (bool) (*(u8 *)val);
428 reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2);
429 if (short_preamble) {
430 reg_tmp |= 0x02;
431 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
432 } else {
433 reg_tmp |= 0xFD;
434 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
435 }
436 break; }
437 case HW_VAR_WPA_CONFIG:
438 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
439 break;
440 case HW_VAR_AMPDU_MIN_SPACE:{
441 u8 min_spacing_to_set;
442 u8 sec_min_space;
443
444 min_spacing_to_set = *((u8 *)val);
445 if (min_spacing_to_set <= 7) {
446 sec_min_space = 0;
447
448 if (min_spacing_to_set < sec_min_space)
449 min_spacing_to_set = sec_min_space;
450
451 mac->min_space_cfg = ((mac->min_space_cfg &
452 0xf8) | min_spacing_to_set);
453
454 *val = min_spacing_to_set;
455
456 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
457 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
458 mac->min_space_cfg);
459
460 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
461 mac->min_space_cfg);
462 }
463 break; }
464 case HW_VAR_SHORTGI_DENSITY:{
465 u8 density_to_set;
466
467 density_to_set = *((u8 *)val);
468 mac->min_space_cfg |= (density_to_set << 3);
469
470 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
471 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
472 mac->min_space_cfg);
473
474 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
475 mac->min_space_cfg);
476 break; }
477 case HW_VAR_AMPDU_FACTOR:{
478 u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 };
479 u8 factor;
480 u8 *reg = NULL;
481 u8 id = 0;
482
483 reg = regtoset_normal;
484
485 factor = *((u8 *)val);
486 if (factor <= 3) {
487 factor = (1 << (factor + 2));
488 if (factor > 0xf)
489 factor = 0xf;
490
491 for (id = 0; id < 4; id++) {
492 if ((reg[id] & 0xf0) > (factor << 4))
493 reg[id] = (reg[id] & 0x0f) |
494 (factor << 4);
495
496 if ((reg[id] & 0x0f) > factor)
497 reg[id] = (reg[id] & 0xf0) | (factor);
498
499 rtl_write_byte(rtlpriv, (REG_AGGLEN_LMT + id),
500 reg[id]);
501 }
502
503 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
504 "Set HW_VAR_AMPDU_FACTOR: %#x\n", factor);
505 }
506 break; }
507 case HW_VAR_AC_PARAM:{
508 u8 e_aci = *((u8 *)val);
509 rtl88e_dm_init_edca_turbo(hw);
510
511 if (rtlpci->acm_method != eAcmWay2_SW)
512 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
513 (u8 *)(&e_aci));
514 break; }
515 case HW_VAR_ACM_CTRL:{
516 u8 e_aci = *((u8 *)val);
517 union aci_aifsn *p_aci_aifsn =
518 (union aci_aifsn *)(&(mac->ac[0].aifs));
519 u8 acm = p_aci_aifsn->f.acm;
520 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
521
522 acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
523
524 if (acm) {
525 switch (e_aci) {
526 case AC0_BE:
527 acm_ctrl |= ACMHW_BEQEN;
528 break;
529 case AC2_VI:
530 acm_ctrl |= ACMHW_VIQEN;
531 break;
532 case AC3_VO:
533 acm_ctrl |= ACMHW_VOQEN;
534 break;
535 default:
536 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
537 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
538 acm);
539 break;
540 }
541 } else {
542 switch (e_aci) {
543 case AC0_BE:
544 acm_ctrl &= (~ACMHW_BEQEN);
545 break;
546 case AC2_VI:
547 acm_ctrl &= (~ACMHW_VIQEN);
548 break;
549 case AC3_VO:
550 acm_ctrl &= (~ACMHW_BEQEN);
551 break;
552 default:
553 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
554 "switch case not process\n");
555 break;
556 }
557 }
558
559 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
560 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
561 acm_ctrl);
562 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
563 break; }
564 case HW_VAR_RCR:
565 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
566 rtlpci->receive_config = ((u32 *)(val))[0];
567 break;
568 case HW_VAR_RETRY_LIMIT:{
569 u8 retry_limit = ((u8 *)(val))[0];
570
571 rtl_write_word(rtlpriv, REG_RL,
572 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
573 retry_limit << RETRY_LIMIT_LONG_SHIFT);
574 break; }
575 case HW_VAR_DUAL_TSF_RST:
576 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
577 break;
578 case HW_VAR_EFUSE_BYTES:
579 rtlefuse->efuse_usedbytes = *((u16 *)val);
580 break;
581 case HW_VAR_EFUSE_USAGE:
582 rtlefuse->efuse_usedpercentage = *((u8 *)val);
583 break;
584 case HW_VAR_IO_CMD:
585 rtl88e_phy_set_io_cmd(hw, (*(enum io_type *)val));
586 break;
587 case HW_VAR_SET_RPWM:{
588 u8 rpwm_val;
589
590 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
591 udelay(1);
592
593 if (rpwm_val & BIT(7)) {
594 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
595 (*(u8 *)val));
596 } else {
597 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
598 ((*(u8 *)val) | BIT(7)));
599 }
600 break; }
601 case HW_VAR_H2C_FW_PWRMODE:
602 rtl88e_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
603 break;
604 case HW_VAR_FW_PSMODE_STATUS:
605 ppsc->fw_current_inpsmode = *((bool *)val);
606 break;
607 case HW_VAR_RESUME_CLK_ON:
608 _rtl88ee_set_fw_ps_rf_on(hw);
609 break;
610 case HW_VAR_FW_LPS_ACTION:{
611 bool enter_fwlps = *((bool *)val);
612
613 if (enter_fwlps)
614 _rtl88ee_fwlps_enter(hw);
615 else
616 _rtl88ee_fwlps_leave(hw);
617 break; }
618 case HW_VAR_H2C_FW_JOINBSSRPT:{
619 u8 mstatus = (*(u8 *)val);
620 u8 tmp, tmp_reg422, uval;
621 u8 count = 0, dlbcn_count = 0;
622 bool recover = false;
623
624 if (mstatus == RT_MEDIA_CONNECT) {
625 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
626
627 tmp = rtl_read_byte(rtlpriv, REG_CR + 1);
628 rtl_write_byte(rtlpriv, REG_CR + 1, (tmp | BIT(0)));
629
630 _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(3));
631 _rtl88ee_set_bcn_ctrl_reg(hw, BIT(4), 0);
632
633 tmp_reg422 = rtl_read_byte(rtlpriv,
634 REG_FWHW_TXQ_CTRL + 2);
635 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
636 tmp_reg422 & (~BIT(6)));
637 if (tmp_reg422 & BIT(6))
638 recover = true;
639
640 do {
641 uval = rtl_read_byte(rtlpriv, REG_TDECTRL+2);
642 rtl_write_byte(rtlpriv, REG_TDECTRL+2,
643 (uval | BIT(0)));
644 _rtl88ee_return_beacon_queue_skb(hw);
645
646 rtl88e_set_fw_rsvdpagepkt(hw, 0);
647 uval = rtl_read_byte(rtlpriv, REG_TDECTRL+2);
648 count = 0;
649 while (!(uval & BIT(0)) && count < 20) {
650 count++;
651 udelay(10);
652 uval = rtl_read_byte(rtlpriv,
653 REG_TDECTRL+2);
654 }
655 dlbcn_count++;
656 } while (!(uval & BIT(0)) && dlbcn_count < 5);
657
658 if (uval & BIT(0))
659 rtl_write_byte(rtlpriv, REG_TDECTRL+2, BIT(0));
660
661 _rtl88ee_set_bcn_ctrl_reg(hw, BIT(3), 0);
662 _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(4));
663
664 if (recover) {
665 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
666 tmp_reg422);
667 }
668 rtl_write_byte(rtlpriv, REG_CR + 1, (tmp & ~(BIT(0))));
669 }
670 rtl88e_set_fw_joinbss_report_cmd(hw, (*(u8 *)val));
671 break; }
672 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
673 rtl88e_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
674 break;
675 case HW_VAR_AID:{
676 u16 u2btmp;
677 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
678 u2btmp &= 0xC000;
679 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp |
680 mac->assoc_id));
681 break; }
682 case HW_VAR_CORRECT_TSF:{
683 u8 btype_ibss = ((u8 *)(val))[0];
684
685 if (btype_ibss == true)
686 _rtl88ee_stop_tx_beacon(hw);
687
688 _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(3));
689
690 rtl_write_dword(rtlpriv, REG_TSFTR,
691 (u32) (mac->tsf & 0xffffffff));
692 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
693 (u32) ((mac->tsf >> 32) & 0xffffffff));
694
695 _rtl88ee_set_bcn_ctrl_reg(hw, BIT(3), 0);
696
697 if (btype_ibss == true)
698 _rtl88ee_resume_tx_beacon(hw);
699 break; }
700 default:
701 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
702 "switch case not process %x\n", variable);
703 break;
704 }
705}
706
707static bool _rtl88ee_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
708{
709 struct rtl_priv *rtlpriv = rtl_priv(hw);
710 bool status = true;
711 long count = 0;
712 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
713 _LLT_OP(_LLT_WRITE_ACCESS);
714
715 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
716
717 do {
718 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
719 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
720 break;
721
722 if (count > POLLING_LLT_THRESHOLD) {
723 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
724 "Failed to polling write LLT done at address %d!\n",
725 address);
726 status = false;
727 break;
728 }
729 } while (++count);
730
731 return status;
732}
733
734static bool _rtl88ee_llt_table_init(struct ieee80211_hw *hw)
735{
736 struct rtl_priv *rtlpriv = rtl_priv(hw);
737 unsigned short i;
738 u8 txpktbuf_bndy;
739 u8 maxpage;
740 bool status;
741
742 maxpage = 0xAF;
743 txpktbuf_bndy = 0xAB;
744
745 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x01);
746 rtl_write_dword(rtlpriv, REG_RQPN, 0x80730d29);
747
748
749 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x25FF0000 | txpktbuf_bndy));
750 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
751
752 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
753 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
754
755 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
756 rtl_write_byte(rtlpriv, REG_PBP, 0x11);
757 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
758
759 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
760 status = _rtl88ee_llt_write(hw, i, i + 1);
761 if (true != status)
762 return status;
763 }
764
765 status = _rtl88ee_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
766 if (true != status)
767 return status;
768
769 for (i = txpktbuf_bndy; i < maxpage; i++) {
770 status = _rtl88ee_llt_write(hw, i, (i + 1));
771 if (true != status)
772 return status;
773 }
774
775 status = _rtl88ee_llt_write(hw, maxpage, txpktbuf_bndy);
776 if (true != status)
777 return status;
778
779 return true;
780}
781
782static void _rtl88ee_gen_refresh_led_state(struct ieee80211_hw *hw)
783{
784 struct rtl_priv *rtlpriv = rtl_priv(hw);
785 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
786 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
787 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
788
789 if (rtlpriv->rtlhal.up_first_time)
790 return;
791
792 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
793 rtl88ee_sw_led_on(hw, pLed0);
794 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
795 rtl88ee_sw_led_on(hw, pLed0);
796 else
797 rtl88ee_sw_led_off(hw, pLed0);
798}
799
800static bool _rtl88ee_init_mac(struct ieee80211_hw *hw)
801{
802 struct rtl_priv *rtlpriv = rtl_priv(hw);
803 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
804 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
805 u8 bytetmp;
806 u16 wordtmp;
807
808 /*Disable XTAL OUTPUT for power saving. YJ, add, 111206. */
809 bytetmp = rtl_read_byte(rtlpriv, REG_XCK_OUT_CTRL) & (~BIT(0));
810 rtl_write_byte(rtlpriv, REG_XCK_OUT_CTRL, bytetmp);
811 /*Auto Power Down to CHIP-off State*/
812 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
813 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
814
815 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
816 /* HW Power on sequence */
817 if (!rtl88_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
818 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
819 Rtl8188E_NIC_ENABLE_FLOW)) {
820 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
821 "init MAC Fail as rtl88_hal_pwrseqcmdparsing\n");
822 return false;
823 }
824
825 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
826 rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
827
828 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+2);
829 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+2, bytetmp|BIT(2));
830
831 bytetmp = rtl_read_byte(rtlpriv, REG_WATCH_DOG+1);
832 rtl_write_byte(rtlpriv, REG_WATCH_DOG+1, bytetmp|BIT(7));
833
834 bytetmp = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL_EXT+1);
835 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL_EXT+1, bytetmp|BIT(1));
836
837 bytetmp = rtl_read_byte(rtlpriv, REG_TX_RPT_CTRL);
838 rtl_write_byte(rtlpriv, REG_TX_RPT_CTRL, bytetmp|BIT(1)|BIT(0));
839 rtl_write_byte(rtlpriv, REG_TX_RPT_CTRL+1, 2);
840 rtl_write_word(rtlpriv, REG_TX_RPT_TIME, 0xcdf0);
841
842 /*Add for wake up online*/
843 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
844
845 rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp|BIT(3));
846 bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG+1);
847 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG+1, (bytetmp & (~BIT(4))));
848 rtl_write_byte(rtlpriv, 0x367, 0x80);
849
850 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
851 rtl_write_byte(rtlpriv, REG_CR+1, 0x06);
852 rtl_write_byte(rtlpriv, REG_CR+2, 0x00);
853
854 if (!rtlhal->mac_func_enable) {
855 if (_rtl88ee_llt_table_init(hw) == false) {
856 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
857 "LLT table init fail\n");
858 return false;
859 }
860 }
861
862
863 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
864 rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
865
866 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
867 wordtmp &= 0xf;
868 wordtmp |= 0xE771;
869 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
870
871 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
872 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xffff);
873 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
874
875 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
876 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
877 DMA_BIT_MASK(32));
878 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
879 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
880 DMA_BIT_MASK(32));
881 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
882 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
883 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
884 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
885 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
886 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
887 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
888 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
889 rtl_write_dword(rtlpriv, REG_HQ_DESA,
890 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
891 DMA_BIT_MASK(32));
892 rtl_write_dword(rtlpriv, REG_RX_DESA,
893 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
894 DMA_BIT_MASK(32));
895
896 /* if we want to support 64 bit DMA, we should set it here,
897 * but at the moment we do not support 64 bit DMA
898 */
899
900 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
901
902 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
903 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+1, 0);/*Enable RX DMA */
904
905 if (rtlhal->earlymode_enable) {/*Early mode enable*/
906 bytetmp = rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL);
907 bytetmp |= 0x1f;
908 rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, bytetmp);
909 rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL+3, 0x81);
910 }
911 _rtl88ee_gen_refresh_led_state(hw);
912 return true;
913}
914
915static void _rtl88ee_hw_configure(struct ieee80211_hw *hw)
916{
917 struct rtl_priv *rtlpriv = rtl_priv(hw);
918 u32 reg_prsr;
919
920 reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
921
922 rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr);
923 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
924}
925
926static void _rtl88ee_enable_aspm_back_door(struct ieee80211_hw *hw)
927{
928 struct rtl_priv *rtlpriv = rtl_priv(hw);
929 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
930 u8 tmp1byte = 0;
931 u32 tmp4Byte = 0, count;
932
933 rtl_write_word(rtlpriv, 0x354, 0x8104);
934 rtl_write_word(rtlpriv, 0x358, 0x24);
935
936 rtl_write_word(rtlpriv, 0x350, 0x70c);
937 rtl_write_byte(rtlpriv, 0x352, 0x2);
938 tmp1byte = rtl_read_byte(rtlpriv, 0x352);
939 count = 0;
940 while (tmp1byte && count < 20) {
941 udelay(10);
942 tmp1byte = rtl_read_byte(rtlpriv, 0x352);
943 count++;
944 }
945 if (0 == tmp1byte) {
946 tmp4Byte = rtl_read_dword(rtlpriv, 0x34c);
947 rtl_write_dword(rtlpriv, 0x348, tmp4Byte|BIT(31));
948 rtl_write_word(rtlpriv, 0x350, 0xf70c);
949 rtl_write_byte(rtlpriv, 0x352, 0x1);
950 }
951
952 tmp1byte = rtl_read_byte(rtlpriv, 0x352);
953 count = 0;
954 while (tmp1byte && count < 20) {
955 udelay(10);
956 tmp1byte = rtl_read_byte(rtlpriv, 0x352);
957 count++;
958 }
959
960 rtl_write_word(rtlpriv, 0x350, 0x718);
961 rtl_write_byte(rtlpriv, 0x352, 0x2);
962 tmp1byte = rtl_read_byte(rtlpriv, 0x352);
963 count = 0;
964 while (tmp1byte && count < 20) {
965 udelay(10);
966 tmp1byte = rtl_read_byte(rtlpriv, 0x352);
967 count++;
968 }
969 if (ppsc->support_backdoor || (0 == tmp1byte)) {
970 tmp4Byte = rtl_read_dword(rtlpriv, 0x34c);
971 rtl_write_dword(rtlpriv, 0x348, tmp4Byte|BIT(11)|BIT(12));
972 rtl_write_word(rtlpriv, 0x350, 0xf718);
973 rtl_write_byte(rtlpriv, 0x352, 0x1);
974 }
975 tmp1byte = rtl_read_byte(rtlpriv, 0x352);
976 count = 0;
977 while (tmp1byte && count < 20) {
978 udelay(10);
979 tmp1byte = rtl_read_byte(rtlpriv, 0x352);
980 count++;
981 }
982}
983
984void rtl88ee_enable_hw_security_config(struct ieee80211_hw *hw)
985{
986 struct rtl_priv *rtlpriv = rtl_priv(hw);
987 u8 sec_reg_value;
988
989 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
990 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
991 rtlpriv->sec.pairwise_enc_algorithm,
992 rtlpriv->sec.group_enc_algorithm);
993
994 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
995 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
996 "not open hw encryption\n");
997 return;
998 }
999 sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
1000
1001 if (rtlpriv->sec.use_defaultkey) {
1002 sec_reg_value |= SCR_TXUSEDK;
1003 sec_reg_value |= SCR_RXUSEDK;
1004 }
1005
1006 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
1007
1008 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
1009
1010 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1011 "The SECR-value %x\n", sec_reg_value);
1012 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
1013}
1014
1015int rtl88ee_hw_init(struct ieee80211_hw *hw)
1016{
1017 struct rtl_priv *rtlpriv = rtl_priv(hw);
1018 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1019 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1020 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1021 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1022 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1023 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1024 bool rtstatus = true;
1025 int err = 0;
1026 u8 tmp_u1b, u1byte;
1027
1028 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Rtl8188EE hw init\n");
1029 rtlpriv->rtlhal.being_init_adapter = true;
1030 rtlpriv->intf_ops->disable_aspm(hw);
1031
1032 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR+1);
1033 u1byte = rtl_read_byte(rtlpriv, REG_CR);
1034 if ((tmp_u1b & BIT(3)) && (u1byte != 0 && u1byte != 0xEA)) {
1035 rtlhal->mac_func_enable = true;
1036 } else {
1037 rtlhal->mac_func_enable = false;
1038 rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_88E;
1039 }
1040
1041 rtstatus = _rtl88ee_init_mac(hw);
1042 if (rtstatus != true) {
1043 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
1044 err = 1;
1045 return err;
1046 }
1047
1048 err = rtl88e_download_fw(hw, false);
1049 if (err) {
1050 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1051 "Failed to download FW. Init HW without FW now..\n");
1052 err = 1;
1053 rtlhal->fw_ready = false;
1054 return err;
1055 } else {
1056 rtlhal->fw_ready = true;
1057 }
1058 /*fw related variable initialize */
1059 rtlhal->last_hmeboxnum = 0;
1060 rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_88E;
1061 rtlhal->fw_clk_change_in_progress = false;
1062 rtlhal->allow_sw_to_change_hwclc = false;
1063 ppsc->fw_current_inpsmode = false;
1064
1065 rtl88e_phy_mac_config(hw);
1066 /* because last function modifies RCR, we update
1067 * rcr var here, or TP will be unstable for receive_config
1068 * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx
1069 * RCR_APP_ICV will cause mac80211 disassoc for cisco 1252
1070 */
1071 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1072 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1073
1074 rtl88e_phy_bb_config(hw);
1075 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
1076 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
1077
1078 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
1079 rtl88e_phy_rf_config(hw);
1080
1081 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1082 RF_CHNLBW, RFREG_OFFSET_MASK);
1083 rtlphy->rfreg_chnlval[0] = rtlphy->rfreg_chnlval[0] & 0xfff00fff;
1084
1085 _rtl88ee_hw_configure(hw);
1086 rtl_cam_reset_all_entry(hw);
1087 rtl88ee_enable_hw_security_config(hw);
1088
1089 rtlhal->mac_func_enable = true;
1090 ppsc->rfpwr_state = ERFON;
1091
1092 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1093 _rtl88ee_enable_aspm_back_door(hw);
1094 rtlpriv->intf_ops->enable_aspm(hw);
1095
1096 if (ppsc->rfpwr_state == ERFON) {
1097 if ((rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) ||
1098 ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) &&
1099 (rtlhal->oem_id == RT_CID_819x_HP))) {
1100 rtl88e_phy_set_rfpath_switch(hw, true);
1101 rtlpriv->dm.fat_table.rx_idle_ant = MAIN_ANT;
1102 } else {
1103 rtl88e_phy_set_rfpath_switch(hw, false);
1104 rtlpriv->dm.fat_table.rx_idle_ant = AUX_ANT;
1105 }
1106 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1107 "rx idle ant %s\n",
1108 (rtlpriv->dm.fat_table.rx_idle_ant == MAIN_ANT) ?
1109 ("MAIN_ANT") : ("AUX_ANT"));
1110
1111 if (rtlphy->iqk_initialized) {
1112 rtl88e_phy_iq_calibrate(hw, true);
1113 } else {
1114 rtl88e_phy_iq_calibrate(hw, false);
1115 rtlphy->iqk_initialized = true;
1116 }
1117 rtl88e_dm_check_txpower_tracking(hw);
1118 rtl88e_phy_lc_calibrate(hw);
1119 }
1120
1121 tmp_u1b = efuse_read_1byte(hw, 0x1FA);
1122 if (!(tmp_u1b & BIT(0))) {
1123 rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
1124 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "PA BIAS path A\n");
1125 }
1126
1127 if (!(tmp_u1b & BIT(4))) {
1128 tmp_u1b = rtl_read_byte(rtlpriv, 0x16);
1129 tmp_u1b &= 0x0F;
1130 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
1131 udelay(10);
1132 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
1133 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "under 1.5V\n");
1134 }
1135 rtl_write_byte(rtlpriv, REG_NAV_CTRL+2, ((30000+127)/128));
1136 rtl88e_dm_init(hw);
1137 rtlpriv->rtlhal.being_init_adapter = false;
1138 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "end of Rtl8188EE hw init %x\n",
1139 err);
1140 return 0;
1141}
1142
1143static enum version_8188e _rtl88ee_read_chip_version(struct ieee80211_hw *hw)
1144{
1145 struct rtl_priv *rtlpriv = rtl_priv(hw);
1146 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1147 enum version_8188e version = VERSION_UNKNOWN;
1148 u32 value32;
1149
1150 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
1151 if (value32 & TRP_VAUX_EN) {
1152 version = (enum version_8188e) VERSION_TEST_CHIP_88E;
1153 } else {
1154 version = NORMAL_CHIP;
1155 version = version | ((value32 & TYPE_ID) ? RF_TYPE_2T2R : 0);
1156 version = version | ((value32 & VENDOR_ID) ?
1157 CHIP_VENDOR_UMC : 0);
1158 }
1159
1160 rtlphy->rf_type = RF_1T1R;
1161 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1162 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
1163 "RF_2T2R" : "RF_1T1R");
1164
1165 return version;
1166}
1167
1168static int _rtl88ee_set_media_status(struct ieee80211_hw *hw,
1169 enum nl80211_iftype type)
1170{
1171 struct rtl_priv *rtlpriv = rtl_priv(hw);
1172 u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
1173 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1174 bt_msr &= 0xfc;
1175
1176 if (type == NL80211_IFTYPE_UNSPECIFIED ||
1177 type == NL80211_IFTYPE_STATION) {
1178 _rtl88ee_stop_tx_beacon(hw);
1179 _rtl88ee_enable_bcn_sub_func(hw);
1180 } else if (type == NL80211_IFTYPE_ADHOC ||
1181 type == NL80211_IFTYPE_AP ||
1182 type == NL80211_IFTYPE_MESH_POINT) {
1183 _rtl88ee_resume_tx_beacon(hw);
1184 _rtl88ee_disable_bcn_sub_func(hw);
1185 } else {
1186 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1187 "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1188 type);
1189 }
1190
1191 switch (type) {
1192 case NL80211_IFTYPE_UNSPECIFIED:
1193 bt_msr |= MSR_NOLINK;
1194 ledaction = LED_CTL_LINK;
1195 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1196 "Set Network type to NO LINK!\n");
1197 break;
1198 case NL80211_IFTYPE_ADHOC:
1199 bt_msr |= MSR_ADHOC;
1200 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1201 "Set Network type to Ad Hoc!\n");
1202 break;
1203 case NL80211_IFTYPE_STATION:
1204 bt_msr |= MSR_INFRA;
1205 ledaction = LED_CTL_LINK;
1206 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1207 "Set Network type to STA!\n");
1208 break;
1209 case NL80211_IFTYPE_AP:
1210 bt_msr |= MSR_AP;
1211 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1212 "Set Network type to AP!\n");
1213 break;
1214 case NL80211_IFTYPE_MESH_POINT:
1215 bt_msr |= MSR_ADHOC;
1216 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1217 "Set Network type to Mesh Point!\n");
1218 break;
1219 default:
1220 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1221 "Network type %d not support!\n", type);
1222 return 1;
1223 }
1224
1225 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1226 rtlpriv->cfg->ops->led_control(hw, ledaction);
1227 if ((bt_msr & 0xfc) == MSR_AP)
1228 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1229 else
1230 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1231 return 0;
1232}
1233
1234void rtl88ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1235{
1236 struct rtl_priv *rtlpriv = rtl_priv(hw);
1237 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1238 u32 reg_rcr = rtlpci->receive_config;
1239
1240 if (rtlpriv->psc.rfpwr_state != ERFON)
1241 return;
1242
1243 if (check_bssid == true) {
1244 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1245 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1246 (u8 *)(&reg_rcr));
1247 _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(4));
1248 } else if (check_bssid == false) {
1249 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1250 _rtl88ee_set_bcn_ctrl_reg(hw, BIT(4), 0);
1251 rtlpriv->cfg->ops->set_hw_reg(hw,
1252 HW_VAR_RCR, (u8 *)(&reg_rcr));
1253 }
1254}
1255
1256int rtl88ee_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
1257{
1258 struct rtl_priv *rtlpriv = rtl_priv(hw);
1259
1260 if (_rtl88ee_set_media_status(hw, type))
1261 return -EOPNOTSUPP;
1262
1263 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1264 if (type != NL80211_IFTYPE_AP &&
1265 type != NL80211_IFTYPE_MESH_POINT)
1266 rtl88ee_set_check_bssid(hw, true);
1267 } else {
1268 rtl88ee_set_check_bssid(hw, false);
1269 }
1270
1271 return 0;
1272}
1273
1274/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
1275void rtl88ee_set_qos(struct ieee80211_hw *hw, int aci)
1276{
1277 struct rtl_priv *rtlpriv = rtl_priv(hw);
1278 rtl88e_dm_init_edca_turbo(hw);
1279 switch (aci) {
1280 case AC1_BK:
1281 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1282 break;
1283 case AC0_BE:
1284 break;
1285 case AC2_VI:
1286 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1287 break;
1288 case AC3_VO:
1289 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1290 break;
1291 default:
1292 RT_ASSERT(false, "invalid aci: %d !\n", aci);
1293 break;
1294 }
1295}
1296
1297void rtl88ee_enable_interrupt(struct ieee80211_hw *hw)
1298{
1299 struct rtl_priv *rtlpriv = rtl_priv(hw);
1300 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1301
1302 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1303 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1304 rtlpci->irq_enabled = true;
1305 /* there are some C2H CMDs have been sent before system interrupt
1306 * is enabled, e.g., C2H, CPWM.
1307 * So we need to clear all C2H events that FW has notified, otherwise
1308 * FW won't schedule any commands anymore.
1309 */
1310 rtl_write_byte(rtlpriv, REG_C2HEVT_CLEAR, 0);
1311 /*enable system interrupt*/
1312 rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1313}
1314
1315void rtl88ee_disable_interrupt(struct ieee80211_hw *hw)
1316{
1317 struct rtl_priv *rtlpriv = rtl_priv(hw);
1318 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1319
1320 rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1321 rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1322 rtlpci->irq_enabled = false;
1323 synchronize_irq(rtlpci->pdev->irq);
1324}
1325
1326static void _rtl88ee_poweroff_adapter(struct ieee80211_hw *hw)
1327{
1328 struct rtl_priv *rtlpriv = rtl_priv(hw);
1329 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1330 u8 u1b_tmp;
1331 u32 count = 0;
1332 rtlhal->mac_func_enable = false;
1333 rtlpriv->intf_ops->enable_aspm(hw);
1334
1335 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "POWER OFF adapter\n");
1336 u1b_tmp = rtl_read_byte(rtlpriv, REG_TX_RPT_CTRL);
1337 rtl_write_byte(rtlpriv, REG_TX_RPT_CTRL, u1b_tmp & (~BIT(1)));
1338
1339 u1b_tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1340 while (!(u1b_tmp & BIT(1)) && (count++ < 100)) {
1341 udelay(10);
1342 u1b_tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1343 count++;
1344 }
1345 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+1, 0xFF);
1346
1347 rtl88_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1348 PWR_INTF_PCI_MSK,
1349 Rtl8188E_NIC_LPS_ENTER_FLOW);
1350
1351 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
1352
1353 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready)
1354 rtl88e_firmware_selfreset(hw);
1355
1356 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
1357 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1358 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1359
1360 u1b_tmp = rtl_read_byte(rtlpriv, REG_32K_CTRL);
1361 rtl_write_byte(rtlpriv, REG_32K_CTRL, (u1b_tmp & (~BIT(0))));
1362
1363 rtl88_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1364 PWR_INTF_PCI_MSK, Rtl8188E_NIC_DISABLE_FLOW);
1365
1366 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
1367 rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp & (~BIT(3))));
1368 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
1369 rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp | BIT(3)));
1370
1371 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E);
1372
1373 u1b_tmp = rtl_read_byte(rtlpriv, GPIO_IN);
1374 rtl_write_byte(rtlpriv, GPIO_OUT, u1b_tmp);
1375 rtl_write_byte(rtlpriv, GPIO_IO_SEL, 0x7F);
1376
1377 u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL);
1378 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL, (u1b_tmp << 4) | u1b_tmp);
1379 u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL+1);
1380 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL+1, u1b_tmp | 0x0F);
1381
1382 rtl_write_dword(rtlpriv, REG_GPIO_IO_SEL_2+2, 0x00080808);
1383}
1384
1385void rtl88ee_card_disable(struct ieee80211_hw *hw)
1386{
1387 struct rtl_priv *rtlpriv = rtl_priv(hw);
1388 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1389 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1390 enum nl80211_iftype opmode;
1391
1392 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RTL8188ee card disable\n");
1393
1394 mac->link_state = MAC80211_NOLINK;
1395 opmode = NL80211_IFTYPE_UNSPECIFIED;
1396
1397 _rtl88ee_set_media_status(hw, opmode);
1398
1399 if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1400 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1401 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1402
1403 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1404 _rtl88ee_poweroff_adapter(hw);
1405
1406 /* after power off we should do iqk again */
1407 rtlpriv->phy.iqk_initialized = false;
1408}
1409
1410void rtl88ee_interrupt_recognized(struct ieee80211_hw *hw,
1411 u32 *p_inta, u32 *p_intb)
1412{
1413 struct rtl_priv *rtlpriv = rtl_priv(hw);
1414 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1415
1416 *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1417 rtl_write_dword(rtlpriv, ISR, *p_inta);
1418
1419 *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1];
1420 rtl_write_dword(rtlpriv, REG_HISRE, *p_intb);
1421}
1422
1423void rtl88ee_set_beacon_related_registers(struct ieee80211_hw *hw)
1424{
1425 struct rtl_priv *rtlpriv = rtl_priv(hw);
1426 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1427 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1428 u16 bcn_interval, atim_window;
1429
1430 bcn_interval = mac->beacon_interval;
1431 atim_window = 2; /*FIX MERGE */
1432 rtl88ee_disable_interrupt(hw);
1433 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1434 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1435 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1436 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1437 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1438 rtl_write_byte(rtlpriv, 0x606, 0x30);
1439 rtlpci->reg_bcn_ctrl_val |= BIT(3);
1440 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
1441 /*rtl88ee_enable_interrupt(hw);*/
1442}
1443
1444void rtl88ee_set_beacon_interval(struct ieee80211_hw *hw)
1445{
1446 struct rtl_priv *rtlpriv = rtl_priv(hw);
1447 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1448 u16 bcn_interval = mac->beacon_interval;
1449
1450 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1451 "beacon_interval:%d\n", bcn_interval);
1452 /*rtl88ee_disable_interrupt(hw);*/
1453 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1454 /*rtl88ee_enable_interrupt(hw);*/
1455}
1456
1457void rtl88ee_update_interrupt_mask(struct ieee80211_hw *hw,
1458 u32 add_msr, u32 rm_msr)
1459{
1460 struct rtl_priv *rtlpriv = rtl_priv(hw);
1461 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1462
1463 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1464 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1465
1466 rtl88ee_disable_interrupt(hw);
1467 if (add_msr)
1468 rtlpci->irq_mask[0] |= add_msr;
1469 if (rm_msr)
1470 rtlpci->irq_mask[0] &= (~rm_msr);
1471 rtl88ee_enable_interrupt(hw);
1472}
1473
1474static inline u8 get_chnl_group(u8 chnl)
1475{
1476 u8 group;
1477
1478 group = chnl / 3;
1479 if (chnl == 14)
1480 group = 5;
1481
1482 return group;
1483}
1484
1485static void set_diff0_2g(struct txpower_info_2g *pwr2g, u8 *hwinfo, u32 path,
1486 u32 i, u32 eadr)
1487{
1488 pwr2g->bw40_diff[path][i] = 0;
1489 if (hwinfo[eadr] == 0xFF) {
1490 pwr2g->bw20_diff[path][i] = 0x02;
1491 } else {
1492 pwr2g->bw20_diff[path][i] = (hwinfo[eadr]&0xf0)>>4;
1493 /*bit sign number to 8 bit sign number*/
1494 if (pwr2g->bw20_diff[path][i] & BIT(3))
1495 pwr2g->bw20_diff[path][i] |= 0xF0;
1496 }
1497
1498 if (hwinfo[eadr] == 0xFF) {
1499 pwr2g->ofdm_diff[path][i] = 0x04;
1500 } else {
1501 pwr2g->ofdm_diff[path][i] = (hwinfo[eadr] & 0x0f);
1502 /*bit sign number to 8 bit sign number*/
1503 if (pwr2g->ofdm_diff[path][i] & BIT(3))
1504 pwr2g->ofdm_diff[path][i] |= 0xF0;
1505 }
1506 pwr2g->cck_diff[path][i] = 0;
1507}
1508
1509static void set_diff0_5g(struct txpower_info_5g *pwr5g, u8 *hwinfo, u32 path,
1510 u32 i, u32 eadr)
1511{
1512 pwr5g->bw40_diff[path][i] = 0;
1513 if (hwinfo[eadr] == 0xFF) {
1514 pwr5g->bw20_diff[path][i] = 0;
1515 } else {
1516 pwr5g->bw20_diff[path][i] = (hwinfo[eadr]&0xf0)>>4;
1517 /*bit sign number to 8 bit sign number*/
1518 if (pwr5g->bw20_diff[path][i] & BIT(3))
1519 pwr5g->bw20_diff[path][i] |= 0xF0;
1520 }
1521
1522 if (hwinfo[eadr] == 0xFF) {
1523 pwr5g->ofdm_diff[path][i] = 0x04;
1524 } else {
1525 pwr5g->ofdm_diff[path][i] = (hwinfo[eadr] & 0x0f);
1526 /*bit sign number to 8 bit sign number*/
1527 if (pwr5g->ofdm_diff[path][i] & BIT(3))
1528 pwr5g->ofdm_diff[path][i] |= 0xF0;
1529 }
1530}
1531
1532static void set_diff1_2g(struct txpower_info_2g *pwr2g, u8 *hwinfo, u32 path,
1533 u32 i, u32 eadr)
1534{
1535 if (hwinfo[eadr] == 0xFF) {
1536 pwr2g->bw40_diff[path][i] = 0xFE;
1537 } else {
1538 pwr2g->bw40_diff[path][i] = (hwinfo[eadr]&0xf0)>>4;
1539 if (pwr2g->bw40_diff[path][i] & BIT(3))
1540 pwr2g->bw40_diff[path][i] |= 0xF0;
1541 }
1542
1543 if (hwinfo[eadr] == 0xFF) {
1544 pwr2g->bw20_diff[path][i] = 0xFE;
1545 } else {
1546 pwr2g->bw20_diff[path][i] = (hwinfo[eadr]&0x0f);
1547 if (pwr2g->bw20_diff[path][i] & BIT(3))
1548 pwr2g->bw20_diff[path][i] |= 0xF0;
1549 }
1550}
1551
1552static void set_diff1_5g(struct txpower_info_5g *pwr5g, u8 *hwinfo, u32 path,
1553 u32 i, u32 eadr)
1554{
1555 if (hwinfo[eadr] == 0xFF) {
1556 pwr5g->bw40_diff[path][i] = 0xFE;
1557 } else {
1558 pwr5g->bw40_diff[path][i] = (hwinfo[eadr]&0xf0)>>4;
1559 if (pwr5g->bw40_diff[path][i] & BIT(3))
1560 pwr5g->bw40_diff[path][i] |= 0xF0;
1561 }
1562
1563 if (hwinfo[eadr] == 0xFF) {
1564 pwr5g->bw20_diff[path][i] = 0xFE;
1565 } else {
1566 pwr5g->bw20_diff[path][i] = (hwinfo[eadr] & 0x0f);
1567 if (pwr5g->bw20_diff[path][i] & BIT(3))
1568 pwr5g->bw20_diff[path][i] |= 0xF0;
1569 }
1570}
1571
1572static void set_diff2_2g(struct txpower_info_2g *pwr2g, u8 *hwinfo, u32 path,
1573 u32 i, u32 eadr)
1574{
1575 if (hwinfo[eadr] == 0xFF) {
1576 pwr2g->ofdm_diff[path][i] = 0xFE;
1577 } else {
1578 pwr2g->ofdm_diff[path][i] = (hwinfo[eadr]&0xf0)>>4;
1579 if (pwr2g->ofdm_diff[path][i] & BIT(3))
1580 pwr2g->ofdm_diff[path][i] |= 0xF0;
1581 }
1582
1583 if (hwinfo[eadr] == 0xFF) {
1584 pwr2g->cck_diff[path][i] = 0xFE;
1585 } else {
1586 pwr2g->cck_diff[path][i] = (hwinfo[eadr]&0x0f);
1587 if (pwr2g->cck_diff[path][i] & BIT(3))
1588 pwr2g->cck_diff[path][i] |= 0xF0;
1589 }
1590}
1591
1592static void _rtl8188e_read_power_value_fromprom(struct ieee80211_hw *hw,
1593 struct txpower_info_2g *pwr2g,
1594 struct txpower_info_5g *pwr5g,
1595 bool autoload_fail,
1596 u8 *hwinfo)
1597{
1598 struct rtl_priv *rtlpriv = rtl_priv(hw);
1599 u32 path, eadr = EEPROM_TX_PWR_INX, i;
1600
1601 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1602 "hal_ReadPowerValueFromPROM88E(): PROMContent[0x%x]= 0x%x\n",
1603 (eadr+1), hwinfo[eadr+1]);
1604 if (0xFF == hwinfo[eadr+1])
1605 autoload_fail = true;
1606
1607 if (autoload_fail) {
1608 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1609 "auto load fail : Use Default value!\n");
1610 for (path = 0; path < MAX_RF_PATH; path++) {
1611 /* 2.4G default value */
1612 for (i = 0; i < MAX_CHNL_GROUP_24G; i++) {
1613 pwr2g->index_cck_base[path][i] = 0x2D;
1614 pwr2g->index_bw40_base[path][i] = 0x2D;
1615 }
1616 for (i = 0; i < MAX_TX_COUNT; i++) {
1617 if (i == 0) {
1618 pwr2g->bw20_diff[path][0] = 0x02;
1619 pwr2g->ofdm_diff[path][0] = 0x04;
1620 } else {
1621 pwr2g->bw20_diff[path][i] = 0xFE;
1622 pwr2g->bw40_diff[path][i] = 0xFE;
1623 pwr2g->cck_diff[path][i] = 0xFE;
1624 pwr2g->ofdm_diff[path][i] = 0xFE;
1625 }
1626 }
1627 }
1628 return;
1629 }
1630
1631 for (path = 0; path < MAX_RF_PATH; path++) {
1632 /*2.4G default value*/
1633 for (i = 0; i < MAX_CHNL_GROUP_24G; i++) {
1634 pwr2g->index_cck_base[path][i] = hwinfo[eadr++];
1635 if (pwr2g->index_cck_base[path][i] == 0xFF)
1636 pwr2g->index_cck_base[path][i] = 0x2D;
1637 }
1638 for (i = 0; i < MAX_CHNL_GROUP_24G-1; i++) {
1639 pwr2g->index_bw40_base[path][i] = hwinfo[eadr++];
1640 if (pwr2g->index_bw40_base[path][i] == 0xFF)
1641 pwr2g->index_bw40_base[path][i] = 0x2D;
1642 }
1643 for (i = 0; i < MAX_TX_COUNT; i++) {
1644 if (i == 0) {
1645 set_diff0_2g(pwr2g, hwinfo, path, i, eadr);
1646 eadr++;
1647 } else {
1648 set_diff1_2g(pwr2g, hwinfo, path, i, eadr);
1649 eadr++;
1650
1651 set_diff2_2g(pwr2g, hwinfo, path, i, eadr);
1652 eadr++;
1653 }
1654 }
1655
1656 /*5G default value*/
1657 for (i = 0; i < MAX_CHNL_GROUP_5G; i++) {
1658 pwr5g->index_bw40_base[path][i] = hwinfo[eadr++];
1659 if (pwr5g->index_bw40_base[path][i] == 0xFF)
1660 pwr5g->index_bw40_base[path][i] = 0xFE;
1661 }
1662
1663 for (i = 0; i < MAX_TX_COUNT; i++) {
1664 if (i == 0) {
1665 set_diff0_5g(pwr5g, hwinfo, path, i, eadr);
1666 eadr++;
1667 } else {
1668 set_diff1_5g(pwr5g, hwinfo, path, i, eadr);
1669 eadr++;
1670 }
1671 }
1672
1673 if (hwinfo[eadr] == 0xFF) {
1674 pwr5g->ofdm_diff[path][1] = 0xFE;
1675 pwr5g->ofdm_diff[path][2] = 0xFE;
1676 } else {
1677 pwr5g->ofdm_diff[path][1] = (hwinfo[eadr] & 0xf0) >> 4;
1678 pwr5g->ofdm_diff[path][2] = (hwinfo[eadr] & 0x0f);
1679 }
1680 eadr++;
1681
1682 if (hwinfo[eadr] == 0xFF)
1683 pwr5g->ofdm_diff[path][3] = 0xFE;
1684 else
1685 pwr5g->ofdm_diff[path][3] = (hwinfo[eadr]&0x0f);
1686 eadr++;
1687
1688 for (i = 1; i < MAX_TX_COUNT; i++) {
1689 if (pwr5g->ofdm_diff[path][i] == 0xFF)
1690 pwr5g->ofdm_diff[path][i] = 0xFE;
1691 else if (pwr5g->ofdm_diff[path][i] & BIT(3))
1692 pwr5g->ofdm_diff[path][i] |= 0xF0;
1693 }
1694 }
1695}
1696
1697static void _rtl88ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1698 bool autoload_fail,
1699 u8 *hwinfo)
1700{
1701 struct rtl_priv *rtlpriv = rtl_priv(hw);
1702 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1703 struct txpower_info_2g pwrinfo24g;
1704 struct txpower_info_5g pwrinfo5g;
1705 u8 rf_path, index;
1706 u8 i;
1707 int jj = EEPROM_RF_BOARD_OPTION_88E;
1708 int kk = EEPROM_THERMAL_METER_88E;
1709
1710 _rtl8188e_read_power_value_fromprom(hw, &pwrinfo24g, &pwrinfo5g,
1711 autoload_fail, hwinfo);
1712
1713 for (rf_path = 0; rf_path < 2; rf_path++) {
1714 for (i = 0; i < 14; i++) {
1715 index = get_chnl_group(i+1);
1716
1717 rtlefuse->txpwrlevel_cck[rf_path][i] =
1718 pwrinfo24g.index_cck_base[rf_path][index];
1719 if (i == 13)
1720 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1721 pwrinfo24g.index_bw40_base[rf_path][4];
1722 else
1723 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1724 pwrinfo24g.index_bw40_base[rf_path][index];
1725 rtlefuse->txpwr_ht20diff[rf_path][i] =
1726 pwrinfo24g.bw20_diff[rf_path][0];
1727 rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
1728 pwrinfo24g.ofdm_diff[rf_path][0];
1729 }
1730
1731 for (i = 0; i < 14; i++) {
1732 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1733 "RF(%d)-Ch(%d) [CCK / HT40_1S ] = "
1734 "[0x%x / 0x%x ]\n", rf_path, i,
1735 rtlefuse->txpwrlevel_cck[rf_path][i],
1736 rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1737 }
1738 }
1739
1740 if (!autoload_fail)
1741 rtlefuse->eeprom_thermalmeter = hwinfo[kk];
1742 else
1743 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
1744
1745 if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
1746 rtlefuse->apk_thermalmeterignore = true;
1747 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
1748 }
1749
1750 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
1751 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1752 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1753
1754 if (!autoload_fail) {
1755 rtlefuse->eeprom_regulatory = hwinfo[jj] & 0x07;/*bit0~2*/
1756 if (hwinfo[jj] == 0xFF)
1757 rtlefuse->eeprom_regulatory = 0;
1758 } else {
1759 rtlefuse->eeprom_regulatory = 0;
1760 }
1761 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1762 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
1763}
1764
1765static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
1766{
1767 struct rtl_priv *rtlpriv = rtl_priv(hw);
1768 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1769 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1770 struct rtl_pci_priv *rppriv = rtl_pcipriv(hw);
1771 u16 i, usvalue;
1772 u8 hwinfo[HWSET_MAX_SIZE];
1773 u16 eeprom_id;
1774 int jj = EEPROM_RF_BOARD_OPTION_88E;
1775 int kk = EEPROM_RF_FEATURE_OPTION_88E;
1776
1777 if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
1778 rtl_efuse_shadow_map_update(hw);
1779
1780 memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
1781 HWSET_MAX_SIZE);
1782 } else if (rtlefuse->epromtype == EEPROM_93C46) {
1783 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1784 "RTL819X Not boot from eeprom, check it !!");
1785 }
1786
1787 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
1788 hwinfo, HWSET_MAX_SIZE);
1789
1790 eeprom_id = *((u16 *)&hwinfo[0]);
1791 if (eeprom_id != RTL8188E_EEPROM_ID) {
1792 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1793 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
1794 rtlefuse->autoload_failflag = true;
1795 } else {
1796 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1797 rtlefuse->autoload_failflag = false;
1798 }
1799
1800 if (rtlefuse->autoload_failflag == true)
1801 return;
1802 /*VID DID SVID SDID*/
1803 rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
1804 rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
1805 rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
1806 rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
1807 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1808 "EEPROMId = 0x%4x\n", eeprom_id);
1809 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1810 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
1811 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1812 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
1813 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1814 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
1815 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1816 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
1817 /*customer ID*/
1818 rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
1819 if (rtlefuse->eeprom_oemid == 0xFF)
1820 rtlefuse->eeprom_oemid = 0;
1821
1822 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1823 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
1824 /*EEPROM version*/
1825 rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
1826 /*mac address*/
1827 for (i = 0; i < 6; i += 2) {
1828 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
1829 *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue;
1830 }
1831
1832 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1833 "dev_addr: %pM\n", rtlefuse->dev_addr);
1834 /*channel plan */
1835 rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
1836 /* set channel paln to world wide 13 */
1837 rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
1838 /*tx power*/
1839 _rtl88ee_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
1840 hwinfo);
1841 rtlefuse->txpwr_fromeprom = true;
1842
1843 rtl8188ee_read_bt_coexist_info_from_hwpg(hw,
1844 rtlefuse->autoload_failflag,
1845 hwinfo);
1846 /*board type*/
1847 rtlefuse->board_type = (((*(u8 *)&hwinfo[jj]) & 0xE0) >> 5);
1848 /*Wake on wlan*/
1849 rtlefuse->wowlan_enable = ((hwinfo[kk] & 0x40) >> 6);
1850 /*parse xtal*/
1851 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_88E];
1852 if (hwinfo[EEPROM_XTAL_88E])
1853 rtlefuse->crystalcap = 0x20;
1854 /*antenna diversity*/
1855 rtlefuse->antenna_div_cfg = (hwinfo[jj] & 0x18) >> 3;
1856 if (hwinfo[jj] == 0xFF)
1857 rtlefuse->antenna_div_cfg = 0;
1858 if (rppriv->bt_coexist.eeprom_bt_coexist != 0 &&
1859 rppriv->bt_coexist.eeprom_bt_ant_num == ANT_X1)
1860 rtlefuse->antenna_div_cfg = 0;
1861
1862 rtlefuse->antenna_div_type = hwinfo[EEPROM_RF_ANTENNA_OPT_88E];
1863 if (rtlefuse->antenna_div_type == 0xFF)
1864 rtlefuse->antenna_div_type = 0x01;
1865 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV ||
1866 rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1867 rtlefuse->antenna_div_cfg = 1;
1868
1869 if (rtlhal->oem_id == RT_CID_DEFAULT) {
1870 switch (rtlefuse->eeprom_oemid) {
1871 case EEPROM_CID_DEFAULT:
1872 if (rtlefuse->eeprom_did == 0x8179) {
1873 if (rtlefuse->eeprom_svid == 0x1025) {
1874 rtlhal->oem_id = RT_CID_819x_Acer;
1875 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
1876 rtlefuse->eeprom_smid == 0x0179) ||
1877 (rtlefuse->eeprom_svid == 0x17AA &&
1878 rtlefuse->eeprom_smid == 0x0179)) {
1879 rtlhal->oem_id = RT_CID_819x_Lenovo;
1880 } else if (rtlefuse->eeprom_svid == 0x103c &&
1881 rtlefuse->eeprom_smid == 0x197d) {
1882 rtlhal->oem_id = RT_CID_819x_HP;
1883 } else {
1884 rtlhal->oem_id = RT_CID_DEFAULT;
1885 }
1886 } else {
1887 rtlhal->oem_id = RT_CID_DEFAULT;
1888 }
1889 break;
1890 case EEPROM_CID_TOSHIBA:
1891 rtlhal->oem_id = RT_CID_TOSHIBA;
1892 break;
1893 case EEPROM_CID_QMI:
1894 rtlhal->oem_id = RT_CID_819x_QMI;
1895 break;
1896 case EEPROM_CID_WHQL:
1897 default:
1898 rtlhal->oem_id = RT_CID_DEFAULT;
1899 break;
1900 }
1901 }
1902}
1903
1904static void _rtl88ee_hal_customized_behavior(struct ieee80211_hw *hw)
1905{
1906 struct rtl_priv *rtlpriv = rtl_priv(hw);
1907 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1908 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1909
1910 pcipriv->ledctl.led_opendrain = true;
1911
1912 switch (rtlhal->oem_id) {
1913 case RT_CID_819x_HP:
1914 pcipriv->ledctl.led_opendrain = true;
1915 break;
1916 case RT_CID_819x_Lenovo:
1917 case RT_CID_DEFAULT:
1918 case RT_CID_TOSHIBA:
1919 case RT_CID_CCX:
1920 case RT_CID_819x_Acer:
1921 case RT_CID_WHQL:
1922 default:
1923 break;
1924 }
1925 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1926 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
1927}
1928
1929void rtl88ee_read_eeprom_info(struct ieee80211_hw *hw)
1930{
1931 struct rtl_priv *rtlpriv = rtl_priv(hw);
1932 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1933 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1934 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1935 u8 tmp_u1b;
1936
1937 rtlhal->version = _rtl88ee_read_chip_version(hw);
1938 if (get_rf_type(rtlphy) == RF_1T1R) {
1939 rtlpriv->dm.rfpath_rxenable[0] = true;
1940 } else {
1941 rtlpriv->dm.rfpath_rxenable[0] = true;
1942 rtlpriv->dm.rfpath_rxenable[1] = true;
1943 }
1944 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
1945 rtlhal->version);
1946 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
1947 if (tmp_u1b & BIT(4)) {
1948 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
1949 rtlefuse->epromtype = EEPROM_93C46;
1950 } else {
1951 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
1952 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
1953 }
1954 if (tmp_u1b & BIT(5)) {
1955 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1956 rtlefuse->autoload_failflag = false;
1957 _rtl88ee_read_adapter_info(hw);
1958 } else {
1959 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
1960 }
1961 _rtl88ee_hal_customized_behavior(hw);
1962}
1963
1964static void rtl88ee_update_hal_rate_table(struct ieee80211_hw *hw,
1965 struct ieee80211_sta *sta)
1966{
1967 struct rtl_priv *rtlpriv = rtl_priv(hw);
1968 struct rtl_pci_priv *rppriv = rtl_pcipriv(hw);
1969 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1970 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1971 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1972 u32 ratr_value;
1973 u8 ratr_index = 0;
1974 u8 nmode = mac->ht_enable;
1975 u8 mimo_ps = IEEE80211_SMPS_OFF;
1976 u16 shortgi_rate;
1977 u32 tmp_ratr_value;
1978 u8 ctx40 = mac->bw_40;
1979 u16 cap = sta->ht_cap.cap;
1980 u8 short40 = (cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0;
1981 u8 short20 = (cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0;
1982 enum wireless_mode wirelessmode = mac->mode;
1983
1984 if (rtlhal->current_bandtype == BAND_ON_5G)
1985 ratr_value = sta->supp_rates[1] << 4;
1986 else
1987 ratr_value = sta->supp_rates[0];
1988 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1989 ratr_value = 0xfff;
1990 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
1991 sta->ht_cap.mcs.rx_mask[0] << 12);
1992 switch (wirelessmode) {
1993 case WIRELESS_MODE_B:
1994 if (ratr_value & 0x0000000c)
1995 ratr_value &= 0x0000000d;
1996 else
1997 ratr_value &= 0x0000000f;
1998 break;
1999 case WIRELESS_MODE_G:
2000 ratr_value &= 0x00000FF5;
2001 break;
2002 case WIRELESS_MODE_N_24G:
2003 case WIRELESS_MODE_N_5G:
2004 nmode = 1;
2005 if (mimo_ps == IEEE80211_SMPS_STATIC) {
2006 ratr_value &= 0x0007F005;
2007 } else {
2008 u32 ratr_mask;
2009
2010 if (get_rf_type(rtlphy) == RF_1T2R ||
2011 get_rf_type(rtlphy) == RF_1T1R)
2012 ratr_mask = 0x000ff005;
2013 else
2014 ratr_mask = 0x0f0ff005;
2015
2016 ratr_value &= ratr_mask;
2017 }
2018 break;
2019 default:
2020 if (rtlphy->rf_type == RF_1T2R)
2021 ratr_value &= 0x000ff0ff;
2022 else
2023 ratr_value &= 0x0f0ff0ff;
2024
2025 break;
2026 }
2027
2028 if ((rppriv->bt_coexist.bt_coexistence) &&
2029 (rppriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) &&
2030 (rppriv->bt_coexist.bt_cur_state) &&
2031 (rppriv->bt_coexist.bt_ant_isolation) &&
2032 ((rppriv->bt_coexist.bt_service == BT_SCO) ||
2033 (rppriv->bt_coexist.bt_service == BT_BUSY)))
2034 ratr_value &= 0x0fffcfc0;
2035 else
2036 ratr_value &= 0x0FFFFFFF;
2037
2038 if (nmode && ((ctx40 && short40) ||
2039 (!ctx40 && short20))) {
2040 ratr_value |= 0x10000000;
2041 tmp_ratr_value = (ratr_value >> 12);
2042
2043 for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
2044 if ((1 << shortgi_rate) & tmp_ratr_value)
2045 break;
2046 }
2047
2048 shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
2049 (shortgi_rate << 4) | (shortgi_rate);
2050 }
2051
2052 rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
2053
2054 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2055 "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0));
2056}
2057
2058static void rtl88ee_update_hal_rate_mask(struct ieee80211_hw *hw,
2059 struct ieee80211_sta *sta, u8 rssi)
2060{
2061 struct rtl_priv *rtlpriv = rtl_priv(hw);
2062 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2063 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2064 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2065 struct rtl_sta_info *sta_entry = NULL;
2066 u32 ratr_bitmap;
2067 u8 ratr_index;
2068 u16 cap = sta->ht_cap.cap;
2069 u8 ctx40 = (cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
2070 u8 short40 = (cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0;
2071 u8 short20 = (cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0;
2072 enum wireless_mode wirelessmode = 0;
2073 bool shortgi = false;
2074 u8 rate_mask[5];
2075 u8 macid = 0;
2076 u8 mimo_ps = IEEE80211_SMPS_OFF;
2077
2078 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2079 wirelessmode = sta_entry->wireless_mode;
2080 if (mac->opmode == NL80211_IFTYPE_STATION ||
2081 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2082 ctx40 = mac->bw_40;
2083 else if (mac->opmode == NL80211_IFTYPE_AP ||
2084 mac->opmode == NL80211_IFTYPE_ADHOC)
2085 macid = sta->aid + 1;
2086
2087 if (rtlhal->current_bandtype == BAND_ON_5G)
2088 ratr_bitmap = sta->supp_rates[1] << 4;
2089 else
2090 ratr_bitmap = sta->supp_rates[0];
2091 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2092 ratr_bitmap = 0xfff;
2093 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2094 sta->ht_cap.mcs.rx_mask[0] << 12);
2095 switch (wirelessmode) {
2096 case WIRELESS_MODE_B:
2097 ratr_index = RATR_INX_WIRELESS_B;
2098 if (ratr_bitmap & 0x0000000c)
2099 ratr_bitmap &= 0x0000000d;
2100 else
2101 ratr_bitmap &= 0x0000000f;
2102 break;
2103 case WIRELESS_MODE_G:
2104 ratr_index = RATR_INX_WIRELESS_GB;
2105
2106 if (rssi == 1)
2107 ratr_bitmap &= 0x00000f00;
2108 else if (rssi == 2)
2109 ratr_bitmap &= 0x00000ff0;
2110 else
2111 ratr_bitmap &= 0x00000ff5;
2112 break;
2113 case WIRELESS_MODE_A:
2114 ratr_index = RATR_INX_WIRELESS_A;
2115 ratr_bitmap &= 0x00000ff0;
2116 break;
2117 case WIRELESS_MODE_N_24G:
2118 case WIRELESS_MODE_N_5G:
2119 ratr_index = RATR_INX_WIRELESS_NGB;
2120
2121 if (mimo_ps == IEEE80211_SMPS_STATIC) {
2122 if (rssi == 1)
2123 ratr_bitmap &= 0x00070000;
2124 else if (rssi == 2)
2125 ratr_bitmap &= 0x0007f000;
2126 else
2127 ratr_bitmap &= 0x0007f005;
2128 } else {
2129 if (rtlphy->rf_type == RF_1T2R ||
2130 rtlphy->rf_type == RF_1T1R) {
2131 if (ctx40) {
2132 if (rssi == 1)
2133 ratr_bitmap &= 0x000f0000;
2134 else if (rssi == 2)
2135 ratr_bitmap &= 0x000ff000;
2136 else
2137 ratr_bitmap &= 0x000ff015;
2138 } else {
2139 if (rssi == 1)
2140 ratr_bitmap &= 0x000f0000;
2141 else if (rssi == 2)
2142 ratr_bitmap &= 0x000ff000;
2143 else
2144 ratr_bitmap &= 0x000ff005;
2145 }
2146 } else {
2147 if (ctx40) {
2148 if (rssi == 1)
2149 ratr_bitmap &= 0x0f8f0000;
2150 else if (rssi == 2)
2151 ratr_bitmap &= 0x0f8ff000;
2152 else
2153 ratr_bitmap &= 0x0f8ff015;
2154 } else {
2155 if (rssi == 1)
2156 ratr_bitmap &= 0x0f8f0000;
2157 else if (rssi == 2)
2158 ratr_bitmap &= 0x0f8ff000;
2159 else
2160 ratr_bitmap &= 0x0f8ff005;
2161 }
2162 }
2163 }
2164
2165 if ((ctx40 && short40) || (!ctx40 && short20)) {
2166 if (macid == 0)
2167 shortgi = true;
2168 else if (macid == 1)
2169 shortgi = false;
2170 }
2171 break;
2172 default:
2173 ratr_index = RATR_INX_WIRELESS_NGB;
2174
2175 if (rtlphy->rf_type == RF_1T2R)
2176 ratr_bitmap &= 0x000ff0ff;
2177 else
2178 ratr_bitmap &= 0x0f0ff0ff;
2179 break;
2180 }
2181 sta_entry->ratr_index = ratr_index;
2182
2183 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2184 "ratr_bitmap :%x\n", ratr_bitmap);
2185 *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
2186 (ratr_index << 28);
2187 rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
2188 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2189 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
2190 ratr_index, ratr_bitmap, rate_mask[0], rate_mask[1],
2191 rate_mask[2], rate_mask[3], rate_mask[4]);
2192 rtl88e_fill_h2c_cmd(hw, H2C_88E_RA_MASK, 5, rate_mask);
2193 _rtl88ee_set_bcn_ctrl_reg(hw, BIT(3), 0);
2194}
2195
2196void rtl88ee_update_hal_rate_tbl(struct ieee80211_hw *hw,
2197 struct ieee80211_sta *sta, u8 rssi)
2198{
2199 struct rtl_priv *rtlpriv = rtl_priv(hw);
2200
2201 if (rtlpriv->dm.useramask)
2202 rtl88ee_update_hal_rate_mask(hw, sta, rssi);
2203 else
2204 rtl88ee_update_hal_rate_table(hw, sta);
2205}
2206
2207void rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw)
2208{
2209 struct rtl_priv *rtlpriv = rtl_priv(hw);
2210 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2211 u16 sifs_timer;
2212
2213 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
2214 (u8 *)&mac->slot_time);
2215 if (!mac->ht_enable)
2216 sifs_timer = 0x0a0a;
2217 else
2218 sifs_timer = 0x0e0e;
2219 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2220}
2221
2222bool rtl88ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2223{
2224 struct rtl_priv *rtlpriv = rtl_priv(hw);
2225 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2226 enum rf_pwrstate state_toset;
2227 u32 u4tmp;
2228 bool actuallyset = false;
2229
2230 if (rtlpriv->rtlhal.being_init_adapter)
2231 return false;
2232
2233 if (ppsc->swrf_processing)
2234 return false;
2235
2236 spin_lock(&rtlpriv->locks.rf_ps_lock);
2237 if (ppsc->rfchange_inprogress) {
2238 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2239 return false;
2240 } else {
2241 ppsc->rfchange_inprogress = true;
2242 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2243 }
2244
2245 u4tmp = rtl_read_dword(rtlpriv, REG_GPIO_OUTPUT);
2246 state_toset = (u4tmp & BIT(31)) ? ERFON : ERFOFF;
2247
2248
2249 if ((ppsc->hwradiooff == true) && (state_toset == ERFON)) {
2250 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2251 "GPIOChangeRF - HW Radio ON, RF ON\n");
2252
2253 state_toset = ERFON;
2254 ppsc->hwradiooff = false;
2255 actuallyset = true;
2256 } else if ((ppsc->hwradiooff == false) && (state_toset == ERFOFF)) {
2257 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2258 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2259
2260 state_toset = ERFOFF;
2261 ppsc->hwradiooff = true;
2262 actuallyset = true;
2263 }
2264
2265 if (actuallyset) {
2266 spin_lock(&rtlpriv->locks.rf_ps_lock);
2267 ppsc->rfchange_inprogress = false;
2268 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2269 } else {
2270 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2271 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2272
2273 spin_lock(&rtlpriv->locks.rf_ps_lock);
2274 ppsc->rfchange_inprogress = false;
2275 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2276 }
2277
2278 *valid = 1;
2279 return !ppsc->hwradiooff;
2280}
2281
2282static void add_one_key(struct ieee80211_hw *hw, u8 *macaddr,
2283 struct rtl_mac *mac, u32 key, u32 id,
2284 u8 enc_algo, bool is_pairwise)
2285{
2286 struct rtl_priv *rtlpriv = rtl_priv(hw);
2287 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2288
2289 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "add one entry\n");
2290 if (is_pairwise) {
2291 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "set Pairwise key\n");
2292
2293 rtl_cam_add_one_entry(hw, macaddr, key, id, enc_algo,
2294 CAM_CONFIG_NO_USEDK,
2295 rtlpriv->sec.key_buf[key]);
2296 } else {
2297 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "set group key\n");
2298
2299 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2300 rtl_cam_add_one_entry(hw, rtlefuse->dev_addr,
2301 PAIRWISE_KEYIDX,
2302 CAM_PAIRWISE_KEY_POSITION,
2303 enc_algo,
2304 CAM_CONFIG_NO_USEDK,
2305 rtlpriv->sec.key_buf[id]);
2306 }
2307
2308 rtl_cam_add_one_entry(hw, macaddr, key, id, enc_algo,
2309 CAM_CONFIG_NO_USEDK,
2310 rtlpriv->sec.key_buf[id]);
2311 }
2312}
2313
2314void rtl88ee_set_key(struct ieee80211_hw *hw, u32 key,
2315 u8 *mac_ad, bool is_group, u8 enc_algo,
2316 bool is_wepkey, bool clear_all)
2317{
2318 struct rtl_priv *rtlpriv = rtl_priv(hw);
2319 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2320 u8 *macaddr = mac_ad;
2321 u32 id = 0;
2322 bool is_pairwise = false;
2323
2324 static u8 cam_const_addr[4][6] = {
2325 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2326 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2327 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2328 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2329 };
2330 static u8 cam_const_broad[] = {
2331 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2332 };
2333
2334 if (clear_all) {
2335 u8 idx = 0;
2336 u8 cam_offset = 0;
2337 u8 clear_number = 5;
2338
2339 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2340
2341 for (idx = 0; idx < clear_number; idx++) {
2342 rtl_cam_mark_invalid(hw, cam_offset + idx);
2343 rtl_cam_empty_entry(hw, cam_offset + idx);
2344
2345 if (idx < 5) {
2346 memset(rtlpriv->sec.key_buf[idx], 0,
2347 MAX_KEY_LEN);
2348 rtlpriv->sec.key_len[idx] = 0;
2349 }
2350 }
2351
2352 } else {
2353 switch (enc_algo) {
2354 case WEP40_ENCRYPTION:
2355 enc_algo = CAM_WEP40;
2356 break;
2357 case WEP104_ENCRYPTION:
2358 enc_algo = CAM_WEP104;
2359 break;
2360 case TKIP_ENCRYPTION:
2361 enc_algo = CAM_TKIP;
2362 break;
2363 case AESCCMP_ENCRYPTION:
2364 enc_algo = CAM_AES;
2365 break;
2366 default:
2367 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2368 "switch case not processed\n");
2369 enc_algo = CAM_TKIP;
2370 break;
2371 }
2372
2373 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2374 macaddr = cam_const_addr[key];
2375 id = key;
2376 } else {
2377 if (is_group) {
2378 macaddr = cam_const_broad;
2379 id = key;
2380 } else {
2381 if (mac->opmode == NL80211_IFTYPE_AP ||
2382 mac->opmode == NL80211_IFTYPE_MESH_POINT) {
2383 id = rtl_cam_get_free_entry(hw, mac_ad);
2384 if (id >= TOTAL_CAM_ENTRY) {
2385 RT_TRACE(rtlpriv, COMP_SEC,
2386 DBG_EMERG,
2387 "Can not find free hw security cam entry\n");
2388 return;
2389 }
2390 } else {
2391 id = CAM_PAIRWISE_KEY_POSITION;
2392 }
2393
2394 key = PAIRWISE_KEYIDX;
2395 is_pairwise = true;
2396 }
2397 }
2398
2399 if (rtlpriv->sec.key_len[key] == 0) {
2400 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2401 "delete one entry, id is %d\n", id);
2402 if (mac->opmode == NL80211_IFTYPE_AP ||
2403 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2404 rtl_cam_del_entry(hw, mac_ad);
2405 rtl_cam_delete_one_entry(hw, mac_ad, id);
2406 } else {
2407 add_one_key(hw, macaddr, mac, key, id, enc_algo,
2408 is_pairwise);
2409 }
2410 }
2411}
2412
2413static void rtl8188ee_bt_var_init(struct ieee80211_hw *hw)
2414{
2415 struct rtl_pci_priv *rppriv = rtl_pcipriv(hw);
2416 struct bt_coexist_info coexist = rppriv->bt_coexist;
2417
2418 coexist.bt_coexistence = rppriv->bt_coexist.eeprom_bt_coexist;
2419 coexist.bt_ant_num = coexist.eeprom_bt_ant_num;
2420 coexist.bt_coexist_type = coexist.eeprom_bt_type;
2421
2422 if (coexist.reg_bt_iso == 2)
2423 coexist.bt_ant_isolation = coexist.eeprom_bt_ant_isol;
2424 else
2425 coexist.bt_ant_isolation = coexist.reg_bt_iso;
2426
2427 coexist.bt_radio_shared_type = coexist.eeprom_bt_radio_shared;
2428
2429 if (coexist.bt_coexistence) {
2430 if (coexist.reg_bt_sco == 1)
2431 coexist.bt_service = BT_OTHER_ACTION;
2432 else if (coexist.reg_bt_sco == 2)
2433 coexist.bt_service = BT_SCO;
2434 else if (coexist.reg_bt_sco == 4)
2435 coexist.bt_service = BT_BUSY;
2436 else if (coexist.reg_bt_sco == 5)
2437 coexist.bt_service = BT_OTHERBUSY;
2438 else
2439 coexist.bt_service = BT_IDLE;
2440
2441 coexist.bt_edca_ul = 0;
2442 coexist.bt_edca_dl = 0;
2443 coexist.bt_rssi_state = 0xff;
2444 }
2445}
2446
2447void rtl8188ee_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2448 bool auto_load_fail, u8 *hwinfo)
2449{
2450 rtl8188ee_bt_var_init(hw);
2451}
2452
2453void rtl8188ee_bt_reg_init(struct ieee80211_hw *hw)
2454{
2455 struct rtl_pci_priv *rppriv = rtl_pcipriv(hw);
2456
2457 /* 0:Low, 1:High, 2:From Efuse. */
2458 rppriv->bt_coexist.reg_bt_iso = 2;
2459 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2460 rppriv->bt_coexist.reg_bt_sco = 3;
2461 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2462 rppriv->bt_coexist.reg_bt_sco = 0;
2463}
2464
2465void rtl8188ee_bt_hw_init(struct ieee80211_hw *hw)
2466{
2467 struct rtl_priv *rtlpriv = rtl_priv(hw);
2468 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2469 struct rtl_pci_priv *rppriv = rtl_pcipriv(hw);
2470 struct bt_coexist_info coexist = rppriv->bt_coexist;
2471 u8 u1_tmp;
2472
2473 if (coexist.bt_coexistence &&
2474 ((coexist.bt_coexist_type == BT_CSR_BC4) ||
2475 coexist.bt_coexist_type == BT_CSR_BC8)) {
2476 if (coexist.bt_ant_isolation)
2477 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
2478
2479 u1_tmp = rtl_read_byte(rtlpriv, 0x4fd) &
2480 BIT_OFFSET_LEN_MASK_32(0, 1);
2481 u1_tmp = u1_tmp | ((coexist.bt_ant_isolation == 1) ?
2482 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
2483 ((coexist.bt_service == BT_SCO) ?
2484 0 : BIT_OFFSET_LEN_MASK_32(2, 1));
2485 rtl_write_byte(rtlpriv, 0x4fd, u1_tmp);
2486
2487 rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+4, 0xaaaa9aaa);
2488 rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+8, 0xffbd0040);
2489 rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+0xc, 0x40000010);
2490
2491 /* Config to 1T1R. */
2492 if (rtlphy->rf_type == RF_1T1R) {
2493 u1_tmp = rtl_read_byte(rtlpriv, ROFDM0_TRXPATHENABLE);
2494 u1_tmp &= ~(BIT_OFFSET_LEN_MASK_32(1, 1));
2495 rtl_write_byte(rtlpriv, ROFDM0_TRXPATHENABLE, u1_tmp);
2496
2497 u1_tmp = rtl_read_byte(rtlpriv, ROFDM1_TRXPATHENABLE);
2498 u1_tmp &= ~(BIT_OFFSET_LEN_MASK_32(1, 1));
2499 rtl_write_byte(rtlpriv, ROFDM1_TRXPATHENABLE, u1_tmp);
2500 }
2501 }
2502}
2503
2504void rtl88ee_suspend(struct ieee80211_hw *hw)
2505{
2506}
2507
2508void rtl88ee_resume(struct ieee80211_hw *hw)
2509{
2510}
2511
2512/* Turn on AAP (RCR:bit 0) for promicuous mode. */
2513void rtl88ee_allow_all_destaddr(struct ieee80211_hw *hw,
2514 bool allow_all_da, bool write_into_reg)
2515{
2516 struct rtl_priv *rtlpriv = rtl_priv(hw);
2517 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2518
2519 if (allow_all_da) /* Set BIT0 */
2520 rtlpci->receive_config |= RCR_AAP;
2521 else /* Clear BIT0 */
2522 rtlpci->receive_config &= ~RCR_AAP;
2523
2524 if (write_into_reg)
2525 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
2526
2527 RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
2528 "receive_config = 0x%08X, write_into_reg =%d\n",
2529 rtlpci->receive_config, write_into_reg);
2530}
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.h b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.h
new file mode 100644
index 000000000000..b4460a41bd01
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.h
@@ -0,0 +1,68 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92CE_HW_H__
31#define __RTL92CE_HW_H__
32
33void rtl88ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
34void rtl88ee_read_eeprom_info(struct ieee80211_hw *hw);
35void rtl88ee_interrupt_recognized(struct ieee80211_hw *hw,
36 u32 *p_inta, u32 *p_intb);
37int rtl88ee_hw_init(struct ieee80211_hw *hw);
38void rtl88ee_card_disable(struct ieee80211_hw *hw);
39void rtl88ee_enable_interrupt(struct ieee80211_hw *hw);
40void rtl88ee_disable_interrupt(struct ieee80211_hw *hw);
41int rtl88ee_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
42void rtl88ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
43void rtl88ee_set_qos(struct ieee80211_hw *hw, int aci);
44void rtl88ee_set_beacon_related_registers(struct ieee80211_hw *hw);
45void rtl88ee_set_beacon_interval(struct ieee80211_hw *hw);
46void rtl88ee_update_interrupt_mask(struct ieee80211_hw *hw,
47 u32 add_msr, u32 rm_msr);
48void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
49void rtl88ee_update_hal_rate_tbl(struct ieee80211_hw *hw,
50 struct ieee80211_sta *sta, u8 rssi_level);
51void rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw);
52bool rtl88ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
53void rtl88ee_enable_hw_security_config(struct ieee80211_hw *hw);
54void rtl88ee_set_key(struct ieee80211_hw *hw, u32 key_index,
55 u8 *p_macaddr, bool is_group, u8 enc_algo,
56 bool is_wepkey, bool clear_all);
57
58void rtl8188ee_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
59 bool autoload_fail, u8 *hwinfo);
60void rtl8188ee_bt_reg_init(struct ieee80211_hw *hw);
61void rtl8188ee_bt_hw_init(struct ieee80211_hw *hw);
62void rtl88ee_suspend(struct ieee80211_hw *hw);
63void rtl88ee_resume(struct ieee80211_hw *hw);
64void rtl88ee_allow_all_destaddr(struct ieee80211_hw *hw,
65 bool allow_all_da, bool write_into_reg);
66void rtl88ee_fw_clk_off_timer_callback(unsigned long data);
67
68#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/led.c b/drivers/net/wireless/rtlwifi/rtl8188ee/led.c
new file mode 100644
index 000000000000..c81a9cb6894c
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/led.c
@@ -0,0 +1,157 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "reg.h"
33#include "led.h"
34
35static void rtl88ee_init_led(struct ieee80211_hw *hw,
36 struct rtl_led *pled, enum rtl_led_pin ledpin)
37{
38 pled->hw = hw;
39 pled->ledpin = ledpin;
40 pled->ledon = false;
41}
42
43void rtl88ee_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
44{
45 u8 ledcfg;
46 struct rtl_priv *rtlpriv = rtl_priv(hw);
47
48 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
49 "LedAddr:%X ledpin =%d\n", REG_LEDCFG2, pled->ledpin);
50
51 switch (pled->ledpin) {
52 case LED_PIN_GPIO0:
53 break;
54 case LED_PIN_LED0:
55 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
56 rtl_write_byte(rtlpriv, REG_LEDCFG2,
57 (ledcfg & 0xf0) | BIT(5) | BIT(6));
58 break;
59 case LED_PIN_LED1:
60 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
61 rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10);
62 break;
63 default:
64 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
65 "switch case not processed\n");
66 break;
67 }
68 pled->ledon = true;
69}
70
71void rtl88ee_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
72{
73 struct rtl_priv *rtlpriv = rtl_priv(hw);
74 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
75 u8 ledcfg;
76 u8 val;
77
78 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
79 "LedAddr:%X ledpin =%d\n", REG_LEDCFG2, pled->ledpin);
80
81 switch (pled->ledpin) {
82 case LED_PIN_GPIO0:
83 break;
84 case LED_PIN_LED0:
85 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
86 ledcfg &= 0xf0;
87 val = ledcfg | BIT(3) | BIT(5) | BIT(6);
88 if (pcipriv->ledctl.led_opendrain == true) {
89 rtl_write_byte(rtlpriv, REG_LEDCFG2, val);
90 ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
91 val = ledcfg & 0xFE;
92 rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, val);
93 } else {
94 rtl_write_byte(rtlpriv, REG_LEDCFG2, val);
95 }
96 break;
97 case LED_PIN_LED1:
98 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
99 ledcfg &= 0x10;
100 rtl_write_byte(rtlpriv, REG_LEDCFG1, (ledcfg | BIT(3)));
101 break;
102 default:
103 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
104 "switch case not processed\n");
105 break;
106 }
107 pled->ledon = false;
108}
109
110void rtl88ee_init_sw_leds(struct ieee80211_hw *hw)
111{
112 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
113
114 rtl88ee_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
115 rtl88ee_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
116}
117
118static void rtl88ee_sw_led_control(struct ieee80211_hw *hw,
119 enum led_ctl_mode ledaction)
120{
121 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
122 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
123
124 switch (ledaction) {
125 case LED_CTL_POWER_ON:
126 case LED_CTL_LINK:
127 case LED_CTL_NO_LINK:
128 rtl88ee_sw_led_on(hw, pLed0);
129 break;
130 case LED_CTL_POWER_OFF:
131 rtl88ee_sw_led_off(hw, pLed0);
132 break;
133 default:
134 break;
135 }
136}
137
138void rtl88ee_led_control(struct ieee80211_hw *hw,
139 enum led_ctl_mode ledaction)
140{
141 struct rtl_priv *rtlpriv = rtl_priv(hw);
142 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
143
144 if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
145 (ledaction == LED_CTL_TX ||
146 ledaction == LED_CTL_RX ||
147 ledaction == LED_CTL_SITE_SURVEY ||
148 ledaction == LED_CTL_LINK ||
149 ledaction == LED_CTL_NO_LINK ||
150 ledaction == LED_CTL_START_TO_LINK ||
151 ledaction == LED_CTL_POWER_ON)) {
152 return;
153 }
154 RT_TRACE(rtlpriv, COMP_LED, DBG_TRACE, "ledaction %d,\n",
155 ledaction);
156 rtl88ee_sw_led_control(hw, ledaction);
157}
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/led.h b/drivers/net/wireless/rtlwifi/rtl8188ee/led.h
new file mode 100644
index 000000000000..4073f6f847b2
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/led.h
@@ -0,0 +1,38 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92CE_LED_H__
31#define __RTL92CE_LED_H__
32
33void rtl88ee_init_sw_leds(struct ieee80211_hw *hw);
34void rtl88ee_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
35void rtl88ee_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
36void rtl88ee_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
37
38#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
new file mode 100644
index 000000000000..e655c0473225
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
@@ -0,0 +1,2202 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../ps.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "rf.h"
37#include "dm.h"
38#include "table.h"
39
40static void set_baseband_phy_config(struct ieee80211_hw *hw);
41static void set_baseband_agc_config(struct ieee80211_hw *hw);
42static void store_pwrindex_offset(struct ieee80211_hw *hw,
43 u32 regaddr, u32 bitmask,
44 u32 data);
45static bool check_cond(struct ieee80211_hw *hw, const u32 condition);
46
47static u32 rf_serial_read(struct ieee80211_hw *hw,
48 enum radio_path rfpath, u32 offset)
49{
50 struct rtl_priv *rtlpriv = rtl_priv(hw);
51 struct rtl_phy *rtlphy = &(rtlpriv->phy);
52 struct bb_reg_def *phreg = &rtlphy->phyreg_def[rfpath];
53 u32 newoffset;
54 u32 tmplong, tmplong2;
55 u8 rfpi_enable = 0;
56 u32 ret;
57 int jj = RF90_PATH_A;
58 int kk = RF90_PATH_B;
59
60 offset &= 0xff;
61 newoffset = offset;
62 if (RT_CANNOT_IO(hw)) {
63 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
64 return 0xFFFFFFFF;
65 }
66 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
67 if (rfpath == jj)
68 tmplong2 = tmplong;
69 else
70 tmplong2 = rtl_get_bbreg(hw, phreg->rfhssi_para2, MASKDWORD);
71 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
72 (newoffset << 23) | BLSSIREADEDGE;
73 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
74 tmplong & (~BLSSIREADEDGE));
75 mdelay(1);
76 rtl_set_bbreg(hw, phreg->rfhssi_para2, MASKDWORD, tmplong2);
77 mdelay(2);
78 if (rfpath == jj)
79 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
80 BIT(8));
81 else if (rfpath == kk)
82 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
83 BIT(8));
84 if (rfpi_enable)
85 ret = rtl_get_bbreg(hw, phreg->rf_rbpi, BLSSIREADBACKDATA);
86 else
87 ret = rtl_get_bbreg(hw, phreg->rf_rb, BLSSIREADBACKDATA);
88 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]= 0x%x\n",
89 rfpath, phreg->rf_rb, ret);
90 return ret;
91}
92
93static void rf_serial_write(struct ieee80211_hw *hw,
94 enum radio_path rfpath, u32 offset,
95 u32 data)
96{
97 u32 data_and_addr;
98 u32 newoffset;
99 struct rtl_priv *rtlpriv = rtl_priv(hw);
100 struct rtl_phy *rtlphy = &(rtlpriv->phy);
101 struct bb_reg_def *phreg = &rtlphy->phyreg_def[rfpath];
102
103 if (RT_CANNOT_IO(hw)) {
104 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
105 return;
106 }
107 offset &= 0xff;
108 newoffset = offset;
109 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
110 rtl_set_bbreg(hw, phreg->rf3wire_offset, MASKDWORD, data_and_addr);
111 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]= 0x%x\n",
112 rfpath, phreg->rf3wire_offset, data_and_addr);
113}
114
115static u32 cal_bit_shift(u32 bitmask)
116{
117 u32 i;
118
119 for (i = 0; i <= 31; i++) {
120 if (((bitmask >> i) & 0x1) == 1)
121 break;
122 }
123 return i;
124}
125
126static bool config_bb_with_header(struct ieee80211_hw *hw,
127 u8 configtype)
128{
129 if (configtype == BASEBAND_CONFIG_PHY_REG)
130 set_baseband_phy_config(hw);
131 else if (configtype == BASEBAND_CONFIG_AGC_TAB)
132 set_baseband_agc_config(hw);
133 return true;
134}
135
136static bool config_bb_with_pgheader(struct ieee80211_hw *hw,
137 u8 configtype)
138{
139 struct rtl_priv *rtlpriv = rtl_priv(hw);
140 int i;
141 u32 *table_pg;
142 u16 tbl_page_len;
143 u32 v1 = 0, v2 = 0;
144
145 tbl_page_len = RTL8188EEPHY_REG_ARRAY_PGLEN;
146 table_pg = RTL8188EEPHY_REG_ARRAY_PG;
147
148 if (configtype == BASEBAND_CONFIG_PHY_REG) {
149 for (i = 0; i < tbl_page_len; i = i + 3) {
150 v1 = table_pg[i];
151 v2 = table_pg[i + 1];
152
153 if (v1 < 0xcdcdcdcd) {
154 if (table_pg[i] == 0xfe)
155 mdelay(50);
156 else if (table_pg[i] == 0xfd)
157 mdelay(5);
158 else if (table_pg[i] == 0xfc)
159 mdelay(1);
160 else if (table_pg[i] == 0xfb)
161 udelay(50);
162 else if (table_pg[i] == 0xfa)
163 udelay(5);
164 else if (table_pg[i] == 0xf9)
165 udelay(1);
166
167 store_pwrindex_offset(hw, table_pg[i],
168 table_pg[i + 1],
169 table_pg[i + 2]);
170 continue;
171 } else {
172 if (!check_cond(hw, table_pg[i])) {
173 /*don't need the hw_body*/
174 i += 2; /* skip the pair of expression*/
175 v1 = table_pg[i];
176 v2 = table_pg[i + 1];
177 while (v2 != 0xDEAD) {
178 i += 3;
179 v1 = table_pg[i];
180 v2 = table_pg[i + 1];
181 }
182 }
183 }
184 }
185 } else {
186 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
187 "configtype != BaseBand_Config_PHY_REG\n");
188 }
189 return true;
190}
191
192static bool config_parafile(struct ieee80211_hw *hw)
193{
194 struct rtl_priv *rtlpriv = rtl_priv(hw);
195 struct rtl_phy *rtlphy = &(rtlpriv->phy);
196 struct rtl_efuse *fuse = rtl_efuse(rtl_priv(hw));
197 bool rtstatus;
198
199 rtstatus = config_bb_with_header(hw, BASEBAND_CONFIG_PHY_REG);
200 if (rtstatus != true) {
201 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
202 return false;
203 }
204
205 if (fuse->autoload_failflag == false) {
206 rtlphy->pwrgroup_cnt = 0;
207 rtstatus = config_bb_with_pgheader(hw, BASEBAND_CONFIG_PHY_REG);
208 }
209 if (rtstatus != true) {
210 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
211 return false;
212 }
213 rtstatus = config_bb_with_header(hw, BASEBAND_CONFIG_AGC_TAB);
214 if (rtstatus != true) {
215 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
216 return false;
217 }
218 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
219 RFPGA0_XA_HSSIPARAMETER2, 0x200));
220
221 return true;
222}
223
224static void rtl88e_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
225{
226 struct rtl_priv *rtlpriv = rtl_priv(hw);
227 struct rtl_phy *rtlphy = &(rtlpriv->phy);
228 int jj = RF90_PATH_A;
229 int kk = RF90_PATH_B;
230
231 rtlphy->phyreg_def[jj].rfintfs = RFPGA0_XAB_RFINTERFACESW;
232 rtlphy->phyreg_def[kk].rfintfs = RFPGA0_XAB_RFINTERFACESW;
233 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
234 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
235
236 rtlphy->phyreg_def[jj].rfintfi = RFPGA0_XAB_RFINTERFACERB;
237 rtlphy->phyreg_def[kk].rfintfi = RFPGA0_XAB_RFINTERFACERB;
238 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
239 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
240
241 rtlphy->phyreg_def[jj].rfintfo = RFPGA0_XA_RFINTERFACEOE;
242 rtlphy->phyreg_def[kk].rfintfo = RFPGA0_XB_RFINTERFACEOE;
243
244 rtlphy->phyreg_def[jj].rfintfe = RFPGA0_XA_RFINTERFACEOE;
245 rtlphy->phyreg_def[kk].rfintfe = RFPGA0_XB_RFINTERFACEOE;
246
247 rtlphy->phyreg_def[jj].rf3wire_offset = RFPGA0_XA_LSSIPARAMETER;
248 rtlphy->phyreg_def[kk].rf3wire_offset = RFPGA0_XB_LSSIPARAMETER;
249
250 rtlphy->phyreg_def[jj].rflssi_select = rFPGA0_XAB_RFPARAMETER;
251 rtlphy->phyreg_def[kk].rflssi_select = rFPGA0_XAB_RFPARAMETER;
252 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
253 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
254
255 rtlphy->phyreg_def[jj].rftxgain_stage = RFPGA0_TXGAINSTAGE;
256 rtlphy->phyreg_def[kk].rftxgain_stage = RFPGA0_TXGAINSTAGE;
257 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
258 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
259
260 rtlphy->phyreg_def[jj].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
261 rtlphy->phyreg_def[kk].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
262
263 rtlphy->phyreg_def[jj].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
264 rtlphy->phyreg_def[kk].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
265
266 rtlphy->phyreg_def[jj].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
267 rtlphy->phyreg_def[kk].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
268 rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
269 rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
270
271 rtlphy->phyreg_def[jj].rfagc_control1 = ROFDM0_XAAGCCORE1;
272 rtlphy->phyreg_def[kk].rfagc_control1 = ROFDM0_XBAGCCORE1;
273 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
274 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
275
276 rtlphy->phyreg_def[jj].rfagc_control2 = ROFDM0_XAAGCCORE2;
277 rtlphy->phyreg_def[kk].rfagc_control2 = ROFDM0_XBAGCCORE2;
278 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
279 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
280
281 rtlphy->phyreg_def[jj].rfrxiq_imbal = ROFDM0_XARXIQIMBAL;
282 rtlphy->phyreg_def[kk].rfrxiq_imbal = ROFDM0_XBRXIQIMBAL;
283 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBAL;
284 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBAL;
285
286 rtlphy->phyreg_def[jj].rfrx_afe = ROFDM0_XARXAFE;
287 rtlphy->phyreg_def[kk].rfrx_afe = ROFDM0_XBRXAFE;
288 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
289 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
290
291 rtlphy->phyreg_def[jj].rftxiq_imbal = ROFDM0_XATXIQIMBAL;
292 rtlphy->phyreg_def[kk].rftxiq_imbal = ROFDM0_XBTXIQIMBAL;
293 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBAL;
294 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBAL;
295
296 rtlphy->phyreg_def[jj].rftx_afe = ROFDM0_XATXAFE;
297 rtlphy->phyreg_def[kk].rftx_afe = ROFDM0_XBTXAFE;
298
299 rtlphy->phyreg_def[jj].rf_rb = RFPGA0_XA_LSSIREADBACK;
300 rtlphy->phyreg_def[kk].rf_rb = RFPGA0_XB_LSSIREADBACK;
301
302 rtlphy->phyreg_def[jj].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
303 rtlphy->phyreg_def[kk].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
304}
305
306static bool rtl88e_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
307 u32 cmdtableidx, u32 cmdtablesz,
308 enum swchnlcmd_id cmdid,
309 u32 para1, u32 para2, u32 msdelay)
310{
311 struct swchnlcmd *pcmd;
312
313 if (cmdtable == NULL) {
314 RT_ASSERT(false, "cmdtable cannot be NULL.\n");
315 return false;
316 }
317
318 if (cmdtableidx >= cmdtablesz)
319 return false;
320
321 pcmd = cmdtable + cmdtableidx;
322 pcmd->cmdid = cmdid;
323 pcmd->para1 = para1;
324 pcmd->para2 = para2;
325 pcmd->msdelay = msdelay;
326 return true;
327}
328
329static bool chnl_step_by_step(struct ieee80211_hw *hw,
330 u8 channel, u8 *stage, u8 *step,
331 u32 *delay)
332{
333 struct rtl_priv *rtlpriv = rtl_priv(hw);
334 struct rtl_phy *rtlphy = &(rtlpriv->phy);
335 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
336 u32 precommoncmdcnt;
337 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
338 u32 postcommoncmdcnt;
339 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
340 u32 rfdependcmdcnt;
341 struct swchnlcmd *currentcmd = NULL;
342 u8 rfpath;
343 u8 num_total_rfpath = rtlphy->num_total_rfpath;
344
345 precommoncmdcnt = 0;
346 rtl88e_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
347 MAX_PRECMD_CNT,
348 CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
349 rtl88e_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
350 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
351
352 postcommoncmdcnt = 0;
353
354 rtl88e_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
355 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
356
357 rfdependcmdcnt = 0;
358
359 RT_ASSERT((channel >= 1 && channel <= 14),
360 "illegal channel for Zebra: %d\n", channel);
361
362 rtl88e_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
363 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
364 RF_CHNLBW, channel, 10);
365
366 rtl88e_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
367 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
368 0);
369
370 do {
371 switch (*stage) {
372 case 0:
373 currentcmd = &precommoncmd[*step];
374 break;
375 case 1:
376 currentcmd = &rfdependcmd[*step];
377 break;
378 case 2:
379 currentcmd = &postcommoncmd[*step];
380 break;
381 }
382
383 if (currentcmd->cmdid == CMDID_END) {
384 if ((*stage) == 2) {
385 return true;
386 } else {
387 (*stage)++;
388 (*step) = 0;
389 continue;
390 }
391 }
392
393 switch (currentcmd->cmdid) {
394 case CMDID_SET_TXPOWEROWER_LEVEL:
395 rtl88e_phy_set_txpower_level(hw, channel);
396 break;
397 case CMDID_WRITEPORT_ULONG:
398 rtl_write_dword(rtlpriv, currentcmd->para1,
399 currentcmd->para2);
400 break;
401 case CMDID_WRITEPORT_USHORT:
402 rtl_write_word(rtlpriv, currentcmd->para1,
403 (u16) currentcmd->para2);
404 break;
405 case CMDID_WRITEPORT_UCHAR:
406 rtl_write_byte(rtlpriv, currentcmd->para1,
407 (u8) currentcmd->para2);
408 break;
409 case CMDID_RF_WRITEREG:
410 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
411 rtlphy->rfreg_chnlval[rfpath] =
412 ((rtlphy->rfreg_chnlval[rfpath] &
413 0xfffffc00) | currentcmd->para2);
414
415 rtl_set_rfreg(hw, (enum radio_path)rfpath,
416 currentcmd->para1,
417 RFREG_OFFSET_MASK,
418 rtlphy->rfreg_chnlval[rfpath]);
419 }
420 break;
421 default:
422 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
423 "switch case not processed\n");
424 break;
425 }
426
427 break;
428 } while (true);
429
430 (*delay) = currentcmd->msdelay;
431 (*step)++;
432 return false;
433}
434
435static long rtl88e_pwr_idx_dbm(struct ieee80211_hw *hw,
436 enum wireless_mode wirelessmode,
437 u8 txpwridx)
438{
439 long offset;
440 long pwrout_dbm;
441
442 switch (wirelessmode) {
443 case WIRELESS_MODE_B:
444 offset = -7;
445 break;
446 case WIRELESS_MODE_G:
447 case WIRELESS_MODE_N_24G:
448 offset = -8;
449 break;
450 default:
451 offset = -8;
452 break;
453 }
454 pwrout_dbm = txpwridx / 2 + offset;
455 return pwrout_dbm;
456}
457
458static void rtl88e_phy_set_io(struct ieee80211_hw *hw)
459{
460 struct rtl_priv *rtlpriv = rtl_priv(hw);
461 struct rtl_phy *rtlphy = &(rtlpriv->phy);
462 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
463
464 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
465 "--->Cmd(%#x), set_io_inprogress(%d)\n",
466 rtlphy->current_io_type, rtlphy->set_io_inprogress);
467 switch (rtlphy->current_io_type) {
468 case IO_CMD_RESUME_DM_BY_SCAN:
469 dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
470 /*rtl92c_dm_write_dig(hw);*/
471 rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel);
472 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
473 break;
474 case IO_CMD_PAUSE_DM_BY_SCAN:
475 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
476 dm_digtable->cur_igvalue = 0x17;
477 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
478 break;
479 default:
480 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
481 "switch case not processed\n");
482 break;
483 }
484 rtlphy->set_io_inprogress = false;
485 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
486 "(%#x)\n", rtlphy->current_io_type);
487}
488
489u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
490{
491 struct rtl_priv *rtlpriv = rtl_priv(hw);
492 u32 returnvalue, originalvalue, bitshift;
493
494 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
495 "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
496 originalvalue = rtl_read_dword(rtlpriv, regaddr);
497 bitshift = cal_bit_shift(bitmask);
498 returnvalue = (originalvalue & bitmask) >> bitshift;
499
500 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
501 "BBR MASK = 0x%x Addr[0x%x]= 0x%x\n", bitmask,
502 regaddr, originalvalue);
503
504 return returnvalue;
505}
506
507void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw,
508 u32 regaddr, u32 bitmask, u32 data)
509{
510 struct rtl_priv *rtlpriv = rtl_priv(hw);
511 u32 originalvalue, bitshift;
512
513 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
514 "regaddr(%#x), bitmask(%#x),data(%#x)\n",
515 regaddr, bitmask, data);
516
517 if (bitmask != MASKDWORD) {
518 originalvalue = rtl_read_dword(rtlpriv, regaddr);
519 bitshift = cal_bit_shift(bitmask);
520 data = ((originalvalue & (~bitmask)) | (data << bitshift));
521 }
522
523 rtl_write_dword(rtlpriv, regaddr, data);
524
525 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
526 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
527 regaddr, bitmask, data);
528}
529
530u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw,
531 enum radio_path rfpath, u32 regaddr, u32 bitmask)
532{
533 struct rtl_priv *rtlpriv = rtl_priv(hw);
534 u32 original_value, readback_value, bitshift;
535 unsigned long flags;
536
537 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
538 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
539 regaddr, rfpath, bitmask);
540
541 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
542
543
544 original_value = rf_serial_read(hw, rfpath, regaddr);
545 bitshift = cal_bit_shift(bitmask);
546 readback_value = (original_value & bitmask) >> bitshift;
547
548 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
549
550 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
551 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
552 regaddr, rfpath, bitmask, original_value);
553
554 return readback_value;
555}
556
557void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw,
558 enum radio_path rfpath,
559 u32 regaddr, u32 bitmask, u32 data)
560{
561 struct rtl_priv *rtlpriv = rtl_priv(hw);
562 u32 original_value, bitshift;
563 unsigned long flags;
564
565 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
566 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
567 regaddr, bitmask, data, rfpath);
568
569 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
570
571 if (bitmask != RFREG_OFFSET_MASK) {
572 original_value = rf_serial_read(hw, rfpath, regaddr);
573 bitshift = cal_bit_shift(bitmask);
574 data = ((original_value & (~bitmask)) |
575 (data << bitshift));
576 }
577
578 rf_serial_write(hw, rfpath, regaddr, data);
579
580
581 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
582
583 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
584 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
585 regaddr, bitmask, data, rfpath);
586}
587
588static bool config_mac_with_header(struct ieee80211_hw *hw)
589{
590 struct rtl_priv *rtlpriv = rtl_priv(hw);
591 u32 i;
592 u32 arraylength;
593 u32 *ptrarray;
594
595 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8188EMACPHY_Array\n");
596 arraylength = RTL8188EEMAC_1T_ARRAYLEN;
597 ptrarray = RTL8188EEMAC_1T_ARRAY;
598 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
599 "Img:RTL8188EEMAC_1T_ARRAY LEN %d\n", arraylength);
600 for (i = 0; i < arraylength; i = i + 2)
601 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
602 return true;
603}
604
605bool rtl88e_phy_mac_config(struct ieee80211_hw *hw)
606{
607 struct rtl_priv *rtlpriv = rtl_priv(hw);
608 bool rtstatus = config_mac_with_header(hw);
609
610 rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
611 return rtstatus;
612}
613
614bool rtl88e_phy_bb_config(struct ieee80211_hw *hw)
615{
616 bool rtstatus = true;
617 struct rtl_priv *rtlpriv = rtl_priv(hw);
618 u16 regval;
619 u8 reg_hwparafile = 1;
620 u32 tmp;
621 rtl88e_phy_init_bb_rf_register_definition(hw);
622 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
623 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
624 regval | BIT(13) | BIT(0) | BIT(1));
625
626 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
627 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
628 FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
629 FEN_BB_GLB_RSTN | FEN_BBRSTB);
630 tmp = rtl_read_dword(rtlpriv, 0x4c);
631 rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
632 if (reg_hwparafile == 1)
633 rtstatus = config_parafile(hw);
634 return rtstatus;
635}
636
637bool rtl88e_phy_rf_config(struct ieee80211_hw *hw)
638{
639 return rtl88e_phy_rf6052_config(hw);
640}
641
642static bool check_cond(struct ieee80211_hw *hw,
643 const u32 condition)
644{
645 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
646 struct rtl_efuse *fuse = rtl_efuse(rtl_priv(hw));
647 u32 _board = fuse->board_type; /*need efuse define*/
648 u32 _interface = rtlhal->interface;
649 u32 _platform = 0x08;/*SupportPlatform */
650 u32 cond = condition;
651
652 if (condition == 0xCDCDCDCD)
653 return true;
654
655 cond = condition & 0xFF;
656 if ((_board & cond) == 0 && cond != 0x1F)
657 return false;
658
659 cond = condition & 0xFF00;
660 cond = cond >> 8;
661 if ((_interface & cond) == 0 && cond != 0x07)
662 return false;
663
664 cond = condition & 0xFF0000;
665 cond = cond >> 16;
666 if ((_platform & cond) == 0 && cond != 0x0F)
667 return false;
668 return true;
669}
670
671static void _rtl8188e_config_rf_reg(struct ieee80211_hw *hw,
672 u32 addr, u32 data, enum radio_path rfpath,
673 u32 regaddr)
674{
675 if (addr == 0xffe) {
676 mdelay(50);
677 } else if (addr == 0xfd) {
678 mdelay(5);
679 } else if (addr == 0xfc) {
680 mdelay(1);
681 } else if (addr == 0xfb) {
682 udelay(50);
683 } else if (addr == 0xfa) {
684 udelay(5);
685 } else if (addr == 0xf9) {
686 udelay(1);
687 } else {
688 rtl_set_rfreg(hw, rfpath, regaddr,
689 RFREG_OFFSET_MASK,
690 data);
691 udelay(1);
692 }
693}
694
695static void rtl88_config_s(struct ieee80211_hw *hw,
696 u32 addr, u32 data)
697{
698 u32 content = 0x1000; /*RF Content: radio_a_txt*/
699 u32 maskforphyset = (u32)(content & 0xE000);
700
701 _rtl8188e_config_rf_reg(hw, addr, data, RF90_PATH_A,
702 addr | maskforphyset);
703}
704
705static void _rtl8188e_config_bb_reg(struct ieee80211_hw *hw,
706 u32 addr, u32 data)
707{
708 if (addr == 0xfe) {
709 mdelay(50);
710 } else if (addr == 0xfd) {
711 mdelay(5);
712 } else if (addr == 0xfc) {
713 mdelay(1);
714 } else if (addr == 0xfb) {
715 udelay(50);
716 } else if (addr == 0xfa) {
717 udelay(5);
718 } else if (addr == 0xf9) {
719 udelay(1);
720 } else {
721 rtl_set_bbreg(hw, addr, MASKDWORD, data);
722 udelay(1);
723 }
724}
725
726
727#define NEXT_PAIR(v1, v2, i) \
728 do { \
729 i += 2; v1 = array_table[i]; \
730 v2 = array_table[i + 1]; \
731 } while (0)
732
733static void set_baseband_agc_config(struct ieee80211_hw *hw)
734{
735 int i;
736 u32 *array_table;
737 u16 arraylen;
738 struct rtl_priv *rtlpriv = rtl_priv(hw);
739 u32 v1 = 0, v2 = 0;
740
741 arraylen = RTL8188EEAGCTAB_1TARRAYLEN;
742 array_table = RTL8188EEAGCTAB_1TARRAY;
743
744 for (i = 0; i < arraylen; i += 2) {
745 v1 = array_table[i];
746 v2 = array_table[i + 1];
747 if (v1 < 0xCDCDCDCD) {
748 rtl_set_bbreg(hw, array_table[i], MASKDWORD,
749 array_table[i + 1]);
750 udelay(1);
751 continue;
752 } else {/*This line is the start line of branch.*/
753 if (!check_cond(hw, array_table[i])) {
754 /*Discard the following (offset, data) pairs*/
755 NEXT_PAIR(v1, v2, i);
756 while (v2 != 0xDEAD && v2 != 0xCDEF &&
757 v2 != 0xCDCD && i < arraylen - 2) {
758 NEXT_PAIR(v1, v2, i);
759 }
760 i -= 2; /* compensate for loop's += 2*/
761 } else {
762 /* Configure matched pairs and skip to end */
763 NEXT_PAIR(v1, v2, i);
764 while (v2 != 0xDEAD && v2 != 0xCDEF &&
765 v2 != 0xCDCD && i < arraylen - 2) {
766 rtl_set_bbreg(hw, array_table[i],
767 MASKDWORD,
768 array_table[i + 1]);
769 udelay(1);
770 NEXT_PAIR(v1, v2, i);
771 }
772
773 while (v2 != 0xDEAD && i < arraylen - 2)
774 NEXT_PAIR(v1, v2, i);
775 }
776 }
777 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
778 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
779 array_table[i],
780 array_table[i + 1]);
781 }
782}
783
784static void set_baseband_phy_config(struct ieee80211_hw *hw)
785{
786 int i;
787 u32 *array_table;
788 u16 arraylen;
789 u32 v1 = 0, v2 = 0;
790
791 arraylen = RTL8188EEPHY_REG_1TARRAYLEN;
792 array_table = RTL8188EEPHY_REG_1TARRAY;
793
794 for (i = 0; i < arraylen; i += 2) {
795 v1 = array_table[i];
796 v2 = array_table[i + 1];
797 if (v1 < 0xcdcdcdcd) {
798 _rtl8188e_config_bb_reg(hw, v1, v2);
799 } else {/*This line is the start line of branch.*/
800 if (!check_cond(hw, array_table[i])) {
801 /*Discard the following (offset, data) pairs*/
802 NEXT_PAIR(v1, v2, i);
803 while (v2 != 0xDEAD &&
804 v2 != 0xCDEF &&
805 v2 != 0xCDCD && i < arraylen - 2)
806 NEXT_PAIR(v1, v2, i);
807 i -= 2; /* prevent from for-loop += 2*/
808 } else {
809 /* Configure matched pairs and skip to end */
810 NEXT_PAIR(v1, v2, i);
811 while (v2 != 0xDEAD &&
812 v2 != 0xCDEF &&
813 v2 != 0xCDCD && i < arraylen - 2) {
814 _rtl8188e_config_bb_reg(hw, v1, v2);
815 NEXT_PAIR(v1, v2, i);
816 }
817
818 while (v2 != 0xDEAD && i < arraylen - 2)
819 NEXT_PAIR(v1, v2, i);
820 }
821 }
822 }
823}
824
825static void store_pwrindex_offset(struct ieee80211_hw *hw,
826 u32 regaddr, u32 bitmask,
827 u32 data)
828{
829 struct rtl_priv *rtlpriv = rtl_priv(hw);
830 struct rtl_phy *rtlphy = &(rtlpriv->phy);
831
832 if (regaddr == RTXAGC_A_RATE18_06) {
833 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0] = data;
834 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
835 "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
836 rtlphy->pwrgroup_cnt,
837 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0]);
838 }
839 if (regaddr == RTXAGC_A_RATE54_24) {
840 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1] = data;
841 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
842 "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
843 rtlphy->pwrgroup_cnt,
844 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1]);
845 }
846 if (regaddr == RTXAGC_A_CCK1_MCS32) {
847 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6] = data;
848 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
849 "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
850 rtlphy->pwrgroup_cnt,
851 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6]);
852 }
853 if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
854 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7] = data;
855 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
856 "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
857 rtlphy->pwrgroup_cnt,
858 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7]);
859 }
860 if (regaddr == RTXAGC_A_MCS03_MCS00) {
861 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2] = data;
862 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
863 "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
864 rtlphy->pwrgroup_cnt,
865 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2]);
866 }
867 if (regaddr == RTXAGC_A_MCS07_MCS04) {
868 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3] = data;
869 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
870 "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
871 rtlphy->pwrgroup_cnt,
872 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3]);
873 }
874 if (regaddr == RTXAGC_A_MCS11_MCS08) {
875 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4] = data;
876 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
877 "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
878 rtlphy->pwrgroup_cnt,
879 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4]);
880 }
881 if (regaddr == RTXAGC_A_MCS15_MCS12) {
882 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5] = data;
883 if (get_rf_type(rtlphy) == RF_1T1R)
884 rtlphy->pwrgroup_cnt++;
885 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
886 "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
887 rtlphy->pwrgroup_cnt,
888 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5]);
889 }
890 if (regaddr == RTXAGC_B_RATE18_06) {
891 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8] = data;
892 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
893 "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
894 rtlphy->pwrgroup_cnt,
895 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8]);
896 }
897 if (regaddr == RTXAGC_B_RATE54_24) {
898 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9] = data;
899 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
900 "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
901 rtlphy->pwrgroup_cnt,
902 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9]);
903 }
904 if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
905 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14] = data;
906 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
907 "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
908 rtlphy->pwrgroup_cnt,
909 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14]);
910 }
911 if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
912 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15] = data;
913 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
914 "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
915 rtlphy->pwrgroup_cnt,
916 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15]);
917 }
918 if (regaddr == RTXAGC_B_MCS03_MCS00) {
919 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10] = data;
920 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
921 "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
922 rtlphy->pwrgroup_cnt,
923 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10]);
924 }
925 if (regaddr == RTXAGC_B_MCS07_MCS04) {
926 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11] = data;
927 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
928 "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
929 rtlphy->pwrgroup_cnt,
930 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11]);
931 }
932 if (regaddr == RTXAGC_B_MCS11_MCS08) {
933 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12] = data;
934 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
935 "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
936 rtlphy->pwrgroup_cnt,
937 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12]);
938 }
939 if (regaddr == RTXAGC_B_MCS15_MCS12) {
940 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13] = data;
941 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
942 "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
943 rtlphy->pwrgroup_cnt,
944 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13]);
945 if (get_rf_type(rtlphy) != RF_1T1R)
946 rtlphy->pwrgroup_cnt++;
947 }
948}
949
950#define READ_NEXT_RF_PAIR(v1, v2, i) \
951 do { \
952 i += 2; v1 = a_table[i]; \
953 v2 = a_table[i + 1]; \
954 } while (0)
955
956bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
957 enum radio_path rfpath)
958{
959 int i;
960 u32 *a_table;
961 u16 a_len;
962 struct rtl_priv *rtlpriv = rtl_priv(hw);
963 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
964 u32 v1 = 0, v2 = 0;
965
966 a_len = RTL8188EE_RADIOA_1TARRAYLEN;
967 a_table = RTL8188EE_RADIOA_1TARRAY;
968 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
969 "Radio_A:RTL8188EE_RADIOA_1TARRAY %d\n", a_len);
970 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
971 switch (rfpath) {
972 case RF90_PATH_A:
973 for (i = 0; i < a_len; i = i + 2) {
974 v1 = a_table[i];
975 v2 = a_table[i + 1];
976 if (v1 < 0xcdcdcdcd) {
977 rtl88_config_s(hw, v1, v2);
978 } else {/*This line is the start line of branch.*/
979 if (!check_cond(hw, a_table[i])) {
980 /* Discard the following (offset, data)
981 * pairs
982 */
983 READ_NEXT_RF_PAIR(v1, v2, i);
984 while (v2 != 0xDEAD && v2 != 0xCDEF &&
985 v2 != 0xCDCD && i < a_len - 2)
986 READ_NEXT_RF_PAIR(v1, v2, i);
987 i -= 2; /* prevent from for-loop += 2*/
988 } else {
989 /* Configure matched pairs and skip to
990 * end of if-else.
991 */
992 READ_NEXT_RF_PAIR(v1, v2, i);
993 while (v2 != 0xDEAD && v2 != 0xCDEF &&
994 v2 != 0xCDCD && i < a_len - 2) {
995 rtl88_config_s(hw, v1, v2);
996 READ_NEXT_RF_PAIR(v1, v2, i);
997 }
998
999 while (v2 != 0xDEAD && i < a_len - 2)
1000 READ_NEXT_RF_PAIR(v1, v2, i);
1001 }
1002 }
1003 }
1004
1005 if (rtlhal->oem_id == RT_CID_819x_HP)
1006 rtl88_config_s(hw, 0x52, 0x7E4BD);
1007
1008 break;
1009
1010 case RF90_PATH_B:
1011 case RF90_PATH_C:
1012 case RF90_PATH_D:
1013 default:
1014 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1015 "switch case not processed\n");
1016 break;
1017 }
1018 return true;
1019}
1020
1021void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1022{
1023 struct rtl_priv *rtlpriv = rtl_priv(hw);
1024 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1025
1026 rtlphy->default_initialgain[0] = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1,
1027 MASKBYTE0);
1028 rtlphy->default_initialgain[1] = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1,
1029 MASKBYTE0);
1030 rtlphy->default_initialgain[2] = rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1,
1031 MASKBYTE0);
1032 rtlphy->default_initialgain[3] = rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1,
1033 MASKBYTE0);
1034
1035 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1036 "Default initial gain (c50 = 0x%x, c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n",
1037 rtlphy->default_initialgain[0],
1038 rtlphy->default_initialgain[1],
1039 rtlphy->default_initialgain[2],
1040 rtlphy->default_initialgain[3]);
1041
1042 rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
1043 MASKBYTE0);
1044 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
1045 MASKDWORD);
1046
1047 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1048 "Default framesync (0x%x) = 0x%x\n",
1049 ROFDM0_RXDETECTOR3, rtlphy->framesync);
1050}
1051
1052void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
1053{
1054 struct rtl_priv *rtlpriv = rtl_priv(hw);
1055 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1056 u8 level;
1057 long dbm;
1058
1059 level = rtlphy->cur_cck_txpwridx;
1060 dbm = rtl88e_pwr_idx_dbm(hw, WIRELESS_MODE_B, level);
1061 level = rtlphy->cur_ofdm24g_txpwridx;
1062 if (rtl88e_pwr_idx_dbm(hw, WIRELESS_MODE_G, level) > dbm)
1063 dbm = rtl88e_pwr_idx_dbm(hw, WIRELESS_MODE_G, level);
1064 level = rtlphy->cur_ofdm24g_txpwridx;
1065 if (rtl88e_pwr_idx_dbm(hw, WIRELESS_MODE_N_24G, level) > dbm)
1066 dbm = rtl88e_pwr_idx_dbm(hw, WIRELESS_MODE_N_24G, level);
1067 *powerlevel = dbm;
1068}
1069
1070static void _rtl88e_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
1071 u8 *cckpower, u8 *ofdm, u8 *bw20_pwr,
1072 u8 *bw40_pwr)
1073{
1074 struct rtl_efuse *fuse = rtl_efuse(rtl_priv(hw));
1075 u8 i = (channel - 1);
1076 u8 rf_path = 0;
1077 int jj = RF90_PATH_A;
1078 int kk = RF90_PATH_B;
1079
1080 for (rf_path = 0; rf_path < 2; rf_path++) {
1081 if (rf_path == jj) {
1082 cckpower[jj] = fuse->txpwrlevel_cck[jj][i];
1083 if (fuse->txpwr_ht20diff[jj][i] > 0x0f) /*-8~7 */
1084 bw20_pwr[jj] = fuse->txpwrlevel_ht40_1s[jj][i] -
1085 (~(fuse->txpwr_ht20diff[jj][i]) + 1);
1086 else
1087 bw20_pwr[jj] = fuse->txpwrlevel_ht40_1s[jj][i] +
1088 fuse->txpwr_ht20diff[jj][i];
1089 if (fuse->txpwr_legacyhtdiff[jj][i] > 0xf)
1090 ofdm[jj] = fuse->txpwrlevel_ht40_1s[jj][i] -
1091 (~(fuse->txpwr_legacyhtdiff[jj][i])+1);
1092 else
1093 ofdm[jj] = fuse->txpwrlevel_ht40_1s[jj][i] +
1094 fuse->txpwr_legacyhtdiff[jj][i];
1095 bw40_pwr[jj] = fuse->txpwrlevel_ht40_1s[jj][i];
1096
1097 } else if (rf_path == kk) {
1098 cckpower[kk] = fuse->txpwrlevel_cck[kk][i];
1099 bw20_pwr[kk] = fuse->txpwrlevel_ht40_1s[kk][i] +
1100 fuse->txpwr_ht20diff[kk][i];
1101 ofdm[kk] = fuse->txpwrlevel_ht40_1s[kk][i] +
1102 fuse->txpwr_legacyhtdiff[kk][i];
1103 bw40_pwr[kk] = fuse->txpwrlevel_ht40_1s[kk][i];
1104 }
1105 }
1106}
1107
1108static void _rtl88e_ccxpower_index_check(struct ieee80211_hw *hw,
1109 u8 channel, u8 *cckpower,
1110 u8 *ofdm, u8 *bw20_pwr,
1111 u8 *bw40_pwr)
1112{
1113 struct rtl_priv *rtlpriv = rtl_priv(hw);
1114 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1115
1116 rtlphy->cur_cck_txpwridx = cckpower[0];
1117 rtlphy->cur_ofdm24g_txpwridx = ofdm[0];
1118 rtlphy->cur_bw20_txpwridx = bw20_pwr[0];
1119 rtlphy->cur_bw40_txpwridx = bw40_pwr[0];
1120}
1121
1122void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1123{
1124 struct rtl_efuse *fuse = rtl_efuse(rtl_priv(hw));
1125 u8 cckpower[MAX_TX_COUNT] = {0}, ofdm[MAX_TX_COUNT] = {0};
1126 u8 bw20_pwr[MAX_TX_COUNT] = {0}, bw40_pwr[MAX_TX_COUNT] = {0};
1127
1128 if (fuse->txpwr_fromeprom == false)
1129 return;
1130 _rtl88e_get_txpower_index(hw, channel, &cckpower[0], &ofdm[0],
1131 &bw20_pwr[0], &bw40_pwr[0]);
1132 _rtl88e_ccxpower_index_check(hw, channel, &cckpower[0], &ofdm[0],
1133 &bw20_pwr[0], &bw40_pwr[0]);
1134 rtl88e_phy_rf6052_set_cck_txpower(hw, &cckpower[0]);
1135 rtl88e_phy_rf6052_set_ofdm_txpower(hw, &ofdm[0], &bw20_pwr[0],
1136 &bw40_pwr[0], channel);
1137}
1138
1139void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1140{
1141 struct rtl_priv *rtlpriv = rtl_priv(hw);
1142 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1143 enum io_type iotype;
1144
1145 if (!is_hal_stop(rtlhal)) {
1146 switch (operation) {
1147 case SCAN_OPT_BACKUP:
1148 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1149 rtlpriv->cfg->ops->set_hw_reg(hw,
1150 HW_VAR_IO_CMD,
1151 (u8 *)&iotype);
1152 break;
1153 case SCAN_OPT_RESTORE:
1154 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1155 rtlpriv->cfg->ops->set_hw_reg(hw,
1156 HW_VAR_IO_CMD,
1157 (u8 *)&iotype);
1158 break;
1159 default:
1160 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1161 "Unknown Scan Backup operation.\n");
1162 break;
1163 }
1164 }
1165}
1166
1167void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1168{
1169 struct rtl_priv *rtlpriv = rtl_priv(hw);
1170 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1171 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1172 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1173 u8 reg_bw_opmode;
1174 u8 reg_prsr_rsc;
1175
1176 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1177 "Switch to %s bandwidth\n",
1178 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1179 "20MHz" : "40MHz");
1180
1181 if (is_hal_stop(rtlhal)) {
1182 rtlphy->set_bwmode_inprogress = false;
1183 return;
1184 }
1185
1186 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1187 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1188
1189 switch (rtlphy->current_chan_bw) {
1190 case HT_CHANNEL_WIDTH_20:
1191 reg_bw_opmode |= BW_OPMODE_20MHZ;
1192 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1193 break;
1194 case HT_CHANNEL_WIDTH_20_40:
1195 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1196 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1197 reg_prsr_rsc =
1198 (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
1199 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1200 break;
1201 default:
1202 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1203 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1204 break;
1205 }
1206
1207 switch (rtlphy->current_chan_bw) {
1208 case HT_CHANNEL_WIDTH_20:
1209 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1210 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1211 /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/
1212 break;
1213 case HT_CHANNEL_WIDTH_20_40:
1214 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1215 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1216
1217 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1218 (mac->cur_40_prime_sc >> 1));
1219 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1220 /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/
1221
1222 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1223 (mac->cur_40_prime_sc ==
1224 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1225 break;
1226 default:
1227 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1228 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1229 break;
1230 }
1231 rtl88e_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1232 rtlphy->set_bwmode_inprogress = false;
1233 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1234}
1235
1236void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw,
1237 enum nl80211_channel_type ch_type)
1238{
1239 struct rtl_priv *rtlpriv = rtl_priv(hw);
1240 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1241 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1242 u8 tmp_bw = rtlphy->current_chan_bw;
1243
1244 if (rtlphy->set_bwmode_inprogress)
1245 return;
1246 rtlphy->set_bwmode_inprogress = true;
1247 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1248 rtl88e_phy_set_bw_mode_callback(hw);
1249 } else {
1250 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1251 "FALSE driver sleep or unload\n");
1252 rtlphy->set_bwmode_inprogress = false;
1253 rtlphy->current_chan_bw = tmp_bw;
1254 }
1255}
1256
1257void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1258{
1259 struct rtl_priv *rtlpriv = rtl_priv(hw);
1260 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1261 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1262 u32 delay;
1263
1264 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1265 "switch to channel%d\n", rtlphy->current_channel);
1266 if (is_hal_stop(rtlhal))
1267 return;
1268 do {
1269 if (!rtlphy->sw_chnl_inprogress)
1270 break;
1271 if (!chnl_step_by_step(hw, rtlphy->current_channel,
1272 &rtlphy->sw_chnl_stage,
1273 &rtlphy->sw_chnl_step, &delay)) {
1274 if (delay > 0)
1275 mdelay(delay);
1276 else
1277 continue;
1278 } else {
1279 rtlphy->sw_chnl_inprogress = false;
1280 }
1281 break;
1282 } while (true);
1283 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1284}
1285
1286u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw)
1287{
1288 struct rtl_priv *rtlpriv = rtl_priv(hw);
1289 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1290 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1291
1292 if (rtlphy->sw_chnl_inprogress)
1293 return 0;
1294 if (rtlphy->set_bwmode_inprogress)
1295 return 0;
1296 RT_ASSERT((rtlphy->current_channel <= 14),
1297 "WIRELESS_MODE_G but channel>14");
1298 rtlphy->sw_chnl_inprogress = true;
1299 rtlphy->sw_chnl_stage = 0;
1300 rtlphy->sw_chnl_step = 0;
1301 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1302 rtl88e_phy_sw_chnl_callback(hw);
1303 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1304 "sw_chnl_inprogress false schdule workitem current channel %d\n",
1305 rtlphy->current_channel);
1306 rtlphy->sw_chnl_inprogress = false;
1307 } else {
1308 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1309 "sw_chnl_inprogress false driver sleep or unload\n");
1310 rtlphy->sw_chnl_inprogress = false;
1311 }
1312 return 1;
1313}
1314
1315static u8 _rtl88e_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1316{
1317 u32 reg_eac, reg_e94, reg_e9c;
1318 u8 result = 0x00;
1319
1320 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c);
1321 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c);
1322 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a);
1323 rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000);
1324
1325 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1326 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1327 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1328
1329 mdelay(IQK_DELAY_TIME);
1330
1331 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1332 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1333 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1334
1335 if (!(reg_eac & BIT(28)) &&
1336 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1337 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1338 result |= 0x01;
1339 return result;
1340}
1341
1342static u8 _rtl88e_phy_path_b_iqk(struct ieee80211_hw *hw)
1343{
1344 u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
1345 u8 result = 0x00;
1346
1347 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
1348 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
1349 mdelay(IQK_DELAY_TIME);
1350 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1351 reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1352 reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1353 reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1354 reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1355
1356 if (!(reg_eac & BIT(31)) &&
1357 (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
1358 (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
1359 result |= 0x01;
1360 else
1361 return result;
1362 if (!(reg_eac & BIT(30)) &&
1363 (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
1364 (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
1365 result |= 0x02;
1366 return result;
1367}
1368
1369static u8 _rtl88e_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
1370{
1371 u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32temp;
1372 u8 result = 0x00;
1373 int jj = RF90_PATH_A;
1374
1375 /*Get TXIMR Setting*/
1376 /*Modify RX IQK mode table*/
1377 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1378 rtl_set_rfreg(hw, jj, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1379 rtl_set_rfreg(hw, jj, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1380 rtl_set_rfreg(hw, jj, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
1381 rtl_set_rfreg(hw, jj, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
1382 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1383
1384 /*IQK Setting*/
1385 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1386 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x81004800);
1387
1388 /*path a IQK setting*/
1389 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x10008c1c);
1390 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x30008c1c);
1391 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160804);
1392 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1393
1394 /*LO calibration Setting*/
1395 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1396 /*one shot, path A LOK & iqk*/
1397 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1398 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1399
1400 mdelay(IQK_DELAY_TIME);
1401
1402 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1403 reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1404 reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1405
1406
1407 if (!(reg_eac & BIT(28)) &&
1408 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1409 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1410 result |= 0x01;
1411 else
1412 return result;
1413
1414 u32temp = 0x80007C00 | (reg_e94&0x3FF0000) |
1415 ((reg_e9c&0x3FF0000) >> 16);
1416 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
1417 /*RX IQK*/
1418 /*Modify RX IQK mode table*/
1419 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1420 rtl_set_rfreg(hw, jj, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1421 rtl_set_rfreg(hw, jj, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1422 rtl_set_rfreg(hw, jj, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
1423 rtl_set_rfreg(hw, jj, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
1424 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1425
1426 /*IQK Setting*/
1427 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1428
1429 /*path a IQK setting*/
1430 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x30008c1c);
1431 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x10008c1c);
1432 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c05);
1433 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c05);
1434
1435 /*LO calibration Setting*/
1436 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1437 /*one shot, path A LOK & iqk*/
1438 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1439 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1440
1441 mdelay(IQK_DELAY_TIME);
1442
1443 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1444 reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1445 reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1446 reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1447
1448 if (!(reg_eac & BIT(27)) &&
1449 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1450 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1451 result |= 0x02;
1452 return result;
1453}
1454
1455static void fill_iqk(struct ieee80211_hw *hw, bool iqk_ok, long result[][8],
1456 u8 final, bool btxonly)
1457{
1458 u32 oldval_0, x, tx0_a, reg;
1459 long y, tx0_c;
1460
1461 if (final == 0xFF) {
1462 return;
1463 } else if (iqk_ok) {
1464 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBAL,
1465 MASKDWORD) >> 22) & 0x3FF;
1466 x = result[final][0];
1467 if ((x & 0x00000200) != 0)
1468 x = x | 0xFFFFFC00;
1469 tx0_a = (x * oldval_0) >> 8;
1470 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBAL, 0x3FF, tx0_a);
1471 rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(31),
1472 ((x * oldval_0 >> 7) & 0x1));
1473 y = result[final][1];
1474 if ((y & 0x00000200) != 0)
1475 y |= 0xFFFFFC00;
1476 tx0_c = (y * oldval_0) >> 8;
1477 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1478 ((tx0_c & 0x3C0) >> 6));
1479 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBAL, 0x003F0000,
1480 (tx0_c & 0x3F));
1481 rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(29),
1482 ((y * oldval_0 >> 7) & 0x1));
1483 if (btxonly)
1484 return;
1485 reg = result[final][2];
1486 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBAL, 0x3FF, reg);
1487 reg = result[final][3] & 0x3F;
1488 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBAL, 0xFC00, reg);
1489 reg = (result[final][3] >> 6) & 0xF;
1490 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1491 }
1492}
1493
1494static void save_adda_reg(struct ieee80211_hw *hw,
1495 const u32 *addareg, u32 *backup,
1496 u32 registernum)
1497{
1498 u32 i;
1499
1500 for (i = 0; i < registernum; i++)
1501 backup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1502}
1503
1504static void save_mac_reg(struct ieee80211_hw *hw, const u32 *macreg,
1505 u32 *macbackup)
1506{
1507 struct rtl_priv *rtlpriv = rtl_priv(hw);
1508 u32 i;
1509
1510 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1511 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1512 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1513}
1514
1515static void reload_adda(struct ieee80211_hw *hw, const u32 *addareg,
1516 u32 *backup, u32 reg_num)
1517{
1518 u32 i;
1519
1520 for (i = 0; i < reg_num; i++)
1521 rtl_set_bbreg(hw, addareg[i], MASKDWORD, backup[i]);
1522}
1523
1524static void reload_mac(struct ieee80211_hw *hw, const u32 *macreg,
1525 u32 *macbackup)
1526{
1527 struct rtl_priv *rtlpriv = rtl_priv(hw);
1528 u32 i;
1529
1530 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1531 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1532 rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1533}
1534
1535static void _rtl88e_phy_path_adda_on(struct ieee80211_hw *hw,
1536 const u32 *addareg, bool is_patha_on,
1537 bool is2t)
1538{
1539 u32 pathon;
1540 u32 i;
1541
1542 pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1543 if (false == is2t) {
1544 pathon = 0x0bdb25a0;
1545 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1546 } else {
1547 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
1548 }
1549
1550 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1551 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon);
1552}
1553
1554static void _rtl88e_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1555 const u32 *macreg,
1556 u32 *macbackup)
1557{
1558 struct rtl_priv *rtlpriv = rtl_priv(hw);
1559 u32 i = 0;
1560
1561 rtl_write_byte(rtlpriv, macreg[i], 0x3F);
1562
1563 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1564 rtl_write_byte(rtlpriv, macreg[i],
1565 (u8) (macbackup[i] & (~BIT(3))));
1566 rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1567}
1568
1569static void _rtl88e_phy_path_a_standby(struct ieee80211_hw *hw)
1570{
1571 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1572 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1573 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1574}
1575
1576static void _rtl88e_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1577{
1578 u32 mode;
1579
1580 mode = pi_mode ? 0x01000100 : 0x01000000;
1581 rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1582 rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1583}
1584
1585static bool sim_comp(struct ieee80211_hw *hw, long result[][8], u8 c1, u8 c2)
1586{
1587 u32 i, j, diff, bitmap, bound;
1588 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1589
1590 u8 final[2] = {0xFF, 0xFF};
1591 bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1592
1593 if (is2t)
1594 bound = 8;
1595 else
1596 bound = 4;
1597
1598 bitmap = 0;
1599
1600 for (i = 0; i < bound; i++) {
1601 diff = (result[c1][i] > result[c2][i]) ?
1602 (result[c1][i] - result[c2][i]) :
1603 (result[c2][i] - result[c1][i]);
1604
1605 if (diff > MAX_TOLERANCE) {
1606 if ((i == 2 || i == 6) && !bitmap) {
1607 if (result[c1][i] + result[c1][i + 1] == 0)
1608 final[(i / 4)] = c2;
1609 else if (result[c2][i] + result[c2][i + 1] == 0)
1610 final[(i / 4)] = c1;
1611 else
1612 bitmap = bitmap | (1 << i);
1613 } else {
1614 bitmap = bitmap | (1 << i);
1615 }
1616 }
1617 }
1618
1619 if (bitmap == 0) {
1620 for (i = 0; i < (bound / 4); i++) {
1621 if (final[i] != 0xFF) {
1622 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1623 result[3][j] = result[final[i]][j];
1624 bresult = false;
1625 }
1626 }
1627 return bresult;
1628 } else if (!(bitmap & 0x0F)) {
1629 for (i = 0; i < 4; i++)
1630 result[3][i] = result[c1][i];
1631 return false;
1632 } else if (!(bitmap & 0xF0) && is2t) {
1633 for (i = 4; i < 8; i++)
1634 result[3][i] = result[c1][i];
1635 return false;
1636 } else {
1637 return false;
1638 }
1639}
1640
1641static void _rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw,
1642 long result[][8], u8 t, bool is2t)
1643{
1644 struct rtl_priv *rtlpriv = rtl_priv(hw);
1645 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1646 u32 i;
1647 u8 patha_ok, pathb_ok;
1648 const u32 adda_reg[IQK_ADDA_REG_NUM] = {
1649 0x85c, 0xe6c, 0xe70, 0xe74,
1650 0xe78, 0xe7c, 0xe80, 0xe84,
1651 0xe88, 0xe8c, 0xed0, 0xed4,
1652 0xed8, 0xedc, 0xee0, 0xeec
1653 };
1654 const u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1655 0x522, 0x550, 0x551, 0x040
1656 };
1657 const u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1658 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR, RFPGA0_XCD_RFINTERFACESW,
1659 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0x800
1660 };
1661 const u32 retrycount = 2;
1662
1663 if (t == 0) {
1664 save_adda_reg(hw, adda_reg, rtlphy->adda_backup, 16);
1665 save_mac_reg(hw, iqk_mac_reg, rtlphy->iqk_mac_backup);
1666 save_adda_reg(hw, iqk_bb_reg, rtlphy->iqk_bb_backup,
1667 IQK_BB_REG_NUM);
1668 }
1669 _rtl88e_phy_path_adda_on(hw, adda_reg, true, is2t);
1670 if (t == 0) {
1671 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1672 RFPGA0_XA_HSSIPARAMETER1, BIT(8));
1673 }
1674
1675 if (!rtlphy->rfpi_enable)
1676 _rtl88e_phy_pi_mode_switch(hw, true);
1677 /*BB Setting*/
1678 rtl_set_bbreg(hw, 0x800, BIT(24), 0x00);
1679 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1680 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1681 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1682
1683 rtl_set_bbreg(hw, 0x870, BIT(10), 0x01);
1684 rtl_set_bbreg(hw, 0x870, BIT(26), 0x01);
1685 rtl_set_bbreg(hw, 0x860, BIT(10), 0x00);
1686 rtl_set_bbreg(hw, 0x864, BIT(10), 0x00);
1687
1688 if (is2t) {
1689 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1690 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1691 }
1692 _rtl88e_phy_mac_setting_calibration(hw, iqk_mac_reg,
1693 rtlphy->iqk_mac_backup);
1694 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
1695 if (is2t)
1696 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000);
1697
1698 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1699 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1700 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800);
1701 for (i = 0; i < retrycount; i++) {
1702 patha_ok = _rtl88e_phy_path_a_iqk(hw, is2t);
1703 if (patha_ok == 0x01) {
1704 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1705 "Path A Tx IQK Success!!\n");
1706 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1707 0x3FF0000) >> 16;
1708 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1709 0x3FF0000) >> 16;
1710 break;
1711 }
1712 }
1713
1714 for (i = 0; i < retrycount; i++) {
1715 patha_ok = _rtl88e_phy_path_a_rx_iqk(hw, is2t);
1716 if (patha_ok == 0x03) {
1717 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1718 "Path A Rx IQK Success!!\n");
1719 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1720 0x3FF0000) >> 16;
1721 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1722 0x3FF0000) >> 16;
1723 break;
1724 } else {
1725 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1726 "Path a RX iqk fail!!!\n");
1727 }
1728 }
1729
1730 if (0 == patha_ok) {
1731 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1732 "Path A IQK Success!!\n");
1733 }
1734 if (is2t) {
1735 _rtl88e_phy_path_a_standby(hw);
1736 _rtl88e_phy_path_adda_on(hw, adda_reg, false, is2t);
1737 for (i = 0; i < retrycount; i++) {
1738 pathb_ok = _rtl88e_phy_path_b_iqk(hw);
1739 if (pathb_ok == 0x03) {
1740 result[t][4] = (rtl_get_bbreg(hw,
1741 0xeb4, MASKDWORD) &
1742 0x3FF0000) >> 16;
1743 result[t][5] =
1744 (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1745 0x3FF0000) >> 16;
1746 result[t][6] =
1747 (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1748 0x3FF0000) >> 16;
1749 result[t][7] =
1750 (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1751 0x3FF0000) >> 16;
1752 break;
1753 } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1754 result[t][4] = (rtl_get_bbreg(hw,
1755 0xeb4, MASKDWORD) &
1756 0x3FF0000) >> 16;
1757 }
1758 result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1759 0x3FF0000) >> 16;
1760 }
1761 }
1762
1763 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1764
1765 if (t != 0) {
1766 if (!rtlphy->rfpi_enable)
1767 _rtl88e_phy_pi_mode_switch(hw, false);
1768 reload_adda(hw, adda_reg, rtlphy->adda_backup, 16);
1769 reload_mac(hw, iqk_mac_reg, rtlphy->iqk_mac_backup);
1770 reload_adda(hw, iqk_bb_reg, rtlphy->iqk_bb_backup,
1771 IQK_BB_REG_NUM);
1772
1773 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1774 if (is2t)
1775 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1776 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
1777 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
1778 }
1779 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "88ee IQK Finish!!\n");
1780}
1781
1782static void _rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1783{
1784 u8 tmpreg;
1785 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1786 struct rtl_priv *rtlpriv = rtl_priv(hw);
1787 int jj = RF90_PATH_A;
1788 int kk = RF90_PATH_B;
1789
1790 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1791
1792 if ((tmpreg & 0x70) != 0)
1793 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1794 else
1795 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1796
1797 if ((tmpreg & 0x70) != 0) {
1798 rf_a_mode = rtl_get_rfreg(hw, jj, 0x00, MASK12BITS);
1799
1800 if (is2t)
1801 rf_b_mode = rtl_get_rfreg(hw, kk, 0x00,
1802 MASK12BITS);
1803
1804 rtl_set_rfreg(hw, jj, 0x00, MASK12BITS,
1805 (rf_a_mode & 0x8FFFF) | 0x10000);
1806
1807 if (is2t)
1808 rtl_set_rfreg(hw, kk, 0x00, MASK12BITS,
1809 (rf_b_mode & 0x8FFFF) | 0x10000);
1810 }
1811 lc_cal = rtl_get_rfreg(hw, jj, 0x18, MASK12BITS);
1812
1813 rtl_set_rfreg(hw, jj, 0x18, MASK12BITS, lc_cal | 0x08000);
1814
1815 mdelay(100);
1816
1817 if ((tmpreg & 0x70) != 0) {
1818 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1819 rtl_set_rfreg(hw, jj, 0x00, MASK12BITS, rf_a_mode);
1820
1821 if (is2t)
1822 rtl_set_rfreg(hw, kk, 0x00, MASK12BITS,
1823 rf_b_mode);
1824 } else {
1825 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1826 }
1827 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1828}
1829
1830static void rfpath_switch(struct ieee80211_hw *hw,
1831 bool bmain, bool is2t)
1832{
1833 struct rtl_priv *rtlpriv = rtl_priv(hw);
1834 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1835 struct rtl_efuse *fuse = rtl_efuse(rtl_priv(hw));
1836 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1837
1838 if (is_hal_stop(rtlhal)) {
1839 u8 u1btmp;
1840 u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
1841 rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
1842 rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1843 }
1844 if (is2t) {
1845 if (bmain)
1846 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1847 BIT(5) | BIT(6), 0x1);
1848 else
1849 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1850 BIT(5) | BIT(6), 0x2);
1851 } else {
1852 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
1853 rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
1854
1855 /* We use the RF definition of MAIN and AUX, left antenna and
1856 * right antenna repectively.
1857 * Default output at AUX.
1858 */
1859 if (bmain) {
1860 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(14) |
1861 BIT(13) | BIT(12), 0);
1862 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(5) |
1863 BIT(4) | BIT(3), 0);
1864 if (fuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1865 rtl_set_bbreg(hw, RCONFIG_RAM64X16, BIT(31), 0);
1866 } else {
1867 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(14) |
1868 BIT(13) | BIT(12), 1);
1869 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(5) |
1870 BIT(4) | BIT(3), 1);
1871 if (fuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1872 rtl_set_bbreg(hw, RCONFIG_RAM64X16, BIT(31), 1);
1873 }
1874 }
1875}
1876
1877#undef IQK_ADDA_REG_NUM
1878#undef IQK_DELAY_TIME
1879
1880void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1881{
1882 struct rtl_priv *rtlpriv = rtl_priv(hw);
1883 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1884 long result[4][8];
1885 u8 i, final;
1886 bool patha_ok;
1887 long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_tmp = 0;
1888 bool is12simular, is13simular, is23simular;
1889 u32 iqk_bb_reg[9] = {
1890 ROFDM0_XARXIQIMBAL,
1891 ROFDM0_XBRXIQIMBAL,
1892 ROFDM0_ECCATHRES,
1893 ROFDM0_AGCRSSITABLE,
1894 ROFDM0_XATXIQIMBAL,
1895 ROFDM0_XBTXIQIMBAL,
1896 ROFDM0_XCTXAFE,
1897 ROFDM0_XDTXAFE,
1898 ROFDM0_RXIQEXTANTA
1899 };
1900
1901 if (recovery) {
1902 reload_adda(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9);
1903 return;
1904 }
1905
1906 memset(result, 0, 32 * sizeof(long));
1907 final = 0xff;
1908 patha_ok = false;
1909 is12simular = false;
1910 is23simular = false;
1911 is13simular = false;
1912 for (i = 0; i < 3; i++) {
1913 if (get_rf_type(rtlphy) == RF_2T2R)
1914 _rtl88e_phy_iq_calibrate(hw, result, i, true);
1915 else
1916 _rtl88e_phy_iq_calibrate(hw, result, i, false);
1917 if (i == 1) {
1918 is12simular = sim_comp(hw, result, 0, 1);
1919 if (is12simular) {
1920 final = 0;
1921 break;
1922 }
1923 }
1924 if (i == 2) {
1925 is13simular = sim_comp(hw, result, 0, 2);
1926 if (is13simular) {
1927 final = 0;
1928 break;
1929 }
1930 is23simular = sim_comp(hw, result, 1, 2);
1931 if (is23simular) {
1932 final = 1;
1933 } else {
1934 for (i = 0; i < 8; i++)
1935 reg_tmp += result[3][i];
1936
1937 if (reg_tmp != 0)
1938 final = 3;
1939 else
1940 final = 0xFF;
1941 }
1942 }
1943 }
1944 for (i = 0; i < 4; i++) {
1945 reg_e94 = result[i][0];
1946 reg_e9c = result[i][1];
1947 reg_ea4 = result[i][2];
1948 reg_eb4 = result[i][4];
1949 reg_ebc = result[i][5];
1950 }
1951 if (final != 0xff) {
1952 reg_e94 = result[final][0];
1953 rtlphy->reg_e94 = reg_e94;
1954 reg_e9c = result[final][1];
1955 rtlphy->reg_e9c = reg_e9c;
1956 reg_ea4 = result[final][2];
1957 reg_eb4 = result[final][4];
1958 rtlphy->reg_eb4 = reg_eb4;
1959 reg_ebc = result[final][5];
1960 rtlphy->reg_ebc = reg_ebc;
1961 patha_ok = true;
1962 } else {
1963 rtlphy->reg_e94 = 0x100;
1964 rtlphy->reg_eb4 = 0x100;
1965 rtlphy->reg_ebc = 0x0;
1966 rtlphy->reg_e9c = 0x0;
1967 }
1968 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1969 fill_iqk(hw, patha_ok, result, final, (reg_ea4 == 0));
1970 if (final != 0xFF) {
1971 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
1972 rtlphy->iqk_matrix[0].value[0][i] = result[final][i];
1973 rtlphy->iqk_matrix[0].iqk_done = true;
1974 }
1975 save_adda_reg(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9);
1976}
1977
1978void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw)
1979{
1980 struct rtl_priv *rtlpriv = rtl_priv(hw);
1981 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1982 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
1983 bool start_conttx = false, singletone = false;
1984 u32 timeout = 2000, timecount = 0;
1985
1986 if (start_conttx || singletone)
1987 return;
1988
1989 while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
1990 udelay(50);
1991 timecount += 50;
1992 }
1993
1994 rtlphy->lck_inprogress = true;
1995 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1996 "LCK:Start!!! currentband %x delay %d ms\n",
1997 rtlhal->current_bandtype, timecount);
1998
1999 _rtl88e_phy_lc_calibrate(hw, false);
2000
2001 rtlphy->lck_inprogress = false;
2002}
2003
2004void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2005{
2006 rfpath_switch(hw, bmain, false);
2007}
2008
2009bool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2010{
2011 struct rtl_priv *rtlpriv = rtl_priv(hw);
2012 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2013 bool postprocessing = false;
2014
2015 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2016 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2017 iotype, rtlphy->set_io_inprogress);
2018 do {
2019 switch (iotype) {
2020 case IO_CMD_RESUME_DM_BY_SCAN:
2021 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2022 "[IO CMD] Resume DM after scan.\n");
2023 postprocessing = true;
2024 break;
2025 case IO_CMD_PAUSE_DM_BY_SCAN:
2026 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2027 "[IO CMD] Pause DM before scan.\n");
2028 postprocessing = true;
2029 break;
2030 default:
2031 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2032 "switch case not processed\n");
2033 break;
2034 }
2035 } while (false);
2036 if (postprocessing && !rtlphy->set_io_inprogress) {
2037 rtlphy->set_io_inprogress = true;
2038 rtlphy->current_io_type = iotype;
2039 } else {
2040 return false;
2041 }
2042 rtl88e_phy_set_io(hw);
2043 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2044 return true;
2045}
2046
2047static void rtl88ee_phy_set_rf_on(struct ieee80211_hw *hw)
2048{
2049 struct rtl_priv *rtlpriv = rtl_priv(hw);
2050
2051 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2052 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2053 /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/
2054 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2055 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2056 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2057}
2058
2059static void _rtl88ee_phy_set_rf_sleep(struct ieee80211_hw *hw)
2060{
2061 struct rtl_priv *rtlpriv = rtl_priv(hw);
2062 int jj = RF90_PATH_A;
2063
2064 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2065 rtl_set_rfreg(hw, jj, 0x00, RFREG_OFFSET_MASK, 0x00);
2066 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2067 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2068}
2069
2070static bool _rtl88ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
2071 enum rf_pwrstate rfpwr_state)
2072{
2073 struct rtl_priv *rtlpriv = rtl_priv(hw);
2074 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2075 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2076 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2077 struct rtl8192_tx_ring *ring = NULL;
2078 bool bresult = true;
2079 u8 i, queue_id;
2080
2081 switch (rfpwr_state) {
2082 case ERFON:{
2083 if ((ppsc->rfpwr_state == ERFOFF) &&
2084 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2085 bool rtstatus;
2086 u32 init = 0;
2087 do {
2088 init++;
2089 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2090 "IPS Set eRf nic enable\n");
2091 rtstatus = rtl_ps_enable_nic(hw);
2092 } while ((rtstatus != true) && (init < 10));
2093 RT_CLEAR_PS_LEVEL(ppsc,
2094 RT_RF_OFF_LEVL_HALT_NIC);
2095 } else {
2096 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2097 "Set ERFON sleeped:%d ms\n",
2098 jiffies_to_msecs(jiffies - ppsc->
2099 last_sleep_jiffies));
2100 ppsc->last_awake_jiffies = jiffies;
2101 rtl88ee_phy_set_rf_on(hw);
2102 }
2103 if (mac->link_state == MAC80211_LINKED)
2104 rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2105 else
2106 rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2107 break; }
2108 case ERFOFF:{
2109 for (queue_id = 0, i = 0;
2110 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2111 ring = &pcipriv->dev.tx_ring[queue_id];
2112 if (skb_queue_len(&ring->queue) == 0) {
2113 queue_id++;
2114 continue;
2115 } else {
2116 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2117 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2118 (i + 1), queue_id,
2119 skb_queue_len(&ring->queue));
2120
2121 udelay(10);
2122 i++;
2123 }
2124 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2125 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2126 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2127 MAX_DOZE_WAITING_TIMES_9x,
2128 queue_id,
2129 skb_queue_len(&ring->queue));
2130 break;
2131 }
2132 }
2133 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2134 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2135 "IPS Set eRf nic disable\n");
2136 rtl_ps_disable_nic(hw);
2137 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2138 } else {
2139 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2140 rtlpriv->cfg->ops->led_control(hw,
2141 LED_CTL_NO_LINK);
2142 } else {
2143 rtlpriv->cfg->ops->led_control(hw,
2144 LED_CTL_POWER_OFF);
2145 }
2146 }
2147 break; }
2148 case ERFSLEEP:{
2149 if (ppsc->rfpwr_state == ERFOFF)
2150 break;
2151 for (queue_id = 0, i = 0;
2152 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2153 ring = &pcipriv->dev.tx_ring[queue_id];
2154 if (skb_queue_len(&ring->queue) == 0) {
2155 queue_id++;
2156 continue;
2157 } else {
2158 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2159 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2160 (i + 1), queue_id,
2161 skb_queue_len(&ring->queue));
2162
2163 udelay(10);
2164 i++;
2165 }
2166 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2167 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2168 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2169 MAX_DOZE_WAITING_TIMES_9x,
2170 queue_id,
2171 skb_queue_len(&ring->queue));
2172 break;
2173 }
2174 }
2175 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2176 "Set ERFSLEEP awaked:%d ms\n",
2177 jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
2178 ppsc->last_sleep_jiffies = jiffies;
2179 _rtl88ee_phy_set_rf_sleep(hw);
2180 break; }
2181 default:
2182 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2183 "switch case not processed\n");
2184 bresult = false;
2185 break;
2186 }
2187 if (bresult)
2188 ppsc->rfpwr_state = rfpwr_state;
2189 return bresult;
2190}
2191
2192bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw,
2193 enum rf_pwrstate rfpwr_state)
2194{
2195 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2196 bool bresult;
2197
2198 if (rfpwr_state == ppsc->rfpwr_state)
2199 return false;
2200 bresult = _rtl88ee_phy_set_rf_power_state(hw, rfpwr_state);
2201 return bresult;
2202}
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h
new file mode 100644
index 000000000000..f1acd6d27e44
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h
@@ -0,0 +1,236 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C_PHY_H__
31#define __RTL92C_PHY_H__
32
33/*It must always set to 4, otherwise read efuse table secquence will be wrong.*/
34#define MAX_TX_COUNT 4
35
36#define MAX_PRECMD_CNT 16
37#define MAX_RFDEPENDCMD_CNT 16
38#define MAX_POSTCMD_CNT 16
39
40#define MAX_DOZE_WAITING_TIMES_9x 64
41
42#define RT_CANNOT_IO(hw) false
43#define HIGHPOWER_RADIOA_ARRAYLEN 22
44
45#define IQK_ADDA_REG_NUM 16
46#define IQK_BB_REG_NUM 9
47#define MAX_TOLERANCE 5
48#define IQK_DELAY_TIME 10
49#define IDX_MAP 15
50
51#define APK_BB_REG_NUM 5
52#define APK_AFE_REG_NUM 16
53#define APK_CURVE_REG_NUM 4
54#define PATH_NUM 2
55
56#define LOOP_LIMIT 5
57#define MAX_STALL_TIME 50
58#define ANTENNADIVERSITYVALUE 0x80
59#define MAX_TXPWR_IDX_NMODE_92S 63
60#define RESET_CNT_LIMIT 3
61
62#define IQK_ADDA_REG_NUM 16
63#define IQK_MAC_REG_NUM 4
64
65#define RF6052_MAX_PATH 2
66
67#define CT_OFFSET_MAC_ADDR 0X16
68
69#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
70#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
71#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66
72#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
73#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
74
75#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
76#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
77
78#define CT_OFFSET_CHANNEL_PLAH 0x75
79#define CT_OFFSET_THERMAL_METER 0x78
80#define CT_OFFSET_RF_OPTION 0x79
81#define CT_OFFSET_VERSION 0x7E
82#define CT_OFFSET_CUSTOMER_ID 0x7F
83
84#define RTL92C_MAX_PATH_NUM 2
85
86enum swchnlcmd_id {
87 CMDID_END,
88 CMDID_SET_TXPOWEROWER_LEVEL,
89 CMDID_BBREGWRITE10,
90 CMDID_WRITEPORT_ULONG,
91 CMDID_WRITEPORT_USHORT,
92 CMDID_WRITEPORT_UCHAR,
93 CMDID_RF_WRITEREG,
94};
95
96struct swchnlcmd {
97 enum swchnlcmd_id cmdid;
98 u32 para1;
99 u32 para2;
100 u32 msdelay;
101};
102
103enum hw90_block_e {
104 HW90_BLOCK_MAC = 0,
105 HW90_BLOCK_PHY0 = 1,
106 HW90_BLOCK_PHY1 = 2,
107 HW90_BLOCK_RF = 3,
108 HW90_BLOCK_MAXIMUM = 4,
109};
110
111enum baseband_config_type {
112 BASEBAND_CONFIG_PHY_REG = 0,
113 BASEBAND_CONFIG_AGC_TAB = 1,
114};
115
116enum ra_offset_area {
117 RA_OFFSET_LEGACY_OFDM1,
118 RA_OFFSET_LEGACY_OFDM2,
119 RA_OFFSET_HT_OFDM1,
120 RA_OFFSET_HT_OFDM2,
121 RA_OFFSET_HT_OFDM3,
122 RA_OFFSET_HT_OFDM4,
123 RA_OFFSET_HT_CCK,
124};
125
126enum antenna_path {
127 ANTENNA_NONE,
128 ANTENNA_D,
129 ANTENNA_C,
130 ANTENNA_CD,
131 ANTENNA_B,
132 ANTENNA_BD,
133 ANTENNA_BC,
134 ANTENNA_BCD,
135 ANTENNA_A,
136 ANTENNA_AD,
137 ANTENNA_AC,
138 ANTENNA_ACD,
139 ANTENNA_AB,
140 ANTENNA_ABD,
141 ANTENNA_ABC,
142 ANTENNA_ABCD
143};
144
145struct r_antenna_select_ofdm {
146 u32 r_tx_antenna:4;
147 u32 r_ant_l:4;
148 u32 r_ant_non_ht:4;
149 u32 r_ant_ht1:4;
150 u32 r_ant_ht2:4;
151 u32 r_ant_ht_s1:4;
152 u32 r_ant_non_ht_s1:4;
153 u32 ofdm_txsc:2;
154 u32 reserved:2;
155};
156
157struct r_antenna_select_cck {
158 u8 r_cckrx_enable_2:2;
159 u8 r_cckrx_enable:2;
160 u8 r_ccktx_enable:4;
161};
162
163
164struct efuse_contents {
165 u8 mac_addr[ETH_ALEN];
166 u8 cck_tx_power_idx[6];
167 u8 ht40_1s_tx_power_idx[6];
168 u8 ht40_2s_tx_power_idx_diff[3];
169 u8 ht20_tx_power_idx_diff[3];
170 u8 ofdm_tx_power_idx_diff[3];
171 u8 ht40_max_power_offset[3];
172 u8 ht20_max_power_offset[3];
173 u8 channel_plan;
174 u8 thermal_meter;
175 u8 rf_option[5];
176 u8 version;
177 u8 oem_id;
178 u8 regulatory;
179};
180
181struct tx_power_struct {
182 u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
183 u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
184 u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
185 u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
186 u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
187 u8 legacy_ht_txpowerdiff;
188 u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
189 u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
190 u8 pwrgroup_cnt;
191 u32 mcs_original_offset[4][16];
192};
193
194enum _ANT_DIV_TYPE {
195 NO_ANTDIV = 0xFF,
196 CG_TRX_HW_ANTDIV = 0x01,
197 CGCS_RX_HW_ANTDIV = 0x02,
198 FIXED_HW_ANTDIV = 0x03,
199 CG_TRX_SMART_ANTDIV = 0x04,
200 CGCS_RX_SW_ANTDIV = 0x05,
201};
202
203extern u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw,
204 u32 regaddr, u32 bitmask);
205extern void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw,
206 u32 regaddr, u32 bitmask, u32 data);
207extern u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw,
208 enum radio_path rfpath, u32 regaddr,
209 u32 bitmask);
210extern void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw,
211 enum radio_path rfpath, u32 regaddr,
212 u32 bitmask, u32 data);
213extern bool rtl88e_phy_mac_config(struct ieee80211_hw *hw);
214extern bool rtl88e_phy_bb_config(struct ieee80211_hw *hw);
215extern bool rtl88e_phy_rf_config(struct ieee80211_hw *hw);
216extern void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
217extern void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw,
218 long *powerlevel);
219extern void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
220extern void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw,
221 u8 operation);
222extern void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
223extern void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw,
224 enum nl80211_channel_type ch_type);
225extern void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw);
226extern u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw);
227extern void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
228void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw);
229void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
230bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
231 enum radio_path rfpath);
232bool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
233extern bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw,
234 enum rf_pwrstate rfpwr_state);
235
236#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.c b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.c
new file mode 100644
index 000000000000..6dc4e3a954f6
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.c
@@ -0,0 +1,109 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "pwrseqcmd.h"
31#include "pwrseq.h"
32
33/* drivers should parse below arrays and do the corresponding actions */
34/*3 Power on Array*/
35struct wlan_pwr_cfg rtl8188e_power_on_flow[RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS +
36 RTL8188E_TRANS_END_STEPS] = {
37 RTL8188E_TRANS_CARDEMU_TO_ACT
38 RTL8188E_TRANS_END
39};
40
41/*3Radio off GPIO Array */
42struct wlan_pwr_cfg rtl8188e_radio_off_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS
43 + RTL8188E_TRANS_END_STEPS] = {
44 RTL8188E_TRANS_ACT_TO_CARDEMU
45 RTL8188E_TRANS_END
46};
47
48/*3Card Disable Array*/
49struct wlan_pwr_cfg rtl8188e_card_disable_flow
50 [RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS +
51 RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS +
52 RTL8188E_TRANS_END_STEPS] = {
53 RTL8188E_TRANS_ACT_TO_CARDEMU
54 RTL8188E_TRANS_CARDEMU_TO_CARDDIS
55 RTL8188E_TRANS_END
56};
57
58/*3 Card Enable Array*/
59struct wlan_pwr_cfg rtl8188e_card_enable_flow
60 [RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS +
61 RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS +
62 RTL8188E_TRANS_END_STEPS] = {
63 RTL8188E_TRANS_CARDDIS_TO_CARDEMU
64 RTL8188E_TRANS_CARDEMU_TO_ACT
65 RTL8188E_TRANS_END
66};
67
68/*3Suspend Array*/
69struct wlan_pwr_cfg rtl8188e_suspend_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS
70 + RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS
71 + RTL8188E_TRANS_END_STEPS] = {
72 RTL8188E_TRANS_ACT_TO_CARDEMU
73 RTL8188E_TRANS_CARDEMU_TO_SUS
74 RTL8188E_TRANS_END
75};
76
77/*3 Resume Array*/
78struct wlan_pwr_cfg rtl8188e_resume_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS
79 + RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS
80 + RTL8188E_TRANS_END_STEPS] = {
81 RTL8188E_TRANS_SUS_TO_CARDEMU
82 RTL8188E_TRANS_CARDEMU_TO_ACT
83 RTL8188E_TRANS_END
84};
85
86/*3HWPDN Array*/
87struct wlan_pwr_cfg rtl8188e_hwpdn_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS
88 + RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS
89 + RTL8188E_TRANS_END_STEPS] = {
90 RTL8188E_TRANS_ACT_TO_CARDEMU
91 RTL8188E_TRANS_CARDEMU_TO_PDN
92 RTL8188E_TRANS_END
93};
94
95/*3 Enter LPS */
96struct wlan_pwr_cfg rtl8188e_enter_lps_flow[RTL8188E_TRANS_ACT_TO_LPS_STEPS
97 + RTL8188E_TRANS_END_STEPS] = {
98 /*FW behavior*/
99 RTL8188E_TRANS_ACT_TO_LPS
100 RTL8188E_TRANS_END
101};
102
103/*3 Leave LPS */
104struct wlan_pwr_cfg rtl8188e_leave_lps_flow[RTL8188E_TRANS_LPS_TO_ACT_STEPS
105 + RTL8188E_TRANS_END_STEPS] = {
106 /*FW behavior*/
107 RTL8188E_TRANS_LPS_TO_ACT
108 RTL8188E_TRANS_END
109};
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h
new file mode 100644
index 000000000000..028ec6dd52b4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h
@@ -0,0 +1,327 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL8723E_PWRSEQ_H__
31#define __RTL8723E_PWRSEQ_H__
32
33#include "pwrseqcmd.h"
34/*
35 Check document WM-20110607-Paul-RTL8188E_Power_Architecture-R02.vsd
36 There are 6 HW Power States:
37 0: POFF--Power Off
38 1: PDN--Power Down
39 2: CARDEMU--Card Emulation
40 3: ACT--Active Mode
41 4: LPS--Low Power State
42 5: SUS--Suspend
43
44 The transision from different states are defined below
45 TRANS_CARDEMU_TO_ACT
46 TRANS_ACT_TO_CARDEMU
47 TRANS_CARDEMU_TO_SUS
48 TRANS_SUS_TO_CARDEMU
49 TRANS_CARDEMU_TO_PDN
50 TRANS_ACT_TO_LPS
51 TRANS_LPS_TO_ACT
52
53 TRANS_END
54 PWR SEQ Version: rtl8188e_PwrSeq_V09.h
55*/
56
57#define RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS 10
58#define RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS 10
59#define RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS 10
60#define RTL8188E_TRANS_SUS_TO_CARDEMU_STEPS 10
61#define RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS 10
62#define RTL8188E_TRANS_PDN_TO_CARDEMU_STEPS 10
63#define RTL8188E_TRANS_ACT_TO_LPS_STEPS 15
64#define RTL8188E_TRANS_LPS_TO_ACT_STEPS 15
65#define RTL8188E_TRANS_END_STEPS 1
66
67
68#define RTL8188E_TRANS_CARDEMU_TO_ACT \
69 /* format */ \
70 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\
71 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
72 /* wait till 0x04[17] = 1 power ready*/ \
73 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
74 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
75 /* 0x02[1:0] = 0 reset BB*/ \
76 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0)|BIT(1), 0}, \
77 {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
78 /*0x24[23] = 2b'01 schmit trigger */ \
79 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)}, \
80 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
81 /* 0x04[15] = 0 disable HWPDN (control by DRV)*/ \
82 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \
83 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
84 /*0x04[12:11] = 2b'00 disable WL suspend*/ \
85 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), 0}, \
86 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
87 /*0x04[8] = 1 polling until return 0*/ \
88 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
89 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
90 /*wait till 0x04[8] = 0*/ \
91 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0}, \
92 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
93 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*LDO normal mode*/\
94 {0x0074, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
95 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*SDIO Driving*/\
96
97#define RTL8188E_TRANS_ACT_TO_CARDEMU \
98 /* format */ \
99 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\
100 {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
101 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/\
102 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
103 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*LDO Sleep mode*/\
104 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
105 /*0x04[9] = 1 turn off MAC by HW state machine*/ \
106 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
107 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
108 /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \
109 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, \
110
111
112#define RTL8188E_TRANS_CARDEMU_TO_SUS \
113 /* format */ \
114 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\
115 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
116 PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
117 /*0x04[12:11] = 2b'01enable WL suspend*/ \
118 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, \
119 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
120 /*0x04[12:11] = 2b'11enable WL suspend for PCIe*/ \
121 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4)},\
122 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
123 PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
124 /* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */\
125 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, BIT(7)}, \
126 {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
127 PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
128 /*Clear SIC_EN register 0x40[12] = 1'b0 */ \
129 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
130 {0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
131 PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
132 /*Set USB suspend enable local register 0xfe10[4]= 1 */ \
133 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \
134 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
135 /*Set SDIO suspend local register*/ \
136 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
137 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
138 /*wait power state to suspend*/ \
139 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0},
140
141#define RTL8188E_TRANS_SUS_TO_CARDEMU \
142 /* format */ \
143 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
144 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
145 /*Set SDIO suspend local register*/ \
146 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \
147 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
148 /*wait power state to suspend*/ \
149 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
150 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
151 /*0x04[12:11] = 2b'01enable WL suspend*/ \
152 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0},
153
154#define RTL8188E_TRANS_CARDEMU_TO_CARDDIS \
155 /* format */ \
156 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
157 {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
158 /*0x24[23] = 2b'01 schmit trigger */ \
159 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)}, \
160 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
161 PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
162 /*0x04[12:11] = 2b'01 enable WL suspend*/ \
163 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, \
164 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
165 PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
166 /* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */\
167 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, \
168 {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
169 PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
170 /*Clear SIC_EN register 0x40[12] = 1'b0 */ \
171 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
172 {0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
173 /*Set USB suspend enable local register 0xfe10[4]= 1 */ \
174 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \
175 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
176 /*Set SDIO suspend local register*/ \
177 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
178 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
179 PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/
180
181#define RTL8188E_TRANS_CARDDIS_TO_CARDEMU \
182 /* format */ \
183 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
184 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
185 PWR_BASEADDR_SDIO,\
186 PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/ \
187 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
188 PWR_BASEADDR_SDIO,\
189 PWR_CMD_POLLING, BIT(1), BIT(1)}, /*wait power state to suspend*/\
190 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
191 PWR_BASEADDR_MAC, \
192 PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \
193 /*0x04[12:11] = 2b'01enable WL suspend*/
194
195
196#define RTL8188E_TRANS_CARDEMU_TO_PDN \
197 /* format */ \
198 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
199 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
200 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},/* 0x04[16] = 0*/ \
201 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
202 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)},/* 0x04[15] = 1*/
203
204
205#define RTL8188E_TRANS_PDN_TO_CARDEMU \
206 /* format */ \
207 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
208 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
209 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/* 0x04[15] = 0*/
210
211
212#define RTL8188E_TRANS_ACT_TO_LPS \
213 /* format */ \
214 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\
215 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
216 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F},/*Tx Pause*/ \
217 {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
218 /*zero if no pkt is tx*/\
219 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
220 {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
221 /*Should be zero if no packet is transmitting*/ \
222 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
223 {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
224 /*Should be zero if no packet is transmitting*/ \
225 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
226 {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
227 /*Should be zero if no packet is transmitting*/ \
228 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
229 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
230 /*CCK and OFDM are disabled, and clock are gated*/ \
231 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
232 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
233 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/\
234 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
235 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F},/*Reset MAC TRX*/ \
236 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
237 /*check if removed later*/ \
238 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
239 {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
240 /*Respond TxOK to scheduler*/ \
241 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)}, \
242
243
244#define RTL8188E_TRANS_LPS_TO_ACT \
245 /* format */ \
246 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\
247 {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
248 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/ \
249 {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
250 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/ \
251 {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
252 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/ \
253 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
254 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/ \
255 {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
256 /*. 0x08[4] = 0 switch TSF to 40M*/ \
257 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
258 {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
259 /*Polling 0x109[7]= 0 TSF in 40M*/ \
260 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, \
261 {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
262 /*. 0x29[7:6] = 2b'00 enable BB clock*/ \
263 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, \
264 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
265 /*. 0x101[1] = 1*/\
266 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
267 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
268 /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\
269 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
270 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
271 /*. 0x02[1:0] = 2b'11 enable BB macro*/\
272 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), BIT(1)|BIT(0)}, \
273 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\
274 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/
275
276
277#define RTL8188E_TRANS_END \
278 /* format */ \
279 /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },*/\
280 {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\
281 0, PWR_CMD_END, 0, 0}
282
283extern struct wlan_pwr_cfg rtl8188e_power_on_flow
284 [RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS +
285 RTL8188E_TRANS_END_STEPS];
286extern struct wlan_pwr_cfg rtl8188e_radio_off_flow
287 [RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS +
288 RTL8188E_TRANS_END_STEPS];
289extern struct wlan_pwr_cfg rtl8188e_card_disable_flow
290 [RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS +
291 RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS +
292 RTL8188E_TRANS_END_STEPS];
293extern struct wlan_pwr_cfg rtl8188e_card_enable_flow
294 [RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS +
295 RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS +
296 RTL8188E_TRANS_END_STEPS];
297extern struct wlan_pwr_cfg rtl8188e_suspend_flow
298 [RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS +
299 RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS +
300 RTL8188E_TRANS_END_STEPS];
301extern struct wlan_pwr_cfg rtl8188e_resume_flow
302 [RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS +
303 RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS +
304 RTL8188E_TRANS_END_STEPS];
305extern struct wlan_pwr_cfg rtl8188e_hwpdn_flow
306 [RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS +
307 RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS +
308 RTL8188E_TRANS_END_STEPS];
309extern struct wlan_pwr_cfg rtl8188e_enter_lps_flow
310 [RTL8188E_TRANS_ACT_TO_LPS_STEPS +
311 RTL8188E_TRANS_END_STEPS];
312extern struct wlan_pwr_cfg rtl8188e_leave_lps_flow
313 [RTL8188E_TRANS_LPS_TO_ACT_STEPS +
314 RTL8188E_TRANS_END_STEPS];
315
316/* RTL8723 Power Configuration CMDs for PCIe interface */
317#define Rtl8188E_NIC_PWR_ON_FLOW rtl8188e_power_on_flow
318#define Rtl8188E_NIC_RF_OFF_FLOW rtl8188e_radio_off_flow
319#define Rtl8188E_NIC_DISABLE_FLOW rtl8188e_card_disable_flow
320#define Rtl8188E_NIC_ENABLE_FLOW rtl8188e_card_enable_flow
321#define Rtl8188E_NIC_SUSPEND_FLOW rtl8188e_suspend_flow
322#define Rtl8188E_NIC_RESUME_FLOW rtl8188e_resume_flow
323#define Rtl8188E_NIC_PDN_FLOW rtl8188e_hwpdn_flow
324#define Rtl8188E_NIC_LPS_ENTER_FLOW rtl8188e_enter_lps_flow
325#define Rtl8188E_NIC_LPS_LEAVE_FLOW rtl8188e_leave_lps_flow
326
327#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c
new file mode 100644
index 000000000000..a9cfa13be3a8
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c
@@ -0,0 +1,140 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "pwrseq.h"
31
32
33/* Description:
34 * This routine deal with the Power Configuration CMDs
35 * parsing for RTL8723/RTL8188E Series IC.
36 * Assumption:
37 * We should follow specific format which was released from HW SD.
38 *
39 * 2011.07.07, added by Roger.
40 */
41
42bool rtl88_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
43 u8 fab_version, u8 interface_type,
44 struct wlan_pwr_cfg pwrcfgcmd[])
45{
46 struct wlan_pwr_cfg cmd = {0};
47 bool polling_bit = false;
48 u32 ary_idx = 0;
49 u8 val = 0;
50 u32 offset = 0;
51 u32 polling_count = 0;
52 u32 max_polling_cnt = 5000;
53
54 do {
55 cmd = pwrcfgcmd[ary_idx];
56 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
57 "rtl88_hal_pwrseqcmdparsing(): offset(%#x), cut_msk(%#x), fab_msk(%#x),"
58 "interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), val(%#x)\n",
59 GET_PWR_CFG_OFFSET(cmd),
60 GET_PWR_CFG_CUT_MASK(cmd),
61 GET_PWR_CFG_FAB_MASK(cmd),
62 GET_PWR_CFG_INTF_MASK(cmd),
63 GET_PWR_CFG_BASE(cmd),
64 GET_PWR_CFG_CMD(cmd),
65 GET_PWR_CFG_MASK(cmd),
66 GET_PWR_CFG_VALUE(cmd));
67
68 if ((GET_PWR_CFG_FAB_MASK(cmd) & fab_version) &&
69 (GET_PWR_CFG_CUT_MASK(cmd) & cut_version) &&
70 (GET_PWR_CFG_INTF_MASK(cmd) & interface_type)) {
71 switch (GET_PWR_CFG_CMD(cmd)) {
72 case PWR_CMD_READ:
73 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
74 "rtl88_hal_pwrseqcmdparsing(): PWR_CMD_READ\n");
75 break;
76 case PWR_CMD_WRITE: {
77 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
78 "rtl88_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n");
79 offset = GET_PWR_CFG_OFFSET(cmd);
80
81 /*Read the val from system register*/
82 val = rtl_read_byte(rtlpriv, offset);
83 val &= (~(GET_PWR_CFG_MASK(cmd)));
84 val |= (GET_PWR_CFG_VALUE(cmd) &
85 GET_PWR_CFG_MASK(cmd));
86
87 /*Write the val back to sytem register*/
88 rtl_write_byte(rtlpriv, offset, val);
89 }
90 break;
91 case PWR_CMD_POLLING:
92 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
93 "rtl88_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n");
94 polling_bit = false;
95 offset = GET_PWR_CFG_OFFSET(cmd);
96
97 do {
98 val = rtl_read_byte(rtlpriv, offset);
99
100 val = val & GET_PWR_CFG_MASK(cmd);
101 if (val == (GET_PWR_CFG_VALUE(cmd) &
102 GET_PWR_CFG_MASK(cmd)))
103 polling_bit = true;
104 else
105 udelay(10);
106
107 if (polling_count++ > max_polling_cnt) {
108 RT_TRACE(rtlpriv, COMP_INIT,
109 DBG_LOUD,
110 "polling fail in pwrseqcmd\n");
111 return false;
112 }
113 } while (!polling_bit);
114
115 break;
116 case PWR_CMD_DELAY:
117 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
118 "rtl88_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n");
119 if (GET_PWR_CFG_VALUE(cmd) == PWRSEQ_DELAY_US)
120 udelay(GET_PWR_CFG_OFFSET(cmd));
121 else
122 mdelay(GET_PWR_CFG_OFFSET(cmd));
123 break;
124 case PWR_CMD_END:
125 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
126 "rtl88_hal_pwrseqcmdparsing(): PWR_CMD_END\n");
127 return true;
128 break;
129 default:
130 RT_ASSERT(false,
131 "rtl88_hal_pwrseqcmdparsing(): Unknown CMD!!\n");
132 break;
133 }
134 }
135
136 ary_idx++;
137 } while (1);
138
139 return true;
140}
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.h b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.h
new file mode 100644
index 000000000000..d9ae280bb1a2
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.h
@@ -0,0 +1,97 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL8723E_PWRSEQCMD_H__
31#define __RTL8723E_PWRSEQCMD_H__
32
33#include "../wifi.h"
34/*---------------------------------------------*/
35/* The value of cmd: 4 bits */
36/*---------------------------------------------*/
37#define PWR_CMD_READ 0x00
38#define PWR_CMD_WRITE 0x01
39#define PWR_CMD_POLLING 0x02
40#define PWR_CMD_DELAY 0x03
41#define PWR_CMD_END 0x04
42
43/* define the base address of each block */
44#define PWR_BASEADDR_MAC 0x00
45#define PWR_BASEADDR_USB 0x01
46#define PWR_BASEADDR_PCIE 0x02
47#define PWR_BASEADDR_SDIO 0x03
48
49#define PWR_INTF_SDIO_MSK BIT(0)
50#define PWR_INTF_USB_MSK BIT(1)
51#define PWR_INTF_PCI_MSK BIT(2)
52#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
53
54#define PWR_FAB_TSMC_MSK BIT(0)
55#define PWR_FAB_UMC_MSK BIT(1)
56#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
57
58#define PWR_CUT_TESTCHIP_MSK BIT(0)
59#define PWR_CUT_A_MSK BIT(1)
60#define PWR_CUT_B_MSK BIT(2)
61#define PWR_CUT_C_MSK BIT(3)
62#define PWR_CUT_D_MSK BIT(4)
63#define PWR_CUT_E_MSK BIT(5)
64#define PWR_CUT_F_MSK BIT(6)
65#define PWR_CUT_G_MSK BIT(7)
66#define PWR_CUT_ALL_MSK 0xFF
67
68enum pwrseq_delay_unit {
69 PWRSEQ_DELAY_US,
70 PWRSEQ_DELAY_MS,
71};
72
73struct wlan_pwr_cfg {
74 u16 offset;
75 u8 cut_msk;
76 u8 fab_msk:4;
77 u8 interface_msk:4;
78 u8 base:4;
79 u8 cmd:4;
80 u8 msk;
81 u8 value;
82};
83
84#define GET_PWR_CFG_OFFSET(__PWR) (__PWR.offset)
85#define GET_PWR_CFG_CUT_MASK(__PWR) (__PWR.cut_msk)
86#define GET_PWR_CFG_FAB_MASK(__PWR) (__PWR.fab_msk)
87#define GET_PWR_CFG_INTF_MASK(__PWR) (__PWR.interface_msk)
88#define GET_PWR_CFG_BASE(__PWR) (__PWR.base)
89#define GET_PWR_CFG_CMD(__PWR) (__PWR.cmd)
90#define GET_PWR_CFG_MASK(__PWR) (__PWR.msk)
91#define GET_PWR_CFG_VALUE(__PWR) (__PWR.value)
92
93bool rtl88_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
94 u8 fab_version, u8 interface_type,
95 struct wlan_pwr_cfg pwrcfgcmd[]);
96
97#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h b/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
new file mode 100644
index 000000000000..d849abf7d94a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
@@ -0,0 +1,2258 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C_REG_H__
31#define __RTL92C_REG_H__
32
33#define TXPKT_BUF_SELECT 0x69
34#define RXPKT_BUF_SELECT 0xA5
35#define DISABLE_TRXPKT_BUF_ACCESS 0x0
36
37#define REG_SYS_ISO_CTRL 0x0000
38#define REG_SYS_FUNC_EN 0x0002
39#define REG_APS_FSMCO 0x0004
40#define REG_SYS_CLKR 0x0008
41#define REG_9346CR 0x000A
42#define REG_EE_VPD 0x000C
43#define REG_AFE_MISC 0x0010
44#define REG_SPS0_CTRL 0x0011
45#define REG_SPS_OCP_CFG 0x0018
46#define REG_RSV_CTRL 0x001C
47#define REG_RF_CTRL 0x001F
48#define REG_LDOA15_CTRL 0x0020
49#define REG_LDOV12D_CTRL 0x0021
50#define REG_LDOHCI12_CTRL 0x0022
51#define REG_LPLDO_CTRL 0x0023
52#define REG_AFE_XTAL_CTRL 0x0024
53#define REG_AFE_LDO_CTRL 0x0027 /* 1.5v for 8188EE test
54 * chip, 1.4v for MP chip
55 */
56#define REG_AFE_PLL_CTRL 0x0028
57#define REG_EFUSE_CTRL 0x0030
58#define REG_EFUSE_TEST 0x0034
59#define REG_PWR_DATA 0x0038
60#define REG_CAL_TIMER 0x003C
61#define REG_ACLK_MON 0x003E
62#define REG_GPIO_MUXCFG 0x0040
63#define REG_GPIO_IO_SEL 0x0042
64#define REG_MAC_PINMUX_CFG 0x0043
65#define REG_GPIO_PIN_CTRL 0x0044
66#define REG_GPIO_INTM 0x0048
67#define REG_LEDCFG0 0x004C
68#define REG_LEDCFG1 0x004D
69#define REG_LEDCFG2 0x004E
70#define REG_LEDCFG3 0x004F
71#define REG_FSIMR 0x0050
72#define REG_FSISR 0x0054
73#define REG_HSIMR 0x0058
74#define REG_HSISR 0x005c
75#define REG_GPIO_PIN_CTRL_2 0x0060
76#define REG_GPIO_IO_SEL_2 0x0062
77#define REG_GPIO_OUTPUT 0x006c
78#define REG_AFE_XTAL_CTRL_EXT 0x0078
79#define REG_XCK_OUT_CTRL 0x007c
80#define REG_MCUFWDL 0x0080
81#define REG_WOL_EVENT 0x0081
82#define REG_MCUTSTCFG 0x0084
83
84
85#define REG_HIMR 0x00B0
86#define REG_HISR 0x00B4
87#define REG_HIMRE 0x00B8
88#define REG_HISRE 0x00BC
89
90#define REG_EFUSE_ACCESS 0x00CF
91
92#define REG_BIST_SCAN 0x00D0
93#define REG_BIST_RPT 0x00D4
94#define REG_BIST_ROM_RPT 0x00D8
95#define REG_USB_SIE_INTF 0x00E0
96#define REG_PCIE_MIO_INTF 0x00E4
97#define REG_PCIE_MIO_INTD 0x00E8
98#define REG_HPON_FSM 0x00EC
99#define REG_SYS_CFG 0x00F0
100
101#define REG_CR 0x0100
102#define REG_PBP 0x0104
103#define REG_PKT_BUFF_ACCESS_CTRL 0x0106
104#define REG_TRXDMA_CTRL 0x010C
105#define REG_TRXFF_BNDY 0x0114
106#define REG_TRXFF_STATUS 0x0118
107#define REG_RXFF_PTR 0x011C
108
109#define REG_CPWM 0x012F
110#define REG_FWIMR 0x0130
111#define REG_FWISR 0x0134
112#define REG_PKTBUF_DBG_CTRL 0x0140
113#define REG_PKTBUF_DBG_DATA_L 0x0144
114#define REG_PKTBUF_DBG_DATA_H 0x0148
115#define REG_RXPKTBUF_CTRL (REG_PKTBUF_DBG_CTRL+2)
116
117#define REG_TC0_CTRL 0x0150
118#define REG_TC1_CTRL 0x0154
119#define REG_TC2_CTRL 0x0158
120#define REG_TC3_CTRL 0x015C
121#define REG_TC4_CTRL 0x0160
122#define REG_TCUNIT_BASE 0x0164
123#define REG_MBIST_START 0x0174
124#define REG_MBIST_DONE 0x0178
125#define REG_MBIST_FAIL 0x017C
126#define REG_32K_CTRL 0x0194
127#define REG_C2HEVT_MSG_NORMAL 0x01A0
128#define REG_C2HEVT_CLEAR 0x01AF
129#define REG_C2HEVT_MSG_TEST 0x01B8
130#define REG_MCUTST_1 0x01c0
131#define REG_FMETHR 0x01C8
132#define REG_HMETFR 0x01CC
133#define REG_HMEBOX_0 0x01D0
134#define REG_HMEBOX_1 0x01D4
135#define REG_HMEBOX_2 0x01D8
136#define REG_HMEBOX_3 0x01DC
137
138#define REG_LLT_INIT 0x01E0
139#define REG_BB_ACCEESS_CTRL 0x01E8
140#define REG_BB_ACCESS_DATA 0x01EC
141
142#define REG_HMEBOX_EXT_0 0x01F0
143#define REG_HMEBOX_EXT_1 0x01F4
144#define REG_HMEBOX_EXT_2 0x01F8
145#define REG_HMEBOX_EXT_3 0x01FC
146
147#define REG_RQPN 0x0200
148#define REG_FIFOPAGE 0x0204
149#define REG_TDECTRL 0x0208
150#define REG_TXDMA_OFFSET_CHK 0x020C
151#define REG_TXDMA_STATUS 0x0210
152#define REG_RQPN_NPQ 0x0214
153
154#define REG_RXDMA_AGG_PG_TH 0x0280
155#define REG_FW_UPD_RDPTR 0x0284 /* FW shall update this
156 * register before FW * write
157 * RXPKT_RELEASE_POLL to 1
158 */
159#define REG_RXDMA_CONTROL 0x0286 /* Control the RX DMA.*/
160#define REG_RXPKT_NUM 0x0287 /* The number of packets
161 * in RXPKTBUF.
162 */
163#define REG_PCIE_CTRL_REG 0x0300
164#define REG_INT_MIG 0x0304
165#define REG_BCNQ_DESA 0x0308
166#define REG_HQ_DESA 0x0310
167#define REG_MGQ_DESA 0x0318
168#define REG_VOQ_DESA 0x0320
169#define REG_VIQ_DESA 0x0328
170#define REG_BEQ_DESA 0x0330
171#define REG_BKQ_DESA 0x0338
172#define REG_RX_DESA 0x0340
173
174#define REG_DBI 0x0348
175#define REG_MDIO 0x0354
176#define REG_DBG_SEL 0x0360
177#define REG_PCIE_HRPWM 0x0361
178#define REG_PCIE_HCPWM 0x0363
179#define REG_UART_CTRL 0x0364
180#define REG_WATCH_DOG 0x0368
181#define REG_UART_TX_DESA 0x0370
182#define REG_UART_RX_DESA 0x0378
183
184
185#define REG_HDAQ_DESA_NODEF 0x0000
186#define REG_CMDQ_DESA_NODEF 0x0000
187
188#define REG_VOQ_INFORMATION 0x0400
189#define REG_VIQ_INFORMATION 0x0404
190#define REG_BEQ_INFORMATION 0x0408
191#define REG_BKQ_INFORMATION 0x040C
192#define REG_MGQ_INFORMATION 0x0410
193#define REG_HGQ_INFORMATION 0x0414
194#define REG_BCNQ_INFORMATION 0x0418
195#define REG_TXPKT_EMPTY 0x041A
196
197
198#define REG_CPU_MGQ_INFORMATION 0x041C
199#define REG_FWHW_TXQ_CTRL 0x0420
200#define REG_HWSEQ_CTRL 0x0423
201#define REG_TXPKTBUF_BCNQ_BDNY 0x0424
202#define REG_TXPKTBUF_MGQ_BDNY 0x0425
203#define REG_MULTI_BCNQ_EN 0x0426
204#define REG_MULTI_BCNQ_OFFSET 0x0427
205#define REG_SPEC_SIFS 0x0428
206#define REG_RL 0x042A
207#define REG_DARFRC 0x0430
208#define REG_RARFRC 0x0438
209#define REG_RRSR 0x0440
210#define REG_ARFR0 0x0444
211#define REG_ARFR1 0x0448
212#define REG_ARFR2 0x044C
213#define REG_ARFR3 0x0450
214#define REG_AGGLEN_LMT 0x0458
215#define REG_AMPDU_MIN_SPACE 0x045C
216#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D
217#define REG_FAST_EDCA_CTRL 0x0460
218#define REG_RD_RESP_PKT_TH 0x0463
219#define REG_INIRTS_RATE_SEL 0x0480
220#define REG_INIDATA_RATE_SEL 0x0484
221#define REG_POWER_STATUS 0x04A4
222#define REG_POWER_STAGE1 0x04B4
223#define REG_POWER_STAGE2 0x04B8
224#define REG_PKT_LIFE_TIME 0x04C0
225#define REG_STBC_SETTING 0x04C4
226#define REG_PROT_MODE_CTRL 0x04C8
227#define REG_BAR_MODE_CTRL 0x04CC
228#define REG_RA_TRY_RATE_AGG_LMT 0x04CF
229#define REG_EARLY_MODE_CONTROL 0x04D0
230#define REG_NQOS_SEQ 0x04DC
231#define REG_QOS_SEQ 0x04DE
232#define REG_NEED_CPU_HANDLE 0x04E0
233#define REG_PKT_LOSE_RPT 0x04E1
234#define REG_PTCL_ERR_STATUS 0x04E2
235#define REG_TX_RPT_CTRL 0x04EC
236#define REG_TX_RPT_TIME 0x04F0
237#define REG_DUMMY 0x04FC
238
239#define REG_EDCA_VO_PARAM 0x0500
240#define REG_EDCA_VI_PARAM 0x0504
241#define REG_EDCA_BE_PARAM 0x0508
242#define REG_EDCA_BK_PARAM 0x050C
243#define REG_BCNTCFG 0x0510
244#define REG_PIFS 0x0512
245#define REG_RDG_PIFS 0x0513
246#define REG_SIFS_CTX 0x0514
247#define REG_SIFS_TRX 0x0516
248#define REG_AGGR_BREAK_TIME 0x051A
249#define REG_SLOT 0x051B
250#define REG_TX_PTCL_CTRL 0x0520
251#define REG_TXPAUSE 0x0522
252#define REG_DIS_TXREQ_CLR 0x0523
253#define REG_RD_CTRL 0x0524
254#define REG_TBTT_PROHIBIT 0x0540
255#define REG_RD_NAV_NXT 0x0544
256#define REG_NAV_PROT_LEN 0x0546
257#define REG_BCN_CTRL 0x0550
258#define REG_USTIME_TSF 0x0551
259#define REG_MBID_NUM 0x0552
260#define REG_DUAL_TSF_RST 0x0553
261#define REG_BCN_INTERVAL 0x0554
262#define REG_MBSSID_BCN_SPACE 0x0554
263#define REG_DRVERLYINT 0x0558
264#define REG_BCNDMATIM 0x0559
265#define REG_ATIMWND 0x055A
266#define REG_BCN_MAX_ERR 0x055D
267#define REG_RXTSF_OFFSET_CCK 0x055E
268#define REG_RXTSF_OFFSET_OFDM 0x055F
269#define REG_TSFTR 0x0560
270#define REG_INIT_TSFTR 0x0564
271#define REG_PSTIMER 0x0580
272#define REG_TIMER0 0x0584
273#define REG_TIMER1 0x0588
274#define REG_ACMHWCTRL 0x05C0
275#define REG_ACMRSTCTRL 0x05C1
276#define REG_ACMAVG 0x05C2
277#define REG_VO_ADMTIME 0x05C4
278#define REG_VI_ADMTIME 0x05C6
279#define REG_BE_ADMTIME 0x05C8
280#define REG_EDCA_RANDOM_GEN 0x05CC
281#define REG_SCH_TXCMD 0x05D0
282
283#define REG_APSD_CTRL 0x0600
284#define REG_BWOPMODE 0x0603
285#define REG_TCR 0x0604
286#define REG_RCR 0x0608
287#define REG_RX_PKT_LIMIT 0x060C
288#define REG_RX_DLK_TIME 0x060D
289#define REG_RX_DRVINFO_SZ 0x060F
290
291#define REG_MACID 0x0610
292#define REG_BSSID 0x0618
293#define REG_MAR 0x0620
294#define REG_MBIDCAMCFG 0x0628
295
296#define REG_USTIME_EDCA 0x0638
297#define REG_MAC_SPEC_SIFS 0x063A
298#define REG_RESP_SIFS_CCK 0x063C
299#define REG_RESP_SIFS_OFDM 0x063E
300#define REG_ACKTO 0x0640
301#define REG_CTS2TO 0x0641
302#define REG_EIFS 0x0642
303
304#define REG_NAV_CTRL 0x0650
305#define REG_BACAMCMD 0x0654
306#define REG_BACAMCONTENT 0x0658
307#define REG_LBDLY 0x0660
308#define REG_FWDLY 0x0661
309#define REG_RXERR_RPT 0x0664
310#define REG_TRXPTCL_CTL 0x0668
311
312#define REG_CAMCMD 0x0670
313#define REG_CAMWRITE 0x0674
314#define REG_CAMREAD 0x0678
315#define REG_CAMDBG 0x067C
316#define REG_SECCFG 0x0680
317
318#define REG_WOW_CTRL 0x0690
319#define REG_PSSTATUS 0x0691
320#define REG_PS_RX_INFO 0x0692
321#define REG_UAPSD_TID 0x0693
322#define REG_LPNAV_CTRL 0x0694
323#define REG_WKFMCAM_NUM 0x0698
324#define REG_WKFMCAM_RWD 0x069C
325#define REG_RXFLTMAP0 0x06A0
326#define REG_RXFLTMAP1 0x06A2
327#define REG_RXFLTMAP2 0x06A4
328#define REG_BCN_PSR_RPT 0x06A8
329#define REG_CALB32K_CTRL 0x06AC
330#define REG_PKT_MON_CTRL 0x06B4
331#define REG_BT_COEX_TABLE 0x06C0
332#define REG_WMAC_RESP_TXINFO 0x06D8
333
334#define REG_USB_INFO 0xFE17
335#define REG_USB_SPECIAL_OPTION 0xFE55
336#define REG_USB_DMA_AGG_TO 0xFE5B
337#define REG_USB_AGG_TO 0xFE5C
338#define REG_USB_AGG_TH 0xFE5D
339
340#define REG_TEST_USB_TXQS 0xFE48
341#define REG_TEST_SIE_VID 0xFE60
342#define REG_TEST_SIE_PID 0xFE62
343#define REG_TEST_SIE_OPTIONAL 0xFE64
344#define REG_TEST_SIE_CHIRP_K 0xFE65
345#define REG_TEST_SIE_PHY 0xFE66
346#define REG_TEST_SIE_MAC_ADDR 0xFE70
347#define REG_TEST_SIE_STRING 0xFE80
348
349#define REG_NORMAL_SIE_VID 0xFE60
350#define REG_NORMAL_SIE_PID 0xFE62
351#define REG_NORMAL_SIE_OPTIONAL 0xFE64
352#define REG_NORMAL_SIE_EP 0xFE65
353#define REG_NORMAL_SIE_PHY 0xFE68
354#define REG_NORMAL_SIE_MAC_ADDR 0xFE70
355#define REG_NORMAL_SIE_STRING 0xFE80
356
357#define CR9346 REG_9346CR
358#define MSR (REG_CR + 2)
359#define ISR REG_HISR
360#define TSFR REG_TSFTR
361
362#define MACIDR0 REG_MACID
363#define MACIDR4 (REG_MACID + 4)
364
365#define PBP REG_PBP
366
367#define IDR0 MACIDR0
368#define IDR4 MACIDR4
369
370#define UNUSED_REGISTER 0x1BF
371#define DCAM UNUSED_REGISTER
372#define PSR UNUSED_REGISTER
373#define BBADDR UNUSED_REGISTER
374#define PHYDATAR UNUSED_REGISTER
375
376#define INVALID_BBRF_VALUE 0x12345678
377
378#define MAX_MSS_DENSITY_2T 0x13
379#define MAX_MSS_DENSITY_1T 0x0A
380
381#define CMDEEPROM_EN BIT(5)
382#define CMDEEPROM_SEL BIT(4)
383#define CMD9346CR_9356SEL BIT(4)
384#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL)
385#define AUTOLOAD_EFUSE CMDEEPROM_EN
386
387#define GPIOSEL_GPIO 0
388#define GPIOSEL_ENBT BIT(5)
389
390#define GPIO_IN REG_GPIO_PIN_CTRL
391#define GPIO_OUT (REG_GPIO_PIN_CTRL+1)
392#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2)
393#define GPIO_MOD (REG_GPIO_PIN_CTRL+3)
394
395/* 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) */
396#define HSIMR_GPIO12_0_INT_EN BIT(0)
397#define HSIMR_SPS_OCP_INT_EN BIT(5)
398#define HSIMR_RON_INT_EN BIT(6)
399#define HSIMR_PDN_INT_EN BIT(7)
400#define HSIMR_GPIO9_INT_EN BIT(25)
401
402
403/* 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) */
404#define HSISR_GPIO12_0_INT BIT(0)
405#define HSISR_SPS_OCP_INT BIT(5)
406#define HSISR_RON_INT_EN BIT(6)
407#define HSISR_PDNINT BIT(7)
408#define HSISR_GPIO9_INT BIT(25)
409
410#define MSR_NOLINK 0x00
411#define MSR_ADHOC 0x01
412#define MSR_INFRA 0x02
413#define MSR_AP 0x03
414
415#define RRSR_RSC_OFFSET 21
416#define RRSR_SHORT_OFFSET 23
417#define RRSR_RSC_BW_40M 0x600000
418#define RRSR_RSC_UPSUBCHNL 0x400000
419#define RRSR_RSC_LOWSUBCHNL 0x200000
420#define RRSR_SHORT 0x800000
421#define RRSR_1M BIT(0)
422#define RRSR_2M BIT(1)
423#define RRSR_5_5M BIT(2)
424#define RRSR_11M BIT(3)
425#define RRSR_6M BIT(4)
426#define RRSR_9M BIT(5)
427#define RRSR_12M BIT(6)
428#define RRSR_18M BIT(7)
429#define RRSR_24M BIT(8)
430#define RRSR_36M BIT(9)
431#define RRSR_48M BIT(10)
432#define RRSR_54M BIT(11)
433#define RRSR_MCS0 BIT(12)
434#define RRSR_MCS1 BIT(13)
435#define RRSR_MCS2 BIT(14)
436#define RRSR_MCS3 BIT(15)
437#define RRSR_MCS4 BIT(16)
438#define RRSR_MCS5 BIT(17)
439#define RRSR_MCS6 BIT(18)
440#define RRSR_MCS7 BIT(19)
441#define BRSR_ACKSHORTPMB BIT(23)
442
443#define RATR_1M 0x00000001
444#define RATR_2M 0x00000002
445#define RATR_55M 0x00000004
446#define RATR_11M 0x00000008
447#define RATR_6M 0x00000010
448#define RATR_9M 0x00000020
449#define RATR_12M 0x00000040
450#define RATR_18M 0x00000080
451#define RATR_24M 0x00000100
452#define RATR_36M 0x00000200
453#define RATR_48M 0x00000400
454#define RATR_54M 0x00000800
455#define RATR_MCS0 0x00001000
456#define RATR_MCS1 0x00002000
457#define RATR_MCS2 0x00004000
458#define RATR_MCS3 0x00008000
459#define RATR_MCS4 0x00010000
460#define RATR_MCS5 0x00020000
461#define RATR_MCS6 0x00040000
462#define RATR_MCS7 0x00080000
463#define RATR_MCS8 0x00100000
464#define RATR_MCS9 0x00200000
465#define RATR_MCS10 0x00400000
466#define RATR_MCS11 0x00800000
467#define RATR_MCS12 0x01000000
468#define RATR_MCS13 0x02000000
469#define RATR_MCS14 0x04000000
470#define RATR_MCS15 0x08000000
471
472#define RATE_1M BIT(0)
473#define RATE_2M BIT(1)
474#define RATE_5_5M BIT(2)
475#define RATE_11M BIT(3)
476#define RATE_6M BIT(4)
477#define RATE_9M BIT(5)
478#define RATE_12M BIT(6)
479#define RATE_18M BIT(7)
480#define RATE_24M BIT(8)
481#define RATE_36M BIT(9)
482#define RATE_48M BIT(10)
483#define RATE_54M BIT(11)
484#define RATE_MCS0 BIT(12)
485#define RATE_MCS1 BIT(13)
486#define RATE_MCS2 BIT(14)
487#define RATE_MCS3 BIT(15)
488#define RATE_MCS4 BIT(16)
489#define RATE_MCS5 BIT(17)
490#define RATE_MCS6 BIT(18)
491#define RATE_MCS7 BIT(19)
492#define RATE_MCS8 BIT(20)
493#define RATE_MCS9 BIT(21)
494#define RATE_MCS10 BIT(22)
495#define RATE_MCS11 BIT(23)
496#define RATE_MCS12 BIT(24)
497#define RATE_MCS13 BIT(25)
498#define RATE_MCS14 BIT(26)
499#define RATE_MCS15 BIT(27)
500
501#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
502#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M | \
503 RATR_24M | RATR_36M | RATR_48M | RATR_54M)
504#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \
505 RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \
506 RATR_MCS6 | RATR_MCS7)
507#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \
508 RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \
509 RATR_MCS14 | RATR_MCS15)
510
511#define BW_OPMODE_20MHZ BIT(2)
512#define BW_OPMODE_5G BIT(1)
513#define BW_OPMODE_11J BIT(0)
514
515#define CAM_VALID BIT(15)
516#define CAM_NOTVALID 0x0000
517#define CAM_USEDK BIT(5)
518
519#define CAM_NONE 0x0
520#define CAM_WEP40 0x01
521#define CAM_TKIP 0x02
522#define CAM_AES 0x04
523#define CAM_WEP104 0x05
524
525#define TOTAL_CAM_ENTRY 32
526#define HALF_CAM_ENTRY 16
527
528#define CAM_WRITE BIT(16)
529#define CAM_READ 0x00000000
530#define CAM_POLLINIG BIT(31)
531
532#define SCR_USEDK 0x01
533#define SCR_TXSEC_ENABLE 0x02
534#define SCR_RXSEC_ENABLE 0x04
535
536#define WOW_PMEN BIT(0)
537#define WOW_WOMEN BIT(1)
538#define WOW_MAGIC BIT(2)
539#define WOW_UWF BIT(3)
540
541/*********************************************
542* 8188 IMR/ISR bits
543**********************************************/
544#define IMR_DISABLED 0x0
545/* IMR DW0(0x0060-0063) Bit 0-31 */
546#define IMR_TXCCK BIT(30) /* TXRPT interrupt when CCX bit of
547 * the packet is set
548 */
549#define IMR_PSTIMEOUT BIT(29) /* Power Save Time Out Interrupt */
550#define IMR_GTINT4 BIT(28) /* When GTIMER4 expires,
551 * this bit is set to 1
552 */
553#define IMR_GTINT3 BIT(27) /* When GTIMER3 expires,
554 * this bit is set to 1
555 */
556#define IMR_TBDER BIT(26) /* Transmit Beacon0 Error */
557#define IMR_TBDOK BIT(25) /* Transmit Beacon0 OK */
558#define IMR_TSF_BIT32_TOGGLE BIT(24) /* TSF Timer BIT32 toggle ind int */
559#define IMR_BCNDMAINT0 BIT(20) /* Beacon DMA Interrupt 0 */
560#define IMR_BCNDOK0 BIT(16) /* Beacon Queue DMA OK0 */
561#define IMR_HSISR_IND_ON_INT BIT(15) /* HSISR Indicator (HSIMR & HSISR is
562 * true, this bit is set to 1)
563 */
564#define IMR_BCNDMAINT_E BIT(14) /* Beacon DMA Int Extension for Win7 */
565#define IMR_ATIMEND BIT(12) /* CTWidnow End or ATIM Window End */
566#define IMR_HISR1_IND_INT BIT(11) /* HISR1 Indicator (HISR1 & HIMR1 is
567 * true, this bit is set to 1)
568 */
569#define IMR_C2HCMD BIT(10) /* CPU to Host Command INT Status,
570 * Write 1 clear
571 */
572#define IMR_CPWM2 BIT(9) /* CPU power Mode exchange INT Status,
573 * Write 1 clear
574 */
575#define IMR_CPWM BIT(8) /* CPU power Mode exchange INT Status,
576 * Write 1 clear
577 */
578#define IMR_HIGHDOK BIT(7) /* High Queue DMA OK */
579#define IMR_MGNTDOK BIT(6) /* Management Queue DMA OK */
580#define IMR_BKDOK BIT(5) /* AC_BK DMA OK */
581#define IMR_BEDOK BIT(4) /* AC_BE DMA OK */
582#define IMR_VIDOK BIT(3) /* AC_VI DMA OK */
583#define IMR_VODOK BIT(2) /* AC_VO DMA OK */
584#define IMR_RDU BIT(1) /* Rx Descriptor Unavailable */
585#define IMR_ROK BIT(0) /* Receive DMA OK */
586
587/* IMR DW1(0x00B4-00B7) Bit 0-31 */
588#define IMR_BCNDMAINT7 BIT(27) /* Beacon DMA Interrupt 7 */
589#define IMR_BCNDMAINT6 BIT(26) /* Beacon DMA Interrupt 6 */
590#define IMR_BCNDMAINT5 BIT(25) /* Beacon DMA Interrupt 5 */
591#define IMR_BCNDMAINT4 BIT(24) /* Beacon DMA Interrupt 4 */
592#define IMR_BCNDMAINT3 BIT(23) /* Beacon DMA Interrupt 3 */
593#define IMR_BCNDMAINT2 BIT(22) /* Beacon DMA Interrupt 2 */
594#define IMR_BCNDMAINT1 BIT(21) /* Beacon DMA Interrupt 1 */
595#define IMR_BCNDOK7 BIT(20) /* Beacon Queue DMA OK Interrup 7 */
596#define IMR_BCNDOK6 BIT(19) /* Beacon Queue DMA OK Interrup 6 */
597#define IMR_BCNDOK5 BIT(18) /* Beacon Queue DMA OK Interrup 5 */
598#define IMR_BCNDOK4 BIT(17) /* Beacon Queue DMA OK Interrup 4 */
599#define IMR_BCNDOK3 BIT(16) /* Beacon Queue DMA OK Interrup 3 */
600#define IMR_BCNDOK2 BIT(15) /* Beacon Queue DMA OK Interrup 2 */
601#define IMR_BCNDOK1 BIT(14) /* Beacon Queue DMA OK Interrup 1 */
602#define IMR_ATIMEND_E BIT(13) /* ATIM Window End Extension for Win7 */
603#define IMR_TXERR BIT(11) /* Tx Err Flag Int Status,
604 * write 1 clear.
605 */
606#define IMR_RXERR BIT(10) /* Rx Err Flag INT Status,
607 * Write 1 clear
608 */
609#define IMR_TXFOVW BIT(9) /* Transmit FIFO Overflow */
610#define IMR_RXFOVW BIT(8) /* Receive FIFO Overflow */
611
612
613#define HWSET_MAX_SIZE 512
614#define EFUSE_MAX_SECTION 64
615#define EFUSE_REAL_CONTENT_LEN 256
616#define EFUSE_OOB_PROTECT_BYTES 18 /* PG data exclude header,
617 * dummy 7 bytes frome CP
618 * test and reserved 1byte.
619 */
620
621#define EEPROM_DEFAULT_TSSI 0x0
622#define EEPROM_DEFAULT_TXPOWERDIFF 0x0
623#define EEPROM_DEFAULT_CRYSTALCAP 0x5
624#define EEPROM_DEFAULT_BOARDTYPE 0x02
625#define EEPROM_DEFAULT_TXPOWER 0x1010
626#define EEPROM_DEFAULT_HT2T_TXPWR 0x10
627
628#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
629#define EEPROM_DEFAULT_THERMALMETER 0x18
630#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0
631#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5
632#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22
633#define EEPROM_DEFAULT_HT40_2SDIFF 0x0
634#define EEPROM_DEFAULT_HT20_DIFF 2
635#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
636#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0
637#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0
638
639#define RF_OPTION1 0x79
640#define RF_OPTION2 0x7A
641#define RF_OPTION3 0x7B
642#define RF_OPTION4 0x7C
643
644#define EEPROM_DEFAULT_PID 0x1234
645#define EEPROM_DEFAULT_VID 0x5678
646#define EEPROM_DEFAULT_CUSTOMERID 0xAB
647#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD
648#define EEPROM_DEFAULT_VERSION 0
649
650#define EEPROM_CHANNEL_PLAN_FCC 0x0
651#define EEPROM_CHANNEL_PLAN_IC 0x1
652#define EEPROM_CHANNEL_PLAN_ETSI 0x2
653#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
654#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
655#define EEPROM_CHANNEL_PLAN_MKK 0x5
656#define EEPROM_CHANNEL_PLAN_MKK1 0x6
657#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
658#define EEPROM_CHANNEL_PLAN_TELEC 0x8
659#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
660#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
661#define EEPROM_CHANNEL_PLAN_NCC 0xB
662#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
663
664#define EEPROM_CID_DEFAULT 0x0
665#define EEPROM_CID_TOSHIBA 0x4
666#define EEPROM_CID_CCX 0x10
667#define EEPROM_CID_QMI 0x0D
668#define EEPROM_CID_WHQL 0xFE
669
670#define RTL8188E_EEPROM_ID 0x8129
671
672#define EEPROM_HPON 0x02
673#define EEPROM_CLK 0x06
674#define EEPROM_TESTR 0x08
675
676#define EEPROM_TXPOWERCCK 0x10
677#define EEPROM_TXPOWERHT40_1S 0x16
678#define EEPROM_TXPOWERHT20DIFF 0x1B
679#define EEPROM_TXPOWER_OFDMDIFF 0x1B
680
681#define EEPROM_TX_PWR_INX 0x10
682
683#define EEPROM_CHANNELPLAN 0xB8
684#define EEPROM_XTAL_88E 0xB9
685#define EEPROM_THERMAL_METER_88E 0xBA
686#define EEPROM_IQK_LCK_88E 0xBB
687
688#define EEPROM_RF_BOARD_OPTION_88E 0xC1
689#define EEPROM_RF_FEATURE_OPTION_88E 0xC2
690#define EEPROM_RF_BT_SETTING_88E 0xC3
691#define EEPROM_VERSION 0xC4
692#define EEPROM_CUSTOMER_ID 0xC5
693#define EEPROM_RF_ANTENNA_OPT_88E 0xC9
694
695#define EEPROM_MAC_ADDR 0xD0
696#define EEPROM_VID 0xD6
697#define EEPROM_DID 0xD8
698#define EEPROM_SVID 0xDA
699#define EEPROM_SMID 0xDC
700
701#define STOPBECON BIT(6)
702#define STOPHIGHT BIT(5)
703#define STOPMGT BIT(4)
704#define STOPVO BIT(3)
705#define STOPVI BIT(2)
706#define STOPBE BIT(1)
707#define STOPBK BIT(0)
708
709#define RCR_APPFCS BIT(31)
710#define RCR_APP_MIC BIT(30)
711#define RCR_APP_ICV BIT(29)
712#define RCR_APP_PHYST_RXFF BIT(28)
713#define RCR_APP_BA_SSN BIT(27)
714#define RCR_ENMBID BIT(24)
715#define RCR_LSIGEN BIT(23)
716#define RCR_MFBEN BIT(22)
717#define RCR_HTC_LOC_CTRL BIT(14)
718#define RCR_AMF BIT(13)
719#define RCR_ACF BIT(12)
720#define RCR_ADF BIT(11)
721#define RCR_AICV BIT(9)
722#define RCR_ACRC32 BIT(8)
723#define RCR_CBSSID_BCN BIT(7)
724#define RCR_CBSSID_DATA BIT(6)
725#define RCR_CBSSID RCR_CBSSID_DATA
726#define RCR_APWRMGT BIT(5)
727#define RCR_ADD3 BIT(4)
728#define RCR_AB BIT(3)
729#define RCR_AM BIT(2)
730#define RCR_APM BIT(1)
731#define RCR_AAP BIT(0)
732#define RCR_MXDMA_OFFSET 8
733#define RCR_FIFO_OFFSET 13
734
735#define RSV_CTRL 0x001C
736#define RD_CTRL 0x0524
737
738#define REG_USB_INFO 0xFE17
739#define REG_USB_SPECIAL_OPTION 0xFE55
740#define REG_USB_DMA_AGG_TO 0xFE5B
741#define REG_USB_AGG_TO 0xFE5C
742#define REG_USB_AGG_TH 0xFE5D
743
744#define REG_USB_VID 0xFE60
745#define REG_USB_PID 0xFE62
746#define REG_USB_OPTIONAL 0xFE64
747#define REG_USB_CHIRP_K 0xFE65
748#define REG_USB_PHY 0xFE66
749#define REG_USB_MAC_ADDR 0xFE70
750#define REG_USB_HRPWM 0xFE58
751#define REG_USB_HCPWM 0xFE57
752
753#define SW18_FPWM BIT(3)
754
755#define ISO_MD2PP BIT(0)
756#define ISO_UA2USB BIT(1)
757#define ISO_UD2CORE BIT(2)
758#define ISO_PA2PCIE BIT(3)
759#define ISO_PD2CORE BIT(4)
760#define ISO_IP2MAC BIT(5)
761#define ISO_DIOP BIT(6)
762#define ISO_DIOE BIT(7)
763#define ISO_EB2CORE BIT(8)
764#define ISO_DIOR BIT(9)
765
766#define PWC_EV25V BIT(14)
767#define PWC_EV12V BIT(15)
768
769#define FEN_BBRSTB BIT(0)
770#define FEN_BB_GLB_RSTN BIT(1)
771#define FEN_USBA BIT(2)
772#define FEN_UPLL BIT(3)
773#define FEN_USBD BIT(4)
774#define FEN_DIO_PCIE BIT(5)
775#define FEN_PCIEA BIT(6)
776#define FEN_PPLL BIT(7)
777#define FEN_PCIED BIT(8)
778#define FEN_DIOE BIT(9)
779#define FEN_CPUEN BIT(10)
780#define FEN_DCORE BIT(11)
781#define FEN_ELDR BIT(12)
782#define FEN_DIO_RF BIT(13)
783#define FEN_HWPDN BIT(14)
784#define FEN_MREGEN BIT(15)
785
786#define PFM_LDALL BIT(0)
787#define PFM_ALDN BIT(1)
788#define PFM_LDKP BIT(2)
789#define PFM_WOWL BIT(3)
790#define ENPDN BIT(4)
791#define PDN_PL BIT(5)
792#define APFM_ONMAC BIT(8)
793#define APFM_OFF BIT(9)
794#define APFM_RSM BIT(10)
795#define AFSM_HSUS BIT(11)
796#define AFSM_PCIE BIT(12)
797#define APDM_MAC BIT(13)
798#define APDM_HOST BIT(14)
799#define APDM_HPDN BIT(15)
800#define RDY_MACON BIT(16)
801#define SUS_HOST BIT(17)
802#define ROP_ALD BIT(20)
803#define ROP_PWR BIT(21)
804#define ROP_SPS BIT(22)
805#define SOP_MRST BIT(25)
806#define SOP_FUSE BIT(26)
807#define SOP_ABG BIT(27)
808#define SOP_AMB BIT(28)
809#define SOP_RCK BIT(29)
810#define SOP_A8M BIT(30)
811#define XOP_BTCK BIT(31)
812
813#define ANAD16V_EN BIT(0)
814#define ANA8M BIT(1)
815#define MACSLP BIT(4)
816#define LOADER_CLK_EN BIT(5)
817#define _80M_SSC_DIS BIT(7)
818#define _80M_SSC_EN_HO BIT(8)
819#define PHY_SSC_RSTB BIT(9)
820#define SEC_CLK_EN BIT(10)
821#define MAC_CLK_EN BIT(11)
822#define SYS_CLK_EN BIT(12)
823#define RING_CLK_EN BIT(13)
824
825#define BOOT_FROM_EEPROM BIT(4)
826#define EEPROM_EN BIT(5)
827
828#define AFE_BGEN BIT(0)
829#define AFE_MBEN BIT(1)
830#define MAC_ID_EN BIT(7)
831
832#define WLOCK_ALL BIT(0)
833#define WLOCK_00 BIT(1)
834#define WLOCK_04 BIT(2)
835#define WLOCK_08 BIT(3)
836#define WLOCK_40 BIT(4)
837#define R_DIS_PRST_0 BIT(5)
838#define R_DIS_PRST_1 BIT(6)
839#define LOCK_ALL_EN BIT(7)
840
841#define RF_EN BIT(0)
842#define RF_RSTB BIT(1)
843#define RF_SDMRSTB BIT(2)
844
845#define LDA15_EN BIT(0)
846#define LDA15_STBY BIT(1)
847#define LDA15_OBUF BIT(2)
848#define LDA15_REG_VOS BIT(3)
849#define _LDA15_VOADJ(x) (((x) & 0x7) << 4)
850
851#define LDV12_EN BIT(0)
852#define LDV12_SDBY BIT(1)
853#define LPLDO_HSM BIT(2)
854#define LPLDO_LSM_DIS BIT(3)
855#define _LDV12_VADJ(x) (((x) & 0xF) << 4)
856
857#define XTAL_EN BIT(0)
858#define XTAL_BSEL BIT(1)
859#define _XTAL_BOSC(x) (((x) & 0x3) << 2)
860#define _XTAL_CADJ(x) (((x) & 0xF) << 4)
861#define XTAL_GATE_USB BIT(8)
862#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9)
863#define XTAL_GATE_AFE BIT(11)
864#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12)
865#define XTAL_RF_GATE BIT(14)
866#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15)
867#define XTAL_GATE_DIG BIT(17)
868#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18)
869#define XTAL_BT_GATE BIT(20)
870#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21)
871#define _XTAL_GPIO(x) (((x) & 0x7) << 23)
872
873#define CKDLY_AFE BIT(26)
874#define CKDLY_USB BIT(27)
875#define CKDLY_DIG BIT(28)
876#define CKDLY_BT BIT(29)
877
878#define APLL_EN BIT(0)
879#define APLL_320_EN BIT(1)
880#define APLL_FREF_SEL BIT(2)
881#define APLL_EDGE_SEL BIT(3)
882#define APLL_WDOGB BIT(4)
883#define APLL_LPFEN BIT(5)
884
885#define APLL_REF_CLK_13MHZ 0x1
886#define APLL_REF_CLK_19_2MHZ 0x2
887#define APLL_REF_CLK_20MHZ 0x3
888#define APLL_REF_CLK_25MHZ 0x4
889#define APLL_REF_CLK_26MHZ 0x5
890#define APLL_REF_CLK_38_4MHZ 0x6
891#define APLL_REF_CLK_40MHZ 0x7
892
893#define APLL_320EN BIT(14)
894#define APLL_80EN BIT(15)
895#define APLL_1MEN BIT(24)
896
897#define ALD_EN BIT(18)
898#define EF_PD BIT(19)
899#define EF_FLAG BIT(31)
900
901#define EF_TRPT BIT(7)
902#define LDOE25_EN BIT(31)
903
904#define RSM_EN BIT(0)
905#define TIMER_EN BIT(4)
906
907#define TRSW0EN BIT(2)
908#define TRSW1EN BIT(3)
909#define EROM_EN BIT(4)
910#define ENBT BIT(5)
911#define ENUART BIT(8)
912#define UART_910 BIT(9)
913#define ENPMAC BIT(10)
914#define SIC_SWRST BIT(11)
915#define ENSIC BIT(12)
916#define SIC_23 BIT(13)
917#define ENHDP BIT(14)
918#define SIC_LBK BIT(15)
919
920#define LED0PL BIT(4)
921#define LED1PL BIT(12)
922#define LED0DIS BIT(7)
923
924#define MCUFWDL_EN BIT(0)
925#define MCUFWDL_RDY BIT(1)
926#define FWDL_CHKSUM_RPT BIT(2)
927#define MACINI_RDY BIT(3)
928#define BBINI_RDY BIT(4)
929#define RFINI_RDY BIT(5)
930#define WINTINI_RDY BIT(6)
931#define CPRST BIT(23)
932
933#define XCLK_VLD BIT(0)
934#define ACLK_VLD BIT(1)
935#define UCLK_VLD BIT(2)
936#define PCLK_VLD BIT(3)
937#define PCIRSTB BIT(4)
938#define V15_VLD BIT(5)
939#define TRP_B15V_EN BIT(7)
940#define SIC_IDLE BIT(8)
941#define BD_MAC2 BIT(9)
942#define BD_MAC1 BIT(10)
943#define IC_MACPHY_MODE BIT(11)
944#define VENDOR_ID BIT(19)
945#define PAD_HWPD_IDN BIT(22)
946#define TRP_VAUX_EN BIT(23)
947#define TRP_BT_EN BIT(24)
948#define BD_PKG_SEL BIT(25)
949#define BD_HCI_SEL BIT(26)
950#define TYPE_ID BIT(27)
951
952#define CHIP_VER_RTL_MASK 0xF000
953#define CHIP_VER_RTL_SHIFT 12
954
955#define REG_LBMODE (REG_CR + 3)
956
957#define HCI_TXDMA_EN BIT(0)
958#define HCI_RXDMA_EN BIT(1)
959#define TXDMA_EN BIT(2)
960#define RXDMA_EN BIT(3)
961#define PROTOCOL_EN BIT(4)
962#define SCHEDULE_EN BIT(5)
963#define MACTXEN BIT(6)
964#define MACRXEN BIT(7)
965#define ENSWBCN BIT(8)
966#define ENSEC BIT(9)
967
968#define _NETTYPE(x) (((x) & 0x3) << 16)
969#define MASK_NETTYPE 0x30000
970#define NT_NO_LINK 0x0
971#define NT_LINK_AD_HOC 0x1
972#define NT_LINK_AP 0x2
973#define NT_AS_AP 0x3
974
975#define _LBMODE(x) (((x) & 0xF) << 24)
976#define MASK_LBMODE 0xF000000
977#define LOOPBACK_NORMAL 0x0
978#define LOOPBACK_IMMEDIATELY 0xB
979#define LOOPBACK_MAC_DELAY 0x3
980#define LOOPBACK_PHY 0x1
981#define LOOPBACK_DMA 0x7
982
983#define GET_RX_PAGE_SIZE(value) ((value) & 0xF)
984#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4)
985#define _PSRX_MASK 0xF
986#define _PSTX_MASK 0xF0
987#define _PSRX(x) (x)
988#define _PSTX(x) ((x) << 4)
989
990#define PBP_64 0x0
991#define PBP_128 0x1
992#define PBP_256 0x2
993#define PBP_512 0x3
994#define PBP_1024 0x4
995
996#define RXDMA_ARBBW_EN BIT(0)
997#define RXSHFT_EN BIT(1)
998#define RXDMA_AGG_EN BIT(2)
999#define QS_VO_QUEUE BIT(8)
1000#define QS_VI_QUEUE BIT(9)
1001#define QS_BE_QUEUE BIT(10)
1002#define QS_BK_QUEUE BIT(11)
1003#define QS_MANAGER_QUEUE BIT(12)
1004#define QS_HIGH_QUEUE BIT(13)
1005
1006#define HQSEL_VOQ BIT(0)
1007#define HQSEL_VIQ BIT(1)
1008#define HQSEL_BEQ BIT(2)
1009#define HQSEL_BKQ BIT(3)
1010#define HQSEL_MGTQ BIT(4)
1011#define HQSEL_HIQ BIT(5)
1012
1013#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14)
1014#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12)
1015#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10)
1016#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8)
1017#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6)
1018#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4)
1019
1020#define QUEUE_LOW 1
1021#define QUEUE_NORMAL 2
1022#define QUEUE_HIGH 3
1023
1024#define _LLT_NO_ACTIVE 0x0
1025#define _LLT_WRITE_ACCESS 0x1
1026#define _LLT_READ_ACCESS 0x2
1027
1028#define _LLT_INIT_DATA(x) ((x) & 0xFF)
1029#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8)
1030#define _LLT_OP(x) (((x) & 0x3) << 30)
1031#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3)
1032
1033#define BB_WRITE_READ_MASK (BIT(31) | BIT(30))
1034#define BB_WRITE_EN BIT(30)
1035#define BB_READ_EN BIT(31)
1036
1037#define _HPQ(x) ((x) & 0xFF)
1038#define _LPQ(x) (((x) & 0xFF) << 8)
1039#define _PUBQ(x) (((x) & 0xFF) << 16)
1040#define _NPQ(x) ((x) & 0xFF)
1041
1042#define HPQ_PUBLIC_DIS BIT(24)
1043#define LPQ_PUBLIC_DIS BIT(25)
1044#define LD_RQPN BIT(31)
1045
1046#define BCN_VALID BIT(16)
1047#define BCN_HEAD(x) (((x) & 0xFF) << 8)
1048#define BCN_HEAD_MASK 0xFF00
1049
1050#define BLK_DESC_NUM_SHIFT 4
1051#define BLK_DESC_NUM_MASK 0xF
1052
1053#define DROP_DATA_EN BIT(9)
1054
1055#define EN_AMPDU_RTY_NEW BIT(7)
1056
1057#define _INIRTSMCS_SEL(x) ((x) & 0x3F)
1058
1059#define _SPEC_SIFS_CCK(x) ((x) & 0xFF)
1060#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8)
1061
1062#define RATE_REG_BITMAP_ALL 0xFFFFF
1063
1064#define _RRSC_BITMAP(x) ((x) & 0xFFFFF)
1065
1066#define _RRSR_RSC(x) (((x) & 0x3) << 21)
1067#define RRSR_RSC_RESERVED 0x0
1068#define RRSR_RSC_UPPER_SUBCHANNEL 0x1
1069#define RRSR_RSC_LOWER_SUBCHANNEL 0x2
1070#define RRSR_RSC_DUPLICATE_MODE 0x3
1071
1072#define USE_SHORT_G1 BIT(20)
1073
1074#define _AGGLMT_MCS0(x) ((x) & 0xF)
1075#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4)
1076#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8)
1077#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12)
1078#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16)
1079#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20)
1080#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24)
1081#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28)
1082
1083#define RETRY_LIMIT_SHORT_SHIFT 8
1084#define RETRY_LIMIT_LONG_SHIFT 0
1085
1086#define _DARF_RC1(x) ((x) & 0x1F)
1087#define _DARF_RC2(x) (((x) & 0x1F) << 8)
1088#define _DARF_RC3(x) (((x) & 0x1F) << 16)
1089#define _DARF_RC4(x) (((x) & 0x1F) << 24)
1090#define _DARF_RC5(x) ((x) & 0x1F)
1091#define _DARF_RC6(x) (((x) & 0x1F) << 8)
1092#define _DARF_RC7(x) (((x) & 0x1F) << 16)
1093#define _DARF_RC8(x) (((x) & 0x1F) << 24)
1094
1095#define _RARF_RC1(x) ((x) & 0x1F)
1096#define _RARF_RC2(x) (((x) & 0x1F) << 8)
1097#define _RARF_RC3(x) (((x) & 0x1F) << 16)
1098#define _RARF_RC4(x) (((x) & 0x1F) << 24)
1099#define _RARF_RC5(x) ((x) & 0x1F)
1100#define _RARF_RC6(x) (((x) & 0x1F) << 8)
1101#define _RARF_RC7(x) (((x) & 0x1F) << 16)
1102#define _RARF_RC8(x) (((x) & 0x1F) << 24)
1103
1104#define AC_PARAM_TXOP_LIMIT_OFFSET 16
1105#define AC_PARAM_ECW_MAX_OFFSET 12
1106#define AC_PARAM_ECW_MIN_OFFSET 8
1107#define AC_PARAM_AIFS_OFFSET 0
1108
1109#define _AIFS(x) (x)
1110#define _ECW_MAX_MIN(x) ((x) << 8)
1111#define _TXOP_LIMIT(x) ((x) << 16)
1112
1113#define _BCNIFS(x) ((x) & 0xFF)
1114#define _BCNECW(x) ((((x) & 0xF)) << 8)
1115
1116#define _LRL(x) ((x) & 0x3F)
1117#define _SRL(x) (((x) & 0x3F) << 8)
1118
1119#define _SIFS_CCK_CTX(x) ((x) & 0xFF)
1120#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8);
1121
1122#define _SIFS_OFDM_CTX(x) ((x) & 0xFF)
1123#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8);
1124
1125#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8)
1126
1127#define DIS_EDCA_CNT_DWN BIT(11)
1128
1129#define EN_MBSSID BIT(1)
1130#define EN_TXBCN_RPT BIT(2)
1131#define EN_BCN_FUNCTION BIT(3)
1132
1133#define TSFTR_RST BIT(0)
1134#define TSFTR1_RST BIT(1)
1135
1136#define STOP_BCNQ BIT(6)
1137
1138#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4)
1139#define DIS_TSF_UDT0_TEST_CHIP BIT(5)
1140
1141#define ACMHW_HWEN BIT(0)
1142#define ACMHW_BEQEN BIT(1)
1143#define ACMHW_VIQEN BIT(2)
1144#define ACMHW_VOQEN BIT(3)
1145#define ACMHW_BEQSTATUS BIT(4)
1146#define ACMHW_VIQSTATUS BIT(5)
1147#define ACMHW_VOQSTATUS BIT(6)
1148
1149#define APSDOFF BIT(6)
1150#define APSDOFF_STATUS BIT(7)
1151
1152#define BW_20MHZ BIT(2)
1153
1154#define RATE_BITMAP_ALL 0xFFFFF
1155
1156#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1
1157
1158#define TSFRST BIT(0)
1159#define DIS_GCLK BIT(1)
1160#define PAD_SEL BIT(2)
1161#define PWR_ST BIT(6)
1162#define PWRBIT_OW_EN BIT(7)
1163#define ACRC BIT(8)
1164#define CFENDFORM BIT(9)
1165#define ICV BIT(10)
1166
1167#define AAP BIT(0)
1168#define APM BIT(1)
1169#define AM BIT(2)
1170#define AB BIT(3)
1171#define ADD3 BIT(4)
1172#define APWRMGT BIT(5)
1173#define CBSSID BIT(6)
1174#define CBSSID_DATA BIT(6)
1175#define CBSSID_BCN BIT(7)
1176#define ACRC32 BIT(8)
1177#define AICV BIT(9)
1178#define ADF BIT(11)
1179#define ACF BIT(12)
1180#define AMF BIT(13)
1181#define HTC_LOC_CTRL BIT(14)
1182#define UC_DATA_EN BIT(16)
1183#define BM_DATA_EN BIT(17)
1184#define MFBEN BIT(22)
1185#define LSIGEN BIT(23)
1186#define ENMBID BIT(24)
1187#define APP_BASSN BIT(27)
1188#define APP_PHYSTS BIT(28)
1189#define APP_ICV BIT(29)
1190#define APP_MIC BIT(30)
1191#define APP_FCS BIT(31)
1192
1193#define _MIN_SPACE(x) ((x) & 0x7)
1194#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3)
1195
1196#define RXERR_TYPE_OFDM_PPDU 0
1197#define RXERR_TYPE_OFDM_FALSE_ALARM 1
1198#define RXERR_TYPE_OFDM_MPDU_OK 2
1199#define RXERR_TYPE_OFDM_MPDU_FAIL 3
1200#define RXERR_TYPE_CCK_PPDU 4
1201#define RXERR_TYPE_CCK_FALSE_ALARM 5
1202#define RXERR_TYPE_CCK_MPDU_OK 6
1203#define RXERR_TYPE_CCK_MPDU_FAIL 7
1204#define RXERR_TYPE_HT_PPDU 8
1205#define RXERR_TYPE_HT_FALSE_ALARM 9
1206#define RXERR_TYPE_HT_MPDU_TOTAL 10
1207#define RXERR_TYPE_HT_MPDU_OK 11
1208#define RXERR_TYPE_HT_MPDU_FAIL 12
1209#define RXERR_TYPE_RX_FULL_DROP 15
1210
1211#define RXERR_COUNTER_MASK 0xFFFFF
1212#define RXERR_RPT_RST BIT(27)
1213#define _RXERR_RPT_SEL(type) ((type) << 28)
1214
1215#define SCR_TXUSEDK BIT(0)
1216#define SCR_RXUSEDK BIT(1)
1217#define SCR_TXENCENABLE BIT(2)
1218#define SCR_RXDECENABLE BIT(3)
1219#define SCR_SKBYA2 BIT(4)
1220#define SCR_NOSKMC BIT(5)
1221#define SCR_TXBCUSEDK BIT(6)
1222#define SCR_RXBCUSEDK BIT(7)
1223
1224#define USB_IS_HIGH_SPEED 0
1225#define USB_IS_FULL_SPEED 1
1226#define USB_SPEED_MASK BIT(5)
1227
1228#define USB_NORMAL_SIE_EP_MASK 0xF
1229#define USB_NORMAL_SIE_EP_SHIFT 4
1230
1231#define USB_TEST_EP_MASK 0x30
1232#define USB_TEST_EP_SHIFT 4
1233
1234#define USB_AGG_EN BIT(3)
1235
1236#define MAC_ADDR_LEN 6
1237#define LAST_ENTRY_OF_TX_PKT_BUFFER 175/*255 88e*/
1238
1239#define POLLING_LLT_THRESHOLD 20
1240#define POLLING_READY_TIMEOUT_COUNT 3000
1241
1242#define MAX_MSS_DENSITY_2T 0x13
1243#define MAX_MSS_DENSITY_1T 0x0A
1244
1245#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
1246#define EPROM_CMD_CONFIG 0x3
1247#define EPROM_CMD_LOAD 1
1248
1249#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE
1250
1251#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
1252
1253#define RPMAC_RESET 0x100
1254#define RPMAC_TXSTART 0x104
1255#define RPMAC_TXLEGACYSIG 0x108
1256#define RPMAC_TXHTSIG1 0x10c
1257#define RPMAC_TXHTSIG2 0x110
1258#define RPMAC_PHYDEBUG 0x114
1259#define RPMAC_TXPACKETNUM 0x118
1260#define RPMAC_TXIDLE 0x11c
1261#define RPMAC_TXMACHEADER0 0x120
1262#define RPMAC_TXMACHEADER1 0x124
1263#define RPMAC_TXMACHEADER2 0x128
1264#define RPMAC_TXMACHEADER3 0x12c
1265#define RPMAC_TXMACHEADER4 0x130
1266#define RPMAC_TXMACHEADER5 0x134
1267#define RPMAC_TXDADATYPE 0x138
1268#define RPMAC_TXRANDOMSEED 0x13c
1269#define RPMAC_CCKPLCPPREAMBLE 0x140
1270#define RPMAC_CCKPLCPHEADER 0x144
1271#define RPMAC_CCKCRC16 0x148
1272#define RPMAC_OFDMRXCRC32OK 0x170
1273#define RPMAC_OFDMRXCRC32Er 0x174
1274#define RPMAC_OFDMRXPARITYER 0x178
1275#define RPMAC_OFDMRXCRC8ER 0x17c
1276#define RPMAC_CCKCRXRC16ER 0x180
1277#define RPMAC_CCKCRXRC32ER 0x184
1278#define RPMAC_CCKCRXRC32OK 0x188
1279#define RPMAC_TXSTATUS 0x18c
1280
1281#define RFPGA0_RFMOD 0x800
1282
1283#define RFPGA0_TXINFO 0x804
1284#define RFPGA0_PSDFUNCTION 0x808
1285
1286#define RFPGA0_TXGAINSTAGE 0x80c
1287
1288#define RFPGA0_RFTIMING1 0x810
1289#define RFPGA0_RFTIMING2 0x814
1290
1291#define RFPGA0_XA_HSSIPARAMETER1 0x820
1292#define RFPGA0_XA_HSSIPARAMETER2 0x824
1293#define RFPGA0_XB_HSSIPARAMETER1 0x828
1294#define RFPGA0_XB_HSSIPARAMETER2 0x82c
1295
1296#define RFPGA0_XA_LSSIPARAMETER 0x840
1297#define RFPGA0_XB_LSSIPARAMETER 0x844
1298
1299#define RFPGA0_RFWAKEUPPARAMETER 0x850
1300#define RFPGA0_RFSLEEPUPPARAMETER 0x854
1301
1302#define RFPGA0_XAB_SWITCHCONTROL 0x858
1303#define RFPGA0_XCD_SWITCHCONTROL 0x85c
1304
1305#define RFPGA0_XA_RFINTERFACEOE 0x860
1306#define RFPGA0_XB_RFINTERFACEOE 0x864
1307
1308#define RFPGA0_XAB_RFINTERFACESW 0x870
1309#define RFPGA0_XCD_RFINTERFACESW 0x874
1310
1311#define rFPGA0_XAB_RFPARAMETER 0x878
1312#define rFPGA0_XCD_RFPARAMETER 0x87c
1313
1314#define RFPGA0_ANALOGPARAMETER1 0x880
1315#define RFPGA0_ANALOGPARAMETER2 0x884
1316#define RFPGA0_ANALOGPARAMETER3 0x888
1317#define RFPGA0_ANALOGPARAMETER4 0x88c
1318
1319#define RFPGA0_XA_LSSIREADBACK 0x8a0
1320#define RFPGA0_XB_LSSIREADBACK 0x8a4
1321#define RFPGA0_XC_LSSIREADBACK 0x8a8
1322#define RFPGA0_XD_LSSIREADBACK 0x8ac
1323
1324#define RFPGA0_PSDREPORT 0x8b4
1325#define TRANSCEIVEA_HSPI_READBACK 0x8b8
1326#define TRANSCEIVEB_HSPI_READBACK 0x8bc
1327#define REG_SC_CNT 0x8c4
1328#define RFPGA0_XAB_RFINTERFACERB 0x8e0
1329#define RFPGA0_XCD_RFINTERFACERB 0x8e4
1330
1331#define RFPGA1_RFMOD 0x900
1332
1333#define RFPGA1_TXBLOCK 0x904
1334#define RFPGA1_DEBUGSELECT 0x908
1335#define RFPGA1_TXINFO 0x90c
1336
1337#define RCCK0_SYSTEM 0xa00
1338
1339#define RCCK0_AFESETTING 0xa04
1340#define RCCK0_CCA 0xa08
1341
1342#define RCCK0_RXAGC1 0xa0c
1343#define RCCK0_RXAGC2 0xa10
1344
1345#define RCCK0_RXHP 0xa14
1346
1347#define RCCK0_DSPPARAMETER1 0xa18
1348#define RCCK0_DSPPARAMETER2 0xa1c
1349
1350#define RCCK0_TXFILTER1 0xa20
1351#define RCCK0_TXFILTER2 0xa24
1352#define RCCK0_DEBUGPORT 0xa28
1353#define RCCK0_FALSEALARMREPORT 0xa2c
1354#define RCCK0_TRSSIREPORT 0xa50
1355#define RCCK0_RXREPORT 0xa54
1356#define RCCK0_FACOUNTERLOWER 0xa5c
1357#define RCCK0_FACOUNTERUPPER 0xa58
1358#define RCCK0_CCA_CNT 0xa60
1359
1360
1361/* PageB(0xB00) */
1362#define RPDP_ANTA 0xb00
1363#define RPDP_ANTA_4 0xb04
1364#define RPDP_ANTA_8 0xb08
1365#define RPDP_ANTA_C 0xb0c
1366#define RPDP_ANTA_10 0xb10
1367#define RPDP_ANTA_14 0xb14
1368#define RPDP_ANTA_18 0xb18
1369#define RPDP_ANTA_1C 0xb1c
1370#define RPDP_ANTA_20 0xb20
1371#define RPDP_ANTA_24 0xb24
1372
1373#define RCONFIG_PMPD_ANTA 0xb28
1374#define RCONFIG_RAM64X16 0xb2c
1375
1376#define RBNDA 0xb30
1377#define RHSSIPAR 0xb34
1378
1379#define RCONFIG_ANTA 0xb68
1380#define RCONFIG_ANTB 0xb6c
1381
1382#define RPDP_ANTB 0xb70
1383#define RPDP_ANTB_4 0xb74
1384#define RPDP_ANTB_8 0xb78
1385#define RPDP_ANTB_C 0xb7c
1386#define RPDP_ANTB_10 0xb80
1387#define RPDP_ANTB_14 0xb84
1388#define RPDP_ANTB_18 0xb88
1389#define RPDP_ANTB_1C 0xb8c
1390#define RPDP_ANTB_20 0xb90
1391#define RPDP_ANTB_24 0xb94
1392
1393#define RCONFIG_PMPD_ANTB 0xb98
1394
1395#define RBNDB 0xba0
1396
1397#define RAPK 0xbd8
1398#define rPm_Rx0_AntA 0xbdc
1399#define rPm_Rx1_AntA 0xbe0
1400#define rPm_Rx2_AntA 0xbe4
1401#define rPm_Rx3_AntA 0xbe8
1402#define rPm_Rx0_AntB 0xbec
1403#define rPm_Rx1_AntB 0xbf0
1404#define rPm_Rx2_AntB 0xbf4
1405#define rPm_Rx3_AntB 0xbf8
1406
1407/*Page C*/
1408#define ROFDM0_LSTF 0xc00
1409
1410#define ROFDM0_TRXPATHENABLE 0xc04
1411#define ROFDM0_TRMUXPAR 0xc08
1412#define ROFDM0_TRSWISOLATION 0xc0c
1413
1414#define ROFDM0_XARXAFE 0xc10
1415#define ROFDM0_XARXIQIMBAL 0xc14
1416#define ROFDM0_XBRXAFE 0xc18
1417#define ROFDM0_XBRXIQIMBAL 0xc1c
1418#define ROFDM0_XCRXAFE 0xc20
1419#define ROFDM0_XCRXIQIMBAL 0xc24
1420#define ROFDM0_XDRXAFE 0xc28
1421#define ROFDM0_XDRXIQIMBAL 0xc2c
1422
1423#define ROFDM0_RXDETECTOR1 0xc30
1424#define ROFDM0_RXDETECTOR2 0xc34
1425#define ROFDM0_RXDETECTOR3 0xc38
1426#define ROFDM0_RXDETECTOR4 0xc3c
1427
1428#define ROFDM0_RXDSP 0xc40
1429#define ROFDM0_CFOANDDAGC 0xc44
1430#define ROFDM0_CCADROPTHRES 0xc48
1431#define ROFDM0_ECCATHRES 0xc4c
1432
1433#define ROFDM0_XAAGCCORE1 0xc50
1434#define ROFDM0_XAAGCCORE2 0xc54
1435#define ROFDM0_XBAGCCORE1 0xc58
1436#define ROFDM0_XBAGCCORE2 0xc5c
1437#define ROFDM0_XCAGCCORE1 0xc60
1438#define ROFDM0_XCAGCCORE2 0xc64
1439#define ROFDM0_XDAGCCORE1 0xc68
1440#define ROFDM0_XDAGCCORE2 0xc6c
1441
1442#define ROFDM0_AGCPARAMETER1 0xc70
1443#define ROFDM0_AGCPARAMETER2 0xc74
1444#define ROFDM0_AGCRSSITABLE 0xc78
1445#define ROFDM0_HTSTFAGC 0xc7c
1446
1447#define ROFDM0_XATXIQIMBAL 0xc80
1448#define ROFDM0_XATXAFE 0xc84
1449#define ROFDM0_XBTXIQIMBAL 0xc88
1450#define ROFDM0_XBTXAFE 0xc8c
1451#define ROFDM0_XCTXIQIMBAL 0xc90
1452#define ROFDM0_XCTXAFE 0xc94
1453#define ROFDM0_XDTXIQIMBAL 0xc98
1454#define ROFDM0_XDTXAFE 0xc9c
1455
1456#define ROFDM0_RXIQEXTANTA 0xca0
1457#define ROFDM0_TXCOEFF1 0xca4
1458#define ROFDM0_TXCOEFF2 0xca8
1459#define ROFDM0_TXCOEFF3 0xcac
1460#define ROFDM0_TXCOEFF4 0xcb0
1461#define ROFDM0_TXCOEFF5 0xcb4
1462#define ROFDM0_TXCOEFF6 0xcb8
1463
1464#define ROFDM0_RXHPPARAMETER 0xce0
1465#define ROFDM0_TXPSEUDONOISEWGT 0xce4
1466#define ROFDM0_FRAMESYNC 0xcf0
1467#define ROFDM0_DFSREPORT 0xcf4
1468
1469
1470#define ROFDM1_LSTF 0xd00
1471#define ROFDM1_TRXPATHENABLE 0xd04
1472
1473#define ROFDM1_CF0 0xd08
1474#define ROFDM1_CSI1 0xd10
1475#define ROFDM1_SBD 0xd14
1476#define ROFDM1_CSI2 0xd18
1477#define ROFDM1_CFOTRACKING 0xd2c
1478#define ROFDM1_TRXMESAURE1 0xd34
1479#define ROFDM1_INTFDET 0xd3c
1480#define ROFDM1_PSEUDONOISESTATEAB 0xd50
1481#define ROFDM1_PSEUDONOISESTATECD 0xd54
1482#define ROFDM1_RXPSEUDONOISEWGT 0xd58
1483
1484#define ROFDM_PHYCOUNTER1 0xda0
1485#define ROFDM_PHYCOUNTER2 0xda4
1486#define ROFDM_PHYCOUNTER3 0xda8
1487
1488#define ROFDM_SHORTCFOAB 0xdac
1489#define ROFDM_SHORTCFOCD 0xdb0
1490#define ROFDM_LONGCFOAB 0xdb4
1491#define ROFDM_LONGCFOCD 0xdb8
1492#define ROFDM_TAILCF0AB 0xdbc
1493#define ROFDM_TAILCF0CD 0xdc0
1494#define ROFDM_PWMEASURE1 0xdc4
1495#define ROFDM_PWMEASURE2 0xdc8
1496#define ROFDM_BWREPORT 0xdcc
1497#define ROFDM_AGCREPORT 0xdd0
1498#define ROFDM_RXSNR 0xdd4
1499#define ROFDM_RXEVMCSI 0xdd8
1500#define ROFDM_SIGREPORT 0xddc
1501
1502#define RTXAGC_A_RATE18_06 0xe00
1503#define RTXAGC_A_RATE54_24 0xe04
1504#define RTXAGC_A_CCK1_MCS32 0xe08
1505#define RTXAGC_A_MCS03_MCS00 0xe10
1506#define RTXAGC_A_MCS07_MCS04 0xe14
1507#define RTXAGC_A_MCS11_MCS08 0xe18
1508#define RTXAGC_A_MCS15_MCS12 0xe1c
1509
1510#define RTXAGC_B_RATE18_06 0x830
1511#define RTXAGC_B_RATE54_24 0x834
1512#define RTXAGC_B_CCK1_55_MCS32 0x838
1513#define RTXAGC_B_MCS03_MCS00 0x83c
1514#define RTXAGC_B_MCS07_MCS04 0x848
1515#define RTXAGC_B_MCS11_MCS08 0x84c
1516#define RTXAGC_B_MCS15_MCS12 0x868
1517#define RTXAGC_B_CCK11_A_CCK2_11 0x86c
1518
1519#define RFPGA0_IQK 0xe28
1520#define RTX_IQK_TONE_A 0xe30
1521#define RRX_IQK_TONE_A 0xe34
1522#define RTX_IQK_PI_A 0xe38
1523#define RRX_IQK_PI_A 0xe3c
1524
1525#define RTX_IQK 0xe40
1526#define RRX_IQK 0xe44
1527#define RIQK_AGC_PTS 0xe48
1528#define RIQK_AGC_RSP 0xe4c
1529#define RTX_IQK_TONE_B 0xe50
1530#define RRX_IQK_TONE_B 0xe54
1531#define RTX_IQK_PI_B 0xe58
1532#define RRX_IQK_PI_B 0xe5c
1533#define RIQK_AGC_CONT 0xe60
1534
1535#define RBLUE_TOOTH 0xe6c
1536#define RRX_WAIT_CCA 0xe70
1537#define RTX_CCK_RFON 0xe74
1538#define RTX_CCK_BBON 0xe78
1539#define RTX_OFDM_RFON 0xe7c
1540#define RTX_OFDM_BBON 0xe80
1541#define RTX_TO_RX 0xe84
1542#define RTX_TO_TX 0xe88
1543#define RRX_CCK 0xe8c
1544
1545#define RTX_POWER_BEFORE_IQK_A 0xe94
1546#define RTX_POWER_AFTER_IQK_A 0xe9c
1547
1548#define RRX_POWER_BEFORE_IQK_A 0xea0
1549#define RRX_POWER_BEFORE_IQK_A_2 0xea4
1550#define RRX_POWER_AFTER_IQK_A 0xea8
1551#define RRX_POWER_AFTER_IQK_A_2 0xeac
1552
1553#define RTX_POWER_BEFORE_IQK_B 0xeb4
1554#define RTX_POWER_AFTER_IQK_B 0xebc
1555
1556#define RRX_POWER_BEFORE_IQK_B 0xec0
1557#define RRX_POWER_BEFORE_IQK_B_2 0xec4
1558#define RRX_POWER_AFTER_IQK_B 0xec8
1559#define RRX_POWER_AFTER_IQK_B_2 0xecc
1560
1561#define RRX_OFDM 0xed0
1562#define RRX_WAIT_RIFS 0xed4
1563#define RRX_TO_RX 0xed8
1564#define RSTANDBY 0xedc
1565#define RSLEEP 0xee0
1566#define RPMPD_ANAEN 0xeec
1567
1568#define RZEBRA1_HSSIENABLE 0x0
1569#define RZEBRA1_TRXENABLE1 0x1
1570#define RZEBRA1_TRXENABLE2 0x2
1571#define RZEBRA1_AGC 0x4
1572#define RZEBRA1_CHARGEPUMP 0x5
1573#define RZEBRA1_CHANNEL 0x7
1574
1575#define RZEBRA1_TXGAIN 0x8
1576#define RZEBRA1_TXLPF 0x9
1577#define RZEBRA1_RXLPF 0xb
1578#define RZEBRA1_RXHPFCORNER 0xc
1579
1580#define RGLOBALCTRL 0
1581#define RRTL8256_TXLPF 19
1582#define RRTL8256_RXLPF 11
1583#define RRTL8258_TXLPF 0x11
1584#define RRTL8258_RXLPF 0x13
1585#define RRTL8258_RSSILPF 0xa
1586
1587#define RF_AC 0x00
1588
1589#define RF_IQADJ_G1 0x01
1590#define RF_IQADJ_G2 0x02
1591#define RF_POW_TRSW 0x05
1592
1593#define RF_GAIN_RX 0x06
1594#define RF_GAIN_TX 0x07
1595
1596#define RF_TXM_IDAC 0x08
1597#define RF_BS_IQGEN 0x0F
1598
1599#define RF_MODE1 0x10
1600#define RF_MODE2 0x11
1601
1602#define RF_RX_AGC_HP 0x12
1603#define RF_TX_AGC 0x13
1604#define RF_BIAS 0x14
1605#define RF_IPA 0x15
1606#define RF_POW_ABILITY 0x17
1607#define RF_MODE_AG 0x18
1608#define RRFCHANNEL 0x18
1609#define RF_CHNLBW 0x18
1610#define RF_TOP 0x19
1611
1612#define RF_RX_G1 0x1A
1613#define RF_RX_G2 0x1B
1614
1615#define RF_RX_BB2 0x1C
1616#define RF_RX_BB1 0x1D
1617
1618#define RF_RCK1 0x1E
1619#define RF_RCK2 0x1F
1620
1621#define RF_TX_G1 0x20
1622#define RF_TX_G2 0x21
1623#define RF_TX_G3 0x22
1624
1625#define RF_TX_BB1 0x23
1626#define RF_T_METER 0x42
1627
1628#define RF_SYN_G1 0x25
1629#define RF_SYN_G2 0x26
1630#define RF_SYN_G3 0x27
1631#define RF_SYN_G4 0x28
1632#define RF_SYN_G5 0x29
1633#define RF_SYN_G6 0x2A
1634#define RF_SYN_G7 0x2B
1635#define RF_SYN_G8 0x2C
1636
1637#define RF_RCK_OS 0x30
1638#define RF_TXPA_G1 0x31
1639#define RF_TXPA_G2 0x32
1640#define RF_TXPA_G3 0x33
1641
1642#define RF_TX_BIAS_A 0x35
1643#define RF_TX_BIAS_D 0x36
1644#define RF_LOBF_9 0x38
1645#define RF_RXRF_A3 0x3C
1646#define RF_TRSW 0x3F
1647
1648#define RF_TXRF_A2 0x41
1649#define RF_TXPA_G4 0x46
1650#define RF_TXPA_A4 0x4B
1651
1652#define RF_WE_LUT 0xEF
1653
1654#define BBBRESETB 0x100
1655#define BGLOBALRESETB 0x200
1656#define BOFDMTXSTART 0x4
1657#define BCCKTXSTART 0x8
1658#define BCRC32DEBUG 0x100
1659#define BPMACLOOPBACK 0x10
1660#define BTXLSIG 0xffffff
1661#define BOFDMTXRATE 0xf
1662#define BOFDMTXRESERVED 0x10
1663#define BOFDMTXLENGTH 0x1ffe0
1664#define BOFDMTXPARITY 0x20000
1665#define BTXHTSIG1 0xffffff
1666#define BTXHTMCSRATE 0x7f
1667#define BTXHTBW 0x80
1668#define BTXHTLENGTH 0xffff00
1669#define BTXHTSIG2 0xffffff
1670#define BTXHTSMOOTHING 0x1
1671#define BTXHTSOUNDING 0x2
1672#define BTXHTRESERVED 0x4
1673#define BTXHTAGGREATION 0x8
1674#define BTXHTSTBC 0x30
1675#define BTXHTADVANCECODING 0x40
1676#define BTXHTSHORTGI 0x80
1677#define BTXHTNUMBERHT_LTF 0x300
1678#define BTXHTCRC8 0x3fc00
1679#define BCOUNTERRESET 0x10000
1680#define BNUMOFOFDMTX 0xffff
1681#define BNUMOFCCKTX 0xffff0000
1682#define BTXIDLEINTERVAL 0xffff
1683#define BOFDMSERVICE 0xffff0000
1684#define BTXMACHEADER 0xffffffff
1685#define BTXDATAINIT 0xff
1686#define BTXHTMODE 0x100
1687#define BTXDATATYPE 0x30000
1688#define BTXRANDOMSEED 0xffffffff
1689#define BCCKTXPREAMBLE 0x1
1690#define BCCKTXSFD 0xffff0000
1691#define BCCKTXSIG 0xff
1692#define BCCKTXSERVICE 0xff00
1693#define BCCKLENGTHEXT 0x8000
1694#define BCCKTXLENGHT 0xffff0000
1695#define BCCKTXCRC16 0xffff
1696#define BCCKTXSTATUS 0x1
1697#define BOFDMTXSTATUS 0x2
1698#define IS_BB_REG_OFFSET_92S(_offset) \
1699 ((_offset >= 0x800) && (_offset <= 0xfff))
1700
1701#define BRFMOD 0x1
1702#define BJAPANMODE 0x2
1703#define BCCKTXSC 0x30
1704#define BCCKEN 0x1000000
1705#define BOFDMEN 0x2000000
1706
1707#define BOFDMRXADCPHASE 0x10000
1708#define BOFDMTXDACPHASE 0x40000
1709#define BXATXAGC 0x3f
1710
1711#define BXBTXAGC 0xf00
1712#define BXCTXAGC 0xf000
1713#define BXDTXAGC 0xf0000
1714
1715#define BPASTART 0xf0000000
1716#define BTRSTART 0x00f00000
1717#define BRFSTART 0x0000f000
1718#define BBBSTART 0x000000f0
1719#define BBBCCKSTART 0x0000000f
1720#define BPAEND 0xf
1721#define BTREND 0x0f000000
1722#define BRFEND 0x000f0000
1723#define BCCAMASK 0x000000f0
1724#define BR2RCCAMASK 0x00000f00
1725#define BHSSI_R2TDELAY 0xf8000000
1726#define BHSSI_T2RDELAY 0xf80000
1727#define BCONTXHSSI 0x400
1728#define BIGFROMCCK 0x200
1729#define BAGCADDRESS 0x3f
1730#define BRXHPTX 0x7000
1731#define BRXHP2RX 0x38000
1732#define BRXHPCCKINI 0xc0000
1733#define BAGCTXCODE 0xc00000
1734#define BAGCRXCODE 0x300000
1735
1736#define B3WIREDATALENGTH 0x800
1737#define B3WIREADDREAALENGTH 0x400
1738
1739#define B3WIRERFPOWERDOWN 0x1
1740#define B5GPAPEPOLARITY 0x40000000
1741#define B2GPAPEPOLARITY 0x80000000
1742#define BRFSW_TXDEFAULTANT 0x3
1743#define BRFSW_TXOPTIONANT 0x30
1744#define BRFSW_RXDEFAULTANT 0x300
1745#define BRFSW_RXOPTIONANT 0x3000
1746#define BRFSI_3WIREDATA 0x1
1747#define BRFSI_3WIRECLOCK 0x2
1748#define BRFSI_3WIRELOAD 0x4
1749#define BRFSI_3WIRERW 0x8
1750#define BRFSI_3WIRE 0xf
1751
1752#define BRFSI_RFENV 0x10
1753
1754#define BRFSI_TRSW 0x20
1755#define BRFSI_TRSWB 0x40
1756#define BRFSI_ANTSW 0x100
1757#define BRFSI_ANTSWB 0x200
1758#define BRFSI_PAPE 0x400
1759#define BRFSI_PAPE5G 0x800
1760#define BBANDSELECT 0x1
1761#define BHTSIG2_GI 0x80
1762#define BHTSIG2_SMOOTHING 0x01
1763#define BHTSIG2_SOUNDING 0x02
1764#define BHTSIG2_AGGREATON 0x08
1765#define BHTSIG2_STBC 0x30
1766#define BHTSIG2_ADVCODING 0x40
1767#define BHTSIG2_NUMOFHTLTF 0x300
1768#define BHTSIG2_CRC8 0x3fc
1769#define BHTSIG1_MCS 0x7f
1770#define BHTSIG1_BANDWIDTH 0x80
1771#define BHTSIG1_HTLENGTH 0xffff
1772#define BLSIG_RATE 0xf
1773#define BLSIG_RESERVED 0x10
1774#define BLSIG_LENGTH 0x1fffe
1775#define BLSIG_PARITY 0x20
1776#define BCCKRXPHASE 0x4
1777
1778#define BLSSIREADADDRESS 0x7f800000
1779#define BLSSIREADEDGE 0x80000000
1780
1781#define BLSSIREADBACKDATA 0xfffff
1782
1783#define BLSSIREADOKFLAG 0x1000
1784#define BCCKSAMPLERATE 0x8
1785#define BREGULATOR0STANDBY 0x1
1786#define BREGULATORPLLSTANDBY 0x2
1787#define BREGULATOR1STANDBY 0x4
1788#define BPLLPOWERUP 0x8
1789#define BDPLLPOWERUP 0x10
1790#define BDA10POWERUP 0x20
1791#define BAD7POWERUP 0x200
1792#define BDA6POWERUP 0x2000
1793#define BXTALPOWERUP 0x4000
1794#define B40MDCLKPOWERUP 0x8000
1795#define BDA6DEBUGMODE 0x20000
1796#define BDA6SWING 0x380000
1797
1798#define BADCLKPHASE 0x4000000
1799#define B80MCLKDELAY 0x18000000
1800#define BAFEWATCHDOGENABLE 0x20000000
1801
1802#define BXTALCAP01 0xc0000000
1803#define BXTALCAP23 0x3
1804#define BXTALCAP92X 0x0f000000
1805#define BXTALCAP 0x0f000000
1806
1807#define BINTDIFCLKENABLE 0x400
1808#define BEXTSIGCLKENABLE 0x800
1809#define BBANDGAP_MBIAS_POWERUP 0x10000
1810#define BAD11SH_GAIN 0xc0000
1811#define BAD11NPUT_RANGE 0x700000
1812#define BAD110P_CURRENT 0x3800000
1813#define BLPATH_LOOPBACK 0x4000000
1814#define BQPATH_LOOPBACK 0x8000000
1815#define BAFE_LOOPBACK 0x10000000
1816#define BDA10_SWING 0x7e0
1817#define BDA10_REVERSE 0x800
1818#define BDA_CLK_SOURCE 0x1000
1819#define BDA7INPUT_RANGE 0x6000
1820#define BDA7_GAIN 0x38000
1821#define BDA7OUTPUT_CM_MODE 0x40000
1822#define BDA7INPUT_CM_MODE 0x380000
1823#define BDA7CURRENT 0xc00000
1824#define BREGULATOR_ADJUST 0x7000000
1825#define BAD11POWERUP_ATTX 0x1
1826#define BDA10PS_ATTX 0x10
1827#define BAD11POWERUP_ATRX 0x100
1828#define BDA10PS_ATRX 0x1000
1829#define BCCKRX_AGC_FORMAT 0x200
1830#define BPSDFFT_SAMPLE_POINT 0xc000
1831#define BPSD_AVERAGE_NUM 0x3000
1832#define BIQPATH_CONTROL 0xc00
1833#define BPSD_FREQ 0x3ff
1834#define BPSD_ANTENNA_PATH 0x30
1835#define BPSD_IQ_SWITCH 0x40
1836#define BPSD_RX_TRIGGER 0x400000
1837#define BPSD_TX_TRIGGERCW 0x80000000
1838#define BPSD_SINE_TONE_SCALE 0x7f000000
1839#define BPSD_REPORT 0xffff
1840
1841#define BOFDM_TXSC 0x30000000
1842#define BCCK_TXON 0x1
1843#define BOFDM_TXON 0x2
1844#define BDEBUG_PAGE 0xfff
1845#define BDEBUG_ITEM 0xff
1846#define BANTL 0x10
1847#define BANT_NONHT 0x100
1848#define BANT_HT1 0x1000
1849#define BANT_HT2 0x10000
1850#define BANT_HT1S1 0x100000
1851#define BANT_NONHTS1 0x1000000
1852
1853#define BCCK_BBMODE 0x3
1854#define BCCK_TXPOWERSAVING 0x80
1855#define BCCK_RXPOWERSAVING 0x40
1856
1857#define BCCK_SIDEBAND 0x10
1858
1859#define BCCK_SCRAMBLE 0x8
1860#define BCCK_ANTDIVERSITY 0x8000
1861#define BCCK_CARRIER_RECOVERY 0x4000
1862#define BCCK_TXRATE 0x3000
1863#define BCCK_DCCANCEL 0x0800
1864#define BCCK_ISICANCEL 0x0400
1865#define BCCK_MATCH_FILTER 0x0200
1866#define BCCK_EQUALIZER 0x0100
1867#define BCCK_PREAMBLE_DETECT 0x800000
1868#define BCCK_FAST_FALSECCA 0x400000
1869#define BCCK_CH_ESTSTART 0x300000
1870#define BCCK_CCA_COUNT 0x080000
1871#define BCCK_CS_LIM 0x070000
1872#define BCCK_BIST_MODE 0x80000000
1873#define BCCK_CCAMASK 0x40000000
1874#define BCCK_TX_DAC_PHASE 0x4
1875#define BCCK_RX_ADC_PHASE 0x20000000
1876#define BCCKR_CP_MODE 0x0100
1877#define BCCK_TXDC_OFFSET 0xf0
1878#define BCCK_RXDC_OFFSET 0xf
1879#define BCCK_CCA_MODE 0xc000
1880#define BCCK_FALSECS_LIM 0x3f00
1881#define BCCK_CS_RATIO 0xc00000
1882#define BCCK_CORGBIT_SEL 0x300000
1883#define BCCK_PD_LIM 0x0f0000
1884#define BCCK_NEWCCA 0x80000000
1885#define BCCK_RXHP_OF_IG 0x8000
1886#define BCCK_RXIG 0x7f00
1887#define BCCK_LNA_POLARITY 0x800000
1888#define BCCK_RX1ST_BAIN 0x7f0000
1889#define BCCK_RF_EXTEND 0x20000000
1890#define BCCK_RXAGC_SATLEVEL 0x1f000000
1891#define BCCK_RXAGC_SATCOUNT 0xe0
1892#define BCCKRXRFSETTLE 0x1f
1893#define BCCK_FIXED_RXAGC 0x8000
1894#define BCCK_ANTENNA_POLARITY 0x2000
1895#define BCCK_TXFILTER_TYPE 0x0c00
1896#define BCCK_RXAGC_REPORTTYPE 0x0300
1897#define BCCK_RXDAGC_EN 0x80000000
1898#define BCCK_RXDAGC_PERIOD 0x20000000
1899#define BCCK_RXDAGC_SATLEVEL 0x1f000000
1900#define BCCK_TIMING_RECOVERY 0x800000
1901#define BCCK_TXC0 0x3f0000
1902#define BCCK_TXC1 0x3f000000
1903#define BCCK_TXC2 0x3f
1904#define BCCK_TXC3 0x3f00
1905#define BCCK_TXC4 0x3f0000
1906#define BCCK_TXC5 0x3f000000
1907#define BCCK_TXC6 0x3f
1908#define BCCK_TXC7 0x3f00
1909#define BCCK_DEBUGPORT 0xff0000
1910#define BCCK_DAC_DEBUG 0x0f000000
1911#define BCCK_FALSEALARM_ENABLE 0x8000
1912#define BCCK_FALSEALARM_READ 0x4000
1913#define BCCK_TRSSI 0x7f
1914#define BCCK_RXAGC_REPORT 0xfe
1915#define BCCK_RXREPORT_ANTSEL 0x80000000
1916#define BCCK_RXREPORT_MFOFF 0x40000000
1917#define BCCK_RXREPORT_SQLOSS 0x20000000
1918#define BCCK_RXREPORT_PKTLOSS 0x10000000
1919#define BCCK_RXREPORT_LOCKEDBIT 0x08000000
1920#define BCCK_RXREPORT_RATEERROR 0x04000000
1921#define BCCK_RXREPORT_RXRATE 0x03000000
1922#define BCCK_RXFA_COUNTER_LOWER 0xff
1923#define BCCK_RXFA_COUNTER_UPPER 0xff000000
1924#define BCCK_RXHPAGC_START 0xe000
1925#define BCCK_RXHPAGC_FINAL 0x1c00
1926#define BCCK_RXFALSEALARM_ENABLE 0x8000
1927#define BCCK_FACOUNTER_FREEZE 0x4000
1928#define BCCK_TXPATH_SEL 0x10000000
1929#define BCCK_DEFAULT_RXPATH 0xc000000
1930#define BCCK_OPTION_RXPATH 0x3000000
1931
1932#define BNUM_OFSTF 0x3
1933#define BSHIFT_L 0xc0
1934#define BGI_TH 0xc
1935#define BRXPATH_A 0x1
1936#define BRXPATH_B 0x2
1937#define BRXPATH_C 0x4
1938#define BRXPATH_D 0x8
1939#define BTXPATH_A 0x1
1940#define BTXPATH_B 0x2
1941#define BTXPATH_C 0x4
1942#define BTXPATH_D 0x8
1943#define BTRSSI_FREQ 0x200
1944#define BADC_BACKOFF 0x3000
1945#define BDFIR_BACKOFF 0xc000
1946#define BTRSSI_LATCH_PHASE 0x10000
1947#define BRX_LDC_OFFSET 0xff
1948#define BRX_QDC_OFFSET 0xff00
1949#define BRX_DFIR_MODE 0x1800000
1950#define BRX_DCNF_TYPE 0xe000000
1951#define BRXIQIMB_A 0x3ff
1952#define BRXIQIMB_B 0xfc00
1953#define BRXIQIMB_C 0x3f0000
1954#define BRXIQIMB_D 0xffc00000
1955#define BDC_DC_NOTCH 0x60000
1956#define BRXNB_NOTCH 0x1f000000
1957#define BPD_TH 0xf
1958#define BPD_TH_OPT2 0xc000
1959#define BPWED_TH 0x700
1960#define BIFMF_WIN_L 0x800
1961#define BPD_OPTION 0x1000
1962#define BMF_WIN_L 0xe000
1963#define BBW_SEARCH_L 0x30000
1964#define BWIN_ENH_L 0xc0000
1965#define BBW_TH 0x700000
1966#define BED_TH2 0x3800000
1967#define BBW_OPTION 0x4000000
1968#define BRADIO_TH 0x18000000
1969#define BWINDOW_L 0xe0000000
1970#define BSBD_OPTION 0x1
1971#define BFRAME_TH 0x1c
1972#define BFS_OPTION 0x60
1973#define BDC_SLOPE_CHECK 0x80
1974#define BFGUARD_COUNTER_DC_L 0xe00
1975#define BFRAME_WEIGHT_SHORT 0x7000
1976#define BSUB_TUNE 0xe00000
1977#define BFRAME_DC_LENGTH 0xe000000
1978#define BSBD_START_OFFSET 0x30000000
1979#define BFRAME_TH_2 0x7
1980#define BFRAME_GI2_TH 0x38
1981#define BGI2_SYNC_EN 0x40
1982#define BSARCH_SHORT_EARLY 0x300
1983#define BSARCH_SHORT_LATE 0xc00
1984#define BSARCH_GI2_LATE 0x70000
1985#define BCFOANTSUM 0x1
1986#define BCFOACC 0x2
1987#define BCFOSTARTOFFSET 0xc
1988#define BCFOLOOPBACK 0x70
1989#define BCFOSUMWEIGHT 0x80
1990#define BDAGCENABLE 0x10000
1991#define BTXIQIMB_A 0x3ff
1992#define BTXIQIMB_B 0xfc00
1993#define BTXIQIMB_C 0x3f0000
1994#define BTXIQIMB_D 0xffc00000
1995#define BTXIDCOFFSET 0xff
1996#define BTXIQDCOFFSET 0xff00
1997#define BTXDFIRMODE 0x10000
1998#define BTXPESUDO_NOISEON 0x4000000
1999#define BTXPESUDO_NOISE_A 0xff
2000#define BTXPESUDO_NOISE_B 0xff00
2001#define BTXPESUDO_NOISE_C 0xff0000
2002#define BTXPESUDO_NOISE_D 0xff000000
2003#define BCCA_DROPOPTION 0x20000
2004#define BCCA_DROPTHRES 0xfff00000
2005#define BEDCCA_H 0xf
2006#define BEDCCA_L 0xf0
2007#define BLAMBDA_ED 0x300
2008#define BRX_INITIALGAIN 0x7f
2009#define BRX_ANTDIV_EN 0x80
2010#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00
2011#define BRX_HIGHPOWER_FLOW 0x8000
2012#define BRX_AGC_FREEZE_THRES 0xc0000
2013#define BRX_FREEZESTEP_AGC1 0x300000
2014#define BRX_FREEZESTEP_AGC2 0xc00000
2015#define BRX_FREEZESTEP_AGC3 0x3000000
2016#define BRX_FREEZESTEP_AGC0 0xc000000
2017#define BRXRSSI_CMP_EN 0x10000000
2018#define BRXQUICK_AGCEN 0x20000000
2019#define BRXAGC_FREEZE_THRES_MODE 0x40000000
2020#define BRX_OVERFLOW_CHECKTYPE 0x80000000
2021#define BRX_AGCSHIFT 0x7f
2022#define BTRSW_TRI_ONLY 0x80
2023#define BPOWER_THRES 0x300
2024#define BRXAGC_EN 0x1
2025#define BRXAGC_TOGETHER_EN 0x2
2026#define BRXAGC_MIN 0x4
2027#define BRXHP_INI 0x7
2028#define BRXHP_TRLNA 0x70
2029#define BRXHP_RSSI 0x700
2030#define BRXHP_BBP1 0x7000
2031#define BRXHP_BBP2 0x70000
2032#define BRXHP_BBP3 0x700000
2033#define BRSSI_H 0x7f0000
2034#define BRSSI_GEN 0x7f000000
2035#define BRXSETTLE_TRSW 0x7
2036#define BRXSETTLE_LNA 0x38
2037#define BRXSETTLE_RSSI 0x1c0
2038#define BRXSETTLE_BBP 0xe00
2039#define BRXSETTLE_RXHP 0x7000
2040#define BRXSETTLE_ANTSW_RSSI 0x38000
2041#define BRXSETTLE_ANTSW 0xc0000
2042#define BRXPROCESS_TIME_DAGC 0x300000
2043#define BRXSETTLE_HSSI 0x400000
2044#define BRXPROCESS_TIME_BBPPW 0x800000
2045#define BRXANTENNA_POWER_SHIFT 0x3000000
2046#define BRSSI_TABLE_SELECT 0xc000000
2047#define BRXHP_FINAL 0x7000000
2048#define BRXHPSETTLE_BBP 0x7
2049#define BRXHTSETTLE_HSSI 0x8
2050#define BRXHTSETTLE_RXHP 0x70
2051#define BRXHTSETTLE_BBPPW 0x80
2052#define BRXHTSETTLE_IDLE 0x300
2053#define BRXHTSETTLE_RESERVED 0x1c00
2054#define BRXHT_RXHP_EN 0x8000
2055#define BRXAGC_FREEZE_THRES 0x30000
2056#define BRXAGC_TOGETHEREN 0x40000
2057#define BRXHTAGC_MIN 0x80000
2058#define BRXHTAGC_EN 0x100000
2059#define BRXHTDAGC_EN 0x200000
2060#define BRXHT_RXHP_BBP 0x1c00000
2061#define BRXHT_RXHP_FINAL 0xe0000000
2062#define BRXPW_RADIO_TH 0x3
2063#define BRXPW_RADIO_EN 0x4
2064#define BRXMF_HOLD 0x3800
2065#define BRXPD_DELAY_TH1 0x38
2066#define BRXPD_DELAY_TH2 0x1c0
2067#define BRXPD_DC_COUNT_MAX 0x600
2068#define BRXPD_DELAY_TH 0x8000
2069#define BRXPROCESS_DELAY 0xf0000
2070#define BRXSEARCHRANGE_GI2_EARLY 0x700000
2071#define BRXFRAME_FUARD_COUNTER_L 0x3800000
2072#define BRXSGI_GUARD_L 0xc000000
2073#define BRXSGI_SEARCH_L 0x30000000
2074#define BRXSGI_TH 0xc0000000
2075#define BDFSCNT0 0xff
2076#define BDFSCNT1 0xff00
2077#define BDFSFLAG 0xf0000
2078#define BMF_WEIGHT_SUM 0x300000
2079#define BMINIDX_TH 0x7f000000
2080#define BDAFORMAT 0x40000
2081#define BTXCH_EMU_ENABLE 0x01000000
2082#define BTRSW_ISOLATION_A 0x7f
2083#define BTRSW_ISOLATION_B 0x7f00
2084#define BTRSW_ISOLATION_C 0x7f0000
2085#define BTRSW_ISOLATION_D 0x7f000000
2086#define BEXT_LNA_GAIN 0x7c00
2087
2088#define BSTBC_EN 0x4
2089#define BANTENNA_MAPPING 0x10
2090#define BNSS 0x20
2091#define BCFO_ANTSUM_ID 0x200
2092#define BPHY_COUNTER_RESET 0x8000000
2093#define BCFO_REPORT_GET 0x4000000
2094#define BOFDM_CONTINUE_TX 0x10000000
2095#define BOFDM_SINGLE_CARRIER 0x20000000
2096#define BOFDM_SINGLE_TONE 0x40000000
2097#define BHT_DETECT 0x100
2098#define BCFOEN 0x10000
2099#define BCFOVALUE 0xfff00000
2100#define BSIGTONE_RE 0x3f
2101#define BSIGTONE_IM 0x7f00
2102#define BCOUNTER_CCA 0xffff
2103#define BCOUNTER_PARITYFAIL 0xffff0000
2104#define BCOUNTER_RATEILLEGAL 0xffff
2105#define BCOUNTER_CRC8FAIL 0xffff0000
2106#define BCOUNTER_MCSNOSUPPORT 0xffff
2107#define BCOUNTER_FASTSYNC 0xffff
2108#define BSHORTCFO 0xfff
2109#define BSHORTCFOT_LENGTH 12
2110#define BSHORTCFOF_LENGTH 11
2111#define BLONGCFO 0x7ff
2112#define BLONGCFOT_LENGTH 11
2113#define BLONGCFOF_LENGTH 11
2114#define BTAILCFO 0x1fff
2115#define BTAILCFOT_LENGTH 13
2116#define BTAILCFOF_LENGTH 12
2117#define BNOISE_EN_PWDB 0xffff
2118#define BCC_POWER_DB 0xffff0000
2119#define BMOISE_PWDB 0xffff
2120#define BPOWERMEAST_LENGTH 10
2121#define BPOWERMEASF_LENGTH 3
2122#define BRX_HT_BW 0x1
2123#define BRXSC 0x6
2124#define BRX_HT 0x8
2125#define BNB_INTF_DET_ON 0x1
2126#define BINTF_WIN_LEN_CFG 0x30
2127#define BNB_INTF_TH_CFG 0x1c0
2128#define BRFGAIN 0x3f
2129#define BTABLESEL 0x40
2130#define BTRSW 0x80
2131#define BRXSNR_A 0xff
2132#define BRXSNR_B 0xff00
2133#define BRXSNR_C 0xff0000
2134#define BRXSNR_D 0xff000000
2135#define BSNR_EVMT_LENGTH 8
2136#define BSNR_EVMF_LENGTH 1
2137#define BCSI1ST 0xff
2138#define BCSI2ND 0xff00
2139#define BRXEVM1ST 0xff0000
2140#define BRXEVM2ND 0xff000000
2141#define BSIGEVM 0xff
2142#define BPWDB 0xff00
2143#define BSGIEN 0x10000
2144
2145#define BSFACTOR_QMA1 0xf
2146#define BSFACTOR_QMA2 0xf0
2147#define BSFACTOR_QMA3 0xf00
2148#define BSFACTOR_QMA4 0xf000
2149#define BSFACTOR_QMA5 0xf0000
2150#define BSFACTOR_QMA6 0xf0000
2151#define BSFACTOR_QMA7 0xf00000
2152#define BSFACTOR_QMA8 0xf000000
2153#define BSFACTOR_QMA9 0xf0000000
2154#define BCSI_SCHEME 0x100000
2155
2156#define BNOISE_LVL_TOP_SET 0x3
2157#define BCHSMOOTH 0x4
2158#define BCHSMOOTH_CFG1 0x38
2159#define BCHSMOOTH_CFG2 0x1c0
2160#define BCHSMOOTH_CFG3 0xe00
2161#define BCHSMOOTH_CFG4 0x7000
2162#define BMRCMODE 0x800000
2163#define BTHEVMCFG 0x7000000
2164
2165#define BLOOP_FIT_TYPE 0x1
2166#define BUPD_CFO 0x40
2167#define BUPD_CFO_OFFDATA 0x80
2168#define BADV_UPD_CFO 0x100
2169#define BADV_TIME_CTRL 0x800
2170#define BUPD_CLKO 0x1000
2171#define BFC 0x6000
2172#define BTRACKING_MODE 0x8000
2173#define BPHCMP_ENABLE 0x10000
2174#define BUPD_CLKO_LTF 0x20000
2175#define BCOM_CH_CFO 0x40000
2176#define BCSI_ESTI_MODE 0x80000
2177#define BADV_UPD_EQZ 0x100000
2178#define BUCHCFG 0x7000000
2179#define BUPDEQZ 0x8000000
2180
2181#define BRX_PESUDO_NOISE_ON 0x20000000
2182#define BRX_PESUDO_NOISE_A 0xff
2183#define BRX_PESUDO_NOISE_B 0xff00
2184#define BRX_PESUDO_NOISE_C 0xff0000
2185#define BRX_PESUDO_NOISE_D 0xff000000
2186#define BRX_PESUDO_NOISESTATE_A 0xffff
2187#define BRX_PESUDO_NOISESTATE_B 0xffff0000
2188#define BRX_PESUDO_NOISESTATE_C 0xffff
2189#define BRX_PESUDO_NOISESTATE_D 0xffff0000
2190
2191#define BZEBRA1_HSSIENABLE 0x8
2192#define BZEBRA1_TRXCONTROL 0xc00
2193#define BZEBRA1_TRXGAINSETTING 0x07f
2194#define BZEBRA1_RXCOUNTER 0xc00
2195#define BZEBRA1_TXCHANGEPUMP 0x38
2196#define BZEBRA1_RXCHANGEPUMP 0x7
2197#define BZEBRA1_CHANNEL_NUM 0xf80
2198#define BZEBRA1_TXLPFBW 0x400
2199#define BZEBRA1_RXLPFBW 0x600
2200
2201#define BRTL8256REG_MODE_CTRL1 0x100
2202#define BRTL8256REG_MODE_CTRL0 0x40
2203#define BRTL8256REG_TXLPFBW 0x18
2204#define BRTL8256REG_RXLPFBW 0x600
2205
2206#define BRTL8258_TXLPFBW 0xc
2207#define BRTL8258_RXLPFBW 0xc00
2208#define BRTL8258_RSSILPFBW 0xc0
2209
2210#define BBYTE0 0x1
2211#define BBYTE1 0x2
2212#define BBYTE2 0x4
2213#define BBYTE3 0x8
2214#define BWORD0 0x3
2215#define BWORD1 0xc
2216#define BWORD 0xf
2217
2218#define MASKBYTE0 0xff
2219#define MASKBYTE1 0xff00
2220#define MASKBYTE2 0xff0000
2221#define MASKBYTE3 0xff000000
2222#define MASKHWORD 0xffff0000
2223#define MASKLWORD 0x0000ffff
2224#define MASKDWORD 0xffffffff
2225#define MASK12BITS 0xfff
2226#define MASKH4BITS 0xf0000000
2227#define MASKOFDM_D 0xffc00000
2228#define MASKCCK 0x3f3f3f3f
2229
2230#define MASK4BITS 0x0f
2231#define MASK20BITS 0xfffff
2232#define RFREG_OFFSET_MASK 0xfffff
2233
2234#define BENABLE 0x1
2235#define BDISABLE 0x0
2236
2237#define LEFT_ANTENNA 0x0
2238#define RIGHT_ANTENNA 0x1
2239
2240#define TCHECK_TXSTATUS 500
2241#define TUPDATE_RXCOUNTER 100
2242
2243#define REG_UN_USED_REGISTER 0x01bf
2244
2245/* WOL bit information */
2246#define HAL92C_WOL_PTK_UPDATE_EVENT BIT(0)
2247#define HAL92C_WOL_GTK_UPDATE_EVENT BIT(1)
2248#define HAL92C_WOL_DISASSOC_EVENT BIT(2)
2249#define HAL92C_WOL_DEAUTH_EVENT BIT(3)
2250#define HAL92C_WOL_FW_DISCONNECT_EVENT BIT(4)
2251
2252#define WOL_REASON_PTK_UPDATE BIT(0)
2253#define WOL_REASON_GTK_UPDATE BIT(1)
2254#define WOL_REASON_DISASSOC BIT(2)
2255#define WOL_REASON_DEAUTH BIT(3)
2256#define WOL_REASON_FW_DISCONNECT BIT(4)
2257
2258#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/rf.c b/drivers/net/wireless/rtlwifi/rtl8188ee/rf.c
new file mode 100644
index 000000000000..4faafdbab9c6
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/rf.c
@@ -0,0 +1,467 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "reg.h"
32#include "def.h"
33#include "phy.h"
34#include "rf.h"
35#include "dm.h"
36
37void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
38{
39 struct rtl_priv *rtlpriv = rtl_priv(hw);
40 struct rtl_phy *rtlphy = &(rtlpriv->phy);
41
42 switch (bandwidth) {
43 case HT_CHANNEL_WIDTH_20:
44 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
45 0xfffff3ff) | BIT(10) | BIT(11));
46 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
47 rtlphy->rfreg_chnlval[0]);
48 break;
49 case HT_CHANNEL_WIDTH_20_40:
50 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
51 0xfffff3ff) | BIT(10));
52 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
53 rtlphy->rfreg_chnlval[0]);
54 break;
55 default:
56 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
57 "unknown bandwidth: %#X\n", bandwidth);
58 break;
59 }
60}
61
62void rtl88e_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
63 u8 *plevel)
64{
65 struct rtl_priv *rtlpriv = rtl_priv(hw);
66 struct rtl_phy *rtlphy = &(rtlpriv->phy);
67 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
68 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
69 u32 tx_agc[2] = {0, 0}, tmpval;
70 bool turbo_scanoff = false;
71 u8 idx1, idx2;
72 u8 *ptr;
73 u8 direction;
74 u32 pwrtrac_value;
75
76 if (rtlefuse->eeprom_regulatory != 0)
77 turbo_scanoff = true;
78
79 if (mac->act_scanning == true) {
80 tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
81 tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
82
83 if (turbo_scanoff) {
84 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
85 tx_agc[idx1] = plevel[idx1] |
86 (plevel[idx1] << 8) |
87 (plevel[idx1] << 16) |
88 (plevel[idx1] << 24);
89 }
90 }
91 } else {
92 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
93 tx_agc[idx1] = plevel[idx1] | (plevel[idx1] << 8) |
94 (plevel[idx1] << 16) |
95 (plevel[idx1] << 24);
96 }
97
98 if (rtlefuse->eeprom_regulatory == 0) {
99 tmpval = (rtlphy->mcs_offset[0][6]) +
100 (rtlphy->mcs_offset[0][7] << 8);
101 tx_agc[RF90_PATH_A] += tmpval;
102
103 tmpval = (rtlphy->mcs_offset[0][14]) +
104 (rtlphy->mcs_offset[0][15] << 24);
105 tx_agc[RF90_PATH_B] += tmpval;
106 }
107 }
108
109 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
110 ptr = (u8 *)(&(tx_agc[idx1]));
111 for (idx2 = 0; idx2 < 4; idx2++) {
112 if (*ptr > RF6052_MAX_TX_PWR)
113 *ptr = RF6052_MAX_TX_PWR;
114 ptr++;
115 }
116 }
117 rtl88e_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value);
118 if (direction == 1) {
119 tx_agc[0] += pwrtrac_value;
120 tx_agc[1] += pwrtrac_value;
121 } else if (direction == 2) {
122 tx_agc[0] -= pwrtrac_value;
123 tx_agc[1] -= pwrtrac_value;
124 }
125 tmpval = tx_agc[RF90_PATH_A] & 0xff;
126 rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
127
128 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
129 "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
130 RTXAGC_A_CCK1_MCS32);
131
132 tmpval = tx_agc[RF90_PATH_A] >> 8;
133
134 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
135
136 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
137 "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
138 RTXAGC_B_CCK11_A_CCK2_11);
139
140 tmpval = tx_agc[RF90_PATH_B] >> 24;
141 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
142
143 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
144 "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
145 RTXAGC_B_CCK11_A_CCK2_11);
146
147 tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
148 rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
149
150 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
151 "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
152 RTXAGC_B_CCK1_55_MCS32);
153}
154
155static void rtl88e_phy_get_power_base(struct ieee80211_hw *hw,
156 u8 *pwrlvlofdm, u8 *pwrlvlbw20,
157 u8 *pwrlvlbw40, u8 channel,
158 u32 *ofdmbase, u32 *mcsbase)
159{
160 struct rtl_priv *rtlpriv = rtl_priv(hw);
161 struct rtl_phy *rtlphy = &(rtlpriv->phy);
162 u32 base0, base1;
163 u8 i, powerlevel[2];
164
165 for (i = 0; i < 2; i++) {
166 base0 = pwrlvlofdm[i];
167
168 base0 = (base0 << 24) | (base0 << 16) |
169 (base0 << 8) | base0;
170 *(ofdmbase + i) = base0;
171 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
172 "[OFDM power base index rf(%c) = 0x%x]\n",
173 ((i == 0) ? 'A' : 'B'), *(ofdmbase + i));
174 }
175
176 for (i = 0; i < 2; i++) {
177 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20)
178 powerlevel[i] = pwrlvlbw20[i];
179 else
180 powerlevel[i] = pwrlvlbw40[i];
181 base1 = powerlevel[i];
182 base1 = (base1 << 24) |
183 (base1 << 16) | (base1 << 8) | base1;
184
185 *(mcsbase + i) = base1;
186
187 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
188 "[MCS power base index rf(%c) = 0x%x]\n",
189 ((i == 0) ? 'A' : 'B'), *(mcsbase + i));
190 }
191}
192
193static void get_txpwr_by_reg(struct ieee80211_hw *hw, u8 chan, u8 index,
194 u32 *base0, u32 *base1, u32 *outval)
195{
196 struct rtl_priv *rtlpriv = rtl_priv(hw);
197 struct rtl_phy *rtlphy = &(rtlpriv->phy);
198 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
199 u8 i, chg = 0, pwr_lim[4], pwr_diff = 0, cust_pwr_dif;
200 u32 writeval, cust_lim, rf, tmp;
201 u8 ch = chan - 1;
202 u8 j;
203
204 for (rf = 0; rf < 2; rf++) {
205 j = index + (rf ? 8 : 0);
206 tmp = ((index < 2) ? base0[rf] : base1[rf]);
207 switch (rtlefuse->eeprom_regulatory) {
208 case 0:
209 chg = 0;
210
211 writeval = rtlphy->mcs_offset[chg][j] + tmp;
212
213 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
214 "RTK better performance, "
215 "writeval(%c) = 0x%x\n",
216 ((rf == 0) ? 'A' : 'B'), writeval);
217 break;
218 case 1:
219 if (rtlphy->pwrgroup_cnt == 1) {
220 chg = 0;
221 } else {
222 chg = chan / 3;
223 if (chan == 14)
224 chg = 5;
225 }
226 writeval = rtlphy->mcs_offset[chg][j] + tmp;
227
228 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
229 "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n",
230 ((rf == 0) ? 'A' : 'B'), writeval);
231 break;
232 case 2:
233 writeval = ((index < 2) ? base0[rf] : base1[rf]);
234
235 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
236 "Better regulatory, writeval(%c) = 0x%x\n",
237 ((rf == 0) ? 'A' : 'B'), writeval);
238 break;
239 case 3:
240 chg = 0;
241
242 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
243 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
244 "customer's limit, 40MHz rf(%c) = 0x%x\n",
245 ((rf == 0) ? 'A' : 'B'),
246 rtlefuse->pwrgroup_ht40[rf][ch]);
247 } else {
248 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
249 "customer's limit, 20MHz rf(%c) = 0x%x\n",
250 ((rf == 0) ? 'A' : 'B'),
251 rtlefuse->pwrgroup_ht20[rf][ch]);
252 }
253
254 if (index < 2)
255 pwr_diff = rtlefuse->txpwr_legacyhtdiff[rf][ch];
256 else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20)
257 pwr_diff = rtlefuse->txpwr_ht20diff[rf][ch];
258
259 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
260 cust_pwr_dif = rtlefuse->pwrgroup_ht40[rf][ch];
261 else
262 cust_pwr_dif = rtlefuse->pwrgroup_ht20[rf][ch];
263
264 if (pwr_diff > cust_pwr_dif)
265 pwr_diff = 0;
266 else
267 pwr_diff = cust_pwr_dif - pwr_diff;
268
269 for (i = 0; i < 4; i++) {
270 pwr_lim[i] = (u8)((rtlphy->mcs_offset[chg][j] &
271 (0x7f << (i * 8))) >> (i * 8));
272
273 if (pwr_lim[i] > pwr_diff)
274 pwr_lim[i] = pwr_diff;
275 }
276
277 cust_lim = (pwr_lim[3] << 24) | (pwr_lim[2] << 16) |
278 (pwr_lim[1] << 8) | (pwr_lim[0]);
279
280 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
281 "Customer's limit rf(%c) = 0x%x\n",
282 ((rf == 0) ? 'A' : 'B'), cust_lim);
283
284 writeval = cust_lim + tmp;
285
286 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
287 "Customer, writeval rf(%c) = 0x%x\n",
288 ((rf == 0) ? 'A' : 'B'), writeval);
289 break;
290 default:
291 chg = 0;
292 writeval = rtlphy->mcs_offset[chg][j] + tmp;
293
294 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
295 "RTK better performance, writeval "
296 "rf(%c) = 0x%x\n",
297 ((rf == 0) ? 'A' : 'B'), writeval);
298 break;
299 }
300
301 if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
302 writeval = writeval - 0x06060606;
303 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
304 TXHIGHPWRLEVEL_BT2)
305 writeval -= 0x0c0c0c0c;
306 *(outval + rf) = writeval;
307 }
308}
309
310static void write_ofdm_pwr(struct ieee80211_hw *hw, u8 index, u32 *pvalue)
311{
312 struct rtl_priv *rtlpriv = rtl_priv(hw);
313 u16 regoffset_a[6] = {
314 RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
315 RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
316 RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
317 };
318 u16 regoffset_b[6] = {
319 RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
320 RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
321 RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
322 };
323 u8 i, rf, pwr_val[4];
324 u32 writeval;
325 u16 regoffset;
326
327 for (rf = 0; rf < 2; rf++) {
328 writeval = pvalue[rf];
329 for (i = 0; i < 4; i++) {
330 pwr_val[i] = (u8) ((writeval & (0x7f <<
331 (i * 8))) >> (i * 8));
332
333 if (pwr_val[i] > RF6052_MAX_TX_PWR)
334 pwr_val[i] = RF6052_MAX_TX_PWR;
335 }
336 writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
337 (pwr_val[1] << 8) | pwr_val[0];
338
339 if (rf == 0)
340 regoffset = regoffset_a[index];
341 else
342 regoffset = regoffset_b[index];
343 rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);
344
345 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
346 "Set 0x%x = %08x\n", regoffset, writeval);
347 }
348}
349
350void rtl88e_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
351 u8 *pwrlvlofdm,
352 u8 *pwrlvlbw20,
353 u8 *pwrlvlbw40, u8 chan)
354{
355 u32 writeval[2], base0[2], base1[2];
356 u8 index;
357 u8 direction;
358 u32 pwrtrac_value;
359
360 rtl88e_phy_get_power_base(hw, pwrlvlofdm, pwrlvlbw20,
361 pwrlvlbw40, chan, &base0[0],
362 &base1[0]);
363
364 rtl88e_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value);
365
366 for (index = 0; index < 6; index++) {
367 get_txpwr_by_reg(hw, chan, index, &base0[0], &base1[0],
368 &writeval[0]);
369 if (direction == 1) {
370 writeval[0] += pwrtrac_value;
371 writeval[1] += pwrtrac_value;
372 } else if (direction == 2) {
373 writeval[0] -= pwrtrac_value;
374 writeval[1] -= pwrtrac_value;
375 }
376 write_ofdm_pwr(hw, index, &writeval[0]);
377 }
378}
379
380static bool rf6052_conf_para(struct ieee80211_hw *hw)
381{
382 struct rtl_priv *rtlpriv = rtl_priv(hw);
383 struct rtl_phy *rtlphy = &(rtlpriv->phy);
384 u32 u4val = 0;
385 u8 rfpath;
386 bool rtstatus = true;
387 struct bb_reg_def *pphyreg;
388
389 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
390 pphyreg = &rtlphy->phyreg_def[rfpath];
391
392 switch (rfpath) {
393 case RF90_PATH_A:
394 case RF90_PATH_C:
395 u4val = rtl_get_bbreg(hw, pphyreg->rfintfs,
396 BRFSI_RFENV);
397 break;
398 case RF90_PATH_B:
399 case RF90_PATH_D:
400 u4val = rtl_get_bbreg(hw, pphyreg->rfintfs,
401 BRFSI_RFENV << 16);
402 break;
403 }
404
405 rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
406 udelay(1);
407
408 rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
409 udelay(1);
410
411 rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
412 B3WIREADDREAALENGTH, 0x0);
413 udelay(1);
414
415 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
416 udelay(1);
417
418 switch (rfpath) {
419 case RF90_PATH_A:
420 rtstatus = rtl88e_phy_config_rf_with_headerfile(hw,
421 (enum radio_path)rfpath);
422 break;
423 case RF90_PATH_B:
424 rtstatus = rtl88e_phy_config_rf_with_headerfile(hw,
425 (enum radio_path)rfpath);
426 break;
427 case RF90_PATH_C:
428 break;
429 case RF90_PATH_D:
430 break;
431 }
432
433 switch (rfpath) {
434 case RF90_PATH_A:
435 case RF90_PATH_C:
436 rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, u4val);
437 break;
438 case RF90_PATH_B:
439 case RF90_PATH_D:
440 rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
441 u4val);
442 break;
443 }
444
445 if (rtstatus != true) {
446 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
447 "Radio[%d] Fail!!", rfpath);
448 return false;
449 }
450 }
451
452 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "\n");
453 return rtstatus;
454}
455
456bool rtl88e_phy_rf6052_config(struct ieee80211_hw *hw)
457{
458 struct rtl_priv *rtlpriv = rtl_priv(hw);
459 struct rtl_phy *rtlphy = &(rtlpriv->phy);
460
461 if (rtlphy->rf_type == RF_1T1R)
462 rtlphy->num_total_rfpath = 1;
463 else
464 rtlphy->num_total_rfpath = 2;
465
466 return rf6052_conf_para(hw);
467}
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h b/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h
new file mode 100644
index 000000000000..a39a2a3dbcc9
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h
@@ -0,0 +1,46 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C_RF_H__
31#define __RTL92C_RF_H__
32
33#define RF6052_MAX_TX_PWR 0x3F
34#define RF6052_MAX_REG 0x3F
35
36void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
37 u8 bandwidth);
38void rtl88e_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
39 u8 *ppowerlevel);
40void rtl88e_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
41 u8 *ppowerlevel_ofdm,
42 u8 *ppowerlevel_bw20,
43 u8 *ppowerlevel_bw40, u8 channel);
44bool rtl88e_phy_rf6052_config(struct ieee80211_hw *hw);
45
46#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c
new file mode 100644
index 000000000000..c254693a1e6a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c
@@ -0,0 +1,400 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../core.h"
32#include "../pci.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "dm.h"
37#include "hw.h"
38#include "sw.h"
39#include "trx.h"
40#include "led.h"
41#include "table.h"
42
43#include <linux/vmalloc.h>
44#include <linux/module.h>
45
46static void rtl88e_init_aspm_vars(struct ieee80211_hw *hw)
47{
48 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
49
50 /*close ASPM for AMD defaultly */
51 rtlpci->const_amdpci_aspm = 0;
52
53 /* ASPM PS mode.
54 * 0 - Disable ASPM,
55 * 1 - Enable ASPM without Clock Req,
56 * 2 - Enable ASPM with Clock Req,
57 * 3 - Alwyas Enable ASPM with Clock Req,
58 * 4 - Always Enable ASPM without Clock Req.
59 * set defult to RTL8192CE:3 RTL8192E:2
60 */
61 rtlpci->const_pci_aspm = 3;
62
63 /*Setting for PCI-E device */
64 rtlpci->const_devicepci_aspm_setting = 0x03;
65
66 /*Setting for PCI-E bridge */
67 rtlpci->const_hostpci_aspm_setting = 0x02;
68
69 /* In Hw/Sw Radio Off situation.
70 * 0 - Default,
71 * 1 - From ASPM setting without low Mac Pwr,
72 * 2 - From ASPM setting with low Mac Pwr,
73 * 3 - Bus D3
74 * set default to RTL8192CE:0 RTL8192SE:2
75 */
76 rtlpci->const_hwsw_rfoff_d3 = 0;
77
78 /* This setting works for those device with
79 * backdoor ASPM setting such as EPHY setting.
80 * 0 - Not support ASPM,
81 * 1 - Support ASPM,
82 * 2 - According to chipset.
83 */
84 rtlpci->const_support_pciaspm = 1;
85}
86
87int rtl88e_init_sw_vars(struct ieee80211_hw *hw)
88{
89 int err = 0;
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
92 u8 tid;
93
94 rtl8188ee_bt_reg_init(hw);
95
96 rtlpriv->dm.dm_initialgain_enable = 1;
97 rtlpriv->dm.dm_flag = 0;
98 rtlpriv->dm.disable_framebursting = 0;
99 rtlpriv->dm.thermalvalue = 0;
100 rtlpci->transmit_config = CFENDFORM | BIT(15);
101
102 /* compatible 5G band 88ce just 2.4G band & smsp */
103 rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
104 rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
105 rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
106
107 rtlpci->receive_config = (RCR_APPFCS |
108 RCR_APP_MIC |
109 RCR_APP_ICV |
110 RCR_APP_PHYST_RXFF |
111 RCR_HTC_LOC_CTRL |
112 RCR_AMF |
113 RCR_ACF |
114 RCR_ADF |
115 RCR_AICV |
116 RCR_ACRC32 |
117 RCR_AB |
118 RCR_AM |
119 RCR_APM |
120 0);
121
122 rtlpci->irq_mask[0] =
123 (u32) (IMR_PSTIMEOUT |
124 IMR_HSISR_IND_ON_INT |
125 IMR_C2HCMD |
126 IMR_HIGHDOK |
127 IMR_MGNTDOK |
128 IMR_BKDOK |
129 IMR_BEDOK |
130 IMR_VIDOK |
131 IMR_VODOK |
132 IMR_RDU |
133 IMR_ROK |
134 0);
135 rtlpci->irq_mask[1] = (u32) (IMR_RXFOVW | 0);
136 rtlpci->sys_irq_mask = (u32) (HSIMR_PDN_INT_EN | HSIMR_RON_INT_EN);
137
138 /* for debug level */
139 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
140 /* for LPS & IPS */
141 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
142 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
143 rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
144 if (!rtlpriv->psc.inactiveps)
145 pr_info("rtl8188ee: Power Save off (module option)\n");
146 if (!rtlpriv->psc.fwctrl_lps)
147 pr_info("rtl8188ee: FW Power Save off (module option)\n");
148 rtlpriv->psc.reg_fwctrl_lps = 3;
149 rtlpriv->psc.reg_max_lps_awakeintvl = 5;
150 /* for ASPM, you can close aspm through
151 * set const_support_pciaspm = 0
152 */
153 rtl88e_init_aspm_vars(hw);
154
155 if (rtlpriv->psc.reg_fwctrl_lps == 1)
156 rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
157 else if (rtlpriv->psc.reg_fwctrl_lps == 2)
158 rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
159 else if (rtlpriv->psc.reg_fwctrl_lps == 3)
160 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
161
162 /* for firmware buf */
163 rtlpriv->rtlhal.pfirmware = vmalloc(0x8000);
164 if (!rtlpriv->rtlhal.pfirmware) {
165 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
166 "Can't alloc buffer for fw.\n");
167 return 1;
168 }
169
170 rtlpriv->cfg->fw_name = "rtlwifi/rtl8188efw.bin";
171 rtlpriv->max_fw_size = 0x8000;
172 pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
173 err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
174 rtlpriv->io.dev, GFP_KERNEL, hw,
175 rtl_fw_cb);
176 if (err) {
177 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
178 "Failed to request firmware!\n");
179 return 1;
180 }
181
182 /* for early mode */
183 rtlpriv->rtlhal.earlymode_enable = false;
184 rtlpriv->rtlhal.max_earlymode_num = 10;
185 for (tid = 0; tid < 8; tid++)
186 skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
187
188 /*low power */
189 rtlpriv->psc.low_power_enable = false;
190 if (rtlpriv->psc.low_power_enable) {
191 init_timer(&rtlpriv->works.fw_clockoff_timer);
192 setup_timer(&rtlpriv->works.fw_clockoff_timer,
193 rtl88ee_fw_clk_off_timer_callback,
194 (unsigned long)hw);
195 }
196
197 init_timer(&rtlpriv->works.fast_antenna_training_timer);
198 setup_timer(&rtlpriv->works.fast_antenna_training_timer,
199 rtl88e_dm_fast_antenna_training_callback,
200 (unsigned long)hw);
201 return err;
202}
203
204void rtl88e_deinit_sw_vars(struct ieee80211_hw *hw)
205{
206 struct rtl_priv *rtlpriv = rtl_priv(hw);
207
208 if (rtlpriv->rtlhal.pfirmware) {
209 vfree(rtlpriv->rtlhal.pfirmware);
210 rtlpriv->rtlhal.pfirmware = NULL;
211 }
212
213 if (rtlpriv->psc.low_power_enable)
214 del_timer_sync(&rtlpriv->works.fw_clockoff_timer);
215
216 del_timer_sync(&rtlpriv->works.fast_antenna_training_timer);
217}
218
219static struct rtl_hal_ops rtl8188ee_hal_ops = {
220 .init_sw_vars = rtl88e_init_sw_vars,
221 .deinit_sw_vars = rtl88e_deinit_sw_vars,
222 .read_eeprom_info = rtl88ee_read_eeprom_info,
223 .interrupt_recognized = rtl88ee_interrupt_recognized,/*need check*/
224 .hw_init = rtl88ee_hw_init,
225 .hw_disable = rtl88ee_card_disable,
226 .hw_suspend = rtl88ee_suspend,
227 .hw_resume = rtl88ee_resume,
228 .enable_interrupt = rtl88ee_enable_interrupt,
229 .disable_interrupt = rtl88ee_disable_interrupt,
230 .set_network_type = rtl88ee_set_network_type,
231 .set_chk_bssid = rtl88ee_set_check_bssid,
232 .set_qos = rtl88ee_set_qos,
233 .set_bcn_reg = rtl88ee_set_beacon_related_registers,
234 .set_bcn_intv = rtl88ee_set_beacon_interval,
235 .update_interrupt_mask = rtl88ee_update_interrupt_mask,
236 .get_hw_reg = rtl88ee_get_hw_reg,
237 .set_hw_reg = rtl88ee_set_hw_reg,
238 .update_rate_tbl = rtl88ee_update_hal_rate_tbl,
239 .fill_tx_desc = rtl88ee_tx_fill_desc,
240 .fill_tx_cmddesc = rtl88ee_tx_fill_cmddesc,
241 .query_rx_desc = rtl88ee_rx_query_desc,
242 .set_channel_access = rtl88ee_update_channel_access_setting,
243 .radio_onoff_checking = rtl88ee_gpio_radio_on_off_checking,
244 .set_bw_mode = rtl88e_phy_set_bw_mode,
245 .switch_channel = rtl88e_phy_sw_chnl,
246 .dm_watchdog = rtl88e_dm_watchdog,
247 .scan_operation_backup = rtl88e_phy_scan_operation_backup,
248 .set_rf_power_state = rtl88e_phy_set_rf_power_state,
249 .led_control = rtl88ee_led_control,
250 .set_desc = rtl88ee_set_desc,
251 .get_desc = rtl88ee_get_desc,
252 .tx_polling = rtl88ee_tx_polling,
253 .enable_hw_sec = rtl88ee_enable_hw_security_config,
254 .set_key = rtl88ee_set_key,
255 .init_sw_leds = rtl88ee_init_sw_leds,
256 .allow_all_destaddr = rtl88ee_allow_all_destaddr,
257 .get_bbreg = rtl88e_phy_query_bb_reg,
258 .set_bbreg = rtl88e_phy_set_bb_reg,
259 .get_rfreg = rtl88e_phy_query_rf_reg,
260 .set_rfreg = rtl88e_phy_set_rf_reg,
261};
262
263static struct rtl_mod_params rtl88ee_mod_params = {
264 .sw_crypto = false,
265 .inactiveps = true,
266 .swctrl_lps = false,
267 .fwctrl_lps = true,
268 .debug = DBG_EMERG,
269};
270
271static struct rtl_hal_cfg rtl88ee_hal_cfg = {
272 .bar_id = 2,
273 .write_readback = true,
274 .name = "rtl88e_pci",
275 .ops = &rtl8188ee_hal_ops,
276 .mod_params = &rtl88ee_mod_params,
277
278 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
279 .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
280 .maps[SYS_CLK] = REG_SYS_CLKR,
281 .maps[MAC_RCR_AM] = AM,
282 .maps[MAC_RCR_AB] = AB,
283 .maps[MAC_RCR_ACRC32] = ACRC32,
284 .maps[MAC_RCR_ACF] = ACF,
285 .maps[MAC_RCR_AAP] = AAP,
286
287 .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS,
288
289 .maps[EFUSE_TEST] = REG_EFUSE_TEST,
290 .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
291 .maps[EFUSE_CLK] = 0,
292 .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
293 .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
294 .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
295 .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
296 .maps[EFUSE_ANA8M] = ANA8M,
297 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
298 .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
299 .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
300 .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
301
302 .maps[RWCAM] = REG_CAMCMD,
303 .maps[WCAMI] = REG_CAMWRITE,
304 .maps[RCAMO] = REG_CAMREAD,
305 .maps[CAMDBG] = REG_CAMDBG,
306 .maps[SECR] = REG_SECCFG,
307 .maps[SEC_CAM_NONE] = CAM_NONE,
308 .maps[SEC_CAM_WEP40] = CAM_WEP40,
309 .maps[SEC_CAM_TKIP] = CAM_TKIP,
310 .maps[SEC_CAM_AES] = CAM_AES,
311 .maps[SEC_CAM_WEP104] = CAM_WEP104,
312
313 .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
314 .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
315 .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
316 .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
317 .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
318 .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
319/* .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, */ /*need check*/
320 .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
321 .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
322 .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
323 .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
324 .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
325 .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
326 .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
327/* .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/
328/* .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/
329
330 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
331 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
332 .maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0,
333 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
334 .maps[RTL_IMR_RDU] = IMR_RDU,
335 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
336 .maps[RTL_IMR_BDOK] = IMR_BCNDOK0,
337 .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
338 .maps[RTL_IMR_TBDER] = IMR_TBDER,
339 .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
340 .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
341 .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
342 .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
343 .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
344 .maps[RTL_IMR_VODOK] = IMR_VODOK,
345 .maps[RTL_IMR_ROK] = IMR_ROK,
346 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER),
347
348 .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M,
349 .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M,
350 .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M,
351 .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M,
352 .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M,
353 .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M,
354 .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M,
355 .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M,
356 .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M,
357 .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M,
358 .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M,
359 .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M,
360
361 .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7,
362 .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
363};
364
365static DEFINE_PCI_DEVICE_TABLE(rtl88ee_pci_ids) = {
366 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8179, rtl88ee_hal_cfg)},
367 {},
368};
369
370MODULE_DEVICE_TABLE(pci, rtl88ee_pci_ids);
371
372MODULE_AUTHOR("zhiyuan_yang <zhiyuan_yang@realsil.com.cn>");
373MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
374MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
375MODULE_LICENSE("GPL");
376MODULE_DESCRIPTION("Realtek 8188E 802.11n PCI wireless");
377MODULE_FIRMWARE("rtlwifi/rtl8188efw.bin");
378
379module_param_named(swenc, rtl88ee_mod_params.sw_crypto, bool, 0444);
380module_param_named(debug, rtl88ee_mod_params.debug, int, 0444);
381module_param_named(ips, rtl88ee_mod_params.inactiveps, bool, 0444);
382module_param_named(swlps, rtl88ee_mod_params.swctrl_lps, bool, 0444);
383module_param_named(fwlps, rtl88ee_mod_params.fwctrl_lps, bool, 0444);
384MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
385MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
386MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
387MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
388MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
389
390static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
391
392static struct pci_driver rtl88ee_driver = {
393 .name = KBUILD_MODNAME,
394 .id_table = rtl88ee_pci_ids,
395 .probe = rtl_pci_probe,
396 .remove = rtl_pci_disconnect,
397 .driver.pm = &rtlwifi_pm_ops,
398};
399
400module_pci_driver(rtl88ee_driver);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.h b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.h
new file mode 100644
index 000000000000..85e02b3bdff8
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.h
@@ -0,0 +1,36 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92CE_SW_H__
31#define __RTL92CE_SW_H__
32
33int rtl88e_init_sw_vars(struct ieee80211_hw *hw);
34void rtl88e_deinit_sw_vars(struct ieee80211_hw *hw);
35
36#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/table.c b/drivers/net/wireless/rtlwifi/rtl8188ee/table.c
new file mode 100644
index 000000000000..fad373f97b2c
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/table.c
@@ -0,0 +1,643 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Created on 2010/ 5/18, 1:41
27 *
28 * Larry Finger <Larry.Finger@lwfinger.net>
29 *
30 *****************************************************************************/
31
32#include "table.h"
33
34u32 RTL8188EEPHY_REG_1TARRAY[] = {
35 0x800, 0x80040000,
36 0x804, 0x00000003,
37 0x808, 0x0000FC00,
38 0x80C, 0x0000000A,
39 0x810, 0x10001331,
40 0x814, 0x020C3D10,
41 0x818, 0x02200385,
42 0x81C, 0x00000000,
43 0x820, 0x01000100,
44 0x824, 0x00390204,
45 0x828, 0x00000000,
46 0x82C, 0x00000000,
47 0x830, 0x00000000,
48 0x834, 0x00000000,
49 0x838, 0x00000000,
50 0x83C, 0x00000000,
51 0x840, 0x00010000,
52 0x844, 0x00000000,
53 0x848, 0x00000000,
54 0x84C, 0x00000000,
55 0x850, 0x00000000,
56 0x854, 0x00000000,
57 0x858, 0x569A11A9,
58 0x85C, 0x01000014,
59 0x860, 0x66F60110,
60 0x864, 0x061F0649,
61 0x868, 0x00000000,
62 0x86C, 0x27272700,
63 0x870, 0x07000760,
64 0x874, 0x25004000,
65 0x878, 0x00000808,
66 0x87C, 0x00000000,
67 0x880, 0xB0000C1C,
68 0x884, 0x00000001,
69 0x888, 0x00000000,
70 0x88C, 0xCCC000C0,
71 0x890, 0x00000800,
72 0x894, 0xFFFFFFFE,
73 0x898, 0x40302010,
74 0x89C, 0x00706050,
75 0x900, 0x00000000,
76 0x904, 0x00000023,
77 0x908, 0x00000000,
78 0x90C, 0x81121111,
79 0x910, 0x00000002,
80 0x914, 0x00000201,
81 0xA00, 0x00D047C8,
82 0xA04, 0x80FF000C,
83 0xA08, 0x8C838300,
84 0xA0C, 0x2E7F120F,
85 0xA10, 0x9500BB78,
86 0xA14, 0x1114D028,
87 0xA18, 0x00881117,
88 0xA1C, 0x89140F00,
89 0xA20, 0x1A1B0000,
90 0xA24, 0x090E1317,
91 0xA28, 0x00000204,
92 0xA2C, 0x00D30000,
93 0xA70, 0x101FBF00,
94 0xA74, 0x00000007,
95 0xA78, 0x00000900,
96 0xA7C, 0x225B0606,
97 0xA80, 0x218075B1,
98 0xB2C, 0x80000000,
99 0xC00, 0x48071D40,
100 0xC04, 0x03A05611,
101 0xC08, 0x000000E4,
102 0xC0C, 0x6C6C6C6C,
103 0xC10, 0x08800000,
104 0xC14, 0x40000100,
105 0xC18, 0x08800000,
106 0xC1C, 0x40000100,
107 0xC20, 0x00000000,
108 0xC24, 0x00000000,
109 0xC28, 0x00000000,
110 0xC2C, 0x00000000,
111 0xC30, 0x69E9AC47,
112 0xC34, 0x469652AF,
113 0xC38, 0x49795994,
114 0xC3C, 0x0A97971C,
115 0xC40, 0x1F7C403F,
116 0xC44, 0x000100B7,
117 0xC48, 0xEC020107,
118 0xC4C, 0x007F037F,
119 0xC50, 0x69553420,
120 0xC54, 0x43BC0094,
121 0xC58, 0x00013169,
122 0xC5C, 0x00250492,
123 0xC60, 0x00000000,
124 0xC64, 0x7112848B,
125 0xC68, 0x47C00BFF,
126 0xC6C, 0x00000036,
127 0xC70, 0x2C7F000D,
128 0xC74, 0x020610DB,
129 0xC78, 0x0000001F,
130 0xC7C, 0x00B91612,
131 0xC80, 0x390000E4,
132 0xC84, 0x20F60000,
133 0xC88, 0x40000100,
134 0xC8C, 0x20200000,
135 0xC90, 0x00091521,
136 0xC94, 0x00000000,
137 0xC98, 0x00121820,
138 0xC9C, 0x00007F7F,
139 0xCA0, 0x00000000,
140 0xCA4, 0x000300A0,
141 0xCA8, 0x00000000,
142 0xCAC, 0x00000000,
143 0xCB0, 0x00000000,
144 0xCB4, 0x00000000,
145 0xCB8, 0x00000000,
146 0xCBC, 0x28000000,
147 0xCC0, 0x00000000,
148 0xCC4, 0x00000000,
149 0xCC8, 0x00000000,
150 0xCCC, 0x00000000,
151 0xCD0, 0x00000000,
152 0xCD4, 0x00000000,
153 0xCD8, 0x64B22427,
154 0xCDC, 0x00766932,
155 0xCE0, 0x00222222,
156 0xCE4, 0x00000000,
157 0xCE8, 0x37644302,
158 0xCEC, 0x2F97D40C,
159 0xD00, 0x00000740,
160 0xD04, 0x00020401,
161 0xD08, 0x0000907F,
162 0xD0C, 0x20010201,
163 0xD10, 0xA0633333,
164 0xD14, 0x3333BC43,
165 0xD18, 0x7A8F5B6F,
166 0xD2C, 0xCC979975,
167 0xD30, 0x00000000,
168 0xD34, 0x80608000,
169 0xD38, 0x00000000,
170 0xD3C, 0x00127353,
171 0xD40, 0x00000000,
172 0xD44, 0x00000000,
173 0xD48, 0x00000000,
174 0xD4C, 0x00000000,
175 0xD50, 0x6437140A,
176 0xD54, 0x00000000,
177 0xD58, 0x00000282,
178 0xD5C, 0x30032064,
179 0xD60, 0x4653DE68,
180 0xD64, 0x04518A3C,
181 0xD68, 0x00002101,
182 0xD6C, 0x2A201C16,
183 0xD70, 0x1812362E,
184 0xD74, 0x322C2220,
185 0xD78, 0x000E3C24,
186 0xE00, 0x2D2D2D2D,
187 0xE04, 0x2D2D2D2D,
188 0xE08, 0x0390272D,
189 0xE10, 0x2D2D2D2D,
190 0xE14, 0x2D2D2D2D,
191 0xE18, 0x2D2D2D2D,
192 0xE1C, 0x2D2D2D2D,
193 0xE28, 0x00000000,
194 0xE30, 0x1000DC1F,
195 0xE34, 0x10008C1F,
196 0xE38, 0x02140102,
197 0xE3C, 0x681604C2,
198 0xE40, 0x01007C00,
199 0xE44, 0x01004800,
200 0xE48, 0xFB000000,
201 0xE4C, 0x000028D1,
202 0xE50, 0x1000DC1F,
203 0xE54, 0x10008C1F,
204 0xE58, 0x02140102,
205 0xE5C, 0x28160D05,
206 0xE60, 0x00000008,
207 0xE68, 0x001B25A4,
208 0xE6C, 0x00C00014,
209 0xE70, 0x00C00014,
210 0xE74, 0x01000014,
211 0xE78, 0x01000014,
212 0xE7C, 0x01000014,
213 0xE80, 0x01000014,
214 0xE84, 0x00C00014,
215 0xE88, 0x01000014,
216 0xE8C, 0x00C00014,
217 0xED0, 0x00C00014,
218 0xED4, 0x00C00014,
219 0xED8, 0x00C00014,
220 0xEDC, 0x00000014,
221 0xEE0, 0x00000014,
222 0xEEC, 0x01C00014,
223 0xF14, 0x00000003,
224 0xF4C, 0x00000000,
225 0xF00, 0x00000300,
226
227};
228
229u32 RTL8188EEPHY_REG_ARRAY_PG[] = {
230 0xE00, 0xFFFFFFFF, 0x06070809,
231 0xE04, 0xFFFFFFFF, 0x02020405,
232 0xE08, 0x0000FF00, 0x00000006,
233 0x86C, 0xFFFFFF00, 0x00020400,
234 0xE10, 0xFFFFFFFF, 0x08090A0B,
235 0xE14, 0xFFFFFFFF, 0x01030607,
236 0xE18, 0xFFFFFFFF, 0x08090A0B,
237 0xE1C, 0xFFFFFFFF, 0x01030607,
238 0xE00, 0xFFFFFFFF, 0x00000000,
239 0xE04, 0xFFFFFFFF, 0x00000000,
240 0xE08, 0x0000FF00, 0x00000000,
241 0x86C, 0xFFFFFF00, 0x00000000,
242 0xE10, 0xFFFFFFFF, 0x00000000,
243 0xE14, 0xFFFFFFFF, 0x00000000,
244 0xE18, 0xFFFFFFFF, 0x00000000,
245 0xE1C, 0xFFFFFFFF, 0x00000000,
246 0xE00, 0xFFFFFFFF, 0x02020202,
247 0xE04, 0xFFFFFFFF, 0x00020202,
248 0xE08, 0x0000FF00, 0x00000000,
249 0x86C, 0xFFFFFF00, 0x00000000,
250 0xE10, 0xFFFFFFFF, 0x04040404,
251 0xE14, 0xFFFFFFFF, 0x00020404,
252 0xE18, 0xFFFFFFFF, 0x00000000,
253 0xE1C, 0xFFFFFFFF, 0x00000000,
254 0xE00, 0xFFFFFFFF, 0x02020202,
255 0xE04, 0xFFFFFFFF, 0x00020202,
256 0xE08, 0x0000FF00, 0x00000000,
257 0x86C, 0xFFFFFF00, 0x00000000,
258 0xE10, 0xFFFFFFFF, 0x04040404,
259 0xE14, 0xFFFFFFFF, 0x00020404,
260 0xE18, 0xFFFFFFFF, 0x00000000,
261 0xE1C, 0xFFFFFFFF, 0x00000000,
262 0xE00, 0xFFFFFFFF, 0x00000000,
263 0xE04, 0xFFFFFFFF, 0x00000000,
264 0xE08, 0x0000FF00, 0x00000000,
265 0x86C, 0xFFFFFF00, 0x00000000,
266 0xE10, 0xFFFFFFFF, 0x00000000,
267 0xE14, 0xFFFFFFFF, 0x00000000,
268 0xE18, 0xFFFFFFFF, 0x00000000,
269 0xE1C, 0xFFFFFFFF, 0x00000000,
270 0xE00, 0xFFFFFFFF, 0x02020202,
271 0xE04, 0xFFFFFFFF, 0x00020202,
272 0xE08, 0x0000FF00, 0x00000000,
273 0x86C, 0xFFFFFF00, 0x00000000,
274 0xE10, 0xFFFFFFFF, 0x04040404,
275 0xE14, 0xFFFFFFFF, 0x00020404,
276 0xE18, 0xFFFFFFFF, 0x00000000,
277 0xE1C, 0xFFFFFFFF, 0x00000000,
278 0xE00, 0xFFFFFFFF, 0x00000000,
279 0xE04, 0xFFFFFFFF, 0x00000000,
280 0xE08, 0x0000FF00, 0x00000000,
281 0x86C, 0xFFFFFF00, 0x00000000,
282 0xE10, 0xFFFFFFFF, 0x00000000,
283 0xE14, 0xFFFFFFFF, 0x00000000,
284 0xE18, 0xFFFFFFFF, 0x00000000,
285 0xE1C, 0xFFFFFFFF, 0x00000000,
286 0xE00, 0xFFFFFFFF, 0x00000000,
287 0xE04, 0xFFFFFFFF, 0x00000000,
288 0xE08, 0x0000FF00, 0x00000000,
289 0x86C, 0xFFFFFF00, 0x00000000,
290 0xE10, 0xFFFFFFFF, 0x00000000,
291 0xE14, 0xFFFFFFFF, 0x00000000,
292 0xE18, 0xFFFFFFFF, 0x00000000,
293 0xE1C, 0xFFFFFFFF, 0x00000000,
294 0xE00, 0xFFFFFFFF, 0x00000000,
295 0xE04, 0xFFFFFFFF, 0x00000000,
296 0xE08, 0x0000FF00, 0x00000000,
297 0x86C, 0xFFFFFF00, 0x00000000,
298 0xE10, 0xFFFFFFFF, 0x00000000,
299 0xE14, 0xFFFFFFFF, 0x00000000,
300 0xE18, 0xFFFFFFFF, 0x00000000,
301 0xE1C, 0xFFFFFFFF, 0x00000000,
302 0xE00, 0xFFFFFFFF, 0x00000000,
303 0xE04, 0xFFFFFFFF, 0x00000000,
304 0xE08, 0x0000FF00, 0x00000000,
305 0x86C, 0xFFFFFF00, 0x00000000,
306 0xE10, 0xFFFFFFFF, 0x00000000,
307 0xE14, 0xFFFFFFFF, 0x00000000,
308 0xE18, 0xFFFFFFFF, 0x00000000,
309 0xE1C, 0xFFFFFFFF, 0x00000000,
310 0xE00, 0xFFFFFFFF, 0x00000000,
311 0xE04, 0xFFFFFFFF, 0x00000000,
312 0xE08, 0x0000FF00, 0x00000000,
313 0x86C, 0xFFFFFF00, 0x00000000,
314 0xE10, 0xFFFFFFFF, 0x00000000,
315 0xE14, 0xFFFFFFFF, 0x00000000,
316 0xE18, 0xFFFFFFFF, 0x00000000,
317 0xE1C, 0xFFFFFFFF, 0x00000000,
318
319};
320
321u32 RTL8188EE_RADIOA_1TARRAY[] = {
322 0x000, 0x00030000,
323 0x008, 0x00084000,
324 0x018, 0x00000407,
325 0x019, 0x00000012,
326 0x01E, 0x00080009,
327 0x01F, 0x00000880,
328 0x02F, 0x0001A060,
329 0x03F, 0x00000000,
330 0x042, 0x000060C0,
331 0x057, 0x000D0000,
332 0x058, 0x000BE180,
333 0x067, 0x00001552,
334 0x083, 0x00000000,
335 0x0B0, 0x000FF8FC,
336 0x0B1, 0x00054400,
337 0x0B2, 0x000CCC19,
338 0x0B4, 0x00043003,
339 0x0B6, 0x0004953E,
340 0x0B7, 0x0001C718,
341 0x0B8, 0x000060FF,
342 0x0B9, 0x00080001,
343 0x0BA, 0x00040000,
344 0x0BB, 0x00000400,
345 0x0BF, 0x000C0000,
346 0x0C2, 0x00002400,
347 0x0C3, 0x00000009,
348 0x0C4, 0x00040C91,
349 0x0C5, 0x00099999,
350 0x0C6, 0x000000A3,
351 0x0C7, 0x00088820,
352 0x0C8, 0x00076C06,
353 0x0C9, 0x00000000,
354 0x0CA, 0x00080000,
355 0x0DF, 0x00000180,
356 0x0EF, 0x000001A0,
357 0x051, 0x0006B27D,
358 0x052, 0x0007E49D,
359 0x053, 0x00000073,
360 0x056, 0x00051FF3,
361 0x035, 0x00000086,
362 0x035, 0x00000186,
363 0x035, 0x00000286,
364 0x036, 0x00001C25,
365 0x036, 0x00009C25,
366 0x036, 0x00011C25,
367 0x036, 0x00019C25,
368 0x0B6, 0x00048538,
369 0x018, 0x00000C07,
370 0x05A, 0x0004BD00,
371 0x019, 0x000739D0,
372 0x034, 0x0000ADF3,
373 0x034, 0x00009DF0,
374 0x034, 0x00008DED,
375 0x034, 0x00007DEA,
376 0x034, 0x00006DE7,
377 0x034, 0x000054EE,
378 0x034, 0x000044EB,
379 0x034, 0x000034E8,
380 0x034, 0x0000246B,
381 0x034, 0x00001468,
382 0x034, 0x0000006D,
383 0x000, 0x00030159,
384 0x084, 0x00068200,
385 0x086, 0x000000CE,
386 0x087, 0x00048A00,
387 0x08E, 0x00065540,
388 0x08F, 0x00088000,
389 0x0EF, 0x000020A0,
390 0x03B, 0x000F02B0,
391 0x03B, 0x000EF7B0,
392 0x03B, 0x000D4FB0,
393 0x03B, 0x000CF060,
394 0x03B, 0x000B0090,
395 0x03B, 0x000A0080,
396 0x03B, 0x00090080,
397 0x03B, 0x0008F780,
398 0x03B, 0x000722B0,
399 0x03B, 0x0006F7B0,
400 0x03B, 0x00054FB0,
401 0x03B, 0x0004F060,
402 0x03B, 0x00030090,
403 0x03B, 0x00020080,
404 0x03B, 0x00010080,
405 0x03B, 0x0000F780,
406 0x0EF, 0x000000A0,
407 0x000, 0x00010159,
408 0x018, 0x0000F407,
409 0xFFE, 0x00000000,
410 0xFFE, 0x00000000,
411 0x01F, 0x00080003,
412 0xFFE, 0x00000000,
413 0xFFE, 0x00000000,
414 0x01E, 0x00000001,
415 0x01F, 0x00080000,
416 0x000, 0x00033E60,
417
418};
419
420u32 RTL8188EEMAC_1T_ARRAY[] = {
421 0x026, 0x00000041,
422 0x027, 0x00000035,
423 0x428, 0x0000000A,
424 0x429, 0x00000010,
425 0x430, 0x00000000,
426 0x431, 0x00000001,
427 0x432, 0x00000002,
428 0x433, 0x00000004,
429 0x434, 0x00000005,
430 0x435, 0x00000006,
431 0x436, 0x00000007,
432 0x437, 0x00000008,
433 0x438, 0x00000000,
434 0x439, 0x00000000,
435 0x43A, 0x00000001,
436 0x43B, 0x00000002,
437 0x43C, 0x00000004,
438 0x43D, 0x00000005,
439 0x43E, 0x00000006,
440 0x43F, 0x00000007,
441 0x440, 0x0000005D,
442 0x441, 0x00000001,
443 0x442, 0x00000000,
444 0x444, 0x00000015,
445 0x445, 0x000000F0,
446 0x446, 0x0000000F,
447 0x447, 0x00000000,
448 0x458, 0x00000041,
449 0x459, 0x000000A8,
450 0x45A, 0x00000072,
451 0x45B, 0x000000B9,
452 0x460, 0x00000066,
453 0x461, 0x00000066,
454 0x480, 0x00000008,
455 0x4C8, 0x000000FF,
456 0x4C9, 0x00000008,
457 0x4CC, 0x000000FF,
458 0x4CD, 0x000000FF,
459 0x4CE, 0x00000001,
460 0x4D3, 0x00000001,
461 0x500, 0x00000026,
462 0x501, 0x000000A2,
463 0x502, 0x0000002F,
464 0x503, 0x00000000,
465 0x504, 0x00000028,
466 0x505, 0x000000A3,
467 0x506, 0x0000005E,
468 0x507, 0x00000000,
469 0x508, 0x0000002B,
470 0x509, 0x000000A4,
471 0x50A, 0x0000005E,
472 0x50B, 0x00000000,
473 0x50C, 0x0000004F,
474 0x50D, 0x000000A4,
475 0x50E, 0x00000000,
476 0x50F, 0x00000000,
477 0x512, 0x0000001C,
478 0x514, 0x0000000A,
479 0x516, 0x0000000A,
480 0x525, 0x0000004F,
481 0x550, 0x00000010,
482 0x551, 0x00000010,
483 0x559, 0x00000002,
484 0x55D, 0x000000FF,
485 0x605, 0x00000030,
486 0x608, 0x0000000E,
487 0x609, 0x0000002A,
488 0x620, 0x000000FF,
489 0x621, 0x000000FF,
490 0x622, 0x000000FF,
491 0x623, 0x000000FF,
492 0x624, 0x000000FF,
493 0x625, 0x000000FF,
494 0x626, 0x000000FF,
495 0x627, 0x000000FF,
496 0x652, 0x00000020,
497 0x63C, 0x0000000A,
498 0x63D, 0x0000000A,
499 0x63E, 0x0000000E,
500 0x63F, 0x0000000E,
501 0x640, 0x00000040,
502 0x66E, 0x00000005,
503 0x700, 0x00000021,
504 0x701, 0x00000043,
505 0x702, 0x00000065,
506 0x703, 0x00000087,
507 0x708, 0x00000021,
508 0x709, 0x00000043,
509 0x70A, 0x00000065,
510 0x70B, 0x00000087,
511
512};
513
514u32 RTL8188EEAGCTAB_1TARRAY[] = {
515 0xC78, 0xFB000001,
516 0xC78, 0xFB010001,
517 0xC78, 0xFB020001,
518 0xC78, 0xFB030001,
519 0xC78, 0xFB040001,
520 0xC78, 0xFB050001,
521 0xC78, 0xFA060001,
522 0xC78, 0xF9070001,
523 0xC78, 0xF8080001,
524 0xC78, 0xF7090001,
525 0xC78, 0xF60A0001,
526 0xC78, 0xF50B0001,
527 0xC78, 0xF40C0001,
528 0xC78, 0xF30D0001,
529 0xC78, 0xF20E0001,
530 0xC78, 0xF10F0001,
531 0xC78, 0xF0100001,
532 0xC78, 0xEF110001,
533 0xC78, 0xEE120001,
534 0xC78, 0xED130001,
535 0xC78, 0xEC140001,
536 0xC78, 0xEB150001,
537 0xC78, 0xEA160001,
538 0xC78, 0xE9170001,
539 0xC78, 0xE8180001,
540 0xC78, 0xE7190001,
541 0xC78, 0xE61A0001,
542 0xC78, 0xE51B0001,
543 0xC78, 0xE41C0001,
544 0xC78, 0xE31D0001,
545 0xC78, 0xE21E0001,
546 0xC78, 0xE11F0001,
547 0xC78, 0x8A200001,
548 0xC78, 0x89210001,
549 0xC78, 0x88220001,
550 0xC78, 0x87230001,
551 0xC78, 0x86240001,
552 0xC78, 0x85250001,
553 0xC78, 0x84260001,
554 0xC78, 0x83270001,
555 0xC78, 0x82280001,
556 0xC78, 0x6B290001,
557 0xC78, 0x6A2A0001,
558 0xC78, 0x692B0001,
559 0xC78, 0x682C0001,
560 0xC78, 0x672D0001,
561 0xC78, 0x662E0001,
562 0xC78, 0x652F0001,
563 0xC78, 0x64300001,
564 0xC78, 0x63310001,
565 0xC78, 0x62320001,
566 0xC78, 0x61330001,
567 0xC78, 0x46340001,
568 0xC78, 0x45350001,
569 0xC78, 0x44360001,
570 0xC78, 0x43370001,
571 0xC78, 0x42380001,
572 0xC78, 0x41390001,
573 0xC78, 0x403A0001,
574 0xC78, 0x403B0001,
575 0xC78, 0x403C0001,
576 0xC78, 0x403D0001,
577 0xC78, 0x403E0001,
578 0xC78, 0x403F0001,
579 0xC78, 0xFB400001,
580 0xC78, 0xFB410001,
581 0xC78, 0xFB420001,
582 0xC78, 0xFB430001,
583 0xC78, 0xFB440001,
584 0xC78, 0xFB450001,
585 0xC78, 0xFB460001,
586 0xC78, 0xFB470001,
587 0xC78, 0xFB480001,
588 0xC78, 0xFA490001,
589 0xC78, 0xF94A0001,
590 0xC78, 0xF84B0001,
591 0xC78, 0xF74C0001,
592 0xC78, 0xF64D0001,
593 0xC78, 0xF54E0001,
594 0xC78, 0xF44F0001,
595 0xC78, 0xF3500001,
596 0xC78, 0xF2510001,
597 0xC78, 0xF1520001,
598 0xC78, 0xF0530001,
599 0xC78, 0xEF540001,
600 0xC78, 0xEE550001,
601 0xC78, 0xED560001,
602 0xC78, 0xEC570001,
603 0xC78, 0xEB580001,
604 0xC78, 0xEA590001,
605 0xC78, 0xE95A0001,
606 0xC78, 0xE85B0001,
607 0xC78, 0xE75C0001,
608 0xC78, 0xE65D0001,
609 0xC78, 0xE55E0001,
610 0xC78, 0xE45F0001,
611 0xC78, 0xE3600001,
612 0xC78, 0xE2610001,
613 0xC78, 0xC3620001,
614 0xC78, 0xC2630001,
615 0xC78, 0xC1640001,
616 0xC78, 0x8B650001,
617 0xC78, 0x8A660001,
618 0xC78, 0x89670001,
619 0xC78, 0x88680001,
620 0xC78, 0x87690001,
621 0xC78, 0x866A0001,
622 0xC78, 0x856B0001,
623 0xC78, 0x846C0001,
624 0xC78, 0x676D0001,
625 0xC78, 0x666E0001,
626 0xC78, 0x656F0001,
627 0xC78, 0x64700001,
628 0xC78, 0x63710001,
629 0xC78, 0x62720001,
630 0xC78, 0x61730001,
631 0xC78, 0x60740001,
632 0xC78, 0x46750001,
633 0xC78, 0x45760001,
634 0xC78, 0x44770001,
635 0xC78, 0x43780001,
636 0xC78, 0x42790001,
637 0xC78, 0x417A0001,
638 0xC78, 0x407B0001,
639 0xC78, 0x407C0001,
640 0xC78, 0x407D0001,
641 0xC78, 0x407E0001,
642 0xC78, 0x407F0001,
643};
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/table.h b/drivers/net/wireless/rtlwifi/rtl8188ee/table.h
new file mode 100644
index 000000000000..c1218e835129
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/table.h
@@ -0,0 +1,47 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Created on 2010/ 5/18, 1:41
27 *
28 * Larry Finger <Larry.Finger@lwfinger.net>
29 *
30 *****************************************************************************/
31
32#ifndef __RTL92CE_TABLE__H_
33#define __RTL92CE_TABLE__H_
34
35#include <linux/types.h>
36#define RTL8188EEPHY_REG_1TARRAYLEN 382
37extern u32 RTL8188EEPHY_REG_1TARRAY[];
38#define RTL8188EEPHY_REG_ARRAY_PGLEN 264
39extern u32 RTL8188EEPHY_REG_ARRAY_PG[];
40#define RTL8188EE_RADIOA_1TARRAYLEN 190
41extern u32 RTL8188EE_RADIOA_1TARRAY[];
42#define RTL8188EEMAC_1T_ARRAYLEN 180
43extern u32 RTL8188EEMAC_1T_ARRAY[];
44#define RTL8188EEAGCTAB_1TARRAYLEN 256
45extern u32 RTL8188EEAGCTAB_1TARRAY[];
46
47#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
new file mode 100644
index 000000000000..d075237add51
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
@@ -0,0 +1,817 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../base.h"
33#include "../stats.h"
34#include "reg.h"
35#include "def.h"
36#include "phy.h"
37#include "trx.h"
38#include "led.h"
39#include "dm.h"
40
41static u8 _rtl88ee_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
42{
43 __le16 fc = rtl_get_fc(skb);
44
45 if (unlikely(ieee80211_is_beacon(fc)))
46 return QSLT_BEACON;
47 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
48 return QSLT_MGNT;
49
50 return skb->priority;
51}
52
53static void _rtl88ee_query_rxphystatus(struct ieee80211_hw *hw,
54 struct rtl_stats *pstatus, u8 *pdesc,
55 struct rx_fwinfo_88e *p_drvinfo,
56 bool bpacket_match_bssid,
57 bool bpacket_toself, bool packet_beacon)
58{
59 struct rtl_priv *rtlpriv = rtl_priv(hw);
60 struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
61 struct phy_sts_cck_8192s_t *cck_buf;
62 struct phy_status_rpt *phystrpt = (struct phy_status_rpt *)p_drvinfo;
63 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
64 char rx_pwr_all = 0, rx_pwr[4];
65 u8 rf_rx_num = 0, evm, pwdb_all;
66 u8 i, max_spatial_stream;
67 u32 rssi, total_rssi = 0;
68 bool is_cck = pstatus->is_cck;
69 u8 lan_idx, vga_idx;
70
71 /* Record it for next packet processing */
72 pstatus->packet_matchbssid = bpacket_match_bssid;
73 pstatus->packet_toself = bpacket_toself;
74 pstatus->packet_beacon = packet_beacon;
75 pstatus->rx_mimo_sig_qual[0] = -1;
76 pstatus->rx_mimo_sig_qual[1] = -1;
77
78 if (is_cck) {
79 u8 cck_hipwr;
80 u8 cck_agc_rpt;
81 /* CCK Driver info Structure is not the same as OFDM packet. */
82 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
83 cck_agc_rpt = cck_buf->cck_agc_rpt;
84
85 /* (1)Hardware does not provide RSSI for CCK
86 * (2)PWDB, Average PWDB cacluated by
87 * hardware (for rate adaptive)
88 */
89 if (ppsc->rfpwr_state == ERFON)
90 cck_hipwr = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2,
91 BIT(9));
92 else
93 cck_hipwr = false;
94
95 lan_idx = ((cck_agc_rpt & 0xE0) >> 5);
96 vga_idx = (cck_agc_rpt & 0x1f);
97 switch (lan_idx) {
98 case 7:
99 if (vga_idx <= 27)
100 rx_pwr_all = -100 + 2 * (27 - vga_idx);
101 else
102 rx_pwr_all = -100;
103 break;
104 case 6:
105 rx_pwr_all = -48 + 2 * (2 - vga_idx); /*VGA_idx = 2~0*/
106 break;
107 case 5:
108 rx_pwr_all = -42 + 2 * (7 - vga_idx); /*VGA_idx = 7~5*/
109 break;
110 case 4:
111 rx_pwr_all = -36 + 2 * (7 - vga_idx); /*VGA_idx = 7~4*/
112 break;
113 case 3:
114 rx_pwr_all = -24 + 2 * (7 - vga_idx); /*VGA_idx = 7~0*/
115 break;
116 case 2:
117 if (cck_hipwr)
118 rx_pwr_all = -12 + 2 * (5 - vga_idx);
119 else
120 rx_pwr_all = -6 + 2 * (5 - vga_idx);
121 break;
122 case 1:
123 rx_pwr_all = 8 - 2 * vga_idx;
124 break;
125 case 0:
126 rx_pwr_all = 14 - 2 * vga_idx;
127 break;
128 default:
129 break;
130 }
131 rx_pwr_all += 6;
132 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
133 /* CCK gain is smaller than OFDM/MCS gain,
134 * so we add gain diff by experiences,
135 * the val is 6
136 */
137 pwdb_all += 6;
138 if (pwdb_all > 100)
139 pwdb_all = 100;
140 /* modify the offset to make the same
141 * gain index with OFDM.
142 */
143 if (pwdb_all > 34 && pwdb_all <= 42)
144 pwdb_all -= 2;
145 else if (pwdb_all > 26 && pwdb_all <= 34)
146 pwdb_all -= 6;
147 else if (pwdb_all > 14 && pwdb_all <= 26)
148 pwdb_all -= 8;
149 else if (pwdb_all > 4 && pwdb_all <= 14)
150 pwdb_all -= 4;
151 if (cck_hipwr == false) {
152 if (pwdb_all >= 80)
153 pwdb_all = ((pwdb_all - 80)<<1) +
154 ((pwdb_all - 80)>>1) + 80;
155 else if ((pwdb_all <= 78) && (pwdb_all >= 20))
156 pwdb_all += 3;
157 if (pwdb_all > 100)
158 pwdb_all = 100;
159 }
160
161 pstatus->rx_pwdb_all = pwdb_all;
162 pstatus->recvsignalpower = rx_pwr_all;
163
164 /* (3) Get Signal Quality (EVM) */
165 if (bpacket_match_bssid) {
166 u8 sq;
167
168 if (pstatus->rx_pwdb_all > 40) {
169 sq = 100;
170 } else {
171 sq = cck_buf->sq_rpt;
172 if (sq > 64)
173 sq = 0;
174 else if (sq < 20)
175 sq = 100;
176 else
177 sq = ((64 - sq) * 100) / 44;
178 }
179
180 pstatus->signalquality = sq;
181 pstatus->rx_mimo_sig_qual[0] = sq;
182 pstatus->rx_mimo_sig_qual[1] = -1;
183 }
184 } else {
185 rtlpriv->dm.rfpath_rxenable[0] =
186 rtlpriv->dm.rfpath_rxenable[1] = true;
187
188 /* (1)Get RSSI for HT rate */
189 for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
190 /* we will judge RF RX path now. */
191 if (rtlpriv->dm.rfpath_rxenable[i])
192 rf_rx_num++;
193
194 rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f) * 2)-110;
195
196 /* Translate DBM to percentage. */
197 rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
198 total_rssi += rssi;
199
200 /* Get Rx snr value in DB */
201 rtlpriv->stats.rx_snr_db[i] = p_drvinfo->rxsnr[i] / 2;
202
203 /* Record Signal Strength for next packet */
204 if (bpacket_match_bssid)
205 pstatus->rx_mimo_signalstrength[i] = (u8) rssi;
206 }
207
208 /* (2)PWDB, Average PWDB cacluated by
209 * hardware (for rate adaptive)
210 */
211 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
212
213 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
214 pstatus->rx_pwdb_all = pwdb_all;
215 pstatus->rxpower = rx_pwr_all;
216 pstatus->recvsignalpower = rx_pwr_all;
217
218 /* (3)EVM of HT rate */
219 if (pstatus->is_ht && pstatus->rate >= DESC92C_RATEMCS8 &&
220 pstatus->rate <= DESC92C_RATEMCS15)
221 max_spatial_stream = 2;
222 else
223 max_spatial_stream = 1;
224
225 for (i = 0; i < max_spatial_stream; i++) {
226 evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
227
228 if (bpacket_match_bssid) {
229 /* Fill value in RFD, Get the first
230 * spatial stream only
231 */
232 if (i == 0)
233 pstatus->signalquality = evm & 0xff;
234 pstatus->rx_mimo_sig_qual[i] = evm & 0xff;
235 }
236 }
237 }
238
239 /* UI BSS List signal strength(in percentage),
240 * make it good looking, from 0~100.
241 */
242 if (is_cck)
243 pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
244 pwdb_all));
245 else if (rf_rx_num != 0)
246 pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
247 total_rssi /= rf_rx_num));
248 /*HW antenna diversity*/
249 rtldm->fat_table.antsel_rx_keep_0 = phystrpt->ant_sel;
250 rtldm->fat_table.antsel_rx_keep_1 = phystrpt->ant_sel_b;
251 rtldm->fat_table.antsel_rx_keep_2 = phystrpt->antsel_rx_keep_2;
252}
253
254static void _rtl88ee_smart_antenna(struct ieee80211_hw *hw,
255 struct rtl_stats *pstatus)
256{
257 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
258 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
259 u8 ant_mux;
260 struct fast_ant_training *pfat = &(rtldm->fat_table);
261
262 if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV) {
263 if (pfat->fat_state == FAT_TRAINING_STATE) {
264 if (pstatus->packet_toself) {
265 ant_mux = (pfat->antsel_rx_keep_2 << 2) |
266 (pfat->antsel_rx_keep_1 << 1) |
267 pfat->antsel_rx_keep_0;
268 pfat->ant_sum[ant_mux] += pstatus->rx_pwdb_all;
269 pfat->ant_cnt[ant_mux]++;
270 }
271 }
272 } else if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
273 (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)) {
274 if (pstatus->packet_toself || pstatus->packet_matchbssid) {
275 ant_mux = (pfat->antsel_rx_keep_2 << 2) |
276 (pfat->antsel_rx_keep_1 << 1) |
277 pfat->antsel_rx_keep_0;
278 rtl88e_dm_ant_sel_statistics(hw, ant_mux, 0,
279 pstatus->rx_pwdb_all);
280 }
281 }
282}
283
284static void _rtl88ee_translate_rx_signal_stuff(struct ieee80211_hw *hw,
285 struct sk_buff *skb, struct rtl_stats *pstatus,
286 u8 *pdesc, struct rx_fwinfo_88e *p_drvinfo)
287{
288 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
289 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
290 struct ieee80211_hdr *hdr;
291 u8 *tmp_buf;
292 u8 *praddr;
293 u8 *psaddr;
294 __le16 fc;
295 u16 type, ufc;
296 bool match_bssid, packet_toself, packet_beacon, addr;
297
298 tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
299
300 hdr = (struct ieee80211_hdr *)tmp_buf;
301 fc = hdr->frame_control;
302 ufc = le16_to_cpu(fc);
303 type = WLAN_FC_GET_TYPE(fc);
304 praddr = hdr->addr1;
305 psaddr = ieee80211_get_SA(hdr);
306 memcpy(pstatus->psaddr, psaddr, ETH_ALEN);
307
308 addr = (!compare_ether_addr(mac->bssid, (ufc & IEEE80211_FCTL_TODS) ?
309 hdr->addr1 : (ufc & IEEE80211_FCTL_FROMDS) ?
310 hdr->addr2 : hdr->addr3));
311 match_bssid = ((IEEE80211_FTYPE_CTL != type) && (!pstatus->hwerror) &&
312 (!pstatus->crc) && (!pstatus->icv)) && addr;
313
314 addr = (!compare_ether_addr(praddr, rtlefuse->dev_addr));
315 packet_toself = match_bssid && addr;
316
317 if (ieee80211_is_beacon(fc))
318 packet_beacon = true;
319
320 _rtl88ee_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo,
321 match_bssid, packet_toself, packet_beacon);
322 _rtl88ee_smart_antenna(hw, pstatus);
323 rtl_process_phyinfo(hw, tmp_buf, pstatus);
324}
325
326static void insert_em(struct rtl_tcb_desc *ptcb_desc, u8 *virtualaddress)
327{
328 u32 dwtmp = 0;
329
330 memset(virtualaddress, 0, 8);
331
332 SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
333 if (ptcb_desc->empkt_num == 1) {
334 dwtmp = ptcb_desc->empkt_len[0];
335 } else {
336 dwtmp = ptcb_desc->empkt_len[0];
337 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
338 dwtmp += ptcb_desc->empkt_len[1];
339 }
340 SET_EARLYMODE_LEN0(virtualaddress, dwtmp);
341
342 if (ptcb_desc->empkt_num <= 3) {
343 dwtmp = ptcb_desc->empkt_len[2];
344 } else {
345 dwtmp = ptcb_desc->empkt_len[2];
346 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
347 dwtmp += ptcb_desc->empkt_len[3];
348 }
349 SET_EARLYMODE_LEN1(virtualaddress, dwtmp);
350 if (ptcb_desc->empkt_num <= 5) {
351 dwtmp = ptcb_desc->empkt_len[4];
352 } else {
353 dwtmp = ptcb_desc->empkt_len[4];
354 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
355 dwtmp += ptcb_desc->empkt_len[5];
356 }
357 SET_EARLYMODE_LEN2_1(virtualaddress, dwtmp & 0xF);
358 SET_EARLYMODE_LEN2_2(virtualaddress, dwtmp >> 4);
359 if (ptcb_desc->empkt_num <= 7) {
360 dwtmp = ptcb_desc->empkt_len[6];
361 } else {
362 dwtmp = ptcb_desc->empkt_len[6];
363 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
364 dwtmp += ptcb_desc->empkt_len[7];
365 }
366 SET_EARLYMODE_LEN3(virtualaddress, dwtmp);
367 if (ptcb_desc->empkt_num <= 9) {
368 dwtmp = ptcb_desc->empkt_len[8];
369 } else {
370 dwtmp = ptcb_desc->empkt_len[8];
371 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
372 dwtmp += ptcb_desc->empkt_len[9];
373 }
374 SET_EARLYMODE_LEN4(virtualaddress, dwtmp);
375}
376
377bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,
378 struct rtl_stats *status,
379 struct ieee80211_rx_status *rx_status,
380 u8 *pdesc, struct sk_buff *skb)
381{
382 struct rtl_priv *rtlpriv = rtl_priv(hw);
383 struct rx_fwinfo_88e *p_drvinfo;
384 struct ieee80211_hdr *hdr;
385
386 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
387 status->packet_report_type = (u8)GET_RX_STATUS_DESC_RPT_SEL(pdesc);
388 if (status->packet_report_type == TX_REPORT2)
389 status->length = (u16) GET_RX_RPT2_DESC_PKT_LEN(pdesc);
390 else
391 status->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
392 status->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
393 RX_DRV_INFO_SIZE_UNIT;
394 status->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
395 status->icv = (u16) GET_RX_DESC_ICV(pdesc);
396 status->crc = (u16) GET_RX_DESC_CRC32(pdesc);
397 status->hwerror = (status->crc | status->icv);
398 status->decrypted = !GET_RX_DESC_SWDEC(pdesc);
399 status->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
400 status->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
401 status->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
402 status->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) &&
403 (GET_RX_DESC_FAGGR(pdesc) == 1));
404 if (status->packet_report_type == NORMAL_RX)
405 status->timestamp_low = GET_RX_DESC_TSFL(pdesc);
406 status->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
407 status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
408
409 status->is_cck = RTL8188_RX_HAL_IS_CCK_RATE(status->rate);
410
411 status->macid = GET_RX_DESC_MACID(pdesc);
412 if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc))
413 status->wake_match = BIT(2);
414 else if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc))
415 status->wake_match = BIT(1);
416 else if (GET_RX_STATUS_DESC_UNICAST_MATCH(pdesc))
417 status->wake_match = BIT(0);
418 else
419 status->wake_match = 0;
420 if (status->wake_match)
421 RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD,
422 "Get Wakeup Packet!! WakeMatch =%d\n",
423 status->wake_match);
424 rx_status->freq = hw->conf.channel->center_freq;
425 rx_status->band = hw->conf.channel->band;
426
427 if (status->crc)
428 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
429
430 if (status->rx_is40Mhzpacket)
431 rx_status->flag |= RX_FLAG_40MHZ;
432
433 if (status->is_ht)
434 rx_status->flag |= RX_FLAG_HT;
435
436 rx_status->flag |= RX_FLAG_MACTIME_START;
437
438 /* hw will set status->decrypted true, if it finds the
439 * frame is open data frame or mgmt frame.
440 * So hw will not decryption robust managment frame
441 * for IEEE80211w but still set status->decrypted
442 * true, so here we should set it back to undecrypted
443 * for IEEE80211w frame, and mac80211 sw will help
444 * to decrypt it
445 */
446 if (status->decrypted) {
447 hdr = (struct ieee80211_hdr *)(skb->data +
448 status->rx_drvinfo_size + status->rx_bufshift);
449
450 if (!hdr) {
451 /* During testing, hdr was NULL */
452 return false;
453 }
454 if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
455 (ieee80211_has_protected(hdr->frame_control)))
456 rx_status->flag &= ~RX_FLAG_DECRYPTED;
457 else
458 rx_status->flag |= RX_FLAG_DECRYPTED;
459 }
460
461 /* rate_idx: index of data rate into band's
462 * supported rates or MCS index if HT rates
463 * are use (RX_FLAG_HT)
464 * Notice: this is diff with windows define
465 */
466 rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht,
467 status->rate, false);
468
469 rx_status->mactime = status->timestamp_low;
470 if (phystatus == true) {
471 p_drvinfo = (struct rx_fwinfo_88e *)(skb->data +
472 status->rx_bufshift);
473
474 _rtl88ee_translate_rx_signal_stuff(hw, skb, status, pdesc,
475 p_drvinfo);
476 }
477
478 /*rx_status->qual = status->signal; */
479 rx_status->signal = status->recvsignalpower + 10;
480 /*rx_status->noise = -status->noise; */
481 if (status->packet_report_type == TX_REPORT2) {
482 status->macid_valid_entry[0] =
483 GET_RX_RPT2_DESC_MACID_VALID_1(pdesc);
484 status->macid_valid_entry[1] =
485 GET_RX_RPT2_DESC_MACID_VALID_2(pdesc);
486 }
487 return true;
488}
489
490void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw,
491 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
492 struct ieee80211_tx_info *info,
493 struct ieee80211_sta *sta,
494 struct sk_buff *skb,
495 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
496{
497 struct rtl_priv *rtlpriv = rtl_priv(hw);
498 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
499 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
500 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
501 u8 *pdesc = (u8 *)pdesc_tx;
502 u16 seq_number;
503 __le16 fc = hdr->frame_control;
504 unsigned int buf_len = 0;
505 unsigned int skb_len = skb->len;
506 u8 fw_qsel = _rtl88ee_map_hwqueue_to_fwqueue(skb, hw_queue);
507 bool firstseg = ((hdr->seq_ctrl &
508 cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
509 bool lastseg = ((hdr->frame_control &
510 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
511 dma_addr_t mapping;
512 u8 bw_40 = 0;
513 u8 short_gi = 0;
514
515 if (mac->opmode == NL80211_IFTYPE_STATION) {
516 bw_40 = mac->bw_40;
517 } else if (mac->opmode == NL80211_IFTYPE_AP ||
518 mac->opmode == NL80211_IFTYPE_ADHOC) {
519 if (sta)
520 bw_40 = sta->ht_cap.cap &
521 IEEE80211_HT_CAP_SUP_WIDTH_20_40;
522 }
523 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
524 rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
525 /* reserve 8 byte for AMPDU early mode */
526 if (rtlhal->earlymode_enable) {
527 skb_push(skb, EM_HDR_LEN);
528 memset(skb->data, 0, EM_HDR_LEN);
529 }
530 buf_len = skb->len;
531 mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
532 PCI_DMA_TODEVICE);
533 if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
534 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
535 "DMA mapping error");
536 return;
537 }
538 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_88e));
539 if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
540 firstseg = true;
541 lastseg = true;
542 }
543 if (firstseg) {
544 if (rtlhal->earlymode_enable) {
545 SET_TX_DESC_PKT_OFFSET(pdesc, 1);
546 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN +
547 EM_HDR_LEN);
548 if (ptcb_desc->empkt_num) {
549 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
550 "Insert 8 byte.pTcb->EMPktNum:%d\n",
551 ptcb_desc->empkt_num);
552 insert_em(ptcb_desc, (u8 *)(skb->data));
553 }
554 } else {
555 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
556 }
557
558 ptcb_desc->use_driver_rate = true;
559 SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
560 if (ptcb_desc->hw_rate > DESC92C_RATEMCS0)
561 short_gi = (ptcb_desc->use_shortgi) ? 1 : 0;
562 else
563 short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0;
564 SET_TX_DESC_DATA_SHORTGI(pdesc, short_gi);
565
566 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
567 SET_TX_DESC_AGG_ENABLE(pdesc, 1);
568 SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
569 }
570 SET_TX_DESC_SEQ(pdesc, seq_number);
571 SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
572 !ptcb_desc->cts_enable) ? 1 : 0));
573 SET_TX_DESC_HW_RTS_ENABLE(pdesc, 0);
574 SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0));
575 SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
576
577 SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
578 SET_TX_DESC_RTS_BW(pdesc, 0);
579 SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
580 SET_TX_DESC_RTS_SHORT(pdesc,
581 ((ptcb_desc->rts_rate <= DESC92C_RATE54M) ?
582 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
583 (ptcb_desc->rts_use_shortgi ? 1 : 0)));
584
585 if (ptcb_desc->btx_enable_sw_calc_duration)
586 SET_TX_DESC_NAV_USE_HDR(pdesc, 1);
587
588 if (bw_40) {
589 if (ptcb_desc->packet_bw) {
590 SET_TX_DESC_DATA_BW(pdesc, 1);
591 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
592 } else {
593 SET_TX_DESC_DATA_BW(pdesc, 0);
594 SET_TX_DESC_TX_SUB_CARRIER(pdesc,
595 mac->cur_40_prime_sc);
596 }
597 } else {
598 SET_TX_DESC_DATA_BW(pdesc, 0);
599 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
600 }
601
602 SET_TX_DESC_LINIP(pdesc, 0);
603 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len);
604 if (sta) {
605 u8 ampdu_density = sta->ht_cap.ampdu_density;
606 SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
607 }
608 if (info->control.hw_key) {
609 struct ieee80211_key_conf *keyconf;
610 keyconf = info->control.hw_key;
611 switch (keyconf->cipher) {
612 case WLAN_CIPHER_SUITE_WEP40:
613 case WLAN_CIPHER_SUITE_WEP104:
614 case WLAN_CIPHER_SUITE_TKIP:
615 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
616 break;
617 case WLAN_CIPHER_SUITE_CCMP:
618 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
619 break;
620 default:
621 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
622 break;
623 }
624 }
625
626 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
627 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
628 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
629 SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ?
630 1 : 0);
631 SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
632
633 /* Set TxRate and RTSRate in TxDesc */
634 /* This prevent Tx initial rate of new-coming packets */
635 /* from being overwritten by retried packet rate.*/
636 if (!ptcb_desc->use_driver_rate) {
637 /*SET_TX_DESC_RTS_RATE(pdesc, 0x08); */
638 /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */
639 }
640 if (ieee80211_is_data_qos(fc)) {
641 if (mac->rdg_en) {
642 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
643 "Enable RDG function.\n");
644 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
645 SET_TX_DESC_HTC(pdesc, 1);
646 }
647 }
648 }
649
650 SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
651 SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
652 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len);
653 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
654 if (rtlpriv->dm.useramask) {
655 SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
656 SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
657 } else {
658 SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index);
659 SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index);
660 }
661 if (ieee80211_is_data_qos(fc))
662 SET_TX_DESC_QOS(pdesc, 1);
663
664 if (!ieee80211_is_data_qos(fc))
665 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
666 SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
667 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
668 is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
669 SET_TX_DESC_BMC(pdesc, 1);
670
671 rtl88e_dm_set_tx_ant_by_tx_info(hw, pdesc, ptcb_desc->mac_id);
672 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
673}
674
675void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw,
676 u8 *pdesc, bool firstseg,
677 bool lastseg, struct sk_buff *skb)
678{
679 struct rtl_priv *rtlpriv = rtl_priv(hw);
680 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
681 u8 fw_queue = QSLT_BEACON;
682
683 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
684 skb->data, skb->len,
685 PCI_DMA_TODEVICE);
686
687 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
688 __le16 fc = hdr->frame_control;
689
690 if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
691 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
692 "DMA mapping error");
693 return;
694 }
695 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
696
697 if (firstseg)
698 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
699
700 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
701
702 SET_TX_DESC_SEQ(pdesc, 0);
703
704 SET_TX_DESC_LINIP(pdesc, 0);
705
706 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
707
708 SET_TX_DESC_FIRST_SEG(pdesc, 1);
709 SET_TX_DESC_LAST_SEG(pdesc, 1);
710
711 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
712
713 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
714
715 SET_TX_DESC_RATE_ID(pdesc, 7);
716 SET_TX_DESC_MACID(pdesc, 0);
717
718 SET_TX_DESC_OWN(pdesc, 1);
719
720 SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len));
721
722 SET_TX_DESC_FIRST_SEG(pdesc, 1);
723 SET_TX_DESC_LAST_SEG(pdesc, 1);
724
725 SET_TX_DESC_OFFSET(pdesc, 0x20);
726
727 SET_TX_DESC_USE_RATE(pdesc, 1);
728
729 if (!ieee80211_is_data_qos(fc))
730 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
731
732 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
733 "H2C Tx Cmd Content\n",
734 pdesc, TX_DESC_SIZE);
735}
736
737void rtl88ee_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
738{
739 if (istx == true) {
740 switch (desc_name) {
741 case HW_DESC_OWN:
742 SET_TX_DESC_OWN(pdesc, 1);
743 break;
744 case HW_DESC_TX_NEXTDESC_ADDR:
745 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *)val);
746 break;
747 default:
748 RT_ASSERT(false, "ERR txdesc :%d not processed\n",
749 desc_name);
750 break;
751 }
752 } else {
753 switch (desc_name) {
754 case HW_DESC_RXOWN:
755 SET_RX_DESC_OWN(pdesc, 1);
756 break;
757 case HW_DESC_RXBUFF_ADDR:
758 SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *)val);
759 break;
760 case HW_DESC_RXPKT_LEN:
761 SET_RX_DESC_PKT_LEN(pdesc, *(u32 *)val);
762 break;
763 case HW_DESC_RXERO:
764 SET_RX_DESC_EOR(pdesc, 1);
765 break;
766 default:
767 RT_ASSERT(false, "ERR rxdesc :%d not processed\n",
768 desc_name);
769 break;
770 }
771 }
772}
773
774u32 rtl88ee_get_desc(u8 *pdesc, bool istx, u8 desc_name)
775{
776 u32 ret = 0;
777
778 if (istx == true) {
779 switch (desc_name) {
780 case HW_DESC_OWN:
781 ret = GET_TX_DESC_OWN(pdesc);
782 break;
783 case HW_DESC_TXBUFF_ADDR:
784 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc);
785 break;
786 default:
787 RT_ASSERT(false, "ERR txdesc :%d not processed\n",
788 desc_name);
789 break;
790 }
791 } else {
792 switch (desc_name) {
793 case HW_DESC_OWN:
794 ret = GET_RX_DESC_OWN(pdesc);
795 break;
796 case HW_DESC_RXPKT_LEN:
797 ret = GET_RX_DESC_PKT_LEN(pdesc);
798 break;
799 default:
800 RT_ASSERT(false, "ERR rxdesc :%d not processed\n",
801 desc_name);
802 break;
803 }
804 }
805 return ret;
806}
807
808void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
809{
810 struct rtl_priv *rtlpriv = rtl_priv(hw);
811 if (hw_queue == BEACON_QUEUE) {
812 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
813 } else {
814 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
815 BIT(0) << (hw_queue));
816 }
817}
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h
new file mode 100644
index 000000000000..d3a02e73f53a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h
@@ -0,0 +1,795 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92CE_TRX_H__
31#define __RTL92CE_TRX_H__
32
33#define TX_DESC_SIZE 64
34#define TX_DESC_AGGR_SUBFRAME_SIZE 32
35
36#define RX_DESC_SIZE 32
37#define RX_DRV_INFO_SIZE_UNIT 8
38
39#define TX_DESC_NEXT_DESC_OFFSET 40
40#define USB_HWDESC_HEADER_LEN 32
41#define CRCLENGTH 4
42
43#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
44 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
45#define SET_TX_DESC_OFFSET(__pdesc, __val) \
46 SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
47#define SET_TX_DESC_BMC(__pdesc, __val) \
48 SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
49#define SET_TX_DESC_HTC(__pdesc, __val) \
50 SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
51#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
52 SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
53#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
54 SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
55#define SET_TX_DESC_LINIP(__pdesc, __val) \
56 SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
57#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
58 SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
59#define SET_TX_DESC_GF(__pdesc, __val) \
60 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
61#define SET_TX_DESC_OWN(__pdesc, __val) \
62 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
63
64#define GET_TX_DESC_PKT_SIZE(__pdesc) \
65 LE_BITS_TO_4BYTE(__pdesc, 0, 16)
66#define GET_TX_DESC_OFFSET(__pdesc) \
67 LE_BITS_TO_4BYTE(__pdesc, 16, 8)
68#define GET_TX_DESC_BMC(__pdesc) \
69 LE_BITS_TO_4BYTE(__pdesc, 24, 1)
70#define GET_TX_DESC_HTC(__pdesc) \
71 LE_BITS_TO_4BYTE(__pdesc, 25, 1)
72#define GET_TX_DESC_LAST_SEG(__pdesc) \
73 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
74#define GET_TX_DESC_FIRST_SEG(__pdesc) \
75 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
76#define GET_TX_DESC_LINIP(__pdesc) \
77 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
78#define GET_TX_DESC_NO_ACM(__pdesc) \
79 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
80#define GET_TX_DESC_GF(__pdesc) \
81 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
82#define GET_TX_DESC_OWN(__pdesc) \
83 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
84
85#define SET_TX_DESC_MACID(__pdesc, __val) \
86 SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 6, __val)
87#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
88 SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
89#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
90 SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
91#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
92 SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
93#define SET_TX_DESC_PIFS(__pdesc, __val) \
94 SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
95#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
96 SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val)
97#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
98 SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val)
99#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
100 SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
101#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
102 SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
103#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
104 SET_BITS_TO_LE_4BYTE(__pdesc+4, 26, 5, __val)
105#define SET_TX_DESC_PADDING_LEN(__pdesc, __val) \
106 SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val)
107
108#define GET_TX_DESC_MACID(__pdesc) \
109 LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
110#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
111 LE_BITS_TO_4BYTE(__pdesc+4, 5, 1)
112#define GET_TX_DESC_AGG_BREAK(__pdesc) \
113 LE_BITS_TO_4BYTE(__pdesc+4, 6, 1)
114#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
115 LE_BITS_TO_4BYTE(__pdesc+4, 7, 1)
116#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
117 LE_BITS_TO_4BYTE(__pdesc+4, 8, 5)
118#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
119 LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
120#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
121 LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
122#define GET_TX_DESC_PIFS(__pdesc) \
123 LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
124#define GET_TX_DESC_RATE_ID(__pdesc) \
125 LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
126#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
127 LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
128#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
129 LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
130#define GET_TX_DESC_SEC_TYPE(__pdesc) \
131 LE_BITS_TO_4BYTE(__pdesc+4, 22, 2)
132#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
133 LE_BITS_TO_4BYTE(__pdesc+4, 24, 8)
134
135#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
136 SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val)
137#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
138 SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val)
139#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \
140 SET_BITS_TO_LE_4BYTE(__pdesc+8, 12, 1, __val)
141#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
142 SET_BITS_TO_LE_4BYTE(__pdesc+8, 13, 1, __val)
143#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
144 SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
145#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
146 SET_BITS_TO_LE_4BYTE(__pdesc+8, 16, 1, __val)
147#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
148 SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
149#define SET_TX_DESC_RAW(__pdesc, __val) \
150 SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
151#define SET_TX_DESC_CCX(__pdesc, __val) \
152 SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
153#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
154 SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
155#define SET_TX_DESC_BT_INT(__pdesc, __val) \
156 SET_BITS_TO_LE_4BYTE(__pdesc+8, 23, 1, __val)
157#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
158 SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val)
159#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
160 SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val)
161#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
162 SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val)
163#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
164 SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val)
165#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
166 SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val)
167
168#define GET_TX_DESC_RTS_RC(__pdesc) \
169 LE_BITS_TO_4BYTE(__pdesc+8, 0, 6)
170#define GET_TX_DESC_DATA_RC(__pdesc) \
171 LE_BITS_TO_4BYTE(__pdesc+8, 6, 6)
172#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
173 LE_BITS_TO_4BYTE(__pdesc+8, 14, 2)
174#define GET_TX_DESC_MORE_FRAG(__pdesc) \
175 LE_BITS_TO_4BYTE(__pdesc+8, 17, 1)
176#define GET_TX_DESC_RAW(__pdesc) \
177 LE_BITS_TO_4BYTE(__pdesc+8, 18, 1)
178#define GET_TX_DESC_CCX(__pdesc) \
179 LE_BITS_TO_4BYTE(__pdesc+8, 19, 1)
180#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
181 LE_BITS_TO_4BYTE(__pdesc+8, 20, 3)
182#define GET_TX_DESC_ANTSEL_A(__pdesc) \
183 LE_BITS_TO_4BYTE(__pdesc+8, 24, 1)
184#define GET_TX_DESC_ANTSEL_B(__pdesc) \
185 LE_BITS_TO_4BYTE(__pdesc+8, 25, 1)
186#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
187 LE_BITS_TO_4BYTE(__pdesc+8, 26, 2)
188#define GET_TX_DESC_TX_ANTL(__pdesc) \
189 LE_BITS_TO_4BYTE(__pdesc+8, 28, 2)
190#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
191 LE_BITS_TO_4BYTE(__pdesc+8, 30, 2)
192
193#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
194 SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val)
195#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
196 SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val)
197#define SET_TX_DESC_SEQ(__pdesc, __val) \
198 SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val)
199#define SET_TX_DESC_CPU_HANDLE(__pdesc, __val) \
200 SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 1, __val)
201#define SET_TX_DESC_TAG1(__pdesc, __val) \
202 SET_BITS_TO_LE_4BYTE(__pdesc+12, 29, 1, __val)
203#define SET_TX_DESC_TRIGGER_INT(__pdesc, __val) \
204 SET_BITS_TO_LE_4BYTE(__pdesc+12, 30, 1, __val)
205#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
206 SET_BITS_TO_LE_4BYTE(__pdesc+12, 31, 1, __val)
207
208
209#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
210 LE_BITS_TO_4BYTE(__pdesc+12, 0, 8)
211#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
212 LE_BITS_TO_4BYTE(__pdesc+12, 8, 8)
213#define GET_TX_DESC_SEQ(__pdesc) \
214 LE_BITS_TO_4BYTE(__pdesc+12, 16, 12)
215
216
217#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
218 SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val)
219#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
220 SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val)
221#define SET_TX_DESC_QOS(__pdesc, __val) \
222 SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val)
223#define SET_TX_DESC_HWSEQ_SSN(__pdesc, __val) \
224 SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val)
225#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
226 SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val)
227#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
228 SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val)
229#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
230 SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val)
231#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
232 SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val)
233#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
234 SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val)
235#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
236 SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val)
237#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
238 SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val)
239#define SET_TX_DESC_PWR_STATUS(__pdesc, __val) \
240 SET_BITS_TO_LE_4BYTE(__pdesc+16, 15, 3, __val)
241#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
242 SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val)
243#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
244 SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val)
245#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
246 SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val)
247#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
248 SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val)
249#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
250 SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val)
251#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
252 SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val)
253#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
254 SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val)
255#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
256 SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val)
257#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
258 SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val)
259#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
260 SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val)
261
262#define GET_TX_DESC_RTS_RATE(__pdesc) \
263 LE_BITS_TO_4BYTE(__pdesc+16, 0, 5)
264#define GET_TX_DESC_AP_DCFE(__pdesc) \
265 LE_BITS_TO_4BYTE(__pdesc+16, 5, 1)
266#define GET_TX_DESC_QOS(__pdesc) \
267 LE_BITS_TO_4BYTE(__pdesc+16, 6, 1)
268#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
269 LE_BITS_TO_4BYTE(__pdesc+16, 7, 1)
270#define GET_TX_DESC_USE_RATE(__pdesc) \
271 LE_BITS_TO_4BYTE(__pdesc+16, 8, 1)
272#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
273 LE_BITS_TO_4BYTE(__pdesc+16, 9, 1)
274#define GET_TX_DESC_DISABLE_FB(__pdesc) \
275 LE_BITS_TO_4BYTE(__pdesc+16, 10, 1)
276#define GET_TX_DESC_CTS2SELF(__pdesc) \
277 LE_BITS_TO_4BYTE(__pdesc+16, 11, 1)
278#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
279 LE_BITS_TO_4BYTE(__pdesc+16, 12, 1)
280#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
281 LE_BITS_TO_4BYTE(__pdesc+16, 13, 1)
282#define GET_TX_DESC_PORT_ID(__pdesc) \
283 LE_BITS_TO_4BYTE(__pdesc+16, 14, 1)
284#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
285 LE_BITS_TO_4BYTE(__pdesc+16, 18, 1)
286#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
287 LE_BITS_TO_4BYTE(__pdesc+16, 19, 1)
288#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
289 LE_BITS_TO_4BYTE(__pdesc+16, 20, 2)
290#define GET_TX_DESC_TX_STBC(__pdesc) \
291 LE_BITS_TO_4BYTE(__pdesc+16, 22, 2)
292#define GET_TX_DESC_DATA_SHORT(__pdesc) \
293 LE_BITS_TO_4BYTE(__pdesc+16, 24, 1)
294#define GET_TX_DESC_DATA_BW(__pdesc) \
295 LE_BITS_TO_4BYTE(__pdesc+16, 25, 1)
296#define GET_TX_DESC_RTS_SHORT(__pdesc) \
297 LE_BITS_TO_4BYTE(__pdesc+16, 26, 1)
298#define GET_TX_DESC_RTS_BW(__pdesc) \
299 LE_BITS_TO_4BYTE(__pdesc+16, 27, 1)
300#define GET_TX_DESC_RTS_SC(__pdesc) \
301 LE_BITS_TO_4BYTE(__pdesc+16, 28, 2)
302#define GET_TX_DESC_RTS_STBC(__pdesc) \
303 LE_BITS_TO_4BYTE(__pdesc+16, 30, 2)
304
305#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
306 SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val)
307#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
308 SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val)
309#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
310 SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
311#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
312 SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val)
313#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
314 SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
315#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
316 SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val)
317#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
318 SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val)
319#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
320 SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val)
321
322#define GET_TX_DESC_TX_RATE(__pdesc) \
323 LE_BITS_TO_4BYTE(__pdesc+20, 0, 6)
324#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
325 LE_BITS_TO_4BYTE(__pdesc+20, 6, 1)
326#define GET_TX_DESC_CCX_TAG(__pdesc) \
327 LE_BITS_TO_4BYTE(__pdesc+20, 7, 1)
328#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
329 LE_BITS_TO_4BYTE(__pdesc+20, 8, 5)
330#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
331 LE_BITS_TO_4BYTE(__pdesc+20, 13, 4)
332#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
333 LE_BITS_TO_4BYTE(__pdesc+20, 17, 1)
334#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
335 LE_BITS_TO_4BYTE(__pdesc+20, 18, 6)
336#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
337 LE_BITS_TO_4BYTE(__pdesc+20, 24, 8)
338
339#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
340 SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val)
341#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
342 SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val)
343#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
344 SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val)
345#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
346 SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val)
347#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
348 SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val)
349#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
350 SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val)
351#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
352 SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val)
353#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \
354 SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val)
355
356#define GET_TX_DESC_TXAGC_A(__pdesc) \
357 LE_BITS_TO_4BYTE(__pdesc+24, 0, 5)
358#define GET_TX_DESC_TXAGC_B(__pdesc) \
359 LE_BITS_TO_4BYTE(__pdesc+24, 5, 5)
360#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
361 LE_BITS_TO_4BYTE(__pdesc+24, 10, 1)
362#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
363 LE_BITS_TO_4BYTE(__pdesc+24, 11, 5)
364#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
365 LE_BITS_TO_4BYTE(__pdesc+24, 16, 4)
366#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
367 LE_BITS_TO_4BYTE(__pdesc+24, 20, 4)
368#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
369 LE_BITS_TO_4BYTE(__pdesc+24, 24, 4)
370#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
371 LE_BITS_TO_4BYTE(__pdesc+24, 28, 4)
372
373#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
374 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
375#define SET_TX_DESC_SW_OFFSET30(__pdesc, __val) \
376 SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 8, __val)
377#define SET_TX_DESC_SW_OFFSET31(__pdesc, __val) \
378 SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val)
379#define SET_TX_DESC_ANTSEL_C(__pdesc, __val) \
380 SET_BITS_TO_LE_4BYTE(__pdesc+28, 29, 1, __val)
381#define SET_TX_DESC_NULL_0(__pdesc, __val) \
382 SET_BITS_TO_LE_4BYTE(__pdesc+28, 30, 1, __val)
383#define SET_TX_DESC_NULL_1(__pdesc, __val) \
384 SET_BITS_TO_LE_4BYTE(__pdesc+28, 30, 1, __val)
385
386#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
387 LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
388
389
390#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
391 SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val)
392#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
393 SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val)
394
395#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
396 LE_BITS_TO_4BYTE(__pdesc+32, 0, 32)
397#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
398 LE_BITS_TO_4BYTE(__pdesc+36, 0, 32)
399
400#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
401 SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
402#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
403 SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val)
404
405#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
406 LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
407#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
408 LE_BITS_TO_4BYTE(__pdesc+44, 0, 32)
409
410#define GET_RX_DESC_PKT_LEN(__pdesc) \
411 LE_BITS_TO_4BYTE(__pdesc, 0, 14)
412#define GET_RX_DESC_CRC32(__pdesc) \
413 LE_BITS_TO_4BYTE(__pdesc, 14, 1)
414#define GET_RX_DESC_ICV(__pdesc) \
415 LE_BITS_TO_4BYTE(__pdesc, 15, 1)
416#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
417 LE_BITS_TO_4BYTE(__pdesc, 16, 4)
418#define GET_RX_DESC_SECURITY(__pdesc) \
419 LE_BITS_TO_4BYTE(__pdesc, 20, 3)
420#define GET_RX_DESC_QOS(__pdesc) \
421 LE_BITS_TO_4BYTE(__pdesc, 23, 1)
422#define GET_RX_DESC_SHIFT(__pdesc) \
423 LE_BITS_TO_4BYTE(__pdesc, 24, 2)
424#define GET_RX_DESC_PHYST(__pdesc) \
425 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
426#define GET_RX_DESC_SWDEC(__pdesc) \
427 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
428#define GET_RX_DESC_LS(__pdesc) \
429 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
430#define GET_RX_DESC_FS(__pdesc) \
431 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
432#define GET_RX_DESC_EOR(__pdesc) \
433 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
434#define GET_RX_DESC_OWN(__pdesc) \
435 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
436
437#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
438 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
439#define SET_RX_DESC_EOR(__pdesc, __val) \
440 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
441#define SET_RX_DESC_OWN(__pdesc, __val) \
442 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
443
444#define GET_RX_DESC_MACID(__pdesc) \
445 LE_BITS_TO_4BYTE(__pdesc+4, 0, 6)
446#define GET_RX_DESC_PAGGR(__pdesc) \
447 LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
448#define GET_RX_DESC_FAGGR(__pdesc) \
449 LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
450#define GET_RX_DESC_A1_FIT(__pdesc) \
451 LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
452#define GET_RX_DESC_A2_FIT(__pdesc) \
453 LE_BITS_TO_4BYTE(__pdesc+4, 20, 4)
454#define GET_RX_DESC_PAM(__pdesc) \
455 LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
456#define GET_RX_DESC_PWR(__pdesc) \
457 LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
458#define GET_RX_DESC_MD(__pdesc) \
459 LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
460#define GET_RX_DESC_MF(__pdesc) \
461 LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
462#define GET_RX_DESC_TYPE(__pdesc) \
463 LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
464#define GET_RX_DESC_MC(__pdesc) \
465 LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
466#define GET_RX_DESC_BC(__pdesc) \
467 LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
468#define GET_RX_DESC_SEQ(__pdesc) \
469 LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
470#define GET_RX_DESC_FRAG(__pdesc) \
471 LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
472
473#define GET_RX_DESC_RXMCS(__pdesc) \
474 LE_BITS_TO_4BYTE(__pdesc+12, 0, 6)
475#define GET_RX_DESC_RXHT(__pdesc) \
476 LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
477#define GET_RX_STATUS_DESC_RX_GF(__pdesc) \
478 LE_BITS_TO_4BYTE(__pdesc+12, 7, 1)
479#define GET_RX_DESC_SPLCP(__pdesc) \
480 LE_BITS_TO_4BYTE(__pdesc+12, 8, 1)
481#define GET_RX_DESC_BW(__pdesc) \
482 LE_BITS_TO_4BYTE(__pdesc+12, 9, 1)
483#define GET_RX_DESC_HTC(__pdesc) \
484 LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
485#define GET_RX_STATUS_DESC_EOSP(__pdesc) \
486 LE_BITS_TO_4BYTE(__pdesc+12, 11, 1)
487#define GET_RX_STATUS_DESC_BSSID_FIT(__pdesc) \
488 LE_BITS_TO_4BYTE(__pdesc+12, 12, 2)
489#define GET_RX_STATUS_DESC_RPT_SEL(__pdesc) \
490 LE_BITS_TO_4BYTE(__pdesc+12, 14, 2)
491
492#define GET_RX_STATUS_DESC_PATTERN_MATCH(__pdesc) \
493 LE_BITS_TO_4BYTE(__pdesc+12, 29, 1)
494#define GET_RX_STATUS_DESC_UNICAST_MATCH(__pdesc) \
495 LE_BITS_TO_4BYTE(__pdesc+12, 30, 1)
496#define GET_RX_STATUS_DESC_MAGIC_MATCH(__pdesc) \
497 LE_BITS_TO_4BYTE(__pdesc+12, 31, 1)
498
499#define GET_RX_DESC_IV1(__pdesc) \
500 LE_BITS_TO_4BYTE(__pdesc+16, 0, 32)
501#define GET_RX_DESC_TSFL(__pdesc) \
502 LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
503
504#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
505 LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
506#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
507 LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
508
509#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
510 SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
511#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
512 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
513
514/* TX report 2 format in Rx desc*/
515
516#define GET_RX_RPT2_DESC_PKT_LEN(__status) \
517 LE_BITS_TO_4BYTE(__status, 0, 9)
518#define GET_RX_RPT2_DESC_MACID_VALID_1(__status) \
519 LE_BITS_TO_4BYTE(__status+16, 0, 32)
520#define GET_RX_RPT2_DESC_MACID_VALID_2(__status) \
521 LE_BITS_TO_4BYTE(__status+20, 0, 32)
522
523#define SET_EARLYMODE_PKTNUM(__paddr, __value) \
524 SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __value)
525#define SET_EARLYMODE_LEN0(__paddr, __value) \
526 SET_BITS_TO_LE_4BYTE(__paddr, 4, 12, __value)
527#define SET_EARLYMODE_LEN1(__paddr, __value) \
528 SET_BITS_TO_LE_4BYTE(__paddr, 16, 12, __value)
529#define SET_EARLYMODE_LEN2_1(__paddr, __value) \
530 SET_BITS_TO_LE_4BYTE(__paddr, 28, 4, __value)
531#define SET_EARLYMODE_LEN2_2(__paddr, __value) \
532 SET_BITS_TO_LE_4BYTE(__paddr+4, 0, 8, __value)
533#define SET_EARLYMODE_LEN3(__paddr, __value) \
534 SET_BITS_TO_LE_4BYTE(__paddr+4, 8, 12, __value)
535#define SET_EARLYMODE_LEN4(__paddr, __value) \
536 SET_BITS_TO_LE_4BYTE(__paddr+4, 20, 12, __value)
537
538#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
539do { \
540 if (_size > TX_DESC_NEXT_DESC_OFFSET) \
541 memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
542 else \
543 memset(__pdesc, 0, _size); \
544} while (0)
545
546#define RTL8188_RX_HAL_IS_CCK_RATE(rxmcs)\
547 (rxmcs == DESC92C_RATE1M ||\
548 rxmcs == DESC92C_RATE2M ||\
549 rxmcs == DESC92C_RATE5_5M ||\
550 rxmcs == DESC92C_RATE11M)
551
552struct phy_rx_agc_info_t {
553 #if __LITTLE_ENDIAN
554 u8 gain:7, trsw:1;
555 #else
556 u8 trsw:1, gain:7;
557 #endif
558};
559struct phy_status_rpt {
560 struct phy_rx_agc_info_t path_agc[2];
561 u8 ch_corr[2];
562 u8 cck_sig_qual_ofdm_pwdb_all;
563 u8 cck_agc_rpt_ofdm_cfosho_a;
564 u8 cck_rpt_b_ofdm_cfosho_b;
565 u8 rsvd_1;
566 u8 noise_power_db_msb;
567 u8 path_cfotail[2];
568 u8 pcts_mask[2];
569 u8 stream_rxevm[2];
570 u8 path_rxsnr[2];
571 u8 noise_power_db_lsb;
572 u8 rsvd_2[3];
573 u8 stream_csi[2];
574 u8 stream_target_csi[2];
575 u8 sig_evm;
576 u8 rsvd_3;
577#if __LITTLE_ENDIAN
578 u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
579 u8 sgi_en:1;
580 u8 rxsc:2;
581 u8 idle_long:1;
582 u8 r_ant_train_en:1;
583 u8 ant_sel_b:1;
584 u8 ant_sel:1;
585#else /* _BIG_ENDIAN_ */
586 u8 ant_sel:1;
587 u8 ant_sel_b:1;
588 u8 r_ant_train_en:1;
589 u8 idle_long:1;
590 u8 rxsc:2;
591 u8 sgi_en:1;
592 u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
593#endif
594} __packed;
595
596struct rx_fwinfo_88e {
597 u8 gain_trsw[4];
598 u8 pwdb_all;
599 u8 cfosho[4];
600 u8 cfotail[4];
601 char rxevm[2];
602 char rxsnr[4];
603 u8 pdsnr[2];
604 u8 csi_current[2];
605 u8 csi_target[2];
606 u8 sigevm;
607 u8 max_ex_pwr;
608 u8 ex_intf_flag:1;
609 u8 sgi_en:1;
610 u8 rxsc:2;
611 u8 reserve:4;
612} __packed;
613
614struct tx_desc_88e {
615 u32 pktsize:16;
616 u32 offset:8;
617 u32 bmc:1;
618 u32 htc:1;
619 u32 lastseg:1;
620 u32 firstseg:1;
621 u32 linip:1;
622 u32 noacm:1;
623 u32 gf:1;
624 u32 own:1;
625
626 u32 macid:6;
627 u32 rsvd0:2;
628 u32 queuesel:5;
629 u32 rd_nav_ext:1;
630 u32 lsig_txop_en:1;
631 u32 pifs:1;
632 u32 rateid:4;
633 u32 nav_usehdr:1;
634 u32 en_descid:1;
635 u32 sectype:2;
636 u32 pktoffset:8;
637
638 u32 rts_rc:6;
639 u32 data_rc:6;
640 u32 agg_en:1;
641 u32 rdg_en:1;
642 u32 bar_retryht:2;
643 u32 agg_break:1;
644 u32 morefrag:1;
645 u32 raw:1;
646 u32 ccx:1;
647 u32 ampdudensity:3;
648 u32 bt_int:1;
649 u32 ant_sela:1;
650 u32 ant_selb:1;
651 u32 txant_cck:2;
652 u32 txant_l:2;
653 u32 txant_ht:2;
654
655 u32 nextheadpage:8;
656 u32 tailpage:8;
657 u32 seq:12;
658 u32 cpu_handle:1;
659 u32 tag1:1;
660 u32 trigger_int:1;
661 u32 hwseq_en:1;
662
663 u32 rtsrate:5;
664 u32 apdcfe:1;
665 u32 qos:1;
666 u32 hwseq_ssn:1;
667 u32 userrate:1;
668 u32 dis_rtsfb:1;
669 u32 dis_datafb:1;
670 u32 cts2self:1;
671 u32 rts_en:1;
672 u32 hwrts_en:1;
673 u32 portid:1;
674 u32 pwr_status:3;
675 u32 waitdcts:1;
676 u32 cts2ap_en:1;
677 u32 txsc:2;
678 u32 stbc:2;
679 u32 txshort:1;
680 u32 txbw:1;
681 u32 rtsshort:1;
682 u32 rtsbw:1;
683 u32 rtssc:2;
684 u32 rtsstbc:2;
685
686 u32 txrate:6;
687 u32 shortgi:1;
688 u32 ccxt:1;
689 u32 txrate_fb_lmt:5;
690 u32 rtsrate_fb_lmt:4;
691 u32 retrylmt_en:1;
692 u32 txretrylmt:6;
693 u32 usb_txaggnum:8;
694
695 u32 txagca:5;
696 u32 txagcb:5;
697 u32 usemaxlen:1;
698 u32 maxaggnum:5;
699 u32 mcsg1maxlen:4;
700 u32 mcsg2maxlen:4;
701 u32 mcsg3maxlen:4;
702 u32 mcs7sgimaxlen:4;
703
704 u32 txbuffersize:16;
705 u32 sw_offset30:8;
706 u32 sw_offset31:4;
707 u32 rsvd1:1;
708 u32 antsel_c:1;
709 u32 null_0:1;
710 u32 null_1:1;
711
712 u32 txbuffaddr;
713 u32 txbufferaddr64;
714 u32 nextdescaddress;
715 u32 nextdescaddress64;
716
717 u32 reserve_pass_pcie_mm_limit[4];
718} __packed;
719
720struct rx_desc_88e {
721 u32 length:14;
722 u32 crc32:1;
723 u32 icverror:1;
724 u32 drv_infosize:4;
725 u32 security:3;
726 u32 qos:1;
727 u32 shift:2;
728 u32 phystatus:1;
729 u32 swdec:1;
730 u32 lastseg:1;
731 u32 firstseg:1;
732 u32 eor:1;
733 u32 own:1;
734
735 u32 macid:6;
736 u32 tid:4;
737 u32 hwrsvd:5;
738 u32 paggr:1;
739 u32 faggr:1;
740 u32 a1_fit:4;
741 u32 a2_fit:4;
742 u32 pam:1;
743 u32 pwr:1;
744 u32 moredata:1;
745 u32 morefrag:1;
746 u32 type:2;
747 u32 mc:1;
748 u32 bc:1;
749
750 u32 seq:12;
751 u32 frag:4;
752 u32 nextpktlen:14;
753 u32 nextind:1;
754 u32 rsvd:1;
755
756 u32 rxmcs:6;
757 u32 rxht:1;
758 u32 amsdu:1;
759 u32 splcp:1;
760 u32 bandwidth:1;
761 u32 htc:1;
762 u32 tcpchk_rpt:1;
763 u32 ipcchk_rpt:1;
764 u32 tcpchk_valid:1;
765 u32 hwpcerr:1;
766 u32 hwpcind:1;
767 u32 iv0:16;
768
769 u32 iv1;
770
771 u32 tsfl;
772
773 u32 bufferaddress;
774 u32 bufferaddress64;
775
776} __packed;
777
778void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw,
779 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
780 struct ieee80211_tx_info *info,
781 struct ieee80211_sta *sta,
782 struct sk_buff *skb,
783 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc);
784bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,
785 struct rtl_stats *status,
786 struct ieee80211_rx_status *rx_status,
787 u8 *pdesc, struct sk_buff *skb);
788void rtl88ee_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
789u32 rtl88ee_get_desc(u8 *pdesc, bool istx, u8 desc_name);
790void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
791void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
792 bool b_firstseg, bool b_lastseg,
793 struct sk_buff *skb);
794
795#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
index b793a659a465..926e2a34c766 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
@@ -174,8 +174,8 @@ static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
174 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; 174 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
175 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; 175 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
176 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; 176 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
177 dm_digtable->rx_gain_range_max = DM_DIG_MAX; 177 dm_digtable->rx_gain_max = DM_DIG_MAX;
178 dm_digtable->rx_gain_range_min = DM_DIG_MIN; 178 dm_digtable->rx_gain_min = DM_DIG_MIN;
179 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; 179 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
180 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; 180 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
181 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; 181 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
@@ -300,11 +300,11 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
300 } 300 }
301 301
302 if ((digtable->rssi_val_min + 10 - digtable->back_val) > 302 if ((digtable->rssi_val_min + 10 - digtable->back_val) >
303 digtable->rx_gain_range_max) 303 digtable->rx_gain_max)
304 digtable->cur_igvalue = digtable->rx_gain_range_max; 304 digtable->cur_igvalue = digtable->rx_gain_max;
305 else if ((digtable->rssi_val_min + 10 - 305 else if ((digtable->rssi_val_min + 10 -
306 digtable->back_val) < digtable->rx_gain_range_min) 306 digtable->back_val) < digtable->rx_gain_min)
307 digtable->cur_igvalue = digtable->rx_gain_range_min; 307 digtable->cur_igvalue = digtable->rx_gain_min;
308 else 308 else
309 digtable->cur_igvalue = digtable->rssi_val_min + 10 - 309 digtable->cur_igvalue = digtable->rssi_val_min + 10 -
310 digtable->back_val; 310 digtable->back_val;
@@ -1147,75 +1147,6 @@ void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1147} 1147}
1148EXPORT_SYMBOL(rtl92c_dm_init_rate_adaptive_mask); 1148EXPORT_SYMBOL(rtl92c_dm_init_rate_adaptive_mask);
1149 1149
1150static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
1151{
1152 struct rtl_priv *rtlpriv = rtl_priv(hw);
1153 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1154 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1155 struct rate_adaptive *p_ra = &(rtlpriv->ra);
1156 u32 low_rssi_thresh, high_rssi_thresh;
1157 struct ieee80211_sta *sta = NULL;
1158
1159 if (is_hal_stop(rtlhal)) {
1160 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1161 "<---- driver is going to unload\n");
1162 return;
1163 }
1164
1165 if (!rtlpriv->dm.useramask) {
1166 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1167 "<---- driver does not control rate adaptive mask\n");
1168 return;
1169 }
1170
1171 if (mac->link_state == MAC80211_LINKED &&
1172 mac->opmode == NL80211_IFTYPE_STATION) {
1173 switch (p_ra->pre_ratr_state) {
1174 case DM_RATR_STA_HIGH:
1175 high_rssi_thresh = 50;
1176 low_rssi_thresh = 20;
1177 break;
1178 case DM_RATR_STA_MIDDLE:
1179 high_rssi_thresh = 55;
1180 low_rssi_thresh = 20;
1181 break;
1182 case DM_RATR_STA_LOW:
1183 high_rssi_thresh = 50;
1184 low_rssi_thresh = 25;
1185 break;
1186 default:
1187 high_rssi_thresh = 50;
1188 low_rssi_thresh = 20;
1189 break;
1190 }
1191
1192 if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh)
1193 p_ra->ratr_state = DM_RATR_STA_HIGH;
1194 else if (rtlpriv->dm.undec_sm_pwdb > (long)low_rssi_thresh)
1195 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
1196 else
1197 p_ra->ratr_state = DM_RATR_STA_LOW;
1198
1199 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
1200 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld\n",
1201 rtlpriv->dm.undec_sm_pwdb);
1202 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1203 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
1204 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1205 "PreState = %d, CurState = %d\n",
1206 p_ra->pre_ratr_state, p_ra->ratr_state);
1207
1208 rcu_read_lock();
1209 sta = ieee80211_find_sta(mac->vif, mac->bssid);
1210 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1211 p_ra->ratr_state);
1212
1213 p_ra->pre_ratr_state = p_ra->ratr_state;
1214 rcu_read_unlock();
1215 }
1216 }
1217}
1218
1219static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) 1150static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1220{ 1151{
1221 struct rtl_priv *rtlpriv = rtl_priv(hw); 1152 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1437,6 +1368,9 @@ void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
1437 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, 1368 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1438 (u8 *) (&fw_ps_awake)); 1369 (u8 *) (&fw_ps_awake));
1439 1370
1371 if (ppsc->p2p_ps_info.p2p_ps_mode)
1372 fw_ps_awake = false;
1373
1440 if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) && 1374 if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) &&
1441 fw_ps_awake) 1375 fw_ps_awake)
1442 && (!ppsc->rfchange_inprogress)) { 1376 && (!ppsc->rfchange_inprogress)) {
@@ -1446,7 +1380,7 @@ void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
1446 rtl92c_dm_dynamic_bb_powersaving(hw); 1380 rtl92c_dm_dynamic_bb_powersaving(hw);
1447 rtl92c_dm_dynamic_txpower(hw); 1381 rtl92c_dm_dynamic_txpower(hw);
1448 rtl92c_dm_check_txpower_tracking(hw); 1382 rtl92c_dm_check_txpower_tracking(hw);
1449 rtl92c_dm_refresh_rate_adaptive_mask(hw); 1383 /* rtl92c_dm_refresh_rate_adaptive_mask(hw); */
1450 rtl92c_dm_bt_coexist(hw); 1384 rtl92c_dm_bt_coexist(hw);
1451 rtl92c_dm_check_edca_turbo(hw); 1385 rtl92c_dm_check_edca_turbo(hw);
1452 } 1386 }
@@ -1651,7 +1585,7 @@ static void rtl92c_bt_set_normal(struct ieee80211_hw *hw)
1651 } 1585 }
1652} 1586}
1653 1587
1654static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw) 1588static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw, u8 tmp1byte)
1655{ 1589{
1656 struct rtl_priv *rtlpriv = rtl_priv(hw); 1590 struct rtl_priv *rtlpriv = rtl_priv(hw);
1657 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); 1591 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
@@ -1673,9 +1607,9 @@ static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw)
1673 BT_RSSI_STATE_SPECIAL_LOW)) { 1607 BT_RSSI_STATE_SPECIAL_LOW)) {
1674 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); 1608 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
1675 } else if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) { 1609 } else if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) {
1676 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); 1610 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, tmp1byte);
1677 } else { 1611 } else {
1678 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); 1612 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, tmp1byte);
1679 } 1613 }
1680 } 1614 }
1681 1615
@@ -1726,12 +1660,17 @@ static void rtl92c_check_bt_change(struct ieee80211_hw *hw)
1726{ 1660{
1727 struct rtl_priv *rtlpriv = rtl_priv(hw); 1661 struct rtl_priv *rtlpriv = rtl_priv(hw);
1728 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); 1662 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1663 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1664 u8 tmp1byte = 0;
1729 1665
1666 if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version) &&
1667 rtlpcipriv->bt_coexist.bt_coexistence)
1668 tmp1byte |= BIT(5);
1730 if (rtlpcipriv->bt_coexist.bt_cur_state) { 1669 if (rtlpcipriv->bt_coexist.bt_cur_state) {
1731 if (rtlpcipriv->bt_coexist.bt_ant_isolation) 1670 if (rtlpcipriv->bt_coexist.bt_ant_isolation)
1732 rtl92c_bt_ant_isolation(hw); 1671 rtl92c_bt_ant_isolation(hw, tmp1byte);
1733 } else { 1672 } else {
1734 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); 1673 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, tmp1byte);
1735 rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0, 1674 rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0,
1736 rtlpcipriv->bt_coexist.bt_rfreg_origin_1e); 1675 rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
1737 1676
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index 883f23ae9519..04a41628ceed 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -552,7 +552,9 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
552 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); 552 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
553 553
554 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); 554 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
555 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); 555 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
556 (rtlpriv->mac80211.p2p) ?
557 ppsc->smart_ps : 1);
556 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, 558 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
557 ppsc->reg_max_lps_awakeintvl); 559 ppsc->reg_max_lps_awakeintvl);
558 560
@@ -808,3 +810,98 @@ void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
808 rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); 810 rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
809} 811}
810EXPORT_SYMBOL(rtl92c_set_fw_joinbss_report_cmd); 812EXPORT_SYMBOL(rtl92c_set_fw_joinbss_report_cmd);
813
814static void rtl92c_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
815{
816 u8 u1_ctwindow_period[1] = {ctwindow};
817
818 rtl92c_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
819}
820
821void rtl92c_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
822{
823 struct rtl_priv *rtlpriv = rtl_priv(hw);
824 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
825 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
826 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
827 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
828 u8 i;
829 u16 ctwindow;
830 u32 start_time, tsf_low;
831
832 switch (p2p_ps_state) {
833 case P2P_PS_DISABLE:
834 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
835 memset(p2p_ps_offload, 0, sizeof(struct p2p_ps_offload_t));
836 break;
837 case P2P_PS_ENABLE:
838 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
839 /* update CTWindow value. */
840 if (p2pinfo->ctwindow > 0) {
841 p2p_ps_offload->ctwindow_en = 1;
842 ctwindow = p2pinfo->ctwindow;
843 rtl92c_set_p2p_ctw_period_cmd(hw, ctwindow);
844 }
845 /* hw only support 2 set of NoA */
846 for (i = 0; i < p2pinfo->noa_num; i++) {
847 /* To control the register setting for which NOA*/
848 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
849 if (i == 0)
850 p2p_ps_offload->noa0_en = 1;
851 else
852 p2p_ps_offload->noa1_en = 1;
853
854 /* config P2P NoA Descriptor Register */
855 rtl_write_dword(rtlpriv, 0x5E0,
856 p2pinfo->noa_duration[i]);
857 rtl_write_dword(rtlpriv, 0x5E4,
858 p2pinfo->noa_interval[i]);
859
860 /*Get Current TSF value */
861 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
862
863 start_time = p2pinfo->noa_start_time[i];
864 if (p2pinfo->noa_count_type[i] != 1) {
865 while (start_time <= (tsf_low+(50*1024))) {
866 start_time += p2pinfo->noa_interval[i];
867 if (p2pinfo->noa_count_type[i] != 255)
868 p2pinfo->noa_count_type[i]--;
869 }
870 }
871 rtl_write_dword(rtlpriv, 0x5E8, start_time);
872 rtl_write_dword(rtlpriv, 0x5EC,
873 p2pinfo->noa_count_type[i]);
874 }
875
876 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
877 /* rst p2p circuit */
878 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
879
880 p2p_ps_offload->offload_en = 1;
881
882 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
883 p2p_ps_offload->role = 1;
884 p2p_ps_offload->allstasleep = 0;
885 } else {
886 p2p_ps_offload->role = 0;
887 }
888
889 p2p_ps_offload->discovery = 0;
890 }
891 break;
892 case P2P_PS_SCAN:
893 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
894 p2p_ps_offload->discovery = 1;
895 break;
896 case P2P_PS_SCAN_DONE:
897 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
898 p2p_ps_offload->discovery = 0;
899 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
900 break;
901 default:
902 break;
903 }
904
905 rtl92c_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
906}
907EXPORT_SYMBOL_GPL(rtl92c_set_p2p_ps_offload_cmd);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
index 780ea5b1e24c..15b2055e6212 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
@@ -67,6 +67,9 @@ enum rtl8192c_h2c_cmd {
67 H2C_RSVDPAGE = 3, 67 H2C_RSVDPAGE = 3,
68 H2C_RSSI_REPORT = 5, 68 H2C_RSSI_REPORT = 5,
69 H2C_RA_MASK = 6, 69 H2C_RA_MASK = 6,
70 H2C_MACID_PS_MODE = 7,
71 H2C_P2P_PS_OFFLOAD = 8,
72 H2C_P2P_PS_CTW_CMD = 32,
70 MAX_H2CCMD 73 MAX_H2CCMD
71}; 74};
72 75
@@ -95,5 +98,6 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
95void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); 98void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
96void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); 99void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
97void usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, void *data, u16 len); 100void usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, void *data, u16 len);
101void rtl92c_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
98 102
99#endif 103#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index 1b65db7fd651..a82b30a1996c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -475,6 +475,9 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
475 475
476 break; 476 break;
477 } 477 }
478 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
479 rtl92c_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
480 break;
478 case HW_VAR_AID:{ 481 case HW_VAR_AID:{
479 u16 u2btmp; 482 u16 u2btmp;
480 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); 483 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
@@ -505,6 +508,40 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
505 break; 508 break;
506 509
507 } 510 }
511 case HW_VAR_FW_LPS_ACTION: {
512 bool enter_fwlps = *((bool *)val);
513 u8 rpwm_val, fw_pwrmode;
514 bool fw_current_inps;
515
516 if (enter_fwlps) {
517 rpwm_val = 0x02; /* RF off */
518 fw_current_inps = true;
519 rtlpriv->cfg->ops->set_hw_reg(hw,
520 HW_VAR_FW_PSMODE_STATUS,
521 (u8 *)(&fw_current_inps));
522 rtlpriv->cfg->ops->set_hw_reg(hw,
523 HW_VAR_H2C_FW_PWRMODE,
524 (u8 *)(&ppsc->fwctrl_psmode));
525
526 rtlpriv->cfg->ops->set_hw_reg(hw,
527 HW_VAR_SET_RPWM,
528 (u8 *)(&rpwm_val));
529 } else {
530 rpwm_val = 0x0C; /* RF on */
531 fw_pwrmode = FW_PS_ACTIVE_MODE;
532 fw_current_inps = false;
533 rtlpriv->cfg->ops->set_hw_reg(hw,
534 HW_VAR_SET_RPWM,
535 (u8 *)(&rpwm_val));
536 rtlpriv->cfg->ops->set_hw_reg(hw,
537 HW_VAR_H2C_FW_PWRMODE,
538 (u8 *)(&fw_pwrmode));
539
540 rtlpriv->cfg->ops->set_hw_reg(hw,
541 HW_VAR_FW_PSMODE_STATUS,
542 (u8 *)(&fw_current_inps));
543 }
544 break; }
508 default: 545 default:
509 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 546 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
510 "switch case not processed\n"); 547 "switch case not processed\n");
@@ -1105,7 +1142,8 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
1105 type == NL80211_IFTYPE_STATION) { 1142 type == NL80211_IFTYPE_STATION) {
1106 _rtl92ce_stop_tx_beacon(hw); 1143 _rtl92ce_stop_tx_beacon(hw);
1107 _rtl92ce_enable_bcn_sub_func(hw); 1144 _rtl92ce_enable_bcn_sub_func(hw);
1108 } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) { 1145 } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP ||
1146 type == NL80211_IFTYPE_MESH_POINT) {
1109 _rtl92ce_resume_tx_beacon(hw); 1147 _rtl92ce_resume_tx_beacon(hw);
1110 _rtl92ce_disable_bcn_sub_func(hw); 1148 _rtl92ce_disable_bcn_sub_func(hw);
1111 } else { 1149 } else {
@@ -1137,6 +1175,11 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
1137 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1175 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1138 "Set Network type to AP!\n"); 1176 "Set Network type to AP!\n");
1139 break; 1177 break;
1178 case NL80211_IFTYPE_MESH_POINT:
1179 bt_msr |= MSR_ADHOC;
1180 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1181 "Set Network type to Mesh Point!\n");
1182 break;
1140 default: 1183 default:
1141 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1184 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1142 "Network type %d not supported!\n", type); 1185 "Network type %d not supported!\n", type);
@@ -1184,7 +1227,8 @@ int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
1184 return -EOPNOTSUPP; 1227 return -EOPNOTSUPP;
1185 1228
1186 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { 1229 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1187 if (type != NL80211_IFTYPE_AP) 1230 if (type != NL80211_IFTYPE_AP &&
1231 type != NL80211_IFTYPE_MESH_POINT)
1188 rtl92ce_set_check_bssid(hw, true); 1232 rtl92ce_set_check_bssid(hw, true);
1189 } else { 1233 } else {
1190 rtl92ce_set_check_bssid(hw, false); 1234 rtl92ce_set_check_bssid(hw, false);
@@ -1459,7 +1503,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1459 } 1503 }
1460 1504
1461 for (i = 0; i < 14; i++) { 1505 for (i = 0; i < 14; i++) {
1462 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1506 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1463 "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", 1507 "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
1464 rf_path, i, 1508 rf_path, i,
1465 rtlefuse->txpwrlevel_cck[rf_path][i], 1509 rtlefuse->txpwrlevel_cck[rf_path][i],
@@ -1500,11 +1544,11 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1500 & 0xf0) >> 4); 1544 & 0xf0) >> 4);
1501 } 1545 }
1502 1546
1503 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1547 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1504 "RF-%d pwrgroup_ht20[%d] = 0x%x\n", 1548 "RF-%d pwrgroup_ht20[%d] = 0x%x\n",
1505 rf_path, i, 1549 rf_path, i,
1506 rtlefuse->pwrgroup_ht20[rf_path][i]); 1550 rtlefuse->pwrgroup_ht20[rf_path][i]);
1507 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1551 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1508 "RF-%d pwrgroup_ht40[%d] = 0x%x\n", 1552 "RF-%d pwrgroup_ht40[%d] = 0x%x\n",
1509 rf_path, i, 1553 rf_path, i,
1510 rtlefuse->pwrgroup_ht40[rf_path][i]); 1554 rtlefuse->pwrgroup_ht40[rf_path][i]);
@@ -1545,19 +1589,19 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1545 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; 1589 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7];
1546 1590
1547 for (i = 0; i < 14; i++) 1591 for (i = 0; i < 14; i++)
1548 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1592 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1549 "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", 1593 "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
1550 i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); 1594 i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
1551 for (i = 0; i < 14; i++) 1595 for (i = 0; i < 14; i++)
1552 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1596 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1553 "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", 1597 "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
1554 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); 1598 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
1555 for (i = 0; i < 14; i++) 1599 for (i = 0; i < 14; i++)
1556 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1600 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1557 "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", 1601 "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
1558 i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); 1602 i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
1559 for (i = 0; i < 14; i++) 1603 for (i = 0; i < 14; i++)
1560 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1604 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1561 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", 1605 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
1562 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); 1606 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
1563 1607
@@ -1565,7 +1609,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1565 rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); 1609 rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
1566 else 1610 else
1567 rtlefuse->eeprom_regulatory = 0; 1611 rtlefuse->eeprom_regulatory = 0;
1568 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1612 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1569 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); 1613 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
1570 1614
1571 if (!autoload_fail) { 1615 if (!autoload_fail) {
@@ -1575,7 +1619,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1575 rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; 1619 rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI;
1576 rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; 1620 rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI;
1577 } 1621 }
1578 RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", 1622 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
1579 rtlefuse->eeprom_tssi[RF90_PATH_A], 1623 rtlefuse->eeprom_tssi[RF90_PATH_A],
1580 rtlefuse->eeprom_tssi[RF90_PATH_B]); 1624 rtlefuse->eeprom_tssi[RF90_PATH_B]);
1581 1625
@@ -1589,7 +1633,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1589 rtlefuse->apk_thermalmeterignore = true; 1633 rtlefuse->apk_thermalmeterignore = true;
1590 1634
1591 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; 1635 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
1592 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1636 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1593 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); 1637 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1594} 1638}
1595 1639
@@ -1629,6 +1673,21 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
1629 if (rtlefuse->autoload_failflag) 1673 if (rtlefuse->autoload_failflag)
1630 return; 1674 return;
1631 1675
1676 rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
1677 rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
1678 rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
1679 rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
1680 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1681 "EEPROMId = 0x%4x\n", eeprom_id);
1682 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1683 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
1684 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1685 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
1686 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1687 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
1688 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1689 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
1690
1632 for (i = 0; i < 6; i += 2) { 1691 for (i = 0; i < 6; i += 2) {
1633 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; 1692 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
1634 *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; 1693 *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
@@ -1766,6 +1825,9 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw,
1766 ratr_value = sta->supp_rates[1] << 4; 1825 ratr_value = sta->supp_rates[1] << 4;
1767 else 1826 else
1768 ratr_value = sta->supp_rates[0]; 1827 ratr_value = sta->supp_rates[0];
1828 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1829 ratr_value = 0xfff;
1830
1769 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | 1831 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
1770 sta->ht_cap.mcs.rx_mask[0] << 12); 1832 sta->ht_cap.mcs.rx_mask[0] << 12);
1771 switch (wirelessmode) { 1833 switch (wirelessmode) {
@@ -1860,7 +1922,8 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
1860 1922
1861 sta_entry = (struct rtl_sta_info *) sta->drv_priv; 1923 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
1862 wirelessmode = sta_entry->wireless_mode; 1924 wirelessmode = sta_entry->wireless_mode;
1863 if (mac->opmode == NL80211_IFTYPE_STATION) 1925 if (mac->opmode == NL80211_IFTYPE_STATION ||
1926 mac->opmode == NL80211_IFTYPE_MESH_POINT)
1864 curtxbw_40mhz = mac->bw_40; 1927 curtxbw_40mhz = mac->bw_40;
1865 else if (mac->opmode == NL80211_IFTYPE_AP || 1928 else if (mac->opmode == NL80211_IFTYPE_AP ||
1866 mac->opmode == NL80211_IFTYPE_ADHOC) 1929 mac->opmode == NL80211_IFTYPE_ADHOC)
@@ -1870,6 +1933,8 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
1870 ratr_bitmap = sta->supp_rates[1] << 4; 1933 ratr_bitmap = sta->supp_rates[1] << 4;
1871 else 1934 else
1872 ratr_bitmap = sta->supp_rates[0]; 1935 ratr_bitmap = sta->supp_rates[0];
1936 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1937 ratr_bitmap = 0xfff;
1873 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | 1938 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
1874 sta->ht_cap.mcs.rx_mask[0] << 12); 1939 sta->ht_cap.mcs.rx_mask[0] << 12);
1875 switch (wirelessmode) { 1940 switch (wirelessmode) {
@@ -2135,7 +2200,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
2135 macaddr = cam_const_broad; 2200 macaddr = cam_const_broad;
2136 entry_id = key_index; 2201 entry_id = key_index;
2137 } else { 2202 } else {
2138 if (mac->opmode == NL80211_IFTYPE_AP) { 2203 if (mac->opmode == NL80211_IFTYPE_AP ||
2204 mac->opmode == NL80211_IFTYPE_MESH_POINT) {
2139 entry_id = rtl_cam_get_free_entry(hw, 2205 entry_id = rtl_cam_get_free_entry(hw,
2140 p_macaddr); 2206 p_macaddr);
2141 if (entry_id >= TOTAL_CAM_ENTRY) { 2207 if (entry_id >= TOTAL_CAM_ENTRY) {
@@ -2157,7 +2223,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
2157 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 2223 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2158 "delete one entry, entry_id is %d\n", 2224 "delete one entry, entry_id is %d\n",
2159 entry_id); 2225 entry_id);
2160 if (mac->opmode == NL80211_IFTYPE_AP) 2226 if (mac->opmode == NL80211_IFTYPE_AP ||
2227 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2161 rtl_cam_del_entry(hw, p_macaddr); 2228 rtl_cam_del_entry(hw, p_macaddr);
2162 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); 2229 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2163 } else { 2230 } else {
@@ -2338,3 +2405,24 @@ void rtl92ce_suspend(struct ieee80211_hw *hw)
2338void rtl92ce_resume(struct ieee80211_hw *hw) 2405void rtl92ce_resume(struct ieee80211_hw *hw)
2339{ 2406{
2340} 2407}
2408
2409/* Turn on AAP (RCR:bit 0) for promicuous mode. */
2410void rtl92ce_allow_all_destaddr(struct ieee80211_hw *hw,
2411 bool allow_all_da, bool write_into_reg)
2412{
2413 struct rtl_priv *rtlpriv = rtl_priv(hw);
2414 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2415
2416 if (allow_all_da) {/* Set BIT0 */
2417 rtlpci->receive_config |= RCR_AAP;
2418 } else {/* Clear BIT0 */
2419 rtlpci->receive_config &= ~RCR_AAP;
2420 }
2421
2422 if (write_into_reg)
2423 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
2424
2425 RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
2426 "receive_config=0x%08X, write_into_reg=%d\n",
2427 rtlpci->receive_config, write_into_reg);
2428}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
index 52a3aea9b3de..2d063b0c7760 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
@@ -61,6 +61,8 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
61void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); 61void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
62void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw, 62void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
63 struct ieee80211_sta *sta, u8 rssi_level); 63 struct ieee80211_sta *sta, u8 rssi_level);
64void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
65 struct ieee80211_sta *sta, u8 rssi_level);
64void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw); 66void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw);
65bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); 67bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
66void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw); 68void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw);
@@ -74,5 +76,7 @@ void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw);
74void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw); 76void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw);
75void rtl92ce_suspend(struct ieee80211_hw *hw); 77void rtl92ce_suspend(struct ieee80211_hw *hw);
76void rtl92ce_resume(struct ieee80211_hw *hw); 78void rtl92ce_resume(struct ieee80211_hw *hw);
79void rtl92ce_allow_all_destaddr(struct ieee80211_hw *hw,
80 bool allow_all_da, bool write_into_reg);
77 81
78#endif 82#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
index e4d738f6166d..bd4aef74c056 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
@@ -544,6 +544,7 @@
544#define IMR_WLANOFF BIT(0) 544#define IMR_WLANOFF BIT(0)
545 545
546#define EFUSE_REAL_CONTENT_LEN 512 546#define EFUSE_REAL_CONTENT_LEN 512
547#define EFUSE_OOB_PROTECT_BYTES 15
547 548
548#define EEPROM_DEFAULT_TSSI 0x0 549#define EEPROM_DEFAULT_TSSI 0x0
549#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 550#define EEPROM_DEFAULT_TXPOWERDIFF 0x0
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index 49f663bd93ff..14203561b6ee 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -228,6 +228,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {
228 .enable_hw_sec = rtl92ce_enable_hw_security_config, 228 .enable_hw_sec = rtl92ce_enable_hw_security_config,
229 .set_key = rtl92ce_set_key, 229 .set_key = rtl92ce_set_key,
230 .init_sw_leds = rtl92ce_init_sw_leds, 230 .init_sw_leds = rtl92ce_init_sw_leds,
231 .allow_all_destaddr = rtl92ce_allow_all_destaddr,
231 .get_bbreg = rtl92c_phy_query_bb_reg, 232 .get_bbreg = rtl92c_phy_query_bb_reg,
232 .set_bbreg = rtl92c_phy_set_bb_reg, 233 .set_bbreg = rtl92c_phy_set_bb_reg,
233 .set_rfreg = rtl92ce_phy_set_rf_reg, 234 .set_rfreg = rtl92ce_phy_set_rf_reg,
@@ -278,6 +279,7 @@ static struct rtl_hal_cfg rtl92ce_hal_cfg = {
278 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, 279 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
279 .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, 280 .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
280 .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, 281 .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
282 .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
281 283
282 .maps[RWCAM] = REG_CAMCMD, 284 .maps[RWCAM] = REG_CAMCMD,
283 .maps[WCAMI] = REG_CAMWRITE, 285 .maps[WCAMI] = REG_CAMWRITE,
@@ -309,7 +311,7 @@ static struct rtl_hal_cfg rtl92ce_hal_cfg = {
309 311
310 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, 312 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
311 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, 313 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
312 .maps[RTL_IMR_BcnInt] = IMR_BCNINT, 314 .maps[RTL_IMR_BCNINT] = IMR_BCNINT,
313 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, 315 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
314 .maps[RTL_IMR_RDU] = IMR_RDU, 316 .maps[RTL_IMR_RDU] = IMR_RDU,
315 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, 317 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index b9b1a6e0b16e..65bf5fb97002 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -30,6 +30,7 @@
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../pci.h" 31#include "../pci.h"
32#include "../base.h" 32#include "../base.h"
33#include "../stats.h"
33#include "reg.h" 34#include "reg.h"
34#include "def.h" 35#include "def.h"
35#include "phy.h" 36#include "phy.h"
@@ -42,7 +43,7 @@ static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
42 43
43 if (unlikely(ieee80211_is_beacon(fc))) 44 if (unlikely(ieee80211_is_beacon(fc)))
44 return QSLT_BEACON; 45 return QSLT_BEACON;
45 if (ieee80211_is_mgmt(fc)) 46 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
46 return QSLT_MGNT; 47 return QSLT_MGNT;
47 48
48 return skb->priority; 49 return skb->priority;
@@ -78,16 +79,6 @@ static u8 _rtl92c_evm_db_to_percentage(char value)
78 return ret_val; 79 return ret_val;
79} 80}
80 81
81static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw,
82 u8 signal_strength_index)
83{
84 long signal_power;
85
86 signal_power = (long)((signal_strength_index + 1) >> 1);
87 signal_power -= 95;
88 return signal_power;
89}
90
91static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw, 82static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
92 long currsig) 83 long currsig)
93{ 84{
@@ -139,7 +130,6 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
139 pstats->packet_toself = packet_toself; 130 pstats->packet_toself = packet_toself;
140 pstats->is_cck = is_cck_rate; 131 pstats->is_cck = is_cck_rate;
141 pstats->packet_beacon = packet_beacon; 132 pstats->packet_beacon = packet_beacon;
142 pstats->is_cck = is_cck_rate;
143 pstats->rx_mimo_sig_qual[0] = -1; 133 pstats->rx_mimo_sig_qual[0] = -1;
144 pstats->rx_mimo_sig_qual[1] = -1; 134 pstats->rx_mimo_sig_qual[1] = -1;
145 135
@@ -192,10 +182,30 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
192 } 182 }
193 } 183 }
194 184
195 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); 185 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
186 /* CCK gain is smaller than OFDM/MCS gain,
187 * so we add gain diff by experiences,
188 * the val is 6
189 */
190 pwdb_all += 6;
191 if (pwdb_all > 100)
192 pwdb_all = 100;
193 /* modify the offset to make the same
194 * gain index with OFDM.
195 */
196 if (pwdb_all > 34 && pwdb_all <= 42)
197 pwdb_all -= 2;
198 else if (pwdb_all > 26 && pwdb_all <= 34)
199 pwdb_all -= 6;
200 else if (pwdb_all > 14 && pwdb_all <= 26)
201 pwdb_all -= 8;
202 else if (pwdb_all > 4 && pwdb_all <= 14)
203 pwdb_all -= 4;
204
196 pstats->rx_pwdb_all = pwdb_all; 205 pstats->rx_pwdb_all = pwdb_all;
197 pstats->recvsignalpower = rx_pwr_all; 206 pstats->recvsignalpower = rx_pwr_all;
198 207
208 /* (3) Get Signal Quality (EVM) */
199 if (packet_match_bssid) { 209 if (packet_match_bssid) {
200 u8 sq; 210 u8 sq;
201 if (pstats->rx_pwdb_all > 40) 211 if (pstats->rx_pwdb_all > 40)
@@ -217,29 +227,38 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
217 } else { 227 } else {
218 rtlpriv->dm.rfpath_rxenable[0] = 228 rtlpriv->dm.rfpath_rxenable[0] =
219 rtlpriv->dm.rfpath_rxenable[1] = true; 229 rtlpriv->dm.rfpath_rxenable[1] = true;
230 /* (1)Get RSSI for HT rate */
220 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { 231 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
232 /* we will judge RF RX path now. */
221 if (rtlpriv->dm.rfpath_rxenable[i]) 233 if (rtlpriv->dm.rfpath_rxenable[i])
222 rf_rx_num++; 234 rf_rx_num++;
223 235
224 rx_pwr[i] = 236 rx_pwr[i] =
225 ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110; 237 ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
238 /* Translate DBM to percentage. */
226 rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]); 239 rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
227 total_rssi += rssi; 240 total_rssi += rssi;
241 /* Get Rx snr value in DB */
228 rtlpriv->stats.rx_snr_db[i] = 242 rtlpriv->stats.rx_snr_db[i] =
229 (long)(p_drvinfo->rxsnr[i] / 2); 243 (long)(p_drvinfo->rxsnr[i] / 2);
230 244
245 /* Record Signal Strength for next packet */
231 if (packet_match_bssid) 246 if (packet_match_bssid)
232 pstats->rx_mimo_signalstrength[i] = (u8) rssi; 247 pstats->rx_mimo_signalstrength[i] = (u8) rssi;
233 } 248 }
234 249
250 /* (2)PWDB, Average PWDB cacluated by
251 * hardware (for rate adaptive)
252 */
235 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; 253 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
236 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); 254 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
237 pstats->rx_pwdb_all = pwdb_all; 255 pstats->rx_pwdb_all = pwdb_all;
238 pstats->rxpower = rx_pwr_all; 256 pstats->rxpower = rx_pwr_all;
239 pstats->recvsignalpower = rx_pwr_all; 257 pstats->recvsignalpower = rx_pwr_all;
240 258
241 if (pdesc->rxht && pdesc->rxmcs >= DESC92_RATEMCS8 && 259 /* (3)EVM of HT rate */
242 pdesc->rxmcs <= DESC92_RATEMCS15) 260 if (pstats->is_ht && pstats->rate >= DESC92_RATEMCS8 &&
261 pstats->rate <= DESC92_RATEMCS15)
243 max_spatial_stream = 2; 262 max_spatial_stream = 2;
244 else 263 else
245 max_spatial_stream = 1; 264 max_spatial_stream = 1;
@@ -248,6 +267,9 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
248 evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]); 267 evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
249 268
250 if (packet_match_bssid) { 269 if (packet_match_bssid) {
270 /* Fill value in RFD, Get the first
271 * spatial stream only
272 */
251 if (i == 0) 273 if (i == 0)
252 pstats->signalquality = 274 pstats->signalquality =
253 (u8) (evm & 0xff); 275 (u8) (evm & 0xff);
@@ -256,6 +278,9 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
256 } 278 }
257 } 279 }
258 280
281 /* UI BSS List signal strength(in percentage),
282 * make it good looking, from 0~100.
283 */
259 if (is_cck_rate) 284 if (is_cck_rate)
260 pstats->signalstrength = 285 pstats->signalstrength =
261 (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all)); 286 (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
@@ -265,215 +290,6 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
265 (hw, total_rssi /= rf_rx_num)); 290 (hw, total_rssi /= rf_rx_num));
266} 291}
267 292
268static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
269 struct rtl_stats *pstats)
270{
271 struct rtl_priv *rtlpriv = rtl_priv(hw);
272 struct rtl_phy *rtlphy = &(rtlpriv->phy);
273 u8 rfpath;
274 u32 last_rssi, tmpval;
275
276 if (pstats->packet_toself || pstats->packet_beacon) {
277 rtlpriv->stats.rssi_calculate_cnt++;
278
279 if (rtlpriv->stats.ui_rssi.total_num++ >=
280 PHY_RSSI_SLID_WIN_MAX) {
281
282 rtlpriv->stats.ui_rssi.total_num =
283 PHY_RSSI_SLID_WIN_MAX;
284 last_rssi =
285 rtlpriv->stats.ui_rssi.elements[rtlpriv->
286 stats.ui_rssi.index];
287 rtlpriv->stats.ui_rssi.total_val -= last_rssi;
288 }
289
290 rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
291 rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.
292 index++] =
293 pstats->signalstrength;
294
295 if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
296 rtlpriv->stats.ui_rssi.index = 0;
297
298 tmpval = rtlpriv->stats.ui_rssi.total_val /
299 rtlpriv->stats.ui_rssi.total_num;
300 rtlpriv->stats.signal_strength =
301 _rtl92ce_translate_todbm(hw, (u8) tmpval);
302 pstats->rssi = rtlpriv->stats.signal_strength;
303 }
304
305 if (!pstats->is_cck && pstats->packet_toself) {
306 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
307 rfpath++) {
308 if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
309 rtlpriv->stats.rx_rssi_percentage[rfpath] =
310 pstats->rx_mimo_signalstrength[rfpath];
311
312 }
313
314 if (pstats->rx_mimo_signalstrength[rfpath] >
315 rtlpriv->stats.rx_rssi_percentage[rfpath]) {
316 rtlpriv->stats.rx_rssi_percentage[rfpath] =
317 ((rtlpriv->stats.
318 rx_rssi_percentage[rfpath] *
319 (RX_SMOOTH_FACTOR - 1)) +
320 (pstats->rx_mimo_signalstrength[rfpath])) /
321 (RX_SMOOTH_FACTOR);
322
323 rtlpriv->stats.rx_rssi_percentage[rfpath] =
324 rtlpriv->stats.rx_rssi_percentage[rfpath] +
325 1;
326 } else {
327 rtlpriv->stats.rx_rssi_percentage[rfpath] =
328 ((rtlpriv->stats.
329 rx_rssi_percentage[rfpath] *
330 (RX_SMOOTH_FACTOR - 1)) +
331 (pstats->rx_mimo_signalstrength[rfpath])) /
332 (RX_SMOOTH_FACTOR);
333 }
334
335 }
336 }
337}
338
339static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw,
340 struct rtl_stats *pstats)
341{
342 struct rtl_priv *rtlpriv = rtl_priv(hw);
343 int weighting = 0;
344
345 if (rtlpriv->stats.recv_signal_power == 0)
346 rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
347
348 if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
349 weighting = 5;
350
351 else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
352 weighting = (-5);
353
354 rtlpriv->stats.recv_signal_power =
355 (rtlpriv->stats.recv_signal_power * 5 +
356 pstats->recvsignalpower + weighting) / 6;
357}
358
359static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw,
360 struct rtl_stats *pstats)
361{
362 struct rtl_priv *rtlpriv = rtl_priv(hw);
363 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
364 long undec_sm_pwdb;
365
366 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
367 return;
368 } else {
369 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
370 }
371
372 if (pstats->packet_toself || pstats->packet_beacon) {
373 if (undec_sm_pwdb < 0)
374 undec_sm_pwdb = pstats->rx_pwdb_all;
375
376 if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
377 undec_sm_pwdb = (((undec_sm_pwdb) *
378 (RX_SMOOTH_FACTOR - 1)) +
379 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
380
381 undec_sm_pwdb += 1;
382 } else {
383 undec_sm_pwdb = (((undec_sm_pwdb) *
384 (RX_SMOOTH_FACTOR - 1)) +
385 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
386 }
387
388 rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
389 _rtl92ce_update_rxsignalstatistics(hw, pstats);
390 }
391}
392
393static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw,
394 struct rtl_stats *pstats)
395{
396 struct rtl_priv *rtlpriv = rtl_priv(hw);
397 u32 last_evm, n_spatialstream, tmpval;
398
399 if (pstats->signalquality != 0) {
400 if (pstats->packet_toself || pstats->packet_beacon) {
401
402 if (rtlpriv->stats.ui_link_quality.total_num++ >=
403 PHY_LINKQUALITY_SLID_WIN_MAX) {
404 rtlpriv->stats.ui_link_quality.total_num =
405 PHY_LINKQUALITY_SLID_WIN_MAX;
406 last_evm =
407 rtlpriv->stats.
408 ui_link_quality.elements[rtlpriv->
409 stats.ui_link_quality.
410 index];
411 rtlpriv->stats.ui_link_quality.total_val -=
412 last_evm;
413 }
414
415 rtlpriv->stats.ui_link_quality.total_val +=
416 pstats->signalquality;
417 rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats.
418 ui_link_quality.
419 index++] =
420 pstats->signalquality;
421
422 if (rtlpriv->stats.ui_link_quality.index >=
423 PHY_LINKQUALITY_SLID_WIN_MAX)
424 rtlpriv->stats.ui_link_quality.index = 0;
425
426 tmpval = rtlpriv->stats.ui_link_quality.total_val /
427 rtlpriv->stats.ui_link_quality.total_num;
428 rtlpriv->stats.signal_quality = tmpval;
429
430 rtlpriv->stats.last_sigstrength_inpercent = tmpval;
431
432 for (n_spatialstream = 0; n_spatialstream < 2;
433 n_spatialstream++) {
434 if (pstats->
435 rx_mimo_sig_qual[n_spatialstream] != -1) {
436 if (rtlpriv->stats.
437 rx_evm_percentage[n_spatialstream]
438 == 0) {
439 rtlpriv->stats.
440 rx_evm_percentage
441 [n_spatialstream] =
442 pstats->rx_mimo_sig_qual
443 [n_spatialstream];
444 }
445
446 rtlpriv->stats.
447 rx_evm_percentage[n_spatialstream] =
448 ((rtlpriv->
449 stats.rx_evm_percentage
450 [n_spatialstream] *
451 (RX_SMOOTH_FACTOR - 1)) +
452 (pstats->rx_mimo_sig_qual
453 [n_spatialstream] * 1)) /
454 (RX_SMOOTH_FACTOR);
455 }
456 }
457 }
458 } else {
459 ;
460 }
461}
462
463static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw,
464 u8 *buffer,
465 struct rtl_stats *pcurrent_stats)
466{
467
468 if (!pcurrent_stats->packet_matchbssid &&
469 !pcurrent_stats->packet_beacon)
470 return;
471
472 _rtl92ce_process_ui_rssi(hw, pcurrent_stats);
473 _rtl92ce_process_pwdb(hw, pcurrent_stats);
474 _rtl92ce_process_ui_link_quality(hw, pcurrent_stats);
475}
476
477static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, 293static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
478 struct sk_buff *skb, 294 struct sk_buff *skb,
479 struct rtl_stats *pstats, 295 struct rtl_stats *pstats,
@@ -516,7 +332,7 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
516 packet_matchbssid, packet_toself, 332 packet_matchbssid, packet_toself,
517 packet_beacon); 333 packet_beacon);
518 334
519 _rtl92ce_process_phyinfo(hw, tmp_buf, pstats); 335 rtl_process_phyinfo(hw, tmp_buf, pstats);
520} 336}
521 337
522bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, 338bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
@@ -526,7 +342,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
526{ 342{
527 struct rx_fwinfo_92c *p_drvinfo; 343 struct rx_fwinfo_92c *p_drvinfo;
528 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; 344 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
529 345 struct ieee80211_hdr *hdr;
530 u32 phystatus = GET_RX_DESC_PHYST(pdesc); 346 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
531 stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); 347 stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
532 stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * 348 stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
@@ -539,37 +355,60 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
539 stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc); 355 stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
540 stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); 356 stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
541 stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); 357 stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
542 stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) 358 stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
543 && (GET_RX_DESC_FAGGR(pdesc) == 1)); 359 && (GET_RX_DESC_FAGGR(pdesc) == 1));
544 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); 360 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
545 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); 361 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
362 stats->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
363
364 stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc);
546 365
547 rx_status->freq = hw->conf.channel->center_freq; 366 rx_status->freq = hw->conf.channel->center_freq;
548 rx_status->band = hw->conf.channel->band; 367 rx_status->band = hw->conf.channel->band;
549 368
550 if (GET_RX_DESC_CRC32(pdesc)) 369 hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
551 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; 370 + stats->rx_bufshift);
552 371
553 if (!GET_RX_DESC_SWDEC(pdesc)) 372 if (stats->crc)
554 rx_status->flag |= RX_FLAG_DECRYPTED; 373 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
555 374
556 if (GET_RX_DESC_BW(pdesc)) 375 if (stats->rx_is40Mhzpacket)
557 rx_status->flag |= RX_FLAG_40MHZ; 376 rx_status->flag |= RX_FLAG_40MHZ;
558 377
559 if (GET_RX_DESC_RXHT(pdesc)) 378 if (stats->is_ht)
560 rx_status->flag |= RX_FLAG_HT; 379 rx_status->flag |= RX_FLAG_HT;
561 380
562 rx_status->flag |= RX_FLAG_MACTIME_START; 381 rx_status->flag |= RX_FLAG_MACTIME_START;
563 382
564 if (stats->decrypted) 383 /* hw will set stats->decrypted true, if it finds the
565 rx_status->flag |= RX_FLAG_DECRYPTED; 384 * frame is open data frame or mgmt frame.
566 385 * So hw will not decryption robust managment frame
386 * for IEEE80211w but still set status->decrypted
387 * true, so here we should set it back to undecrypted
388 * for IEEE80211w frame, and mac80211 sw will help
389 * to decrypt it
390 */
391 if (stats->decrypted) {
392 if (!hdr) {
393 /* In testing, hdr was NULL here */
394 return false;
395 }
396 if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
397 (ieee80211_has_protected(hdr->frame_control)))
398 rx_status->flag &= ~RX_FLAG_DECRYPTED;
399 else
400 rx_status->flag |= RX_FLAG_DECRYPTED;
401 }
402 /* rate_idx: index of data rate into band's
403 * supported rates or MCS index if HT rates
404 * are use (RX_FLAG_HT)
405 * Notice: this is diff with windows define
406 */
567 rx_status->rate_idx = rtlwifi_rate_mapping(hw, 407 rx_status->rate_idx = rtlwifi_rate_mapping(hw,
568 (bool)GET_RX_DESC_RXHT(pdesc), 408 stats->is_ht, stats->rate,
569 (u8)GET_RX_DESC_RXMCS(pdesc), 409 stats->isfirst_ampdu);
570 (bool)GET_RX_DESC_PAGGR(pdesc));
571 410
572 rx_status->mactime = GET_RX_DESC_TSFL(pdesc); 411 rx_status->mactime = stats->timestamp_low;
573 if (phystatus) { 412 if (phystatus) {
574 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + 413 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
575 stats->rx_bufshift); 414 stats->rx_bufshift);
@@ -580,7 +419,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
580 } 419 }
581 420
582 /*rx_status->qual = stats->signal; */ 421 /*rx_status->qual = stats->signal; */
583 rx_status->signal = stats->rssi + 10; 422 rx_status->signal = stats->recvsignalpower + 10;
584 /*rx_status->noise = -stats->noise; */ 423 /*rx_status->noise = -stats->noise; */
585 424
586 return true; 425 return true;
@@ -624,7 +463,8 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
624 if (mac->opmode == NL80211_IFTYPE_STATION) { 463 if (mac->opmode == NL80211_IFTYPE_STATION) {
625 bw_40 = mac->bw_40; 464 bw_40 = mac->bw_40;
626 } else if (mac->opmode == NL80211_IFTYPE_AP || 465 } else if (mac->opmode == NL80211_IFTYPE_AP ||
627 mac->opmode == NL80211_IFTYPE_ADHOC) { 466 mac->opmode == NL80211_IFTYPE_ADHOC ||
467 mac->opmode == NL80211_IFTYPE_MESH_POINT) {
628 if (sta) 468 if (sta)
629 bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40; 469 bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
630 } 470 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index c08d0f4c5f3d..3d0498e69c8c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -202,7 +202,7 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
202 } 202 }
203 } 203 }
204 for (i = 0; i < 14; i++) { 204 for (i = 0; i < 14; i++) {
205 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 205 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
206 "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i, 206 "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i,
207 rtlefuse->txpwrlevel_cck[rf_path][i], 207 rtlefuse->txpwrlevel_cck[rf_path][i],
208 rtlefuse->txpwrlevel_ht40_1s[rf_path][i], 208 rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
@@ -238,11 +238,11 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
238 ((rtlefuse->eeprom_pwrlimit_ht40[index] 238 ((rtlefuse->eeprom_pwrlimit_ht40[index]
239 & 0xf0) >> 4); 239 & 0xf0) >> 4);
240 } 240 }
241 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 241 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
242 "RF-%d pwrgroup_ht20[%d] = 0x%x\n", 242 "RF-%d pwrgroup_ht20[%d] = 0x%x\n",
243 rf_path, i, 243 rf_path, i,
244 rtlefuse->pwrgroup_ht20[rf_path][i]); 244 rtlefuse->pwrgroup_ht20[rf_path][i]);
245 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 245 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
246 "RF-%d pwrgroup_ht40[%d] = 0x%x\n", 246 "RF-%d pwrgroup_ht40[%d] = 0x%x\n",
247 rf_path, i, 247 rf_path, i,
248 rtlefuse->pwrgroup_ht40[rf_path][i]); 248 rtlefuse->pwrgroup_ht40[rf_path][i]);
@@ -273,26 +273,26 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
273 rtlefuse->legacy_ht_txpowerdiff = 273 rtlefuse->legacy_ht_txpowerdiff =
274 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; 274 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7];
275 for (i = 0; i < 14; i++) 275 for (i = 0; i < 14; i++)
276 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 276 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
277 "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", 277 "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
278 i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); 278 i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
279 for (i = 0; i < 14; i++) 279 for (i = 0; i < 14; i++)
280 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 280 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
281 "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", 281 "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
282 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); 282 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
283 for (i = 0; i < 14; i++) 283 for (i = 0; i < 14; i++)
284 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 284 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
285 "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", 285 "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
286 i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); 286 i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
287 for (i = 0; i < 14; i++) 287 for (i = 0; i < 14; i++)
288 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 288 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
289 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", 289 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
290 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); 290 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
291 if (!autoload_fail) 291 if (!autoload_fail)
292 rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); 292 rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
293 else 293 else
294 rtlefuse->eeprom_regulatory = 0; 294 rtlefuse->eeprom_regulatory = 0;
295 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 295 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
296 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); 296 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
297 if (!autoload_fail) { 297 if (!autoload_fail) {
298 rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; 298 rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
@@ -301,7 +301,7 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
301 rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; 301 rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI;
302 rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; 302 rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI;
303 } 303 }
304 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 304 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
305 "TSSI_A = 0x%x, TSSI_B = 0x%x\n", 305 "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
306 rtlefuse->eeprom_tssi[RF90_PATH_A], 306 rtlefuse->eeprom_tssi[RF90_PATH_A],
307 rtlefuse->eeprom_tssi[RF90_PATH_B]); 307 rtlefuse->eeprom_tssi[RF90_PATH_B]);
@@ -316,7 +316,7 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
316 if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) 316 if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail)
317 rtlefuse->apk_thermalmeterignore = true; 317 rtlefuse->apk_thermalmeterignore = true;
318 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; 318 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
319 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 319 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
320 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); 320 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
321} 321}
322 322
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index a73a17bc56dd..23d640a4debd 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -223,7 +223,7 @@ static struct rtl_hal_cfg rtl92cu_hal_cfg = {
223 223
224 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, 224 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
225 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, 225 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
226 .maps[RTL_IMR_BcnInt] = IMR_BCNINT, 226 .maps[RTL_IMR_BCNINT] = IMR_BCNINT,
227 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, 227 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
228 .maps[RTL_IMR_RDU] = IMR_RDU, 228 .maps[RTL_IMR_RDU] = IMR_RDU,
229 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, 229 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index b6222eedb835..710f7904ecdf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -434,7 +434,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
434 (u32)hdr->addr1[2], (u32)hdr->addr1[3], 434 (u32)hdr->addr1[2], (u32)hdr->addr1[3],
435 (u32)hdr->addr1[4], (u32)hdr->addr1[5]); 435 (u32)hdr->addr1[4], (u32)hdr->addr1[5]);
436 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status)); 436 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
437 ieee80211_rx_irqsafe(hw, skb); 437 ieee80211_rx(hw, skb);
438} 438}
439 439
440void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb) 440void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
index 5251fb8a111e..19a765532603 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
@@ -171,8 +171,8 @@ static void rtl92d_dm_diginit(struct ieee80211_hw *hw)
171 de_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; 171 de_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
172 de_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; 172 de_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
173 de_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; 173 de_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
174 de_digtable->rx_gain_range_max = DM_DIG_FA_UPPER; 174 de_digtable->rx_gain_max = DM_DIG_FA_UPPER;
175 de_digtable->rx_gain_range_min = DM_DIG_FA_LOWER; 175 de_digtable->rx_gain_min = DM_DIG_FA_LOWER;
176 de_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; 176 de_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
177 de_digtable->back_range_max = DM_DIG_BACKOFF_MAX; 177 de_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
178 de_digtable->back_range_min = DM_DIG_BACKOFF_MIN; 178 de_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
@@ -444,8 +444,8 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
444 "dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n", 444 "dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n",
445 de_digtable->large_fa_hit, de_digtable->forbidden_igi); 445 de_digtable->large_fa_hit, de_digtable->forbidden_igi);
446 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, 446 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
447 "dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n", 447 "dm_DIG() Before: Recover_cnt=%d, rx_gain_min=%x\n",
448 de_digtable->recover_cnt, de_digtable->rx_gain_range_min); 448 de_digtable->recover_cnt, de_digtable->rx_gain_min);
449 449
450 /* deal with abnorally large false alarm */ 450 /* deal with abnorally large false alarm */
451 if (falsealm_cnt->cnt_all > 10000) { 451 if (falsealm_cnt->cnt_all > 10000) {
@@ -459,9 +459,9 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
459 } 459 }
460 if (de_digtable->large_fa_hit >= 3) { 460 if (de_digtable->large_fa_hit >= 3) {
461 if ((de_digtable->forbidden_igi + 1) > DM_DIG_MAX) 461 if ((de_digtable->forbidden_igi + 1) > DM_DIG_MAX)
462 de_digtable->rx_gain_range_min = DM_DIG_MAX; 462 de_digtable->rx_gain_min = DM_DIG_MAX;
463 else 463 else
464 de_digtable->rx_gain_range_min = 464 de_digtable->rx_gain_min =
465 (de_digtable->forbidden_igi + 1); 465 (de_digtable->forbidden_igi + 1);
466 de_digtable->recover_cnt = 3600; /* 3600=2hr */ 466 de_digtable->recover_cnt = 3600; /* 3600=2hr */
467 } 467 }
@@ -475,12 +475,12 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
475 DM_DIG_FA_LOWER) { 475 DM_DIG_FA_LOWER) {
476 de_digtable->forbidden_igi = 476 de_digtable->forbidden_igi =
477 DM_DIG_FA_LOWER; 477 DM_DIG_FA_LOWER;
478 de_digtable->rx_gain_range_min = 478 de_digtable->rx_gain_min =
479 DM_DIG_FA_LOWER; 479 DM_DIG_FA_LOWER;
480 480
481 } else { 481 } else {
482 de_digtable->forbidden_igi--; 482 de_digtable->forbidden_igi--;
483 de_digtable->rx_gain_range_min = 483 de_digtable->rx_gain_min =
484 (de_digtable->forbidden_igi + 1); 484 (de_digtable->forbidden_igi + 1);
485 } 485 }
486 } else if (de_digtable->large_fa_hit == 3) { 486 } else if (de_digtable->large_fa_hit == 3) {
@@ -492,13 +492,13 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
492 "dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n", 492 "dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n",
493 de_digtable->large_fa_hit, de_digtable->forbidden_igi); 493 de_digtable->large_fa_hit, de_digtable->forbidden_igi);
494 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, 494 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
495 "dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n", 495 "dm_DIG() After: recover_cnt=%d, rx_gain_min=%x\n",
496 de_digtable->recover_cnt, de_digtable->rx_gain_range_min); 496 de_digtable->recover_cnt, de_digtable->rx_gain_min);
497 497
498 if (value_igi > DM_DIG_MAX) 498 if (value_igi > DM_DIG_MAX)
499 value_igi = DM_DIG_MAX; 499 value_igi = DM_DIG_MAX;
500 else if (value_igi < de_digtable->rx_gain_range_min) 500 else if (value_igi < de_digtable->rx_gain_min)
501 value_igi = de_digtable->rx_gain_range_min; 501 value_igi = de_digtable->rx_gain_min;
502 de_digtable->cur_igvalue = value_igi; 502 de_digtable->cur_igvalue = value_igi;
503 rtl92d_dm_write_dig(hw); 503 rtl92d_dm_write_dig(hw);
504 if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) 504 if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G)
@@ -1071,9 +1071,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
1071 } 1071 }
1072 ele_d = (ofdmswing_table[(u8) ofdm_index[0]] & 1072 ele_d = (ofdmswing_table[(u8) ofdm_index[0]] &
1073 0xFFC00000) >> 22; 1073 0xFFC00000) >> 22;
1074 val_x = rtlphy->iqk_matrix_regsetting 1074 val_x = rtlphy->iqk_matrix
1075 [indexforchannel].value[0][0]; 1075 [indexforchannel].value[0][0];
1076 val_y = rtlphy->iqk_matrix_regsetting 1076 val_y = rtlphy->iqk_matrix
1077 [indexforchannel].value[0][1]; 1077 [indexforchannel].value[0][1];
1078 if (val_x != 0) { 1078 if (val_x != 0) {
1079 if ((val_x & 0x00000200) != 0) 1079 if ((val_x & 0x00000200) != 0)
@@ -1175,9 +1175,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
1175 if (is2t) { 1175 if (is2t) {
1176 ele_d = (ofdmswing_table[(u8) ofdm_index[1]] & 1176 ele_d = (ofdmswing_table[(u8) ofdm_index[1]] &
1177 0xFFC00000) >> 22; 1177 0xFFC00000) >> 22;
1178 val_x = rtlphy->iqk_matrix_regsetting 1178 val_x = rtlphy->iqk_matrix
1179 [indexforchannel].value[0][4]; 1179 [indexforchannel].value[0][4];
1180 val_y = rtlphy->iqk_matrix_regsetting 1180 val_y = rtlphy->iqk_matrix
1181 [indexforchannel].value[0][5]; 1181 [indexforchannel].value[0][5];
1182 if (val_x != 0) { 1182 if (val_x != 0) {
1183 if ((val_x & 0x00000200) != 0) 1183 if ((val_x & 0x00000200) != 0)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index aa5b42521bb4..7dd8f6de0550 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -1183,7 +1183,7 @@ void rtl92d_linked_set_reg(struct ieee80211_hw *hw)
1183 u8 channel = rtlphy->current_channel; 1183 u8 channel = rtlphy->current_channel;
1184 1184
1185 indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); 1185 indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
1186 if (!rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done) { 1186 if (!rtlphy->iqk_matrix[indexforchannel].iqk_done) {
1187 RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG, 1187 RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG,
1188 "Do IQK for channel:%d\n", channel); 1188 "Do IQK for channel:%d\n", channel);
1189 rtl92d_phy_iq_calibrate(hw); 1189 rtl92d_phy_iq_calibrate(hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
index 33041bd4da81..840bac5fa2f8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
@@ -2479,9 +2479,9 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
2479 rtlphy->current_channel); 2479 rtlphy->current_channel);
2480 2480
2481 for (i = 0; i < IQK_MATRIX_REG_NUM; i++) 2481 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2482 rtlphy->iqk_matrix_regsetting[indexforchannel]. 2482 rtlphy->iqk_matrix[indexforchannel].
2483 value[0][i] = result[final_candidate][i]; 2483 value[0][i] = result[final_candidate][i];
2484 rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done = 2484 rtlphy->iqk_matrix[indexforchannel].iqk_done =
2485 true; 2485 true;
2486 2486
2487 RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD, 2487 RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD,
@@ -2501,8 +2501,8 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
2501 indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); 2501 indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
2502 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n", 2502 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n",
2503 indexforchannel, 2503 indexforchannel,
2504 rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done); 2504 rtlphy->iqk_matrix[indexforchannel].iqk_done);
2505 if (0 && !rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done && 2505 if (0 && !rtlphy->iqk_matrix[indexforchannel].iqk_done &&
2506 rtlphy->need_iqk) { 2506 rtlphy->need_iqk) {
2507 /* Re Do IQK. */ 2507 /* Re Do IQK. */
2508 RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD, 2508 RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD,
@@ -2516,23 +2516,23 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
2516 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, 2516 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
2517 "Just Read IQK Matrix reg for channel:%d....\n", 2517 "Just Read IQK Matrix reg for channel:%d....\n",
2518 channel); 2518 channel);
2519 if ((rtlphy->iqk_matrix_regsetting[indexforchannel]. 2519 if ((rtlphy->iqk_matrix[indexforchannel].
2520 value[0] != NULL) 2520 value[0] != NULL)
2521 /*&&(regea4 != 0) */) 2521 /*&&(regea4 != 0) */)
2522 _rtl92d_phy_patha_fill_iqk_matrix(hw, true, 2522 _rtl92d_phy_patha_fill_iqk_matrix(hw, true,
2523 rtlphy->iqk_matrix_regsetting[ 2523 rtlphy->iqk_matrix[
2524 indexforchannel].value, 0, 2524 indexforchannel].value, 0,
2525 (rtlphy->iqk_matrix_regsetting[ 2525 (rtlphy->iqk_matrix[
2526 indexforchannel].value[0][2] == 0)); 2526 indexforchannel].value[0][2] == 0));
2527 if (IS_92D_SINGLEPHY(rtlhal->version)) { 2527 if (IS_92D_SINGLEPHY(rtlhal->version)) {
2528 if ((rtlphy->iqk_matrix_regsetting[ 2528 if ((rtlphy->iqk_matrix[
2529 indexforchannel].value[0][4] != 0) 2529 indexforchannel].value[0][4] != 0)
2530 /*&&(regec4 != 0) */) 2530 /*&&(regec4 != 0) */)
2531 _rtl92d_phy_pathb_fill_iqk_matrix(hw, 2531 _rtl92d_phy_pathb_fill_iqk_matrix(hw,
2532 true, 2532 true,
2533 rtlphy->iqk_matrix_regsetting[ 2533 rtlphy->iqk_matrix[
2534 indexforchannel].value, 0, 2534 indexforchannel].value, 0,
2535 (rtlphy->iqk_matrix_regsetting[ 2535 (rtlphy->iqk_matrix[
2536 indexforchannel].value[0][6] 2536 indexforchannel].value[0][6]
2537 == 0)); 2537 == 0));
2538 } 2538 }
@@ -2830,20 +2830,20 @@ void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw)
2830 2830
2831 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 2831 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2832 "settings regs %d default regs %d\n", 2832 "settings regs %d default regs %d\n",
2833 (int)(sizeof(rtlphy->iqk_matrix_regsetting) / 2833 (int)(sizeof(rtlphy->iqk_matrix) /
2834 sizeof(struct iqk_matrix_regs)), 2834 sizeof(struct iqk_matrix_regs)),
2835 IQK_MATRIX_REG_NUM); 2835 IQK_MATRIX_REG_NUM);
2836 /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */ 2836 /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */
2837 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) { 2837 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
2838 rtlphy->iqk_matrix_regsetting[i].value[0][0] = 0x100; 2838 rtlphy->iqk_matrix[i].value[0][0] = 0x100;
2839 rtlphy->iqk_matrix_regsetting[i].value[0][2] = 0x100; 2839 rtlphy->iqk_matrix[i].value[0][2] = 0x100;
2840 rtlphy->iqk_matrix_regsetting[i].value[0][4] = 0x100; 2840 rtlphy->iqk_matrix[i].value[0][4] = 0x100;
2841 rtlphy->iqk_matrix_regsetting[i].value[0][6] = 0x100; 2841 rtlphy->iqk_matrix[i].value[0][6] = 0x100;
2842 rtlphy->iqk_matrix_regsetting[i].value[0][1] = 0x0; 2842 rtlphy->iqk_matrix[i].value[0][1] = 0x0;
2843 rtlphy->iqk_matrix_regsetting[i].value[0][3] = 0x0; 2843 rtlphy->iqk_matrix[i].value[0][3] = 0x0;
2844 rtlphy->iqk_matrix_regsetting[i].value[0][5] = 0x0; 2844 rtlphy->iqk_matrix[i].value[0][5] = 0x0;
2845 rtlphy->iqk_matrix_regsetting[i].value[0][7] = 0x0; 2845 rtlphy->iqk_matrix[i].value[0][7] = 0x0;
2846 rtlphy->iqk_matrix_regsetting[i].iqk_done = false; 2846 rtlphy->iqk_matrix[i].iqk_done = false;
2847 } 2847 }
2848} 2848}
2849 2849
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
index ebb1d5f5e7b5..b7498c5bafc5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
@@ -543,7 +543,7 @@
543#define IMR_TIMEOUT1 BIT(16) 543#define IMR_TIMEOUT1 BIT(16)
544#define IMR_TXFOVW BIT(15) 544#define IMR_TXFOVW BIT(15)
545#define IMR_PSTIMEOUT BIT(14) 545#define IMR_PSTIMEOUT BIT(14)
546#define IMR_BcnInt BIT(13) 546#define IMR_BCNINT BIT(13)
547#define IMR_RXFOVW BIT(12) 547#define IMR_RXFOVW BIT(12)
548#define IMR_RDU BIT(11) 548#define IMR_RDU BIT(11)
549#define IMR_ATIMEND BIT(10) 549#define IMR_ATIMEND BIT(10)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index 03c6d18b2e07..c18c04bf0c13 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -166,7 +166,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
166 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; 166 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
167 167
168 /* for early mode */ 168 /* for early mode */
169 rtlpriv->rtlhal.earlymode_enable = true; 169 rtlpriv->rtlhal.earlymode_enable = false;
170 for (tid = 0; tid < 8; tid++) 170 for (tid = 0; tid < 8; tid++)
171 skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); 171 skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
172 172
@@ -319,7 +319,7 @@ static struct rtl_hal_cfg rtl92de_hal_cfg = {
319 319
320 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, 320 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
321 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, 321 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
322 .maps[RTL_IMR_BcnInt] = IMR_BcnInt, 322 .maps[RTL_IMR_BCNINT] = IMR_BCNINT,
323 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, 323 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
324 .maps[RTL_IMR_RDU] = IMR_RDU, 324 .maps[RTL_IMR_RDU] = IMR_RDU,
325 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, 325 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
@@ -333,7 +333,7 @@ static struct rtl_hal_cfg rtl92de_hal_cfg = {
333 .maps[RTL_IMR_VIDOK] = IMR_VIDOK, 333 .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
334 .maps[RTL_IMR_VODOK] = IMR_VODOK, 334 .maps[RTL_IMR_VODOK] = IMR_VODOK,
335 .maps[RTL_IMR_ROK] = IMR_ROK, 335 .maps[RTL_IMR_ROK] = IMR_ROK,
336 .maps[RTL_IBSS_INT_MASKS] = (IMR_BcnInt | IMR_TBDOK | IMR_TBDER), 336 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
337 337
338 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M, 338 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M,
339 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M, 339 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
index 2d255e02d795..83c98674bfd3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -36,9 +36,6 @@
36#define SHORT_SLOT_TIME 9 36#define SHORT_SLOT_TIME 9
37#define NON_SHORT_SLOT_TIME 20 37#define NON_SHORT_SLOT_TIME 20
38 38
39/* Rx smooth factor */
40#define RX_SMOOTH_FACTOR 20
41
42/* Queue Select Value in TxDesc */ 39/* Queue Select Value in TxDesc */
43#define QSLT_BK 0x2 40#define QSLT_BK 0x2
44#define QSLT_BE 0x0 41#define QSLT_BE 0x0
@@ -49,10 +46,6 @@
49#define QSLT_MGNT 0x12 46#define QSLT_MGNT 0x12
50#define QSLT_CMD 0x13 47#define QSLT_CMD 0x13
51 48
52#define PHY_RSSI_SLID_WIN_MAX 100
53#define PHY_LINKQUALITY_SLID_WIN_MAX 20
54#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
55
56/* Tx Desc */ 49/* Tx Desc */
57#define TX_DESC_SIZE_RTL8192S (16 * 4) 50#define TX_DESC_SIZE_RTL8192S (16 * 4)
58#define TX_CMDDESC_SIZE_RTL8192S (16 * 4) 51#define TX_CMDDESC_SIZE_RTL8192S (16 * 4)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
index e551fe5f9ccd..b3a2d5ec59e6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
@@ -163,6 +163,7 @@ static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
163 struct rtl_priv *rtlpriv = rtl_priv(hw); 163 struct rtl_priv *rtlpriv = rtl_priv(hw);
164 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 164 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
165 u8 thermalvalue = 0; 165 u8 thermalvalue = 0;
166 u32 fw_cmd = 0;
166 167
167 rtlpriv->dm.txpower_trackinginit = true; 168 rtlpriv->dm.txpower_trackinginit = true;
168 169
@@ -175,7 +176,19 @@ static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
175 176
176 if (thermalvalue) { 177 if (thermalvalue) {
177 rtlpriv->dm.thermalvalue = thermalvalue; 178 rtlpriv->dm.thermalvalue = thermalvalue;
178 rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL); 179 if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
180 rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL);
181 } else {
182 fw_cmd = (FW_TXPWR_TRACK_THERMAL |
183 (rtlpriv->efuse.thermalmeter[0] << 8) |
184 (thermalvalue << 16));
185
186 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
187 "Write to FW Thermal Val = 0x%x\n", fw_cmd);
188
189 rtl_write_dword(rtlpriv, WFM5, fw_cmd);
190 rtl92s_phy_chk_fwcmd_iodone(hw);
191 }
179 } 192 }
180 193
181 rtlpriv->dm.txpowercount = 0; 194 rtlpriv->dm.txpowercount = 0;
@@ -217,11 +230,10 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
217 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 230 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
218 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 231 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
219 struct rate_adaptive *ra = &(rtlpriv->ra); 232 struct rate_adaptive *ra = &(rtlpriv->ra);
220 233 struct ieee80211_sta *sta = NULL;
221 u32 low_rssi_thresh = 0; 234 u32 low_rssi_thresh = 0;
222 u32 middle_rssi_thresh = 0; 235 u32 middle_rssi_thresh = 0;
223 u32 high_rssi_thresh = 0; 236 u32 high_rssi_thresh = 0;
224 struct ieee80211_sta *sta = NULL;
225 237
226 if (is_hal_stop(rtlhal)) 238 if (is_hal_stop(rtlhal))
227 return; 239 return;
@@ -229,14 +241,12 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
229 if (!rtlpriv->dm.useramask) 241 if (!rtlpriv->dm.useramask)
230 return; 242 return;
231 243
232 if (!rtlpriv->dm.inform_fw_driverctrldm) { 244 if (hal_get_firmwareversion(rtlpriv) >= 61 &&
245 !rtlpriv->dm.inform_fw_driverctrldm) {
233 rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER); 246 rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER);
234 rtlpriv->dm.inform_fw_driverctrldm = true; 247 rtlpriv->dm.inform_fw_driverctrldm = true;
235 } 248 }
236 249
237 rcu_read_lock();
238 if (mac->opmode == NL80211_IFTYPE_STATION)
239 sta = get_sta(hw, mac->vif, mac->bssid);
240 if ((mac->link_state == MAC80211_LINKED) && 250 if ((mac->link_state == MAC80211_LINKED) &&
241 (mac->opmode == NL80211_IFTYPE_STATION)) { 251 (mac->opmode == NL80211_IFTYPE_STATION)) {
242 switch (ra->pre_ratr_state) { 252 switch (ra->pre_ratr_state) {
@@ -285,12 +295,16 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
285 rtlpriv->dm.undec_sm_pwdb, ra->ratr_state, 295 rtlpriv->dm.undec_sm_pwdb, ra->ratr_state,
286 ra->pre_ratr_state, ra->ratr_state); 296 ra->pre_ratr_state, ra->ratr_state);
287 297
288 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 298 rcu_read_lock();
299 sta = rtl_find_sta(hw, mac->bssid);
300 if (sta)
301 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
289 ra->ratr_state); 302 ra->ratr_state);
303 rcu_read_unlock();
304
290 ra->pre_ratr_state = ra->ratr_state; 305 ra->pre_ratr_state = ra->ratr_state;
291 } 306 }
292 } 307 }
293 rcu_read_unlock();
294} 308}
295 309
296static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw) 310static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw)
@@ -370,7 +384,8 @@ static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
370 ra->ratr_state = DM_RATR_STA_MAX; 384 ra->ratr_state = DM_RATR_STA_MAX;
371 ra->pre_ratr_state = DM_RATR_STA_MAX; 385 ra->pre_ratr_state = DM_RATR_STA_MAX;
372 386
373 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) 387 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER &&
388 hal_get_firmwareversion(rtlpriv) >= 60)
374 rtlpriv->dm.useramask = true; 389 rtlpriv->dm.useramask = true;
375 else 390 else
376 rtlpriv->dm.useramask = false; 391 rtlpriv->dm.useramask = false;
@@ -457,13 +472,13 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
457 digtable->back_val = DM_DIG_BACKOFF; 472 digtable->back_val = DM_DIG_BACKOFF;
458 473
459 if ((digtable->rssi_val + 10 - digtable->back_val) > 474 if ((digtable->rssi_val + 10 - digtable->back_val) >
460 digtable->rx_gain_range_max) 475 digtable->rx_gain_max)
461 digtable->cur_igvalue = 476 digtable->cur_igvalue =
462 digtable->rx_gain_range_max; 477 digtable->rx_gain_max;
463 else if ((digtable->rssi_val + 10 - digtable->back_val) 478 else if ((digtable->rssi_val + 10 - digtable->back_val)
464 < digtable->rx_gain_range_min) 479 < digtable->rx_gain_min)
465 digtable->cur_igvalue = 480 digtable->cur_igvalue =
466 digtable->rx_gain_range_min; 481 digtable->rx_gain_min;
467 else 482 else
468 digtable->cur_igvalue = digtable->rssi_val + 10 483 digtable->cur_igvalue = digtable->rssi_val + 10
469 - digtable->back_val; 484 - digtable->back_val;
@@ -475,7 +490,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
475 490
476 if (falsealm_cnt->cnt_all > 16000) 491 if (falsealm_cnt->cnt_all > 16000)
477 digtable->cur_igvalue = 492 digtable->cur_igvalue =
478 digtable->rx_gain_range_max; 493 digtable->rx_gain_max;
479 /* connected -> connected or disconnected -> disconnected */ 494 /* connected -> connected or disconnected -> disconnected */
480 } else { 495 } else {
481 /* Firmware control DIG, do nothing in driver dm */ 496 /* Firmware control DIG, do nothing in driver dm */
@@ -677,9 +692,9 @@ static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw)
677 /* for dig debug rssi value */ 692 /* for dig debug rssi value */
678 digtable->rssi_val = 50; 693 digtable->rssi_val = 50;
679 digtable->back_val = DM_DIG_BACKOFF; 694 digtable->back_val = DM_DIG_BACKOFF;
680 digtable->rx_gain_range_max = DM_DIG_MAX; 695 digtable->rx_gain_max = DM_DIG_MAX;
681 696
682 digtable->rx_gain_range_min = DM_DIG_MIN; 697 digtable->rx_gain_min = DM_DIG_MIN;
683 698
684 digtable->backoffval_range_max = DM_DIG_BACKOFF_MAX; 699 digtable->backoffval_range_max = DM_DIG_BACKOFF_MAX;
685 digtable->backoffval_range_min = DM_DIG_BACKOFF_MIN; 700 digtable->backoffval_range_min = DM_DIG_BACKOFF_MIN;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index 084e7773bce2..4f461786a7eb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -400,6 +400,39 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
400 400
401 break; 401 break;
402 } 402 }
403 case HW_VAR_FW_LPS_ACTION: {
404 bool enter_fwlps = *((bool *)val);
405 u8 rpwm_val, fw_pwrmode;
406 bool fw_current_inps;
407
408 if (enter_fwlps) {
409 rpwm_val = 0x02; /* RF off */
410 fw_current_inps = true;
411 rtlpriv->cfg->ops->set_hw_reg(hw,
412 HW_VAR_FW_PSMODE_STATUS,
413 (u8 *)(&fw_current_inps));
414 rtlpriv->cfg->ops->set_hw_reg(hw,
415 HW_VAR_H2C_FW_PWRMODE,
416 (u8 *)(&ppsc->fwctrl_psmode));
417
418 rtlpriv->cfg->ops->set_hw_reg(hw,
419 HW_VAR_SET_RPWM,
420 (u8 *)(&rpwm_val));
421 } else {
422 rpwm_val = 0x0C; /* RF on */
423 fw_pwrmode = FW_PS_ACTIVE_MODE;
424 fw_current_inps = false;
425 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
426 (u8 *)(&rpwm_val));
427 rtlpriv->cfg->ops->set_hw_reg(hw,
428 HW_VAR_H2C_FW_PWRMODE,
429 (u8 *)(&fw_pwrmode));
430
431 rtlpriv->cfg->ops->set_hw_reg(hw,
432 HW_VAR_FW_PSMODE_STATUS,
433 (u8 *)(&fw_current_inps));
434 }
435 break; }
403 default: 436 default:
404 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 437 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
405 "switch case not processed\n"); 438 "switch case not processed\n");
@@ -438,7 +471,7 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw)
438 471
439} 472}
440 473
441static u8 _rtl92ce_halset_sysclk(struct ieee80211_hw *hw, u8 data) 474static u8 _rtl92se_halset_sysclk(struct ieee80211_hw *hw, u8 data)
442{ 475{
443 struct rtl_priv *rtlpriv = rtl_priv(hw); 476 struct rtl_priv *rtlpriv = rtl_priv(hw);
444 u8 waitcount = 100; 477 u8 waitcount = 100;
@@ -547,7 +580,7 @@ static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw)
547 tmpu1b &= ~(BIT(6) | BIT(7)); 580 tmpu1b &= ~(BIT(6) | BIT(7));
548 581
549 /* Set failed, return to prevent hang. */ 582 /* Set failed, return to prevent hang. */
550 if (!_rtl92ce_halset_sysclk(hw, tmpu1b)) 583 if (!_rtl92se_halset_sysclk(hw, tmpu1b))
551 return; 584 return;
552 } 585 }
553 586
@@ -650,7 +683,7 @@ static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw)
650 683
651 tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); 684 tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
652 tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6))); 685 tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6)));
653 if (!_rtl92ce_halset_sysclk(hw, tmpu1b)) 686 if (!_rtl92se_halset_sysclk(hw, tmpu1b))
654 return; /* Set failed, return to prevent hang. */ 687 return; /* Set failed, return to prevent hang. */
655 688
656 rtl_write_word(rtlpriv, CMDR, 0x07FC); 689 rtl_write_word(rtlpriv, CMDR, 0x07FC);
@@ -967,6 +1000,15 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
967 return rtstatus; 1000 return rtstatus;
968 } 1001 }
969 1002
1003 /* because last function modify RCR, so we update
1004 * rcr var here, or TP will unstable for receive_config
1005 * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
1006 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1007 */
1008 rtlpci->receive_config = rtl_read_dword(rtlpriv, RCR);
1009 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1010 rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config);
1011
970 /* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */ 1012 /* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */
971 /* We must set flag avoid BB/RF config period later!! */ 1013 /* We must set flag avoid BB/RF config period later!! */
972 rtl_write_dword(rtlpriv, CMDR, 0x37FC); 1014 rtl_write_dword(rtlpriv, CMDR, 0x37FC);
@@ -982,25 +1024,6 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
982 1024
983 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; 1025 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
984 1026
985 /* RF Power Save */
986#if 0
987 /* H/W or S/W RF OFF before sleep. */
988 if (rtlpriv->psc.rfoff_reason > RF_CHANGE_BY_PS) {
989 u32 rfoffreason = rtlpriv->psc.rfoff_reason;
990
991 rtlpriv->psc.rfoff_reason = RF_CHANGE_BY_INIT;
992 rtlpriv->psc.rfpwr_state = ERFON;
993 /* FIXME: check spinlocks if this block is uncommented */
994 rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason);
995 } else {
996 /* gpio radio on/off is out of adapter start */
997 if (rtlpriv->psc.hwradiooff == false) {
998 rtlpriv->psc.rfpwr_state = ERFON;
999 rtlpriv->psc.rfoff_reason = 0;
1000 }
1001 }
1002#endif
1003
1004 /* Before RF-R/W we must execute the IO from Scott's suggestion. */ 1027 /* Before RF-R/W we must execute the IO from Scott's suggestion. */
1005 rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, 0xDB); 1028 rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, 0xDB);
1006 if (rtlhal->version == VERSION_8192S_ACUT) 1029 if (rtlhal->version == VERSION_8192S_ACUT)
@@ -1058,7 +1081,22 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
1058 1081
1059 /* We enable high power and RA related mechanism after NIC 1082 /* We enable high power and RA related mechanism after NIC
1060 * initialized. */ 1083 * initialized. */
1061 rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT); 1084 if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
1085 /* Fw v.53 and later. */
1086 rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT);
1087 } else if (hal_get_firmwareversion(rtlpriv) == 0x34) {
1088 /* Fw v.52. */
1089 rtl_write_dword(rtlpriv, WFM5, FW_RA_INIT);
1090 rtl92s_phy_chk_fwcmd_iodone(hw);
1091 } else {
1092 /* Compatible earlier FW version. */
1093 rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
1094 rtl92s_phy_chk_fwcmd_iodone(hw);
1095 rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
1096 rtl92s_phy_chk_fwcmd_iodone(hw);
1097 rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
1098 rtl92s_phy_chk_fwcmd_iodone(hw);
1099 }
1062 1100
1063 /* Add to prevent ASPM bug. */ 1101 /* Add to prevent ASPM bug. */
1064 /* Always enable hst and NIC clock request. */ 1102 /* Always enable hst and NIC clock request. */
@@ -1229,7 +1267,6 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
1229 synchronize_irq(rtlpci->pdev->irq); 1267 synchronize_irq(rtlpci->pdev->irq);
1230} 1268}
1231 1269
1232
1233static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data) 1270static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data)
1234{ 1271{
1235 struct rtl_priv *rtlpriv = rtl_priv(hw); 1272 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1754,7 +1791,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
1754 } 1791 }
1755 1792
1756 for (i = 0; i < 14; i++) { 1793 for (i = 0; i < 14; i++) {
1757 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1794 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1758 "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", 1795 "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
1759 rf_path, i, 1796 rf_path, i,
1760 rtlefuse->txpwrlevel_cck[rf_path][i], 1797 rtlefuse->txpwrlevel_cck[rf_path][i],
@@ -1791,11 +1828,11 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
1791 ((rtlefuse->eeprom_pwrgroup[rf_path][index] & 1828 ((rtlefuse->eeprom_pwrgroup[rf_path][index] &
1792 0xf0) >> 4); 1829 0xf0) >> 4);
1793 1830
1794 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1831 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1795 "RF-%d pwrgroup_ht20[%d] = 0x%x\n", 1832 "RF-%d pwrgroup_ht20[%d] = 0x%x\n",
1796 rf_path, i, 1833 rf_path, i,
1797 rtlefuse->pwrgroup_ht20[rf_path][i]); 1834 rtlefuse->pwrgroup_ht20[rf_path][i]);
1798 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1835 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1799 "RF-%d pwrgroup_ht40[%d] = 0x%x\n", 1836 "RF-%d pwrgroup_ht40[%d] = 0x%x\n",
1800 rf_path, i, 1837 rf_path, i,
1801 rtlefuse->pwrgroup_ht40[rf_path][i]); 1838 rtlefuse->pwrgroup_ht40[rf_path][i]);
@@ -1850,27 +1887,27 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
1850 rtlefuse->eeprom_regulatory = 1887 rtlefuse->eeprom_regulatory =
1851 (hwinfo[EEPROM_REGULATORY] & 0x1); 1888 (hwinfo[EEPROM_REGULATORY] & 0x1);
1852 } 1889 }
1853 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1890 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1854 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); 1891 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
1855 1892
1856 for (i = 0; i < 14; i++) 1893 for (i = 0; i < 14; i++)
1857 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1894 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1858 "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", 1895 "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
1859 i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); 1896 i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
1860 for (i = 0; i < 14; i++) 1897 for (i = 0; i < 14; i++)
1861 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1898 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1862 "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", 1899 "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
1863 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); 1900 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
1864 for (i = 0; i < 14; i++) 1901 for (i = 0; i < 14; i++)
1865 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1902 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1866 "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", 1903 "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
1867 i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); 1904 i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
1868 for (i = 0; i < 14; i++) 1905 for (i = 0; i < 14; i++)
1869 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1906 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1870 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", 1907 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
1871 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); 1908 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
1872 1909
1873 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1910 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1874 "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag); 1911 "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag);
1875 1912
1876 /* Read RF-indication and Tx Power gain 1913 /* Read RF-indication and Tx Power gain
@@ -1880,7 +1917,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
1880 rtlefuse->legacy_httxpowerdiff = 1917 rtlefuse->legacy_httxpowerdiff =
1881 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; 1918 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0];
1882 1919
1883 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1920 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1884 "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff); 1921 "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff);
1885 1922
1886 /* Get TSSI value for each path. */ 1923 /* Get TSSI value for each path. */
@@ -1889,7 +1926,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
1889 usvalue = hwinfo[EEPROM_TSSI_B]; 1926 usvalue = hwinfo[EEPROM_TSSI_B];
1890 rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff); 1927 rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff);
1891 1928
1892 RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", 1929 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
1893 rtlefuse->eeprom_tssi[RF90_PATH_A], 1930 rtlefuse->eeprom_tssi[RF90_PATH_A],
1894 rtlefuse->eeprom_tssi[RF90_PATH_B]); 1931 rtlefuse->eeprom_tssi[RF90_PATH_B]);
1895 1932
@@ -1897,7 +1934,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
1897 /* and read ThermalMeter from EEPROM */ 1934 /* and read ThermalMeter from EEPROM */
1898 tempval = hwinfo[EEPROM_THERMALMETER]; 1935 tempval = hwinfo[EEPROM_THERMALMETER];
1899 rtlefuse->eeprom_thermalmeter = tempval; 1936 rtlefuse->eeprom_thermalmeter = tempval;
1900 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1937 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1901 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); 1938 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1902 1939
1903 /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */ 1940 /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */
@@ -1914,7 +1951,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
1914 /* Version ID, Channel plan */ 1951 /* Version ID, Channel plan */
1915 rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; 1952 rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
1916 rtlefuse->txpwr_fromeprom = true; 1953 rtlefuse->txpwr_fromeprom = true;
1917 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1954 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1918 "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan); 1955 "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan);
1919 1956
1920 /* Read Customer ID or Board Type!!! */ 1957 /* Read Customer ID or Board Type!!! */
@@ -1999,6 +2036,8 @@ static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw,
1999 ratr_value = sta->supp_rates[1] << 4; 2036 ratr_value = sta->supp_rates[1] << 4;
2000 else 2037 else
2001 ratr_value = sta->supp_rates[0]; 2038 ratr_value = sta->supp_rates[0];
2039 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2040 ratr_value = 0xfff;
2002 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | 2041 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2003 sta->ht_cap.mcs.rx_mask[0] << 12); 2042 sta->ht_cap.mcs.rx_mask[0] << 12);
2004 switch (wirelessmode) { 2043 switch (wirelessmode) {
@@ -2112,6 +2151,8 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
2112 ratr_bitmap = sta->supp_rates[1] << 4; 2151 ratr_bitmap = sta->supp_rates[1] << 4;
2113 else 2152 else
2114 ratr_bitmap = sta->supp_rates[0]; 2153 ratr_bitmap = sta->supp_rates[0];
2154 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2155 ratr_bitmap = 0xfff;
2115 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | 2156 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2116 sta->ht_cap.mcs.rx_mask[0] << 12); 2157 sta->ht_cap.mcs.rx_mask[0] << 12);
2117 switch (wirelessmode) { 2158 switch (wirelessmode) {
@@ -2200,6 +2241,7 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
2200 ratr_bitmap &= 0x0f8ff0ff; 2241 ratr_bitmap &= 0x0f8ff0ff;
2201 break; 2242 break;
2202 } 2243 }
2244 sta_entry->ratr_index = ratr_index;
2203 2245
2204 if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT) 2246 if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT)
2205 ratr_bitmap &= 0x0FFFFFFF; 2247 ratr_bitmap &= 0x0FFFFFFF;
@@ -2438,23 +2480,9 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
2438 rtl_cam_del_entry(hw, p_macaddr); 2480 rtl_cam_del_entry(hw, p_macaddr);
2439 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); 2481 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2440 } else { 2482 } else {
2441 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
2442 "The insert KEY length is %d\n",
2443 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
2444 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
2445 "The insert KEY is %x %x\n",
2446 rtlpriv->sec.key_buf[0][0],
2447 rtlpriv->sec.key_buf[0][1]);
2448
2449 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 2483 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2450 "add one entry\n"); 2484 "add one entry\n");
2451 if (is_pairwise) { 2485 if (is_pairwise) {
2452 RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
2453 "Pairwise Key content",
2454 rtlpriv->sec.pairwise_key,
2455 rtlpriv->sec.
2456 key_len[PAIRWISE_KEYIDX]);
2457
2458 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 2486 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2459 "set Pairwise key\n"); 2487 "set Pairwise key\n");
2460 2488
@@ -2502,3 +2530,23 @@ void rtl92se_resume(struct ieee80211_hw *hw)
2502 pci_write_config_dword(rtlpci->pdev, 0x40, 2530 pci_write_config_dword(rtlpci->pdev, 0x40,
2503 val & 0xffff00ff); 2531 val & 0xffff00ff);
2504} 2532}
2533
2534/* Turn on AAP (RCR:bit 0) for promicuous mode. */
2535void rtl92se_allow_all_destaddr(struct ieee80211_hw *hw,
2536 bool allow_all_da, bool write_into_reg)
2537{
2538 struct rtl_priv *rtlpriv = rtl_priv(hw);
2539 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2540
2541 if (allow_all_da) /* Set BIT0 */
2542 rtlpci->receive_config |= RCR_AAP;
2543 else /* Clear BIT0 */
2544 rtlpci->receive_config &= ~RCR_AAP;
2545
2546 if (write_into_reg)
2547 rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config);
2548
2549 RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
2550 "receive_config=0x%08X, write_into_reg=%d\n",
2551 rtlpci->receive_config, write_into_reg);
2552}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
index a8e068c76e47..da48aa8cbe6f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
@@ -74,6 +74,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw,
74 u8 enc_algo, bool is_wepkey, bool clear_all); 74 u8 enc_algo, bool is_wepkey, bool clear_all);
75void rtl92se_suspend(struct ieee80211_hw *hw); 75void rtl92se_suspend(struct ieee80211_hw *hw);
76void rtl92se_resume(struct ieee80211_hw *hw); 76void rtl92se_resume(struct ieee80211_hw *hw);
77void rtl92se_allow_all_destaddr(struct ieee80211_hw *hw,
78 bool allow_all_da, bool write_into_reg);
77 79
78#endif 80#endif
79
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
index 67404975e00b..9c092e6eb3fe 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
@@ -1307,6 +1307,8 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
1307 if (is_hal_stop(rtlhal)) 1307 if (is_hal_stop(rtlhal))
1308 return; 1308 return;
1309 1309
1310 if (hal_get_firmwareversion(rtlpriv) < 0x34)
1311 goto skip;
1310 /* We re-map RA related CMD IO to combinational ones */ 1312 /* We re-map RA related CMD IO to combinational ones */
1311 /* if FW version is v.52 or later. */ 1313 /* if FW version is v.52 or later. */
1312 switch (rtlhal->current_fwcmd_io) { 1314 switch (rtlhal->current_fwcmd_io) {
@@ -1320,6 +1322,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
1320 break; 1322 break;
1321 } 1323 }
1322 1324
1325skip:
1323 switch (rtlhal->current_fwcmd_io) { 1326 switch (rtlhal->current_fwcmd_io) {
1324 case FW_CMD_RA_RESET: 1327 case FW_CMD_RA_RESET:
1325 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n"); 1328 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n");
@@ -1440,7 +1443,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1440 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 1443 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1441 u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv); 1444 u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv);
1442 u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv); 1445 u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv);
1443 bool bPostProcessing = false; 1446 bool postprocessing = false;
1444 1447
1445 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, 1448 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1446 "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", 1449 "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
@@ -1449,15 +1452,24 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1449 do { 1452 do {
1450 /* We re-map to combined FW CMD ones if firmware version */ 1453 /* We re-map to combined FW CMD ones if firmware version */
1451 /* is v.53 or later. */ 1454 /* is v.53 or later. */
1452 switch (fw_cmdio) { 1455 if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
1453 case FW_CMD_RA_REFRESH_N: 1456 switch (fw_cmdio) {
1454 fw_cmdio = FW_CMD_RA_REFRESH_N_COMB; 1457 case FW_CMD_RA_REFRESH_N:
1455 break; 1458 fw_cmdio = FW_CMD_RA_REFRESH_N_COMB;
1456 case FW_CMD_RA_REFRESH_BG: 1459 break;
1457 fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB; 1460 case FW_CMD_RA_REFRESH_BG:
1458 break; 1461 fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB;
1459 default: 1462 break;
1460 break; 1463 default:
1464 break;
1465 }
1466 } else {
1467 if ((fw_cmdio == FW_CMD_IQK_ENABLE) ||
1468 (fw_cmdio == FW_CMD_RA_REFRESH_N) ||
1469 (fw_cmdio == FW_CMD_RA_REFRESH_BG)) {
1470 postprocessing = true;
1471 break;
1472 }
1461 } 1473 }
1462 1474
1463 /* If firmware version is v.62 or later, 1475 /* If firmware version is v.62 or later,
@@ -1588,19 +1600,19 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1588 fw_cmdmap &= ~FW_DIG_ENABLE_CTL; 1600 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1589 1601
1590 FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 1602 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1591 bPostProcessing = true; 1603 postprocessing = true;
1592 break; 1604 break;
1593 case FW_CMD_PAUSE_DM_BY_SCAN: 1605 case FW_CMD_PAUSE_DM_BY_SCAN:
1594 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | 1606 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL |
1595 FW_HIGH_PWR_ENABLE_CTL | 1607 FW_HIGH_PWR_ENABLE_CTL |
1596 FW_SS_CTL); 1608 FW_SS_CTL);
1597 FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 1609 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1598 bPostProcessing = true; 1610 postprocessing = true;
1599 break; 1611 break;
1600 case FW_CMD_HIGH_PWR_DISABLE: 1612 case FW_CMD_HIGH_PWR_DISABLE:
1601 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; 1613 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1602 FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 1614 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1603 bPostProcessing = true; 1615 postprocessing = true;
1604 break; 1616 break;
1605 case FW_CMD_HIGH_PWR_ENABLE: 1617 case FW_CMD_HIGH_PWR_ENABLE:
1606 if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) && 1618 if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
@@ -1608,7 +1620,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1608 fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL | 1620 fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
1609 FW_SS_CTL); 1621 FW_SS_CTL);
1610 FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 1622 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1611 bPostProcessing = true; 1623 postprocessing = true;
1612 } 1624 }
1613 break; 1625 break;
1614 case FW_CMD_DIG_MODE_FA: 1626 case FW_CMD_DIG_MODE_FA:
@@ -1629,14 +1641,15 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1629 default: 1641 default:
1630 /* Pass to original FW CMD processing callback 1642 /* Pass to original FW CMD processing callback
1631 * routine. */ 1643 * routine. */
1632 bPostProcessing = true; 1644 postprocessing = true;
1633 break; 1645 break;
1634 } 1646 }
1635 } while (false); 1647 } while (false);
1636 1648
1637 /* We shall post processing these FW CMD if 1649 /* We shall post processing these FW CMD if
1638 * variable bPostProcessing is set. */ 1650 * variable postprocessing is set.
1639 if (bPostProcessing && !rtlhal->set_fwcmd_inprogress) { 1651 */
1652 if (postprocessing && !rtlhal->set_fwcmd_inprogress) {
1640 rtlhal->set_fwcmd_inprogress = true; 1653 rtlhal->set_fwcmd_inprogress = true;
1641 /* Update current FW Cmd for callback use. */ 1654 /* Update current FW Cmd for callback use. */
1642 rtlhal->current_fwcmd_io = fw_cmdio; 1655 rtlhal->current_fwcmd_io = fw_cmdio;
@@ -1697,8 +1710,18 @@ void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw)
1697 1710
1698} 1711}
1699 1712
1700void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 BeaconInterval) 1713void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval)
1701{ 1714{
1702 struct rtl_priv *rtlpriv = rtl_priv(hw); 1715 struct rtl_priv *rtlpriv = rtl_priv(hw);
1703 rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | (BeaconInterval << 8)); 1716 u32 new_bcn_num = 0;
1717
1718 if (hal_get_firmwareversion(rtlpriv) >= 0x33) {
1719 /* Fw v.51 and later. */
1720 rtl_write_dword(rtlpriv, WFM5, 0xF1000000 |
1721 (beaconinterval << 8));
1722 } else {
1723 new_bcn_num = beaconinterval * 32 - 64;
1724 rtl_write_dword(rtlpriv, WFM3 + 4, new_bcn_num);
1725 rtl_write_dword(rtlpriv, WFM3, 0xB026007C);
1726 }
1704} 1727}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
index ac0387770630..8acf4765a7a6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
@@ -39,6 +39,7 @@
39#define MAX_POSTCMD_CNT 16 39#define MAX_POSTCMD_CNT 16
40 40
41#define RF90_PATH_MAX 4 41#define RF90_PATH_MAX 4
42#define RF6052_MAX_PATH 2
42 43
43enum version_8192s { 44enum version_8192s {
44 VERSION_8192S_ACUT, 45 VERSION_8192S_ACUT,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
index cecc377e9e61..2e8e6f8d2d51 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -290,6 +290,7 @@ static struct rtl_hal_ops rtl8192se_hal_ops = {
290 .enable_hw_sec = rtl92se_enable_hw_security_config, 290 .enable_hw_sec = rtl92se_enable_hw_security_config,
291 .set_key = rtl92se_set_key, 291 .set_key = rtl92se_set_key,
292 .init_sw_leds = rtl92se_init_sw_leds, 292 .init_sw_leds = rtl92se_init_sw_leds,
293 .allow_all_destaddr = rtl92se_allow_all_destaddr,
293 .get_bbreg = rtl92s_phy_query_bb_reg, 294 .get_bbreg = rtl92s_phy_query_bb_reg,
294 .set_bbreg = rtl92s_phy_set_bb_reg, 295 .set_bbreg = rtl92s_phy_set_bb_reg,
295 .get_rfreg = rtl92s_phy_query_rf_reg, 296 .get_rfreg = rtl92s_phy_query_rf_reg,
@@ -366,7 +367,7 @@ static struct rtl_hal_cfg rtl92se_hal_cfg = {
366 367
367 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, 368 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
368 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, 369 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
369 .maps[RTL_IMR_BcnInt] = IMR_BCNINT, 370 .maps[RTL_IMR_BCNINT] = IMR_BCNINT,
370 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, 371 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
371 .maps[RTL_IMR_RDU] = IMR_RDU, 372 .maps[RTL_IMR_RDU] = IMR_RDU,
372 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, 373 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index 7b0a2e75b8b8..960bc28cc51e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -30,6 +30,7 @@
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../pci.h" 31#include "../pci.h"
32#include "../base.h" 32#include "../base.h"
33#include "../stats.h"
33#include "reg.h" 34#include "reg.h"
34#include "def.h" 35#include "def.h"
35#include "phy.h" 36#include "phy.h"
@@ -43,7 +44,7 @@ static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 skb_queue)
43 44
44 if (unlikely(ieee80211_is_beacon(fc))) 45 if (unlikely(ieee80211_is_beacon(fc)))
45 return QSLT_BEACON; 46 return QSLT_BEACON;
46 if (ieee80211_is_mgmt(fc)) 47 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
47 return QSLT_MGNT; 48 return QSLT_MGNT;
48 if (ieee80211_is_nullfunc(fc)) 49 if (ieee80211_is_nullfunc(fc))
49 return QSLT_HIGH; 50 return QSLT_HIGH;
@@ -51,65 +52,6 @@ static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 skb_queue)
51 return skb->priority; 52 return skb->priority;
52} 53}
53 54
54static u8 _rtl92s_query_rxpwrpercentage(char antpower)
55{
56 if ((antpower <= -100) || (antpower >= 20))
57 return 0;
58 else if (antpower >= 0)
59 return 100;
60 else
61 return 100 + antpower;
62}
63
64static u8 _rtl92s_evm_db_to_percentage(char value)
65{
66 char ret_val;
67 ret_val = value;
68
69 if (ret_val >= 0)
70 ret_val = 0;
71
72 if (ret_val <= -33)
73 ret_val = -33;
74
75 ret_val = 0 - ret_val;
76 ret_val *= 3;
77
78 if (ret_val == 99)
79 ret_val = 100;
80
81 return ret_val;
82}
83
84static long _rtl92se_translate_todbm(struct ieee80211_hw *hw,
85 u8 signal_strength_index)
86{
87 long signal_power;
88
89 signal_power = (long)((signal_strength_index + 1) >> 1);
90 signal_power -= 95;
91 return signal_power;
92}
93
94static long _rtl92se_signal_scale_mapping(struct ieee80211_hw *hw,
95 long currsig)
96{
97 long retsig = 0;
98
99 /* Step 1. Scale mapping. */
100 if (currsig > 47)
101 retsig = 100;
102 else if (currsig > 14 && currsig <= 47)
103 retsig = 100 - ((47 - currsig) * 3) / 2;
104 else if (currsig > 2 && currsig <= 14)
105 retsig = 48 - ((14 - currsig) * 15) / 7;
106 else if (currsig >= 0)
107 retsig = currsig * 9 + 1;
108
109 return retsig;
110}
111
112
113static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, 55static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
114 struct rtl_stats *pstats, u8 *pdesc, 56 struct rtl_stats *pstats, u8 *pdesc,
115 struct rx_fwinfo *p_drvinfo, 57 struct rx_fwinfo *p_drvinfo,
@@ -119,11 +61,11 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
119{ 61{
120 struct rtl_priv *rtlpriv = rtl_priv(hw); 62 struct rtl_priv *rtlpriv = rtl_priv(hw);
121 struct phy_sts_cck_8192s_t *cck_buf; 63 struct phy_sts_cck_8192s_t *cck_buf;
64 struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
122 s8 rx_pwr_all = 0, rx_pwr[4]; 65 s8 rx_pwr_all = 0, rx_pwr[4];
123 u8 rf_rx_num = 0, evm, pwdb_all; 66 u8 rf_rx_num = 0, evm, pwdb_all;
124 u8 i, max_spatial_stream; 67 u8 i, max_spatial_stream;
125 u32 rssi, total_rssi = 0; 68 u32 rssi, total_rssi = 0;
126 bool in_powersavemode = false;
127 bool is_cck = pstats->is_cck; 69 bool is_cck = pstats->is_cck;
128 70
129 pstats->packet_matchbssid = packet_match_bssid; 71 pstats->packet_matchbssid = packet_match_bssid;
@@ -136,7 +78,7 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
136 u8 report, cck_highpwr; 78 u8 report, cck_highpwr;
137 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; 79 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
138 80
139 if (!in_powersavemode) 81 if (ppsc->rfpwr_state == ERFON)
140 cck_highpwr = (u8) rtl_get_bbreg(hw, 82 cck_highpwr = (u8) rtl_get_bbreg(hw,
141 RFPGA0_XA_HSSIPARAMETER2, 83 RFPGA0_XA_HSSIPARAMETER2,
142 0x200); 84 0x200);
@@ -181,7 +123,7 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
181 } 123 }
182 } 124 }
183 125
184 pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all); 126 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
185 127
186 /* CCK gain is smaller than OFDM/MCS gain, */ 128 /* CCK gain is smaller than OFDM/MCS gain, */
187 /* so we add gain diff by experiences, the val is 6 */ 129 /* so we add gain diff by experiences, the val is 6 */
@@ -222,13 +164,13 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
222 } else { 164 } else {
223 rtlpriv->dm.rfpath_rxenable[0] = 165 rtlpriv->dm.rfpath_rxenable[0] =
224 rtlpriv->dm.rfpath_rxenable[1] = true; 166 rtlpriv->dm.rfpath_rxenable[1] = true;
225 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { 167 for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
226 if (rtlpriv->dm.rfpath_rxenable[i]) 168 if (rtlpriv->dm.rfpath_rxenable[i])
227 rf_rx_num++; 169 rf_rx_num++;
228 170
229 rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 171 rx_pwr[i] = ((p_drvinfo->gain_trsw[i] &
230 0x3f) * 2) - 110; 172 0x3f) * 2) - 110;
231 rssi = _rtl92s_query_rxpwrpercentage(rx_pwr[i]); 173 rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
232 total_rssi += rssi; 174 total_rssi += rssi;
233 rtlpriv->stats.rx_snr_db[i] = 175 rtlpriv->stats.rx_snr_db[i] =
234 (long)(p_drvinfo->rxsnr[i] / 2); 176 (long)(p_drvinfo->rxsnr[i] / 2);
@@ -238,7 +180,7 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
238 } 180 }
239 181
240 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; 182 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
241 pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all); 183 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
242 pstats->rx_pwdb_all = pwdb_all; 184 pstats->rx_pwdb_all = pwdb_all;
243 pstats->rxpower = rx_pwr_all; 185 pstats->rxpower = rx_pwr_all;
244 pstats->recvsignalpower = rx_pwr_all; 186 pstats->recvsignalpower = rx_pwr_all;
@@ -250,7 +192,7 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
250 max_spatial_stream = 1; 192 max_spatial_stream = 1;
251 193
252 for (i = 0; i < max_spatial_stream; i++) { 194 for (i = 0; i < max_spatial_stream; i++) {
253 evm = _rtl92s_evm_db_to_percentage(p_drvinfo->rxevm[i]); 195 evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
254 196
255 if (packet_match_bssid) { 197 if (packet_match_bssid) {
256 if (i == 0) 198 if (i == 0)
@@ -262,212 +204,13 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
262 } 204 }
263 205
264 if (is_cck) 206 if (is_cck)
265 pstats->signalstrength = (u8)(_rtl92se_signal_scale_mapping(hw, 207 pstats->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
266 pwdb_all)); 208 pwdb_all));
267 else if (rf_rx_num != 0) 209 else if (rf_rx_num != 0)
268 pstats->signalstrength = (u8) (_rtl92se_signal_scale_mapping(hw, 210 pstats->signalstrength = (u8) (rtl_signal_scale_mapping(hw,
269 total_rssi /= rf_rx_num)); 211 total_rssi /= rf_rx_num));
270} 212}
271 213
272static void _rtl92se_process_ui_rssi(struct ieee80211_hw *hw,
273 struct rtl_stats *pstats)
274{
275 struct rtl_priv *rtlpriv = rtl_priv(hw);
276 struct rtl_phy *rtlphy = &(rtlpriv->phy);
277 u8 rfpath;
278 u32 last_rssi, tmpval;
279
280 if (pstats->packet_toself || pstats->packet_beacon) {
281 rtlpriv->stats.rssi_calculate_cnt++;
282
283 if (rtlpriv->stats.ui_rssi.total_num++ >=
284 PHY_RSSI_SLID_WIN_MAX) {
285 rtlpriv->stats.ui_rssi.total_num =
286 PHY_RSSI_SLID_WIN_MAX;
287 last_rssi = rtlpriv->stats.ui_rssi.elements[
288 rtlpriv->stats.ui_rssi.index];
289 rtlpriv->stats.ui_rssi.total_val -= last_rssi;
290 }
291
292 rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
293 rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++]
294 = pstats->signalstrength;
295
296 if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
297 rtlpriv->stats.ui_rssi.index = 0;
298
299 tmpval = rtlpriv->stats.ui_rssi.total_val /
300 rtlpriv->stats.ui_rssi.total_num;
301 rtlpriv->stats.signal_strength = _rtl92se_translate_todbm(hw,
302 (u8) tmpval);
303 pstats->rssi = rtlpriv->stats.signal_strength;
304 }
305
306 if (!pstats->is_cck && pstats->packet_toself) {
307 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
308 rfpath++) {
309 if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
310 rtlpriv->stats.rx_rssi_percentage[rfpath] =
311 pstats->rx_mimo_signalstrength[rfpath];
312
313 }
314
315 if (pstats->rx_mimo_signalstrength[rfpath] >
316 rtlpriv->stats.rx_rssi_percentage[rfpath]) {
317 rtlpriv->stats.rx_rssi_percentage[rfpath] =
318 ((rtlpriv->stats.rx_rssi_percentage[rfpath]
319 * (RX_SMOOTH_FACTOR - 1)) +
320 (pstats->rx_mimo_signalstrength[rfpath])) /
321 (RX_SMOOTH_FACTOR);
322
323 rtlpriv->stats.rx_rssi_percentage[rfpath] =
324 rtlpriv->stats.rx_rssi_percentage[rfpath]
325 + 1;
326 } else {
327 rtlpriv->stats.rx_rssi_percentage[rfpath] =
328 ((rtlpriv->stats.rx_rssi_percentage[rfpath]
329 * (RX_SMOOTH_FACTOR - 1)) +
330 (pstats->rx_mimo_signalstrength[rfpath])) /
331 (RX_SMOOTH_FACTOR);
332 }
333
334 }
335 }
336}
337
338static void _rtl92se_update_rxsignalstatistics(struct ieee80211_hw *hw,
339 struct rtl_stats *pstats)
340{
341 struct rtl_priv *rtlpriv = rtl_priv(hw);
342 int weighting = 0;
343
344 if (rtlpriv->stats.recv_signal_power == 0)
345 rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
346
347 if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
348 weighting = 5;
349 else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
350 weighting = (-5);
351
352 rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * 5
353 + pstats->recvsignalpower +
354 weighting) / 6;
355}
356
357static void _rtl92se_process_pwdb(struct ieee80211_hw *hw,
358 struct rtl_stats *pstats)
359{
360 struct rtl_priv *rtlpriv = rtl_priv(hw);
361 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
362 long undec_sm_pwdb = 0;
363
364 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
365 return;
366 } else {
367 undec_sm_pwdb =
368 rtlpriv->dm.undec_sm_pwdb;
369 }
370
371 if (pstats->packet_toself || pstats->packet_beacon) {
372 if (undec_sm_pwdb < 0)
373 undec_sm_pwdb = pstats->rx_pwdb_all;
374
375 if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
376 undec_sm_pwdb =
377 (((undec_sm_pwdb) *
378 (RX_SMOOTH_FACTOR - 1)) +
379 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
380
381 undec_sm_pwdb = undec_sm_pwdb + 1;
382 } else {
383 undec_sm_pwdb = (((undec_sm_pwdb) *
384 (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) /
385 (RX_SMOOTH_FACTOR);
386 }
387
388 rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
389 _rtl92se_update_rxsignalstatistics(hw, pstats);
390 }
391}
392
393static void rtl_92s_process_streams(struct ieee80211_hw *hw,
394 struct rtl_stats *pstats)
395{
396 struct rtl_priv *rtlpriv = rtl_priv(hw);
397 u32 stream;
398
399 for (stream = 0; stream < 2; stream++) {
400 if (pstats->rx_mimo_sig_qual[stream] != -1) {
401 if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
402 rtlpriv->stats.rx_evm_percentage[stream] =
403 pstats->rx_mimo_sig_qual[stream];
404 }
405
406 rtlpriv->stats.rx_evm_percentage[stream] =
407 ((rtlpriv->stats.rx_evm_percentage[stream] *
408 (RX_SMOOTH_FACTOR - 1)) +
409 (pstats->rx_mimo_sig_qual[stream] *
410 1)) / (RX_SMOOTH_FACTOR);
411 }
412 }
413}
414
415static void _rtl92se_process_ui_link_quality(struct ieee80211_hw *hw,
416 struct rtl_stats *pstats)
417{
418 struct rtl_priv *rtlpriv = rtl_priv(hw);
419 u32 last_evm = 0, tmpval;
420
421 if (pstats->signalquality != 0) {
422 if (pstats->packet_toself || pstats->packet_beacon) {
423
424 if (rtlpriv->stats.ui_link_quality.total_num++ >=
425 PHY_LINKQUALITY_SLID_WIN_MAX) {
426 rtlpriv->stats.ui_link_quality.total_num =
427 PHY_LINKQUALITY_SLID_WIN_MAX;
428 last_evm =
429 rtlpriv->stats.ui_link_quality.elements[
430 rtlpriv->stats.ui_link_quality.index];
431 rtlpriv->stats.ui_link_quality.total_val -=
432 last_evm;
433 }
434
435 rtlpriv->stats.ui_link_quality.total_val +=
436 pstats->signalquality;
437 rtlpriv->stats.ui_link_quality.elements[
438 rtlpriv->stats.ui_link_quality.index++] =
439 pstats->signalquality;
440
441 if (rtlpriv->stats.ui_link_quality.index >=
442 PHY_LINKQUALITY_SLID_WIN_MAX)
443 rtlpriv->stats.ui_link_quality.index = 0;
444
445 tmpval = rtlpriv->stats.ui_link_quality.total_val /
446 rtlpriv->stats.ui_link_quality.total_num;
447 rtlpriv->stats.signal_quality = tmpval;
448
449 rtlpriv->stats.last_sigstrength_inpercent = tmpval;
450
451 rtl_92s_process_streams(hw, pstats);
452
453 }
454 }
455}
456
457static void _rtl92se_process_phyinfo(struct ieee80211_hw *hw,
458 u8 *buffer,
459 struct rtl_stats *pcurrent_stats)
460{
461
462 if (!pcurrent_stats->packet_matchbssid &&
463 !pcurrent_stats->packet_beacon)
464 return;
465
466 _rtl92se_process_ui_rssi(hw, pcurrent_stats);
467 _rtl92se_process_pwdb(hw, pcurrent_stats);
468 _rtl92se_process_ui_link_quality(hw, pcurrent_stats);
469}
470
471static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw, 214static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
472 struct sk_buff *skb, struct rtl_stats *pstats, 215 struct sk_buff *skb, struct rtl_stats *pstats,
473 u8 *pdesc, struct rx_fwinfo *p_drvinfo) 216 u8 *pdesc, struct rx_fwinfo *p_drvinfo)
@@ -505,7 +248,7 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
505 248
506 _rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, 249 _rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
507 packet_matchbssid, packet_toself, packet_beacon); 250 packet_matchbssid, packet_toself, packet_beacon);
508 _rtl92se_process_phyinfo(hw, tmp_buf, pstats); 251 rtl_process_phyinfo(hw, tmp_buf, pstats);
509} 252}
510 253
511bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, 254bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
@@ -541,9 +284,6 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
541 rx_status->freq = hw->conf.channel->center_freq; 284 rx_status->freq = hw->conf.channel->center_freq;
542 rx_status->band = hw->conf.channel->band; 285 rx_status->band = hw->conf.channel->band;
543 286
544 hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
545 + stats->rx_bufshift);
546
547 if (stats->crc) 287 if (stats->crc)
548 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; 288 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
549 289
@@ -563,6 +303,13 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
563 * for IEEE80211w frame, and mac80211 sw will help 303 * for IEEE80211w frame, and mac80211 sw will help
564 * to decrypt it */ 304 * to decrypt it */
565 if (stats->decrypted) { 305 if (stats->decrypted) {
306 hdr = (struct ieee80211_hdr *)(skb->data +
307 stats->rx_drvinfo_size + stats->rx_bufshift);
308
309 if (!hdr) {
310 /* during testing, hdr was NULL here */
311 return false;
312 }
566 if ((ieee80211_is_robust_mgmt_frame(hdr)) && 313 if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
567 (ieee80211_has_protected(hdr->frame_control))) 314 (ieee80211_has_protected(hdr->frame_control)))
568 rx_status->flag &= ~RX_FLAG_DECRYPTED; 315 rx_status->flag &= ~RX_FLAG_DECRYPTED;
@@ -630,6 +377,11 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
630 377
631 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S); 378 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S);
632 379
380 if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
381 firstseg = true;
382 lastseg = true;
383 }
384
633 if (firstseg) { 385 if (firstseg) {
634 if (rtlpriv->dm.useramask) { 386 if (rtlpriv->dm.useramask) {
635 /* set txdesc macId */ 387 /* set txdesc macId */
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
index 12e2a3cb0701..a36eee28f9e7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
@@ -166,8 +166,8 @@ static void rtl8723ae_dm_diginit(struct ieee80211_hw *hw)
166 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; 166 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
167 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; 167 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
168 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; 168 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
169 dm_digtable->rx_gain_range_max = DM_DIG_MAX; 169 dm_digtable->rx_gain_max = DM_DIG_MAX;
170 dm_digtable->rx_gain_range_min = DM_DIG_MIN; 170 dm_digtable->rx_gain_min = DM_DIG_MIN;
171 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; 171 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
172 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; 172 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
173 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; 173 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
@@ -291,11 +291,11 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
291 } 291 }
292 292
293 if ((dgtbl->rssi_val_min + 10 - dgtbl->back_val) > 293 if ((dgtbl->rssi_val_min + 10 - dgtbl->back_val) >
294 dgtbl->rx_gain_range_max) 294 dgtbl->rx_gain_max)
295 dgtbl->cur_igvalue = dgtbl->rx_gain_range_max; 295 dgtbl->cur_igvalue = dgtbl->rx_gain_max;
296 else if ((dgtbl->rssi_val_min + 10 - 296 else if ((dgtbl->rssi_val_min + 10 -
297 dgtbl->back_val) < dgtbl->rx_gain_range_min) 297 dgtbl->back_val) < dgtbl->rx_gain_min)
298 dgtbl->cur_igvalue = dgtbl->rx_gain_range_min; 298 dgtbl->cur_igvalue = dgtbl->rx_gain_min;
299 else 299 else
300 dgtbl->cur_igvalue = dgtbl->rssi_val_min + 10 - dgtbl->back_val; 300 dgtbl->cur_igvalue = dgtbl->rssi_val_min + 10 - dgtbl->back_val;
301 301
@@ -707,6 +707,77 @@ void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
707 rtlpriv->dm.useramask = false; 707 rtlpriv->dm.useramask = false;
708} 708}
709 709
710static void rtl8723ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
711{
712 struct rtl_priv *rtlpriv = rtl_priv(hw);
713 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
714 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
715 struct rate_adaptive *p_ra = &(rtlpriv->ra);
716 u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
717 struct ieee80211_sta *sta = NULL;
718
719 if (is_hal_stop(rtlhal)) {
720 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
721 " driver is going to unload\n");
722 return;
723 }
724
725 if (!rtlpriv->dm.useramask) {
726 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
727 " driver does not control rate adaptive mask\n");
728 return;
729 }
730
731 if (mac->link_state == MAC80211_LINKED &&
732 mac->opmode == NL80211_IFTYPE_STATION) {
733 switch (p_ra->pre_ratr_state) {
734 case DM_RATR_STA_HIGH:
735 high_rssithresh_for_ra = 50;
736 low_rssithresh_for_ra = 20;
737 break;
738 case DM_RATR_STA_MIDDLE:
739 high_rssithresh_for_ra = 55;
740 low_rssithresh_for_ra = 20;
741 break;
742 case DM_RATR_STA_LOW:
743 high_rssithresh_for_ra = 50;
744 low_rssithresh_for_ra = 25;
745 break;
746 default:
747 high_rssithresh_for_ra = 50;
748 low_rssithresh_for_ra = 20;
749 break;
750 }
751
752 if (rtlpriv->dm.undec_sm_pwdb > high_rssithresh_for_ra)
753 p_ra->ratr_state = DM_RATR_STA_HIGH;
754 else if (rtlpriv->dm.undec_sm_pwdb > low_rssithresh_for_ra)
755 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
756 else
757 p_ra->ratr_state = DM_RATR_STA_LOW;
758
759 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
760 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
761 "RSSI = %ld\n",
762 rtlpriv->dm.undec_sm_pwdb);
763 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
764 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
765 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
766 "PreState = %d, CurState = %d\n",
767 p_ra->pre_ratr_state, p_ra->ratr_state);
768
769 rcu_read_lock();
770 sta = rtl_find_sta(hw, mac->bssid);
771 if (sta)
772 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
773 p_ra->ratr_state);
774 rcu_read_unlock();
775
776 p_ra->pre_ratr_state = p_ra->ratr_state;
777 }
778 }
779}
780
710static void rtl8723ae_dm_init_dynamic_bpowersaving(struct ieee80211_hw *hw) 781static void rtl8723ae_dm_init_dynamic_bpowersaving(struct ieee80211_hw *hw)
711{ 782{
712 struct rtl_priv *rtlpriv = rtl_priv(hw); 783 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -853,6 +924,9 @@ void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw)
853 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, 924 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
854 (u8 *) (&fw_ps_awake)); 925 (u8 *) (&fw_ps_awake));
855 926
927 if (ppsc->p2p_ps_info.p2p_ps_mode)
928 fw_ps_awake = false;
929
856 if ((ppsc->rfpwr_state == ERFON) && 930 if ((ppsc->rfpwr_state == ERFON) &&
857 ((!fw_current_inpsmode) && fw_ps_awake) && 931 ((!fw_current_inpsmode) && fw_ps_awake) &&
858 (!ppsc->rfchange_inprogress)) { 932 (!ppsc->rfchange_inprogress)) {
@@ -861,7 +935,7 @@ void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw)
861 rtl8723ae_dm_false_alarm_counter_statistics(hw); 935 rtl8723ae_dm_false_alarm_counter_statistics(hw);
862 rtl8723ae_dm_dynamic_bpowersaving(hw); 936 rtl8723ae_dm_dynamic_bpowersaving(hw);
863 rtl8723ae_dm_dynamic_txpower(hw); 937 rtl8723ae_dm_dynamic_txpower(hw);
864 /* rtl92c_dm_refresh_rate_adaptive_mask(hw); */ 938 rtl8723ae_dm_refresh_rate_adaptive_mask(hw);
865 rtl8723ae_dm_bt_coexist(hw); 939 rtl8723ae_dm_bt_coexist(hw);
866 rtl8723ae_dm_check_edca_turbo(hw); 940 rtl8723ae_dm_check_edca_turbo(hw);
867 } 941 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
index 39d246196247..a372b0204456 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
@@ -55,7 +55,13 @@
55#define DM_DIG_BACKOFF_MIN -4 55#define DM_DIG_BACKOFF_MIN -4
56#define DM_DIG_BACKOFF_DEFAULT 10 56#define DM_DIG_BACKOFF_DEFAULT 10
57 57
58#define RXPATHSELECTION_SS_TH_LOW 30
59#define RXPATHSELECTION_DIFF_TH 18
60
58#define DM_RATR_STA_INIT 0 61#define DM_RATR_STA_INIT 0
62#define DM_RATR_STA_HIGH 1
63#define DM_RATR_STA_MIDDLE 2
64#define DM_RATR_STA_LOW 3
59 65
60#define TXHIGHPWRLEVEL_NORMAL 0 66#define TXHIGHPWRLEVEL_NORMAL 0
61#define TXHIGHPWRLEVEL_LEVEL1 1 67#define TXHIGHPWRLEVEL_LEVEL1 1
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
index 35cb8f83eed4..dedfa1ed3e02 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
@@ -494,7 +494,9 @@ void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
494 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); 494 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
495 495
496 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); 496 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
497 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); 497 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
498 (rtlpriv->mac80211.p2p) ?
499 ppsc->smart_ps : 1);
498 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, 500 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
499 ppsc->reg_max_lps_awakeintvl); 501 ppsc->reg_max_lps_awakeintvl);
500 502
@@ -741,3 +743,96 @@ void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
741 743
742 rtl8723ae_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); 744 rtl8723ae_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
743} 745}
746
747static void rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
748 u8 ctwindow)
749{
750 u8 u1_ctwindow_period[1] = {ctwindow};
751
752 rtl8723ae_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
753}
754
755void rtl8723ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
756{
757 struct rtl_priv *rtlpriv = rtl_priv(hw);
758 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
759 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
760 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
761 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
762 u8 i;
763 u16 ctwindow;
764 u32 start_time, tsf_low;
765
766 switch (p2p_ps_state) {
767 case P2P_PS_DISABLE:
768 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
769 memset(p2p_ps_offload, 0, sizeof(struct p2p_ps_offload_t));
770 break;
771 case P2P_PS_ENABLE:
772 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
773 /* update CTWindow value. */
774 if (p2pinfo->ctwindow > 0) {
775 p2p_ps_offload->ctwindow_en = 1;
776 ctwindow = p2pinfo->ctwindow;
777 rtl8723e_set_p2p_ctw_period_cmd(hw, ctwindow);
778 }
779
780 /* hw only support 2 set of NoA */
781 for (i = 0; i < p2pinfo->noa_num; i++) {
782 /* To control the register setting for which NOA*/
783 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
784 if (i == 0)
785 p2p_ps_offload->noa0_en = 1;
786 else
787 p2p_ps_offload->noa1_en = 1;
788
789 /* config P2P NoA Descriptor Register */
790 rtl_write_dword(rtlpriv, 0x5E0,
791 p2pinfo->noa_duration[i]);
792 rtl_write_dword(rtlpriv, 0x5E4,
793 p2pinfo->noa_interval[i]);
794
795 /*Get Current TSF value */
796 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
797
798 start_time = p2pinfo->noa_start_time[i];
799 if (p2pinfo->noa_count_type[i] != 1) {
800 while (start_time <= (tsf_low+(50*1024))) {
801 start_time += p2pinfo->noa_interval[i];
802 if (p2pinfo->noa_count_type[i] != 255)
803 p2pinfo->noa_count_type[i]--;
804 }
805 }
806 rtl_write_dword(rtlpriv, 0x5E8, start_time);
807 rtl_write_dword(rtlpriv, 0x5EC,
808 p2pinfo->noa_count_type[i]);
809 }
810 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
811 /* rst p2p circuit */
812 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
813
814 p2p_ps_offload->offload_en = 1;
815
816 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
817 p2p_ps_offload->role = 1;
818 p2p_ps_offload->allstasleep = 0;
819 } else {
820 p2p_ps_offload->role = 0;
821 }
822 p2p_ps_offload->discovery = 0;
823 }
824 break;
825 case P2P_PS_SCAN:
826 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
827 p2p_ps_offload->discovery = 1;
828 break;
829 case P2P_PS_SCAN_DONE:
830 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
831 p2p_ps_offload->discovery = 0;
832 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
833 break;
834 default:
835 break;
836 }
837 rtl8723ae_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
838}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
index 89994e16dc83..ed3b795e6980 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
@@ -70,8 +70,10 @@ enum rtl8192c_h2c_cmd {
70 H2C_SETPWRMODE = 1, 70 H2C_SETPWRMODE = 1,
71 H2C_JOINBSSRPT = 2, 71 H2C_JOINBSSRPT = 2,
72 H2C_RSVDPAGE = 3, 72 H2C_RSVDPAGE = 3,
73 H2C_RSSI_REPORT = 5, 73 H2C_RSSI_REPORT = 4,
74 H2C_RA_MASK = 6, 74 H2C_P2P_PS_CTW_CMD = 5,
75 H2C_P2P_PS_OFFLOAD = 6,
76 H2C_RA_MASK = 7,
75 MAX_H2CCMD 77 MAX_H2CCMD
76}; 78};
77 79
@@ -97,5 +99,6 @@ void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw);
97void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); 99void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
98void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); 100void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
99void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); 101void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
102void rtl8723ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
100 103
101#endif 104#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
index 9a0c71c2e15e..c333dfd116b8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -449,6 +449,9 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
449 rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); 449 rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val));
450 450
451 break; } 451 break; }
452 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
453 rtl8723ae_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
454 break;
452 case HW_VAR_AID:{ 455 case HW_VAR_AID:{
453 u16 u2btmp; 456 u16 u2btmp;
454 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); 457 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
@@ -474,6 +477,39 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
474 if (btype_ibss == true) 477 if (btype_ibss == true)
475 _rtl8723ae_resume_tx_beacon(hw); 478 _rtl8723ae_resume_tx_beacon(hw);
476 break; } 479 break; }
480 case HW_VAR_FW_LPS_ACTION: {
481 bool enter_fwlps = *((bool *)val);
482 u8 rpwm_val, fw_pwrmode;
483 bool fw_current_inps;
484
485 if (enter_fwlps) {
486 rpwm_val = 0x02; /* RF off */
487 fw_current_inps = true;
488 rtlpriv->cfg->ops->set_hw_reg(hw,
489 HW_VAR_FW_PSMODE_STATUS,
490 (u8 *)(&fw_current_inps));
491 rtlpriv->cfg->ops->set_hw_reg(hw,
492 HW_VAR_H2C_FW_PWRMODE,
493 (u8 *)(&ppsc->fwctrl_psmode));
494
495 rtlpriv->cfg->ops->set_hw_reg(hw,
496 HW_VAR_SET_RPWM,
497 (u8 *)(&rpwm_val));
498 } else {
499 rpwm_val = 0x0C; /* RF on */
500 fw_pwrmode = FW_PS_ACTIVE_MODE;
501 fw_current_inps = false;
502 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
503 (u8 *)(&rpwm_val));
504 rtlpriv->cfg->ops->set_hw_reg(hw,
505 HW_VAR_H2C_FW_PWRMODE,
506 (u8 *)(&fw_pwrmode));
507
508 rtlpriv->cfg->ops->set_hw_reg(hw,
509 HW_VAR_FW_PSMODE_STATUS,
510 (u8 *)(&fw_current_inps));
511 }
512 break; }
477 default: 513 default:
478 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 514 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
479 "switch case not processed\n"); 515 "switch case not processed\n");
@@ -1379,7 +1415,7 @@ static void _rtl8723ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1379 } 1415 }
1380 1416
1381 for (i = 0; i < 14; i++) { 1417 for (i = 0; i < 14; i++) {
1382 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1418 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1383 "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " 1419 "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
1384 "[0x%x / 0x%x / 0x%x]\n", rf_path, i, 1420 "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
1385 rtlefuse->txpwrlevel_cck[rf_path][i], 1421 rtlefuse->txpwrlevel_cck[rf_path][i],
@@ -1420,10 +1456,10 @@ static void _rtl8723ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1420 0xf0) >> 4); 1456 0xf0) >> 4);
1421 } 1457 }
1422 1458
1423 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1459 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1424 "RF-%d pwrgroup_ht20[%d] = 0x%x\n", rf_path, i, 1460 "RF-%d pwrgroup_ht20[%d] = 0x%x\n", rf_path, i,
1425 rtlefuse->pwrgroup_ht20[rf_path][i]); 1461 rtlefuse->pwrgroup_ht20[rf_path][i]);
1426 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1462 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1427 "RF-%d pwrgroup_ht40[%d] = 0x%x\n", rf_path, i, 1463 "RF-%d pwrgroup_ht40[%d] = 0x%x\n", rf_path, i,
1428 rtlefuse->pwrgroup_ht40[rf_path][i]); 1464 rtlefuse->pwrgroup_ht40[rf_path][i]);
1429 } 1465 }
@@ -1463,19 +1499,19 @@ static void _rtl8723ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1463 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; 1499 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7];
1464 1500
1465 for (i = 0; i < 14; i++) 1501 for (i = 0; i < 14; i++)
1466 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1502 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1467 "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, 1503 "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
1468 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); 1504 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
1469 for (i = 0; i < 14; i++) 1505 for (i = 0; i < 14; i++)
1470 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1506 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1471 "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, 1507 "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
1472 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); 1508 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
1473 for (i = 0; i < 14; i++) 1509 for (i = 0; i < 14; i++)
1474 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1510 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1475 "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, 1511 "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
1476 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); 1512 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
1477 for (i = 0; i < 14; i++) 1513 for (i = 0; i < 14; i++)
1478 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1514 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1479 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, 1515 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
1480 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); 1516 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
1481 1517
@@ -1483,14 +1519,14 @@ static void _rtl8723ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1483 rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); 1519 rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
1484 else 1520 else
1485 rtlefuse->eeprom_regulatory = 0; 1521 rtlefuse->eeprom_regulatory = 0;
1486 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1522 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1487 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); 1523 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
1488 1524
1489 if (!autoload_fail) 1525 if (!autoload_fail)
1490 rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; 1526 rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
1491 else 1527 else
1492 rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; 1528 rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI;
1493 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1529 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1494 "TSSI_A = 0x%x, TSSI_B = 0x%x\n", 1530 "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
1495 rtlefuse->eeprom_tssi[RF90_PATH_A], 1531 rtlefuse->eeprom_tssi[RF90_PATH_A],
1496 rtlefuse->eeprom_tssi[RF90_PATH_B]); 1532 rtlefuse->eeprom_tssi[RF90_PATH_B]);
@@ -1505,7 +1541,7 @@ static void _rtl8723ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1505 rtlefuse->apk_thermalmeterignore = true; 1541 rtlefuse->apk_thermalmeterignore = true;
1506 1542
1507 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; 1543 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
1508 RTPRINT(rtlpriv, FINIT, INIT_TxPower, 1544 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1509 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); 1545 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1510} 1546}
1511 1547
@@ -1713,19 +1749,7 @@ static void _rtl8723ae_hal_customized_behavior(struct ieee80211_hw *hw)
1713 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 1749 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1714 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1750 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1715 1751
1716 switch (rtlhal->oem_id) { 1752 pcipriv->ledctl.led_opendrain = true;
1717 case RT_CID_819x_HP:
1718 pcipriv->ledctl.led_opendrain = true;
1719 break;
1720 case RT_CID_819x_Lenovo:
1721 case RT_CID_DEFAULT:
1722 case RT_CID_TOSHIBA:
1723 case RT_CID_CCX:
1724 case RT_CID_819x_Acer:
1725 case RT_CID_WHQL:
1726 default:
1727 break;
1728 }
1729 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, 1753 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1730 "RT Customized ID: 0x%02X\n", rtlhal->oem_id); 1754 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
1731} 1755}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/led.c b/drivers/net/wireless/rtlwifi/rtl8723ae/led.c
index 9c4e1d811187..061526fe6e2d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/led.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/led.c
@@ -54,8 +54,9 @@ void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
54 case LED_PIN_GPIO0: 54 case LED_PIN_GPIO0:
55 break; 55 break;
56 case LED_PIN_LED0: 56 case LED_PIN_LED0:
57 ledcfg &= ~BIT(6);
57 rtl_write_byte(rtlpriv, 58 rtl_write_byte(rtlpriv,
58 REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); 59 REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5));
59 break; 60 break;
60 case LED_PIN_LED1: 61 case LED_PIN_LED1:
61 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); 62 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
@@ -84,16 +85,21 @@ void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
84 break; 85 break;
85 case LED_PIN_LED0: 86 case LED_PIN_LED0:
86 ledcfg &= 0xf0; 87 ledcfg &= 0xf0;
87 if (pcipriv->ledctl.led_opendrain) 88 if (pcipriv->ledctl.led_opendrain) {
89 ledcfg &= 0x90;
90 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3)));
91 ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
92 ledcfg &= 0xFE;
93 rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
94 } else {
95 ledcfg &= ~BIT(6);
88 rtl_write_byte(rtlpriv, REG_LEDCFG2, 96 rtl_write_byte(rtlpriv, REG_LEDCFG2,
89 (ledcfg | BIT(1) | BIT(5) | BIT(6))); 97 (ledcfg | BIT(3) | BIT(5)));
90 else 98 }
91 rtl_write_byte(rtlpriv, REG_LEDCFG2,
92 (ledcfg | BIT(3) | BIT(5) | BIT(6)));
93 break; 99 break;
94 case LED_PIN_LED1: 100 case LED_PIN_LED1:
95 ledcfg &= 0x0f; 101 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1) & 0x10;
96 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); 102 rtl_write_byte(rtlpriv, REG_LEDCFG1, (ledcfg | BIT(3)));
97 break; 103 break;
98 default: 104 default:
99 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 105 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
index bb7cc90bafb2..e4c4cdc3eb67 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
@@ -305,7 +305,7 @@ static struct rtl_hal_cfg rtl8723ae_hal_cfg = {
305 305
306 .maps[RTL_IMR_TXFOVW] = PHIMR_TXFOVW, 306 .maps[RTL_IMR_TXFOVW] = PHIMR_TXFOVW,
307 .maps[RTL_IMR_PSTIMEOUT] = PHIMR_PSTIMEOUT, 307 .maps[RTL_IMR_PSTIMEOUT] = PHIMR_PSTIMEOUT,
308 .maps[RTL_IMR_BcnInt] = PHIMR_BCNDMAINT0, 308 .maps[RTL_IMR_BCNINT] = PHIMR_BCNDMAINT0,
309 .maps[RTL_IMR_RXFOVW] = PHIMR_RXFOVW, 309 .maps[RTL_IMR_RXFOVW] = PHIMR_RXFOVW,
310 .maps[RTL_IMR_RDU] = PHIMR_RDU, 310 .maps[RTL_IMR_RDU] = PHIMR_RDU,
311 .maps[RTL_IMR_ATIMEND] = PHIMR_ATIMEND_E, 311 .maps[RTL_IMR_ATIMEND] = PHIMR_ATIMEND_E,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
index ac081297db50..6c64365308d3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
@@ -307,9 +307,6 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,
307 rx_status->freq = hw->conf.channel->center_freq; 307 rx_status->freq = hw->conf.channel->center_freq;
308 rx_status->band = hw->conf.channel->band; 308 rx_status->band = hw->conf.channel->band;
309 309
310 hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size
311 + status->rx_bufshift);
312
313 if (status->crc) 310 if (status->crc)
314 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; 311 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
315 312
@@ -330,6 +327,13 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,
330 * to decrypt it 327 * to decrypt it
331 */ 328 */
332 if (status->decrypted) { 329 if (status->decrypted) {
330 hdr = (struct ieee80211_hdr *)(skb->data +
331 status->rx_drvinfo_size + status->rx_bufshift);
332
333 if (!hdr) {
334 /* during testing, hdr could be NULL here */
335 return false;
336 }
333 if ((ieee80211_is_robust_mgmt_frame(hdr)) && 337 if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
334 (ieee80211_has_protected(hdr->frame_control))) 338 (ieee80211_has_protected(hdr->frame_control)))
335 rx_status->flag &= ~RX_FLAG_DECRYPTED; 339 rx_status->flag &= ~RX_FLAG_DECRYPTED;
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 41dce83ff41a..83915dcd0e58 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -308,6 +308,8 @@ static int _rtl_usb_init_tx(struct ieee80211_hw *hw)
308 return 0; 308 return 0;
309} 309}
310 310
311static void _rtl_rx_work(unsigned long param);
312
311static int _rtl_usb_init_rx(struct ieee80211_hw *hw) 313static int _rtl_usb_init_rx(struct ieee80211_hw *hw)
312{ 314{
313 struct rtl_priv *rtlpriv = rtl_priv(hw); 315 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -324,6 +326,12 @@ static int _rtl_usb_init_rx(struct ieee80211_hw *hw)
324 pr_info("rx_max_size %d, rx_urb_num %d, in_ep %d\n", 326 pr_info("rx_max_size %d, rx_urb_num %d, in_ep %d\n",
325 rtlusb->rx_max_size, rtlusb->rx_urb_num, rtlusb->in_ep); 327 rtlusb->rx_max_size, rtlusb->rx_urb_num, rtlusb->in_ep);
326 init_usb_anchor(&rtlusb->rx_submitted); 328 init_usb_anchor(&rtlusb->rx_submitted);
329 init_usb_anchor(&rtlusb->rx_cleanup_urbs);
330
331 skb_queue_head_init(&rtlusb->rx_queue);
332 rtlusb->rx_work_tasklet.func = _rtl_rx_work;
333 rtlusb->rx_work_tasklet.data = (unsigned long)rtlusb;
334
327 return 0; 335 return 0;
328} 336}
329 337
@@ -405,40 +413,30 @@ static void rtl_usb_init_sw(struct ieee80211_hw *hw)
405 rtlusb->disableHWSM = true; 413 rtlusb->disableHWSM = true;
406} 414}
407 415
408#define __RADIO_TAP_SIZE_RSV 32
409
410static void _rtl_rx_completed(struct urb *urb); 416static void _rtl_rx_completed(struct urb *urb);
411 417
412static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, 418static int _rtl_prep_rx_urb(struct ieee80211_hw *hw, struct rtl_usb *rtlusb,
413 struct rtl_usb *rtlusb, 419 struct urb *urb, gfp_t gfp_mask)
414 struct urb *urb,
415 gfp_t gfp_mask)
416{ 420{
417 struct sk_buff *skb;
418 struct rtl_priv *rtlpriv = rtl_priv(hw); 421 struct rtl_priv *rtlpriv = rtl_priv(hw);
422 void *buf;
419 423
420 skb = __dev_alloc_skb((rtlusb->rx_max_size + __RADIO_TAP_SIZE_RSV), 424 buf = usb_alloc_coherent(rtlusb->udev, rtlusb->rx_max_size, gfp_mask,
421 gfp_mask); 425 &urb->transfer_dma);
422 if (!skb) { 426 if (!buf) {
423 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, 427 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
424 "Failed to __dev_alloc_skb!!\n"); 428 "Failed to usb_alloc_coherent!!\n");
425 return ERR_PTR(-ENOMEM); 429 return -ENOMEM;
426 } 430 }
427 431
428 /* reserve some space for mac80211's radiotap */
429 skb_reserve(skb, __RADIO_TAP_SIZE_RSV);
430 usb_fill_bulk_urb(urb, rtlusb->udev, 432 usb_fill_bulk_urb(urb, rtlusb->udev,
431 usb_rcvbulkpipe(rtlusb->udev, rtlusb->in_ep), 433 usb_rcvbulkpipe(rtlusb->udev, rtlusb->in_ep),
432 skb->data, min(skb_tailroom(skb), 434 buf, rtlusb->rx_max_size, _rtl_rx_completed, rtlusb);
433 (int)rtlusb->rx_max_size), 435 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
434 _rtl_rx_completed, skb);
435 436
436 _rtl_install_trx_info(rtlusb, skb, rtlusb->in_ep); 437 return 0;
437 return skb;
438} 438}
439 439
440#undef __RADIO_TAP_SIZE_RSV
441
442static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw, 440static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw,
443 struct sk_buff *skb) 441 struct sk_buff *skb)
444{ 442{
@@ -522,22 +520,11 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,
522 if (unicast) 520 if (unicast)
523 rtlpriv->link_info.num_rx_inperiod++; 521 rtlpriv->link_info.num_rx_inperiod++;
524 } 522 }
525 if (likely(rtl_action_proc(hw, skb, false))) { 523
526 struct sk_buff *uskb = NULL; 524 if (likely(rtl_action_proc(hw, skb, false)))
527 u8 *pdata; 525 ieee80211_rx(hw, skb);
528 526 else
529 uskb = dev_alloc_skb(skb->len + 128);
530 if (uskb) { /* drop packet on allocation failure */
531 memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
532 sizeof(rx_status));
533 pdata = (u8 *)skb_put(uskb, skb->len);
534 memcpy(pdata, skb->data, skb->len);
535 ieee80211_rx_irqsafe(hw, uskb);
536 }
537 dev_kfree_skb_any(skb);
538 } else {
539 dev_kfree_skb_any(skb); 527 dev_kfree_skb_any(skb);
540 }
541 } 528 }
542} 529}
543 530
@@ -554,15 +541,70 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)
554 while (!skb_queue_empty(&rx_queue)) { 541 while (!skb_queue_empty(&rx_queue)) {
555 _skb = skb_dequeue(&rx_queue); 542 _skb = skb_dequeue(&rx_queue);
556 _rtl_usb_rx_process_agg(hw, _skb); 543 _rtl_usb_rx_process_agg(hw, _skb);
557 ieee80211_rx_irqsafe(hw, _skb); 544 ieee80211_rx(hw, _skb);
558 } 545 }
559} 546}
560 547
548#define __RX_SKB_MAX_QUEUED 32
549
550static void _rtl_rx_work(unsigned long param)
551{
552 struct rtl_usb *rtlusb = (struct rtl_usb *)param;
553 struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf);
554 struct sk_buff *skb;
555
556 while ((skb = skb_dequeue(&rtlusb->rx_queue))) {
557 if (unlikely(IS_USB_STOP(rtlusb))) {
558 dev_kfree_skb_any(skb);
559 continue;
560 }
561
562 if (likely(!rtlusb->usb_rx_segregate_hdl)) {
563 _rtl_usb_rx_process_noagg(hw, skb);
564 } else {
565 /* TO DO */
566 _rtl_rx_pre_process(hw, skb);
567 pr_err("rx agg not supported\n");
568 }
569 }
570}
571
572static unsigned int _rtl_rx_get_padding(struct ieee80211_hdr *hdr,
573 unsigned int len)
574{
575 unsigned int padding = 0;
576
577 /* make function no-op when possible */
578 if (NET_IP_ALIGN == 0 || len < sizeof(*hdr))
579 return 0;
580
581 /* alignment calculation as in lbtf_rx() / carl9170_rx_copy_data() */
582 /* TODO: deduplicate common code, define helper function instead? */
583
584 if (ieee80211_is_data_qos(hdr->frame_control)) {
585 u8 *qc = ieee80211_get_qos_ctl(hdr);
586
587 padding ^= NET_IP_ALIGN;
588
589 /* Input might be invalid, avoid accessing memory outside
590 * the buffer.
591 */
592 if ((unsigned long)qc - (unsigned long)hdr < len &&
593 *qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT)
594 padding ^= NET_IP_ALIGN;
595 }
596
597 if (ieee80211_has_a4(hdr->frame_control))
598 padding ^= NET_IP_ALIGN;
599
600 return padding;
601}
602
603#define __RADIO_TAP_SIZE_RSV 32
604
561static void _rtl_rx_completed(struct urb *_urb) 605static void _rtl_rx_completed(struct urb *_urb)
562{ 606{
563 struct sk_buff *skb = (struct sk_buff *)_urb->context; 607 struct rtl_usb *rtlusb = (struct rtl_usb *)_urb->context;
564 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
565 struct rtl_usb *rtlusb = (struct rtl_usb *)info->rate_driver_data[0];
566 struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); 608 struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf);
567 struct rtl_priv *rtlpriv = rtl_priv(hw); 609 struct rtl_priv *rtlpriv = rtl_priv(hw);
568 int err = 0; 610 int err = 0;
@@ -571,28 +613,50 @@ static void _rtl_rx_completed(struct urb *_urb)
571 goto free; 613 goto free;
572 614
573 if (likely(0 == _urb->status)) { 615 if (likely(0 == _urb->status)) {
574 /* If this code were moved to work queue, would CPU 616 unsigned int padding;
575 * utilization be improved? NOTE: We shall allocate another skb 617 struct sk_buff *skb;
576 * and reuse the original one. 618 unsigned int qlen;
577 */ 619 unsigned int size = _urb->actual_length;
578 skb_put(skb, _urb->actual_length); 620 struct ieee80211_hdr *hdr;
579 621
580 if (likely(!rtlusb->usb_rx_segregate_hdl)) { 622 if (size < RTL_RX_DESC_SIZE + sizeof(struct ieee80211_hdr)) {
581 struct sk_buff *_skb; 623 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
582 _rtl_usb_rx_process_noagg(hw, skb); 624 "Too short packet from bulk IN! (len: %d)\n",
583 _skb = _rtl_prep_rx_urb(hw, rtlusb, _urb, GFP_ATOMIC); 625 size);
584 if (IS_ERR(_skb)) { 626 goto resubmit;
585 err = PTR_ERR(_skb); 627 }
586 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, 628
587 "Can't allocate skb for bulk IN!\n"); 629 qlen = skb_queue_len(&rtlusb->rx_queue);
588 return; 630 if (qlen >= __RX_SKB_MAX_QUEUED) {
589 } 631 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
590 skb = _skb; 632 "Pending RX skbuff queue full! (qlen: %d)\n",
591 } else{ 633 qlen);
592 /* TO DO */ 634 goto resubmit;
593 _rtl_rx_pre_process(hw, skb);
594 pr_err("rx agg not supported\n");
595 } 635 }
636
637 hdr = (void *)(_urb->transfer_buffer + RTL_RX_DESC_SIZE);
638 padding = _rtl_rx_get_padding(hdr, size - RTL_RX_DESC_SIZE);
639
640 skb = dev_alloc_skb(size + __RADIO_TAP_SIZE_RSV + padding);
641 if (!skb) {
642 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
643 "Can't allocate skb for bulk IN!\n");
644 goto resubmit;
645 }
646
647 _rtl_install_trx_info(rtlusb, skb, rtlusb->in_ep);
648
649 /* Make sure the payload data is 4 byte aligned. */
650 skb_reserve(skb, padding);
651
652 /* reserve some space for mac80211's radiotap */
653 skb_reserve(skb, __RADIO_TAP_SIZE_RSV);
654
655 memcpy(skb_put(skb, size), _urb->transfer_buffer, size);
656
657 skb_queue_tail(&rtlusb->rx_queue, skb);
658 tasklet_schedule(&rtlusb->rx_work_tasklet);
659
596 goto resubmit; 660 goto resubmit;
597 } 661 }
598 662
@@ -608,9 +672,6 @@ static void _rtl_rx_completed(struct urb *_urb)
608 } 672 }
609 673
610resubmit: 674resubmit:
611 skb_reset_tail_pointer(skb);
612 skb_trim(skb, 0);
613
614 usb_anchor_urb(_urb, &rtlusb->rx_submitted); 675 usb_anchor_urb(_urb, &rtlusb->rx_submitted);
615 err = usb_submit_urb(_urb, GFP_ATOMIC); 676 err = usb_submit_urb(_urb, GFP_ATOMIC);
616 if (unlikely(err)) { 677 if (unlikely(err)) {
@@ -620,13 +681,34 @@ resubmit:
620 return; 681 return;
621 682
622free: 683free:
623 dev_kfree_skb_irq(skb); 684 /* On some architectures, usb_free_coherent must not be called from
685 * hardirq context. Queue urb to cleanup list.
686 */
687 usb_anchor_urb(_urb, &rtlusb->rx_cleanup_urbs);
688}
689
690#undef __RADIO_TAP_SIZE_RSV
691
692static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw)
693{
694 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
695 struct urb *urb;
696
697 usb_kill_anchored_urbs(&rtlusb->rx_submitted);
698
699 tasklet_kill(&rtlusb->rx_work_tasklet);
700 skb_queue_purge(&rtlusb->rx_queue);
701
702 while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) {
703 usb_free_coherent(urb->dev, urb->transfer_buffer_length,
704 urb->transfer_buffer, urb->transfer_dma);
705 usb_free_urb(urb);
706 }
624} 707}
625 708
626static int _rtl_usb_receive(struct ieee80211_hw *hw) 709static int _rtl_usb_receive(struct ieee80211_hw *hw)
627{ 710{
628 struct urb *urb; 711 struct urb *urb;
629 struct sk_buff *skb;
630 int err; 712 int err;
631 int i; 713 int i;
632 struct rtl_priv *rtlpriv = rtl_priv(hw); 714 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -645,11 +727,10 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw)
645 goto err_out; 727 goto err_out;
646 } 728 }
647 729
648 skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); 730 err = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL);
649 if (IS_ERR(skb)) { 731 if (err < 0) {
650 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, 732 RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
651 "Failed to prep_rx_urb!!\n"); 733 "Failed to prep_rx_urb!!\n");
652 err = PTR_ERR(skb);
653 usb_free_urb(urb); 734 usb_free_urb(urb);
654 goto err_out; 735 goto err_out;
655 } 736 }
@@ -664,6 +745,7 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw)
664 745
665err_out: 746err_out:
666 usb_kill_anchored_urbs(&rtlusb->rx_submitted); 747 usb_kill_anchored_urbs(&rtlusb->rx_submitted);
748 _rtl_usb_cleanup_rx(hw);
667 return err; 749 return err;
668} 750}
669 751
@@ -705,7 +787,7 @@ static void rtl_usb_cleanup(struct ieee80211_hw *hw)
705 SET_USB_STOP(rtlusb); 787 SET_USB_STOP(rtlusb);
706 788
707 /* clean up rx stuff. */ 789 /* clean up rx stuff. */
708 usb_kill_anchored_urbs(&rtlusb->rx_submitted); 790 _rtl_usb_cleanup_rx(hw);
709 791
710 /* clean up tx stuff */ 792 /* clean up tx stuff */
711 for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) { 793 for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) {
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h
index fb986f98d1df..685273ca9561 100644
--- a/drivers/net/wireless/rtlwifi/usb.h
+++ b/drivers/net/wireless/rtlwifi/usb.h
@@ -136,11 +136,14 @@ struct rtl_usb {
136 void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); 136 void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *);
137 137
138 /* Rx */ 138 /* Rx */
139 u8 in_ep_nums ; 139 u8 in_ep_nums;
140 u32 in_ep; /* Bulk IN endpoint number */ 140 u32 in_ep; /* Bulk IN endpoint number */
141 u32 rx_max_size; /* Bulk IN max buffer size */ 141 u32 rx_max_size; /* Bulk IN max buffer size */
142 u32 rx_urb_num; /* How many Bulk INs are submitted to host. */ 142 u32 rx_urb_num; /* How many Bulk INs are submitted to host. */
143 struct usb_anchor rx_submitted; 143 struct usb_anchor rx_submitted;
144 struct usb_anchor rx_cleanup_urbs;
145 struct tasklet_struct rx_work_tasklet;
146 struct sk_buff_head rx_queue;
144 void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, 147 void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *,
145 struct sk_buff_head *); 148 struct sk_buff_head *);
146 void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); 149 void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *);
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index c3eff32acf6c..44328baa6389 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -99,11 +99,36 @@
99#define CHANNEL_GROUP_MAX_5G 9 99#define CHANNEL_GROUP_MAX_5G 9
100#define CHANNEL_MAX_NUMBER_2G 14 100#define CHANNEL_MAX_NUMBER_2G 14
101#define AVG_THERMAL_NUM 8 101#define AVG_THERMAL_NUM 8
102#define AVG_THERMAL_NUM_88E 4
102#define MAX_TID_COUNT 9 103#define MAX_TID_COUNT 9
103 104
104/* for early mode */ 105/* for early mode */
105#define FCS_LEN 4 106#define FCS_LEN 4
106#define EM_HDR_LEN 8 107#define EM_HDR_LEN 8
108
109#define MAX_TX_COUNT 4
110#define MAX_RF_PATH 4
111#define MAX_CHNL_GROUP_24G 6
112#define MAX_CHNL_GROUP_5G 14
113
114struct txpower_info_2g {
115 u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
116 u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
117 /*If only one tx, only BW20 and OFDM are used.*/
118 u8 cck_diff[MAX_RF_PATH][MAX_TX_COUNT];
119 u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT];
120 u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT];
121 u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT];
122};
123
124struct txpower_info_5g {
125 u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_5G];
126 /*If only one tx, only BW20, OFDM, BW80 and BW160 are used.*/
127 u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT];
128 u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT];
129 u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT];
130};
131
107enum intf_type { 132enum intf_type {
108 INTF_PCI = 0, 133 INTF_PCI = 0,
109 INTF_USB = 1, 134 INTF_USB = 1,
@@ -137,6 +162,7 @@ enum hardware_type {
137 HARDWARE_TYPE_RTL8192DU, 162 HARDWARE_TYPE_RTL8192DU,
138 HARDWARE_TYPE_RTL8723AE, 163 HARDWARE_TYPE_RTL8723AE,
139 HARDWARE_TYPE_RTL8723U, 164 HARDWARE_TYPE_RTL8723U,
165 HARDWARE_TYPE_RTL8188EE,
140 166
141 /* keep it last */ 167 /* keep it last */
142 HARDWARE_TYPE_NUM 168 HARDWARE_TYPE_NUM
@@ -263,7 +289,7 @@ enum hw_variables {
263 HW_VAR_RATR_0, 289 HW_VAR_RATR_0,
264 HW_VAR_RRSR, 290 HW_VAR_RRSR,
265 HW_VAR_CPU_RST, 291 HW_VAR_CPU_RST,
266 HW_VAR_CECHK_BSSID, 292 HW_VAR_CHECK_BSSID,
267 HW_VAR_LBK_MODE, 293 HW_VAR_LBK_MODE,
268 HW_VAR_AES_11N_FIX, 294 HW_VAR_AES_11N_FIX,
269 HW_VAR_USB_RX_AGGR, 295 HW_VAR_USB_RX_AGGR,
@@ -278,7 +304,10 @@ enum hw_variables {
278 HW_VAR_SET_RPWM, 304 HW_VAR_SET_RPWM,
279 HW_VAR_H2C_FW_PWRMODE, 305 HW_VAR_H2C_FW_PWRMODE,
280 HW_VAR_H2C_FW_JOINBSSRPT, 306 HW_VAR_H2C_FW_JOINBSSRPT,
307 HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
281 HW_VAR_FW_PSMODE_STATUS, 308 HW_VAR_FW_PSMODE_STATUS,
309 HW_VAR_RESUME_CLK_ON,
310 HW_VAR_FW_LPS_ACTION,
282 HW_VAR_1X1_RECV_COMBINE, 311 HW_VAR_1X1_RECV_COMBINE,
283 HW_VAR_STOP_SEND_BEACON, 312 HW_VAR_STOP_SEND_BEACON,
284 HW_VAR_TSF_TIMER, 313 HW_VAR_TSF_TIMER,
@@ -305,6 +334,7 @@ enum hw_variables {
305 HW_VAR_INT_AC, 334 HW_VAR_INT_AC,
306 HW_VAR_RF_TIMING, 335 HW_VAR_RF_TIMING,
307 336
337 HAL_DEF_WOWLAN,
308 HW_VAR_MRC, 338 HW_VAR_MRC,
309 339
310 HW_VAR_MGT_FILTER, 340 HW_VAR_MGT_FILTER,
@@ -461,6 +491,7 @@ enum rtl_var_map {
461 EFUSE_MAX_SECTION_MAP, 491 EFUSE_MAX_SECTION_MAP,
462 EFUSE_REAL_CONTENT_SIZE, 492 EFUSE_REAL_CONTENT_SIZE,
463 EFUSE_OOB_PROTECT_BYTES_LEN, 493 EFUSE_OOB_PROTECT_BYTES_LEN,
494 EFUSE_ACCESS,
464 495
465 /*CAM map */ 496 /*CAM map */
466 RWCAM, 497 RWCAM,
@@ -493,7 +524,7 @@ enum rtl_var_map {
493 RTL_IMR_TIMEOUT1, /*Timeout interrupt 1 */ 524 RTL_IMR_TIMEOUT1, /*Timeout interrupt 1 */
494 RTL_IMR_TXFOVW, /*Transmit FIFO Overflow */ 525 RTL_IMR_TXFOVW, /*Transmit FIFO Overflow */
495 RTL_IMR_PSTIMEOUT, /*Power save time out interrupt */ 526 RTL_IMR_PSTIMEOUT, /*Power save time out interrupt */
496 RTL_IMR_BcnInt, /*Beacon DMA Interrupt 0 */ 527 RTL_IMR_BCNINT, /*Beacon DMA Interrupt 0 */
497 RTL_IMR_RXFOVW, /*Receive FIFO Overflow */ 528 RTL_IMR_RXFOVW, /*Receive FIFO Overflow */
498 RTL_IMR_RDU, /*Receive Descriptor Unavailable */ 529 RTL_IMR_RDU, /*Receive Descriptor Unavailable */
499 RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */ 530 RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */
@@ -508,7 +539,7 @@ enum rtl_var_map {
508 RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */ 539 RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */
509 RTL_IMR_VODOK, /*AC_VO DMA Interrupt */ 540 RTL_IMR_VODOK, /*AC_VO DMA Interrupt */
510 RTL_IMR_ROK, /*Receive DMA OK Interrupt */ 541 RTL_IMR_ROK, /*Receive DMA OK Interrupt */
511 RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK | 542 RTL_IBSS_INT_MASKS, /*(RTL_IMR_BCNINT | RTL_IMR_TBDOK |
512 * RTL_IMR_TBDER) */ 543 * RTL_IMR_TBDER) */
513 RTL_IMR_C2HCMD, /*fw interrupt*/ 544 RTL_IMR_C2HCMD, /*fw interrupt*/
514 545
@@ -742,6 +773,11 @@ struct false_alarm_statistics {
742 u32 cnt_ofdm_fail; 773 u32 cnt_ofdm_fail;
743 u32 cnt_cck_fail; 774 u32 cnt_cck_fail;
744 u32 cnt_all; 775 u32 cnt_all;
776 u32 cnt_ofdm_cca;
777 u32 cnt_cck_cca;
778 u32 cnt_cca_all;
779 u32 cnt_bw_usc;
780 u32 cnt_bw_lsc;
745}; 781};
746 782
747struct init_gain { 783struct init_gain {
@@ -826,8 +862,67 @@ struct rtl_rfkill {
826 bool rfkill_state; /*0 is off, 1 is on */ 862 bool rfkill_state; /*0 is off, 1 is on */
827}; 863};
828 864
865/*for P2P PS**/
866#define P2P_MAX_NOA_NUM 2
867
868enum p2p_role {
869 P2P_ROLE_DISABLE = 0,
870 P2P_ROLE_DEVICE = 1,
871 P2P_ROLE_CLIENT = 2,
872 P2P_ROLE_GO = 3
873};
874
875enum p2p_ps_state {
876 P2P_PS_DISABLE = 0,
877 P2P_PS_ENABLE = 1,
878 P2P_PS_SCAN = 2,
879 P2P_PS_SCAN_DONE = 3,
880 P2P_PS_ALLSTASLEEP = 4, /* for P2P GO */
881};
882
883enum p2p_ps_mode {
884 P2P_PS_NONE = 0,
885 P2P_PS_CTWINDOW = 1,
886 P2P_PS_NOA = 2,
887 P2P_PS_MIX = 3, /* CTWindow and NoA */
888};
889
890struct rtl_p2p_ps_info {
891 enum p2p_ps_mode p2p_ps_mode; /* indicate p2p ps mode */
892 enum p2p_ps_state p2p_ps_state; /* indicate p2p ps state */
893 u8 noa_index; /* Identifies instance of Notice of Absence timing. */
894 /* Client traffic window. A period of time in TU after TBTT. */
895 u8 ctwindow;
896 u8 opp_ps; /* opportunistic power save. */
897 u8 noa_num; /* number of NoA descriptor in P2P IE. */
898 /* Count for owner, Type of client. */
899 u8 noa_count_type[P2P_MAX_NOA_NUM];
900 /* Max duration for owner, preferred or min acceptable duration
901 * for client.
902 */
903 u32 noa_duration[P2P_MAX_NOA_NUM];
904 /* Length of interval for owner, preferred or max acceptable intervali
905 * of client.
906 */
907 u32 noa_interval[P2P_MAX_NOA_NUM];
908 /* schedule in terms of the lower 4 bytes of the TSF timer. */
909 u32 noa_start_time[P2P_MAX_NOA_NUM];
910};
911
912struct p2p_ps_offload_t {
913 u8 offload_en:1;
914 u8 role:1; /* 1: Owner, 0: Client */
915 u8 ctwindow_en:1;
916 u8 noa0_en:1;
917 u8 noa1_en:1;
918 u8 allstasleep:1;
919 u8 discovery:1;
920 u8 reserved:1;
921};
922
829#define IQK_MATRIX_REG_NUM 8 923#define IQK_MATRIX_REG_NUM 8
830#define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21) 924#define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21)
925
831struct iqk_matrix_regs { 926struct iqk_matrix_regs {
832 bool iqk_done; 927 bool iqk_done;
833 long value[1][IQK_MATRIX_REG_NUM]; 928 long value[1][IQK_MATRIX_REG_NUM];
@@ -889,7 +984,7 @@ struct rtl_phy {
889 984
890 /* Dual mac */ 985 /* Dual mac */
891 bool need_iqk; 986 bool need_iqk;
892 struct iqk_matrix_regs iqk_matrix_regsetting[IQK_MATRIX_SETTINGS_NUM]; 987 struct iqk_matrix_regs iqk_matrix[IQK_MATRIX_SETTINGS_NUM];
893 988
894 bool rfpi_enable; 989 bool rfpi_enable;
895 990
@@ -902,6 +997,8 @@ struct rtl_phy {
902 /* the current Tx power level */ 997 /* the current Tx power level */
903 u8 cur_cck_txpwridx; 998 u8 cur_cck_txpwridx;
904 u8 cur_ofdm24g_txpwridx; 999 u8 cur_ofdm24g_txpwridx;
1000 u8 cur_bw20_txpwridx;
1001 u8 cur_bw40_txpwridx;
905 1002
906 u32 rfreg_chnlval[2]; 1003 u32 rfreg_chnlval[2];
907 bool apk_done; 1004 bool apk_done;
@@ -940,20 +1037,21 @@ struct rtl_ht_agg {
940 u8 rx_agg_state; 1037 u8 rx_agg_state;
941}; 1038};
942 1039
1040struct rssi_sta {
1041 long undec_sm_pwdb;
1042};
1043
943struct rtl_tid_data { 1044struct rtl_tid_data {
944 u16 seq_number; 1045 u16 seq_number;
945 struct rtl_ht_agg agg; 1046 struct rtl_ht_agg agg;
946}; 1047};
947 1048
948struct rssi_sta {
949 long undec_sm_pwdb;
950};
951
952struct rtl_sta_info { 1049struct rtl_sta_info {
953 struct list_head list; 1050 struct list_head list;
954 u8 ratr_index; 1051 u8 ratr_index;
955 u8 wireless_mode; 1052 u8 wireless_mode;
956 u8 mimo_ps; 1053 u8 mimo_ps;
1054 u8 mac_addr[ETH_ALEN];
957 struct rtl_tid_data tids[MAX_TID_COUNT]; 1055 struct rtl_tid_data tids[MAX_TID_COUNT];
958 1056
959 /* just used for ap adhoc or mesh*/ 1057 /* just used for ap adhoc or mesh*/
@@ -1005,6 +1103,8 @@ struct rtl_mac {
1005 int n_bitrates; 1103 int n_bitrates;
1006 1104
1007 bool offchan_delay; 1105 bool offchan_delay;
1106 u8 p2p; /*using p2p role*/
1107 bool p2p_in_use;
1008 1108
1009 /*filters */ 1109 /*filters */
1010 u32 rx_conf; 1110 u32 rx_conf;
@@ -1014,11 +1114,11 @@ struct rtl_mac {
1014 1114
1015 bool act_scanning; 1115 bool act_scanning;
1016 u8 cnt_after_linked; 1116 u8 cnt_after_linked;
1117 bool skip_scan;
1017 1118
1018 /* early mode */ 1119 /* early mode */
1019 /* skb wait queue */ 1120 /* skb wait queue */
1020 struct sk_buff_head skb_waitq[MAX_TID_COUNT]; 1121 struct sk_buff_head skb_waitq[MAX_TID_COUNT];
1021 u8 earlymode_threshold;
1022 1122
1023 /*RDG*/ 1123 /*RDG*/
1024 bool rdg_en; 1124 bool rdg_en;
@@ -1042,6 +1142,7 @@ struct rtl_mac {
1042 u8 retry_short; 1142 u8 retry_short;
1043 u8 retry_long; 1143 u8 retry_long;
1044 u16 assoc_id; 1144 u16 assoc_id;
1145 bool hiddenssid;
1045 1146
1046 /*IBSS*/ 1147 /*IBSS*/
1047 int beacon_interval; 1148 int beacon_interval;
@@ -1111,10 +1212,13 @@ struct bt_coexist_8723 {
1111 1212
1112struct rtl_hal { 1213struct rtl_hal {
1113 struct ieee80211_hw *hw; 1214 struct ieee80211_hw *hw;
1114 struct bt_coexist_8723 hal_coex_8723; 1215 bool driver_is_goingto_unload;
1115 bool up_first_time; 1216 bool up_first_time;
1217 bool first_init;
1116 bool being_init_adapter; 1218 bool being_init_adapter;
1117 bool bbrf_ready; 1219 bool bbrf_ready;
1220 bool mac_func_enable;
1221 struct bt_coexist_8723 hal_coex_8723;
1118 1222
1119 enum intf_type interface; 1223 enum intf_type interface;
1120 u16 hw_type; /*92c or 92d or 92s and so on */ 1224 u16 hw_type; /*92c or 92d or 92s and so on */
@@ -1122,6 +1226,7 @@ struct rtl_hal {
1122 u8 oem_id; 1226 u8 oem_id;
1123 u32 version; /*version of chip */ 1227 u32 version; /*version of chip */
1124 u8 state; /*stop 0, start 1 */ 1228 u8 state; /*stop 0, start 1 */
1229 u8 board_type;
1125 1230
1126 /*firmware */ 1231 /*firmware */
1127 u32 fwsize; 1232 u32 fwsize;
@@ -1141,6 +1246,10 @@ struct rtl_hal {
1141 bool set_fwcmd_inprogress; 1246 bool set_fwcmd_inprogress;
1142 u8 current_fwcmd_io; 1247 u8 current_fwcmd_io;
1143 1248
1249 struct p2p_ps_offload_t p2p_ps_offload;
1250 bool fw_clk_change_in_progress;
1251 bool allow_sw_to_change_hwclc;
1252 u8 fw_ps_state;
1144 /**/ 1253 /**/
1145 bool driver_going2unload; 1254 bool driver_going2unload;
1146 1255
@@ -1157,6 +1266,7 @@ struct rtl_hal {
1157 /* just for DualMac S3S4 */ 1266 /* just for DualMac S3S4 */
1158 u8 macphyctl_reg; 1267 u8 macphyctl_reg;
1159 bool earlymode_enable; 1268 bool earlymode_enable;
1269 u8 max_earlymode_num;
1160 /* Dual mac*/ 1270 /* Dual mac*/
1161 bool during_mac0init_radiob; 1271 bool during_mac0init_radiob;
1162 bool during_mac1init_radioa; 1272 bool during_mac1init_radioa;
@@ -1193,6 +1303,29 @@ struct rtl_security {
1193 u8 *pairwise_key; 1303 u8 *pairwise_key;
1194}; 1304};
1195 1305
1306#define ASSOCIATE_ENTRY_NUM 33
1307
1308struct fast_ant_training {
1309 u8 bssid[6];
1310 u8 antsel_rx_keep_0;
1311 u8 antsel_rx_keep_1;
1312 u8 antsel_rx_keep_2;
1313 u32 ant_sum[7];
1314 u32 ant_cnt[7];
1315 u32 ant_ave[7];
1316 u8 fat_state;
1317 u32 train_idx;
1318 u8 antsel_a[ASSOCIATE_ENTRY_NUM];
1319 u8 antsel_b[ASSOCIATE_ENTRY_NUM];
1320 u8 antsel_c[ASSOCIATE_ENTRY_NUM];
1321 u32 main_ant_sum[ASSOCIATE_ENTRY_NUM];
1322 u32 aux_ant_sum[ASSOCIATE_ENTRY_NUM];
1323 u32 main_ant_cnt[ASSOCIATE_ENTRY_NUM];
1324 u32 aux_ant_cnt[ASSOCIATE_ENTRY_NUM];
1325 u8 rx_idle_ant;
1326 bool becomelinked;
1327};
1328
1196struct rtl_dm { 1329struct rtl_dm {
1197 /*PHY status for Dynamic Management */ 1330 /*PHY status for Dynamic Management */
1198 long entry_min_undec_sm_pwdb; 1331 long entry_min_undec_sm_pwdb;
@@ -1229,9 +1362,24 @@ struct rtl_dm {
1229 bool disable_tx_int; 1362 bool disable_tx_int;
1230 char ofdm_index[2]; 1363 char ofdm_index[2];
1231 char cck_index; 1364 char cck_index;
1365 char delta_power_index;
1366 char delta_power_index_last;
1367 char power_index_offset;
1368
1369 /*88e tx power tracking*/
1370 u8 swing_idx_ofdm[2];
1371 u8 swing_idx_ofdm_cur;
1372 u8 swing_idx_ofdm_base;
1373 bool swing_flag_ofdm;
1374 u8 swing_idx_cck;
1375 u8 swing_idx_cck_cur;
1376 u8 swing_idx_cck_base;
1377 bool swing_flag_cck;
1232 1378
1233 /* DMSP */ 1379 /* DMSP */
1234 bool supp_phymode_switch; 1380 bool supp_phymode_switch;
1381
1382 struct fast_ant_training fat_table;
1235}; 1383};
1236 1384
1237#define EFUSE_MAX_LOGICAL_SIZE 256 1385#define EFUSE_MAX_LOGICAL_SIZE 256
@@ -1264,6 +1412,9 @@ struct rtl_efuse {
1264 u8 external_pa; 1412 u8 external_pa;
1265 1413
1266 u8 dev_addr[6]; 1414 u8 dev_addr[6];
1415 u8 wowlan_enable;
1416 u8 antenna_div_cfg;
1417 u8 antenna_div_type;
1267 1418
1268 bool txpwr_fromeprom; 1419 bool txpwr_fromeprom;
1269 u8 eeprom_crystalcap; 1420 u8 eeprom_crystalcap;
@@ -1319,14 +1470,12 @@ struct rtl_ps_ctl {
1319 bool rfchange_inprogress; 1470 bool rfchange_inprogress;
1320 bool swrf_processing; 1471 bool swrf_processing;
1321 bool hwradiooff; 1472 bool hwradiooff;
1322
1323 /* 1473 /*
1324 * just for PCIE ASPM 1474 * just for PCIE ASPM
1325 * If it supports ASPM, Offset[560h] = 0x40, 1475 * If it supports ASPM, Offset[560h] = 0x40,
1326 * otherwise Offset[560h] = 0x00. 1476 * otherwise Offset[560h] = 0x00.
1327 * */ 1477 * */
1328 bool support_aspm; 1478 bool support_aspm;
1329
1330 bool support_backdoor; 1479 bool support_backdoor;
1331 1480
1332 /*for LPS */ 1481 /*for LPS */
@@ -1341,6 +1490,7 @@ struct rtl_ps_ctl {
1341 bool fw_current_inpsmode; 1490 bool fw_current_inpsmode;
1342 u8 reg_max_lps_awakeintvl; 1491 u8 reg_max_lps_awakeintvl;
1343 bool report_linked; 1492 bool report_linked;
1493 bool low_power_enable;/*for 32k*/
1344 1494
1345 /*for IPS */ 1495 /*for IPS */
1346 bool inactiveps; 1496 bool inactiveps;
@@ -1373,6 +1523,11 @@ struct rtl_ps_ctl {
1373 unsigned long last_beacon; 1523 unsigned long last_beacon;
1374 unsigned long last_action; 1524 unsigned long last_action;
1375 unsigned long last_slept; 1525 unsigned long last_slept;
1526
1527 /*For P2P PS */
1528 struct rtl_p2p_ps_info p2p_ps_info;
1529 u8 pwr_mode;
1530 u8 smart_ps;
1376}; 1531};
1377 1532
1378struct rtl_stats { 1533struct rtl_stats {
@@ -1381,7 +1536,7 @@ struct rtl_stats {
1381 s8 rssi; 1536 s8 rssi;
1382 u8 signal; 1537 u8 signal;
1383 u8 noise; 1538 u8 noise;
1384 u16 rate; /*in 100 kbps */ 1539 u8 rate; /* hw desc rate */
1385 u8 received_channel; 1540 u8 received_channel;
1386 u8 control; 1541 u8 control;
1387 u8 mask; 1542 u8 mask;
@@ -1423,8 +1578,16 @@ struct rtl_stats {
1423 bool packet_toself; 1578 bool packet_toself;
1424 bool packet_beacon; /*for rssi */ 1579 bool packet_beacon; /*for rssi */
1425 char cck_adc_pwdb[4]; /*for rx path selection */ 1580 char cck_adc_pwdb[4]; /*for rx path selection */
1581
1582 u8 packet_report_type;
1583
1584 u32 macid;
1585 u8 wake_match;
1586 u32 bt_rx_rssi_percentage;
1587 u32 macid_valid_entry[2];
1426}; 1588};
1427 1589
1590
1428struct rt_link_detect { 1591struct rt_link_detect {
1429 /* count for roaming */ 1592 /* count for roaming */
1430 u32 bcn_rx_inperiod; 1593 u32 bcn_rx_inperiod;
@@ -1477,7 +1640,8 @@ struct rtl_tcb_desc {
1477 /* early mode */ 1640 /* early mode */
1478 u8 empkt_num; 1641 u8 empkt_num;
1479 /* The max value by HW */ 1642 /* The max value by HW */
1480 u32 empkt_len[5]; 1643 u32 empkt_len[10];
1644 bool btx_enable_sw_calc_duration;
1481}; 1645};
1482 1646
1483struct rtl_hal_ops { 1647struct rtl_hal_ops {
@@ -1553,7 +1717,7 @@ struct rtl_hal_ops {
1553 void (*allow_all_destaddr)(struct ieee80211_hw *hw, 1717 void (*allow_all_destaddr)(struct ieee80211_hw *hw,
1554 bool allow_all_da, bool write_into_reg); 1718 bool allow_all_da, bool write_into_reg);
1555 void (*linked_set_reg) (struct ieee80211_hw *hw); 1719 void (*linked_set_reg) (struct ieee80211_hw *hw);
1556 void (*check_switch_to_dmdp) (struct ieee80211_hw *hw); 1720 void (*chk_switch_dmdp) (struct ieee80211_hw *hw);
1557 void (*dualmac_easy_concurrent) (struct ieee80211_hw *hw); 1721 void (*dualmac_easy_concurrent) (struct ieee80211_hw *hw);
1558 void (*dualmac_switch_to_dmdp) (struct ieee80211_hw *hw); 1722 void (*dualmac_switch_to_dmdp) (struct ieee80211_hw *hw);
1559 bool (*phy_rf6052_config) (struct ieee80211_hw *hw); 1723 bool (*phy_rf6052_config) (struct ieee80211_hw *hw);
@@ -1662,6 +1826,8 @@ struct rtl_locks {
1662 /*spin lock */ 1826 /*spin lock */
1663 spinlock_t ips_lock; 1827 spinlock_t ips_lock;
1664 spinlock_t irq_th_lock; 1828 spinlock_t irq_th_lock;
1829 spinlock_t irq_pci_lock;
1830 spinlock_t tx_lock;
1665 spinlock_t h2c_lock; 1831 spinlock_t h2c_lock;
1666 spinlock_t rf_ps_lock; 1832 spinlock_t rf_ps_lock;
1667 spinlock_t rf_lock; 1833 spinlock_t rf_lock;
@@ -1670,6 +1836,9 @@ struct rtl_locks {
1670 spinlock_t entry_list_lock; 1836 spinlock_t entry_list_lock;
1671 spinlock_t usb_lock; 1837 spinlock_t usb_lock;
1672 1838
1839 /*FW clock change */
1840 spinlock_t fw_ps_lock;
1841
1673 /*Dual mac*/ 1842 /*Dual mac*/
1674 spinlock_t cck_and_rw_pagea_lock; 1843 spinlock_t cck_and_rw_pagea_lock;
1675 1844
@@ -1683,7 +1852,8 @@ struct rtl_works {
1683 /*timer */ 1852 /*timer */
1684 struct timer_list watchdog_timer; 1853 struct timer_list watchdog_timer;
1685 struct timer_list dualmac_easyconcurrent_retrytimer; 1854 struct timer_list dualmac_easyconcurrent_retrytimer;
1686 1855 struct timer_list fw_clockoff_timer;
1856 struct timer_list fast_antenna_training_timer;
1687 /*task */ 1857 /*task */
1688 struct tasklet_struct irq_tasklet; 1858 struct tasklet_struct irq_tasklet;
1689 struct tasklet_struct irq_prepare_bcn_tasklet; 1859 struct tasklet_struct irq_prepare_bcn_tasklet;
@@ -1696,8 +1866,9 @@ struct rtl_works {
1696 /* For SW LPS */ 1866 /* For SW LPS */
1697 struct delayed_work ps_work; 1867 struct delayed_work ps_work;
1698 struct delayed_work ps_rfon_wq; 1868 struct delayed_work ps_rfon_wq;
1869 struct delayed_work fwevt_wq;
1699 1870
1700 struct work_struct lps_leave_work; 1871 struct work_struct lps_change_work;
1701}; 1872};
1702 1873
1703struct rtl_debug { 1874struct rtl_debug {
@@ -1767,10 +1938,12 @@ struct dig_t {
1767 char back_val; 1938 char back_val;
1768 char back_range_max; 1939 char back_range_max;
1769 char back_range_min; 1940 char back_range_min;
1770 u8 rx_gain_range_max; 1941 u8 rx_gain_max;
1771 u8 rx_gain_range_min; 1942 u8 rx_gain_min;
1772 u8 min_undec_pwdb_for_dm; 1943 u8 min_undec_pwdb_for_dm;
1773 u8 rssi_val_min; 1944 u8 rssi_val_min;
1945 u8 pre_cck_cca_thres;
1946 u8 cur_cck_cca_thres;
1774 u8 pre_cck_pd_state; 1947 u8 pre_cck_pd_state;
1775 u8 cur_cck_pd_state; 1948 u8 cur_cck_pd_state;
1776 u8 pre_cck_fa_state; 1949 u8 pre_cck_fa_state;
@@ -1792,6 +1965,13 @@ struct dig_t {
1792 u8 backoff_enable_flag; 1965 u8 backoff_enable_flag;
1793 char backoffval_range_max; 1966 char backoffval_range_max;
1794 char backoffval_range_min; 1967 char backoffval_range_min;
1968 u8 dig_min_0;
1969 u8 dig_min_1;
1970 bool media_connect_0;
1971 bool media_connect_1;
1972
1973 u32 antdiv_rssi_max;
1974 u32 rssi_max;
1795}; 1975};
1796 1976
1797struct rtl_global_var { 1977struct rtl_global_var {
@@ -1802,6 +1982,7 @@ struct rtl_global_var {
1802}; 1982};
1803 1983
1804struct rtl_priv { 1984struct rtl_priv {
1985 struct ieee80211_hw *hw;
1805 struct completion firmware_loading_complete; 1986 struct completion firmware_loading_complete;
1806 struct list_head list; 1987 struct list_head list;
1807 struct rtl_priv *buddy_priv; 1988 struct rtl_priv *buddy_priv;
@@ -1866,6 +2047,7 @@ struct rtl_priv {
1866 bool bt_operation_on; 2047 bool bt_operation_on;
1867 }; 2048 };
1868 }; 2049 };
2050 bool enter_ps; /* true when entering PS */
1869 2051
1870 /*This must be the last item so 2052 /*This must be the last item so
1871 that it points to the data allocated 2053 that it points to the data allocated
@@ -2127,6 +2309,7 @@ value to host byte ordering.*/
2127#define WLAN_FC_GET_TYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) 2309#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) 2310#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) 2311#define WLAN_FC_MORE_DATA(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_MOREDATA)
2312#define rtl_dm(rtlpriv) (&((rtlpriv)->dm))
2130 2313
2131#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */ 2314#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */
2132#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */ 2315#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index e57ee48edff6..e2b3d9c541e8 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -186,8 +186,10 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
186 wl->set_power(true); 186 wl->set_power(true);
187 187
188 ret = pm_runtime_get_sync(&func->dev); 188 ret = pm_runtime_get_sync(&func->dev);
189 if (ret < 0) 189 if (ret < 0) {
190 pm_runtime_put_sync(&func->dev);
190 goto out; 191 goto out;
192 }
191 193
192 sdio_claim_host(func); 194 sdio_claim_host(func);
193 sdio_enable_func(func); 195 sdio_enable_func(func);
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index 09694e39bb14..1c627da85083 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -723,6 +723,7 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
723 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4; 723 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
724 wl->sched_scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5; 724 wl->sched_scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
725 wl->max_channels_5 = WL12XX_MAX_CHANNELS_5GHZ; 725 wl->max_channels_5 = WL12XX_MAX_CHANNELS_5GHZ;
726 wl->ba_rx_session_count_max = WL12XX_RX_BA_MAX_SESSIONS;
726out: 727out:
727 return ret; 728 return ret;
728} 729}
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
index d4552857480c..222d03540200 100644
--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -63,6 +63,8 @@
63 63
64#define WL12XX_NUM_MAC_ADDRESSES 2 64#define WL12XX_NUM_MAC_ADDRESSES 2
65 65
66#define WL12XX_RX_BA_MAX_SESSIONS 3
67
66struct wl127x_rx_mem_pool_addr { 68struct wl127x_rx_mem_pool_addr {
67 u32 addr; 69 u32 addr;
68 u32 addr_extra; 70 u32 addr_extra;
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index da3ef1b10a9c..9fa692d11025 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -678,6 +678,7 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
678 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC; 678 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
679 wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC; 679 wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
680 wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ; 680 wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
681 wl->ba_rx_session_count_max = WL18XX_RX_BA_MAX_SESSIONS;
681out: 682out:
682 return ret; 683 return ret;
683} 684}
@@ -1144,6 +1145,7 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
1144static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) 1145static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1145{ 1146{
1146 u32 fuse; 1147 u32 fuse;
1148 s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0;
1147 int ret; 1149 int ret;
1148 1150
1149 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); 1151 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
@@ -1154,8 +1156,29 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1154 if (ret < 0) 1156 if (ret < 0)
1155 goto out; 1157 goto out;
1156 1158
1159 pg_ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
1160 rom = (fuse & WL18XX_ROM_VER_MASK) >> WL18XX_ROM_VER_OFFSET;
1161
1162 if (rom <= 0xE)
1163 metal = (fuse & WL18XX_METAL_VER_MASK) >>
1164 WL18XX_METAL_VER_OFFSET;
1165 else
1166 metal = (fuse & WL18XX_NEW_METAL_VER_MASK) >>
1167 WL18XX_NEW_METAL_VER_OFFSET;
1168
1169 ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
1170 if (ret < 0)
1171 goto out;
1172
1173 rdl_ver = (fuse & WL18XX_RDL_VER_MASK) >> WL18XX_RDL_VER_OFFSET;
1174 if (rdl_ver > RDL_MAX)
1175 rdl_ver = RDL_NONE;
1176
1177 wl1271_info("wl18xx HW: RDL %d, %s, PG %x.%x (ROM %x)",
1178 rdl_ver, rdl_names[rdl_ver], pg_ver, metal, rom);
1179
1157 if (ver) 1180 if (ver)
1158 *ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; 1181 *ver = pg_ver;
1159 1182
1160 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); 1183 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
1161 1184
diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h
index 937b71d8783f..6306e04cd258 100644
--- a/drivers/net/wireless/ti/wl18xx/reg.h
+++ b/drivers/net/wireless/ti/wl18xx/reg.h
@@ -131,6 +131,16 @@
131#define WL18XX_REG_FUSE_DATA_1_3 0xA0260C 131#define WL18XX_REG_FUSE_DATA_1_3 0xA0260C
132#define WL18XX_PG_VER_MASK 0x70 132#define WL18XX_PG_VER_MASK 0x70
133#define WL18XX_PG_VER_OFFSET 4 133#define WL18XX_PG_VER_OFFSET 4
134#define WL18XX_ROM_VER_MASK 0x3
135#define WL18XX_ROM_VER_OFFSET 0
136#define WL18XX_METAL_VER_MASK 0xC
137#define WL18XX_METAL_VER_OFFSET 2
138#define WL18XX_NEW_METAL_VER_MASK 0x180
139#define WL18XX_NEW_METAL_VER_OFFSET 7
140
141#define WL18XX_REG_FUSE_DATA_2_3 0xA02614
142#define WL18XX_RDL_VER_MASK 0x1f00
143#define WL18XX_RDL_VER_OFFSET 8
134 144
135#define WL18XX_REG_FUSE_BD_ADDR_1 0xA02602 145#define WL18XX_REG_FUSE_BD_ADDR_1 0xA02602
136#define WL18XX_REG_FUSE_BD_ADDR_2 0xA02606 146#define WL18XX_REG_FUSE_BD_ADDR_2 0xA02606
@@ -188,4 +198,23 @@ enum {
188 NUM_BOARD_TYPES, 198 NUM_BOARD_TYPES,
189}; 199};
190 200
201enum {
202 RDL_NONE = 0,
203 RDL_1_HP = 1,
204 RDL_2_SP = 2,
205 RDL_3_HP = 3,
206 RDL_4_SP = 4,
207
208 _RDL_LAST,
209 RDL_MAX = _RDL_LAST - 1,
210};
211
212static const char * const rdl_names[] = {
213 [RDL_NONE] = "",
214 [RDL_1_HP] = "1853 SISO",
215 [RDL_2_SP] = "1857 MIMO",
216 [RDL_3_HP] = "1893 SISO",
217 [RDL_4_SP] = "1897 MIMO",
218};
219
191#endif /* __REG_H__ */ 220#endif /* __REG_H__ */
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index b6739e79efcf..9204e07ee432 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -29,7 +29,7 @@
29#define WL18XX_IFTYPE_VER 5 29#define WL18XX_IFTYPE_VER 5
30#define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE 30#define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE
31#define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE 31#define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE
32#define WL18XX_MINOR_VER 28 32#define WL18XX_MINOR_VER 39
33 33
34#define WL18XX_CMD_MAX_SIZE 740 34#define WL18XX_CMD_MAX_SIZE 740
35 35
@@ -40,6 +40,8 @@
40 40
41#define WL18XX_NUM_MAC_ADDRESSES 3 41#define WL18XX_NUM_MAC_ADDRESSES 3
42 42
43#define WL18XX_RX_BA_MAX_SESSIONS 5
44
43struct wl18xx_priv { 45struct wl18xx_priv {
44 /* buffer for sending commands to FW */ 46 /* buffer for sending commands to FW */
45 u8 cmd_buf[WL18XX_CMD_MAX_SIZE]; 47 u8 cmd_buf[WL18XX_CMD_MAX_SIZE];
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index c79654323396..7a970cd9c555 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -1736,6 +1736,35 @@ out:
1736 1736
1737} 1737}
1738 1738
1739int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1740 s8 *avg_rssi)
1741{
1742 struct acx_roaming_stats *acx;
1743 int ret = 0;
1744
1745 wl1271_debug(DEBUG_ACX, "acx roaming statistics");
1746
1747 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1748 if (!acx) {
1749 ret = -ENOMEM;
1750 goto out;
1751 }
1752
1753 acx->role_id = wlvif->role_id;
1754 ret = wl1271_cmd_interrogate(wl, ACX_ROAMING_STATISTICS_TBL,
1755 acx, sizeof(*acx));
1756 if (ret < 0) {
1757 wl1271_warning("acx roaming statistics failed: %d", ret);
1758 ret = -ENOMEM;
1759 goto out;
1760 }
1761
1762 *avg_rssi = acx->rssi_beacon;
1763out:
1764 kfree(acx);
1765 return ret;
1766}
1767
1739#ifdef CONFIG_PM 1768#ifdef CONFIG_PM
1740/* Set the global behaviour of RX filters - On/Off + default action */ 1769/* Set the global behaviour of RX filters - On/Off + default action */
1741int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, 1770int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index 126536c6a393..6dcfad9b0472 100644
--- a/drivers/net/wireless/ti/wlcore/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -728,8 +728,6 @@ struct wl1271_acx_ht_information {
728 u8 padding[2]; 728 u8 padding[2];
729} __packed; 729} __packed;
730 730
731#define RX_BA_MAX_SESSIONS 3
732
733struct wl1271_acx_ba_initiator_policy { 731struct wl1271_acx_ba_initiator_policy {
734 struct acx_header header; 732 struct acx_header header;
735 733
@@ -955,6 +953,18 @@ struct acx_rx_filter_cfg {
955 u8 fields[0]; 953 u8 fields[0];
956} __packed; 954} __packed;
957 955
956struct acx_roaming_stats {
957 struct acx_header header;
958
959 u8 role_id;
960 u8 pad[3];
961 u32 missed_beacons;
962 u8 snr_data;
963 u8 snr_bacon;
964 s8 rssi_data;
965 s8 rssi_beacon;
966} __packed;
967
958enum { 968enum {
959 ACX_WAKE_UP_CONDITIONS = 0x0000, 969 ACX_WAKE_UP_CONDITIONS = 0x0000,
960 ACX_MEM_CFG = 0x0001, 970 ACX_MEM_CFG = 0x0001,
@@ -1112,6 +1122,8 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
1112int wl1271_acx_fm_coex(struct wl1271 *wl); 1122int wl1271_acx_fm_coex(struct wl1271 *wl);
1113int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); 1123int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
1114int wl12xx_acx_config_hangover(struct wl1271 *wl); 1124int wl12xx_acx_config_hangover(struct wl1271 *wl);
1125int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1126 s8 *avg_rssi);
1115 1127
1116#ifdef CONFIG_PM 1128#ifdef CONFIG_PM
1117int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, 1129int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 6331f9e1cb39..c9e060795d13 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -327,6 +327,14 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
327 wl->links[link].prev_freed_pkts = 327 wl->links[link].prev_freed_pkts =
328 wl->fw_status_2->counters.tx_lnk_free_pkts[link]; 328 wl->fw_status_2->counters.tx_lnk_free_pkts[link];
329 wl->links[link].wlvif = wlvif; 329 wl->links[link].wlvif = wlvif;
330
331 /*
332 * Take saved value for total freed packets from wlvif, in case this is
333 * recovery/resume
334 */
335 if (wlvif->bss_type != BSS_TYPE_AP_BSS)
336 wl->links[link].total_freed_pkts = wlvif->total_freed_pkts;
337
330 *hlid = link; 338 *hlid = link;
331 339
332 wl->active_link_count++; 340 wl->active_link_count++;
@@ -358,6 +366,26 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
358 wl1271_tx_reset_link_queues(wl, *hlid); 366 wl1271_tx_reset_link_queues(wl, *hlid);
359 wl->links[*hlid].wlvif = NULL; 367 wl->links[*hlid].wlvif = NULL;
360 368
369 if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
370 (wlvif->bss_type == BSS_TYPE_AP_BSS &&
371 *hlid == wlvif->ap.bcast_hlid)) {
372 /*
373 * save the total freed packets in the wlvif, in case this is
374 * recovery or suspend
375 */
376 wlvif->total_freed_pkts = wl->links[*hlid].total_freed_pkts;
377
378 /*
379 * increment the initial seq number on recovery to account for
380 * transmitted packets that we haven't yet got in the FW status
381 */
382 if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
383 wlvif->total_freed_pkts +=
384 WL1271_TX_SQN_POST_RECOVERY_PADDING;
385 }
386
387 wl->links[*hlid].total_freed_pkts = 0;
388
361 *hlid = WL12XX_INVALID_LINK_ID; 389 *hlid = WL12XX_INVALID_LINK_ID;
362 wl->active_link_count--; 390 wl->active_link_count--;
363 WARN_ON_ONCE(wl->active_link_count < 0); 391 WARN_ON_ONCE(wl->active_link_count < 0);
@@ -609,6 +637,10 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
609 if (ret < 0) 637 if (ret < 0)
610 goto out_free_global; 638 goto out_free_global;
611 639
640 /* use the previous security seq, if this is a recovery/resume */
641 wl->links[wlvif->ap.bcast_hlid].total_freed_pkts =
642 wlvif->total_freed_pkts;
643
612 cmd->role_id = wlvif->role_id; 644 cmd->role_id = wlvif->role_id;
613 cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period); 645 cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period);
614 cmd->ap.bss_index = WL1271_AP_BSS_INDEX; 646 cmd->ap.bss_index = WL1271_AP_BSS_INDEX;
diff --git a/drivers/net/wireless/ti/wlcore/debug.h b/drivers/net/wireless/ti/wlcore/debug.h
index db4bf5a68ce2..0420bd45e4ee 100644
--- a/drivers/net/wireless/ti/wlcore/debug.h
+++ b/drivers/net/wireless/ti/wlcore/debug.h
@@ -89,25 +89,24 @@ extern u32 wl12xx_debug_level;
89 } while (0) 89 } while (0)
90#endif 90#endif
91 91
92/* TODO: use pr_debug_hex_dump when it becomes available */ 92#define wl1271_dump(level, prefix, buf, len) \
93#define wl1271_dump(level, prefix, buf, len) \ 93 do { \
94 do { \ 94 if (level & wl12xx_debug_level) \
95 if (level & wl12xx_debug_level) \ 95 print_hex_dump_debug(DRIVER_PREFIX prefix, \
96 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ 96 DUMP_PREFIX_OFFSET, 16, 1, \
97 DUMP_PREFIX_OFFSET, 16, 1, \ 97 buf, \
98 buf, \ 98 min_t(size_t, len, DEBUG_DUMP_LIMIT), \
99 min_t(size_t, len, DEBUG_DUMP_LIMIT), \ 99 0); \
100 0); \
101 } while (0) 100 } while (0)
102 101
103#define wl1271_dump_ascii(level, prefix, buf, len) \ 102#define wl1271_dump_ascii(level, prefix, buf, len) \
104 do { \ 103 do { \
105 if (level & wl12xx_debug_level) \ 104 if (level & wl12xx_debug_level) \
106 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ 105 print_hex_dump_debug(DRIVER_PREFIX prefix, \
107 DUMP_PREFIX_OFFSET, 16, 1, \ 106 DUMP_PREFIX_OFFSET, 16, 1, \
108 buf, \ 107 buf, \
109 min_t(size_t, len, DEBUG_DUMP_LIMIT), \ 108 min_t(size_t, len, DEBUG_DUMP_LIMIT), \
110 true); \ 109 true); \
111 } while (0) 110 } while (0)
112 111
113#endif /* __DEBUG_H__ */ 112#endif /* __DEBUG_H__ */
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index e70a7c864865..c3e1f79c7856 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -598,8 +598,7 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
598 VIF_STATE_PRINT_INT(last_rssi_event); 598 VIF_STATE_PRINT_INT(last_rssi_event);
599 VIF_STATE_PRINT_INT(ba_support); 599 VIF_STATE_PRINT_INT(ba_support);
600 VIF_STATE_PRINT_INT(ba_allowed); 600 VIF_STATE_PRINT_INT(ba_allowed);
601 VIF_STATE_PRINT_LLHEX(tx_security_seq); 601 VIF_STATE_PRINT_LLHEX(total_freed_pkts);
602 VIF_STATE_PRINT_INT(tx_security_last_seq_lsb);
603 } 602 }
604 603
605#undef VIF_STATE_PRINT_INT 604#undef VIF_STATE_PRINT_INT
diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c
index 70f289aa1bc6..67f61689b49e 100644
--- a/drivers/net/wireless/ti/wlcore/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -237,6 +237,14 @@ void wlcore_event_beacon_loss(struct wl1271 *wl, unsigned long roles_bitmap)
237 !test_bit(wlvif->role_id , &roles_bitmap)) 237 !test_bit(wlvif->role_id , &roles_bitmap))
238 continue; 238 continue;
239 239
240 vif = wl12xx_wlvif_to_vif(wlvif);
241
242 /* don't attempt roaming in case of p2p */
243 if (wlvif->p2p) {
244 ieee80211_connection_loss(vif);
245 continue;
246 }
247
240 /* 248 /*
241 * if the work is already queued, it should take place. 249 * if the work is already queued, it should take place.
242 * We don't want to delay the connection loss 250 * We don't want to delay the connection loss
@@ -246,7 +254,6 @@ void wlcore_event_beacon_loss(struct wl1271 *wl, unsigned long roles_bitmap)
246 &wlvif->connection_loss_work, 254 &wlvif->connection_loss_work,
247 msecs_to_jiffies(delay)); 255 msecs_to_jiffies(delay));
248 256
249 vif = wl12xx_wlvif_to_vif(wlvif);
250 ieee80211_cqm_rssi_notify( 257 ieee80211_cqm_rssi_notify(
251 vif, 258 vif,
252 NL80211_CQM_RSSI_BEACON_LOSS_EVENT, 259 NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index d7e306333f6c..d10954c0c181 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -108,8 +108,7 @@ static void wl1271_reg_notify(struct wiphy *wiphy,
108 108
109 } 109 }
110 110
111 if (likely(wl->state == WLCORE_STATE_ON)) 111 wlcore_regdomain_config(wl);
112 wlcore_regdomain_config(wl);
113} 112}
114 113
115static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, 114static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
@@ -332,10 +331,9 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
332 struct wl12xx_vif *wlvif, 331 struct wl12xx_vif *wlvif,
333 u8 hlid, u8 tx_pkts) 332 u8 hlid, u8 tx_pkts)
334{ 333{
335 bool fw_ps, single_link; 334 bool fw_ps;
336 335
337 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 336 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
338 single_link = (wl->active_link_count == 1);
339 337
340 /* 338 /*
341 * Wake up from high level PS if the STA is asleep with too little 339 * Wake up from high level PS if the STA is asleep with too little
@@ -348,8 +346,13 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
348 * Start high-level PS if the STA is asleep with enough blocks in FW. 346 * Start high-level PS if the STA is asleep with enough blocks in FW.
349 * Make an exception if this is the only connected link. In this 347 * Make an exception if this is the only connected link. In this
350 * case FW-memory congestion is less of a problem. 348 * case FW-memory congestion is less of a problem.
349 * Note that a single connected STA means 3 active links, since we must
350 * account for the global and broadcast AP links. The "fw_ps" check
351 * assures us the third link is a STA connected to the AP. Otherwise
352 * the FW would not set the PSM bit.
351 */ 353 */
352 else if (!single_link && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) 354 else if (wl->active_link_count > 3 && fw_ps &&
355 tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
353 wl12xx_ps_link_start(wl, wlvif, hlid, true); 356 wl12xx_ps_link_start(wl, wlvif, hlid, true);
354} 357}
355 358
@@ -414,13 +417,21 @@ static int wlcore_fw_status(struct wl1271 *wl,
414 417
415 418
416 for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) { 419 for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) {
420 u8 diff;
417 lnk = &wl->links[i]; 421 lnk = &wl->links[i];
422
418 /* prevent wrap-around in freed-packets counter */ 423 /* prevent wrap-around in freed-packets counter */
419 lnk->allocated_pkts -= 424 diff = (status_2->counters.tx_lnk_free_pkts[i] -
420 (status_2->counters.tx_lnk_free_pkts[i] - 425 lnk->prev_freed_pkts) & 0xff;
421 lnk->prev_freed_pkts) & 0xff; 426
427 if (diff == 0)
428 continue;
422 429
430 lnk->allocated_pkts -= diff;
423 lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i]; 431 lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i];
432
433 /* accumulate the prev_freed_pkts counter */
434 lnk->total_freed_pkts += diff;
424 } 435 }
425 436
426 /* prevent wrap-around in total blocks counter */ 437 /* prevent wrap-around in total blocks counter */
@@ -640,6 +651,25 @@ static irqreturn_t wlcore_irq(int irq, void *cookie)
640 unsigned long flags; 651 unsigned long flags;
641 struct wl1271 *wl = cookie; 652 struct wl1271 *wl = cookie;
642 653
654 /* complete the ELP completion */
655 spin_lock_irqsave(&wl->wl_lock, flags);
656 set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
657 if (wl->elp_compl) {
658 complete(wl->elp_compl);
659 wl->elp_compl = NULL;
660 }
661
662 if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
663 /* don't enqueue a work right now. mark it as pending */
664 set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
665 wl1271_debug(DEBUG_IRQ, "should not enqueue work");
666 disable_irq_nosync(wl->irq);
667 pm_wakeup_event(wl->dev, 0);
668 spin_unlock_irqrestore(&wl->wl_lock, flags);
669 return IRQ_HANDLED;
670 }
671 spin_unlock_irqrestore(&wl->wl_lock, flags);
672
643 /* TX might be handled here, avoid redundant work */ 673 /* TX might be handled here, avoid redundant work */
644 set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); 674 set_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
645 cancel_work_sync(&wl->tx_work); 675 cancel_work_sync(&wl->tx_work);
@@ -919,18 +949,6 @@ static void wl1271_recovery_work(struct work_struct *work)
919 goto out_unlock; 949 goto out_unlock;
920 } 950 }
921 951
922 /*
923 * Advance security sequence number to overcome potential progress
924 * in the firmware during recovery. This doens't hurt if the network is
925 * not encrypted.
926 */
927 wl12xx_for_each_wlvif(wl, wlvif) {
928 if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
929 test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
930 wlvif->tx_security_seq +=
931 WL1271_TX_SQN_POST_RECOVERY_PADDING;
932 }
933
934 /* Prevent spurious TX during FW restart */ 952 /* Prevent spurious TX during FW restart */
935 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART); 953 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
936 954
@@ -2523,6 +2541,8 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2523 wl1271_ps_elp_sleep(wl); 2541 wl1271_ps_elp_sleep(wl);
2524 } 2542 }
2525deinit: 2543deinit:
2544 wl12xx_tx_reset_wlvif(wl, wlvif);
2545
2526 /* clear all hlids (except system_hlid) */ 2546 /* clear all hlids (except system_hlid) */
2527 wlvif->dev_hlid = WL12XX_INVALID_LINK_ID; 2547 wlvif->dev_hlid = WL12XX_INVALID_LINK_ID;
2528 2548
@@ -2546,7 +2566,6 @@ deinit:
2546 2566
2547 dev_kfree_skb(wlvif->probereq); 2567 dev_kfree_skb(wlvif->probereq);
2548 wlvif->probereq = NULL; 2568 wlvif->probereq = NULL;
2549 wl12xx_tx_reset_wlvif(wl, wlvif);
2550 if (wl->last_wlvif == wlvif) 2569 if (wl->last_wlvif == wlvif)
2551 wl->last_wlvif = NULL; 2570 wl->last_wlvif = NULL;
2552 list_del(&wlvif->list); 2571 list_del(&wlvif->list);
@@ -2860,10 +2879,6 @@ static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2860 wlvif->sta.klv_template_id, 2879 wlvif->sta.klv_template_id,
2861 ACX_KEEP_ALIVE_TPL_INVALID); 2880 ACX_KEEP_ALIVE_TPL_INVALID);
2862 2881
2863 /* reset TX security counters on a clean disconnect */
2864 wlvif->tx_security_last_seq_lsb = 0;
2865 wlvif->tx_security_seq = 0;
2866
2867 return 0; 2882 return 0;
2868} 2883}
2869 2884
@@ -3262,6 +3277,7 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3262 u32 tx_seq_32 = 0; 3277 u32 tx_seq_32 = 0;
3263 u16 tx_seq_16 = 0; 3278 u16 tx_seq_16 = 0;
3264 u8 key_type; 3279 u8 key_type;
3280 u8 hlid;
3265 3281
3266 wl1271_debug(DEBUG_MAC80211, "mac80211 set key"); 3282 wl1271_debug(DEBUG_MAC80211, "mac80211 set key");
3267 3283
@@ -3271,6 +3287,22 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3271 key_conf->keylen, key_conf->flags); 3287 key_conf->keylen, key_conf->flags);
3272 wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen); 3288 wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
3273 3289
3290 if (wlvif->bss_type == BSS_TYPE_AP_BSS)
3291 if (sta) {
3292 struct wl1271_station *wl_sta = (void *)sta->drv_priv;
3293 hlid = wl_sta->hlid;
3294 } else {
3295 hlid = wlvif->ap.bcast_hlid;
3296 }
3297 else
3298 hlid = wlvif->sta.hlid;
3299
3300 if (hlid != WL12XX_INVALID_LINK_ID) {
3301 u64 tx_seq = wl->links[hlid].total_freed_pkts;
3302 tx_seq_32 = WL1271_TX_SECURITY_HI32(tx_seq);
3303 tx_seq_16 = WL1271_TX_SECURITY_LO16(tx_seq);
3304 }
3305
3274 switch (key_conf->cipher) { 3306 switch (key_conf->cipher) {
3275 case WLAN_CIPHER_SUITE_WEP40: 3307 case WLAN_CIPHER_SUITE_WEP40:
3276 case WLAN_CIPHER_SUITE_WEP104: 3308 case WLAN_CIPHER_SUITE_WEP104:
@@ -3280,22 +3312,14 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3280 break; 3312 break;
3281 case WLAN_CIPHER_SUITE_TKIP: 3313 case WLAN_CIPHER_SUITE_TKIP:
3282 key_type = KEY_TKIP; 3314 key_type = KEY_TKIP;
3283
3284 key_conf->hw_key_idx = key_conf->keyidx; 3315 key_conf->hw_key_idx = key_conf->keyidx;
3285 tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
3286 tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
3287 break; 3316 break;
3288 case WLAN_CIPHER_SUITE_CCMP: 3317 case WLAN_CIPHER_SUITE_CCMP:
3289 key_type = KEY_AES; 3318 key_type = KEY_AES;
3290
3291 key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; 3319 key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
3292 tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
3293 tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
3294 break; 3320 break;
3295 case WL1271_CIPHER_SUITE_GEM: 3321 case WL1271_CIPHER_SUITE_GEM:
3296 key_type = KEY_GEM; 3322 key_type = KEY_GEM;
3297 tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
3298 tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
3299 break; 3323 break;
3300 default: 3324 default:
3301 wl1271_error("Unknown key algo 0x%x", key_conf->cipher); 3325 wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
@@ -3358,6 +3382,10 @@ void wlcore_regdomain_config(struct wl1271 *wl)
3358 return; 3382 return;
3359 3383
3360 mutex_lock(&wl->mutex); 3384 mutex_lock(&wl->mutex);
3385
3386 if (unlikely(wl->state != WLCORE_STATE_ON))
3387 goto out;
3388
3361 ret = wl1271_ps_elp_wakeup(wl); 3389 ret = wl1271_ps_elp_wakeup(wl);
3362 if (ret < 0) 3390 if (ret < 0)
3363 goto out; 3391 goto out;
@@ -4499,6 +4527,9 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
4499 return -EBUSY; 4527 return -EBUSY;
4500 } 4528 }
4501 4529
4530 /* use the previous security seq, if this is a recovery/resume */
4531 wl->links[wl_sta->hlid].total_freed_pkts = wl_sta->total_freed_pkts;
4532
4502 set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map); 4533 set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map);
4503 memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN); 4534 memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN);
4504 wl->active_sta_count++; 4535 wl->active_sta_count++;
@@ -4507,12 +4538,37 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
4507 4538
4508void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) 4539void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
4509{ 4540{
4541 struct wl1271_station *wl_sta;
4542 struct ieee80211_sta *sta;
4543 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
4544
4510 if (!test_bit(hlid, wlvif->ap.sta_hlid_map)) 4545 if (!test_bit(hlid, wlvif->ap.sta_hlid_map))
4511 return; 4546 return;
4512 4547
4513 clear_bit(hlid, wlvif->ap.sta_hlid_map); 4548 clear_bit(hlid, wlvif->ap.sta_hlid_map);
4514 __clear_bit(hlid, &wl->ap_ps_map); 4549 __clear_bit(hlid, &wl->ap_ps_map);
4515 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 4550 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
4551
4552 /*
4553 * save the last used PN in the private part of iee80211_sta,
4554 * in case of recovery/suspend
4555 */
4556 rcu_read_lock();
4557 sta = ieee80211_find_sta(vif, wl->links[hlid].addr);
4558 if (sta) {
4559 wl_sta = (void *)sta->drv_priv;
4560 wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts;
4561
4562 /*
4563 * increment the initial seq number on recovery to account for
4564 * transmitted packets that we haven't yet got in the FW status
4565 */
4566 if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
4567 wl_sta->total_freed_pkts +=
4568 WL1271_TX_SQN_POST_RECOVERY_PADDING;
4569 }
4570 rcu_read_unlock();
4571
4516 wl12xx_free_link(wl, wlvif, &hlid); 4572 wl12xx_free_link(wl, wlvif, &hlid);
4517 wl->active_sta_count--; 4573 wl->active_sta_count--;
4518 4574
@@ -4616,13 +4672,11 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
4616 enum ieee80211_sta_state new_state) 4672 enum ieee80211_sta_state new_state)
4617{ 4673{
4618 struct wl1271_station *wl_sta; 4674 struct wl1271_station *wl_sta;
4619 u8 hlid;
4620 bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS; 4675 bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
4621 bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS; 4676 bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
4622 int ret; 4677 int ret;
4623 4678
4624 wl_sta = (struct wl1271_station *)sta->drv_priv; 4679 wl_sta = (struct wl1271_station *)sta->drv_priv;
4625 hlid = wl_sta->hlid;
4626 4680
4627 /* Add station (AP mode) */ 4681 /* Add station (AP mode) */
4628 if (is_ap && 4682 if (is_ap &&
@@ -4648,12 +4702,12 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
4648 /* Authorize station (AP mode) */ 4702 /* Authorize station (AP mode) */
4649 if (is_ap && 4703 if (is_ap &&
4650 new_state == IEEE80211_STA_AUTHORIZED) { 4704 new_state == IEEE80211_STA_AUTHORIZED) {
4651 ret = wl12xx_cmd_set_peer_state(wl, wlvif, hlid); 4705 ret = wl12xx_cmd_set_peer_state(wl, wlvif, wl_sta->hlid);
4652 if (ret < 0) 4706 if (ret < 0)
4653 return ret; 4707 return ret;
4654 4708
4655 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, 4709 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true,
4656 hlid); 4710 wl_sta->hlid);
4657 if (ret) 4711 if (ret)
4658 return ret; 4712 return ret;
4659 4713
@@ -4784,7 +4838,7 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
4784 break; 4838 break;
4785 } 4839 }
4786 4840
4787 if (wl->ba_rx_session_count >= RX_BA_MAX_SESSIONS) { 4841 if (wl->ba_rx_session_count >= wl->ba_rx_session_count_max) {
4788 ret = -EBUSY; 4842 ret = -EBUSY;
4789 wl1271_error("exceeded max RX BA sessions"); 4843 wl1271_error("exceeded max RX BA sessions");
4790 break; 4844 break;
@@ -4946,7 +5000,7 @@ out:
4946 mutex_unlock(&wl->mutex); 5000 mutex_unlock(&wl->mutex);
4947} 5001}
4948 5002
4949static void wlcore_op_flush(struct ieee80211_hw *hw, bool drop) 5003static void wlcore_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
4950{ 5004{
4951 struct wl1271 *wl = hw->priv; 5005 struct wl1271 *wl = hw->priv;
4952 5006
@@ -5092,6 +5146,39 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
5092 wlcore_hw_sta_rc_update(wl, wlvif, sta, changed); 5146 wlcore_hw_sta_rc_update(wl, wlvif, sta, changed);
5093} 5147}
5094 5148
5149static int wlcore_op_get_rssi(struct ieee80211_hw *hw,
5150 struct ieee80211_vif *vif,
5151 struct ieee80211_sta *sta,
5152 s8 *rssi_dbm)
5153{
5154 struct wl1271 *wl = hw->priv;
5155 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5156 int ret = 0;
5157
5158 wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi");
5159
5160 mutex_lock(&wl->mutex);
5161
5162 if (unlikely(wl->state != WLCORE_STATE_ON))
5163 goto out;
5164
5165 ret = wl1271_ps_elp_wakeup(wl);
5166 if (ret < 0)
5167 goto out_sleep;
5168
5169 ret = wlcore_acx_average_rssi(wl, wlvif, rssi_dbm);
5170 if (ret < 0)
5171 goto out_sleep;
5172
5173out_sleep:
5174 wl1271_ps_elp_sleep(wl);
5175
5176out:
5177 mutex_unlock(&wl->mutex);
5178
5179 return ret;
5180}
5181
5095static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) 5182static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
5096{ 5183{
5097 struct wl1271 *wl = hw->priv; 5184 struct wl1271 *wl = hw->priv;
@@ -5291,6 +5378,7 @@ static const struct ieee80211_ops wl1271_ops = {
5291 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx, 5378 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
5292 .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx, 5379 .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx,
5293 .sta_rc_update = wlcore_op_sta_rc_update, 5380 .sta_rc_update = wlcore_op_sta_rc_update,
5381 .get_rssi = wlcore_op_get_rssi,
5294 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 5382 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
5295}; 5383};
5296 5384
@@ -5930,35 +6018,6 @@ int wlcore_free_hw(struct wl1271 *wl)
5930} 6018}
5931EXPORT_SYMBOL_GPL(wlcore_free_hw); 6019EXPORT_SYMBOL_GPL(wlcore_free_hw);
5932 6020
5933static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
5934{
5935 struct wl1271 *wl = cookie;
5936 unsigned long flags;
5937
5938 wl1271_debug(DEBUG_IRQ, "IRQ");
5939
5940 /* complete the ELP completion */
5941 spin_lock_irqsave(&wl->wl_lock, flags);
5942 set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
5943 if (wl->elp_compl) {
5944 complete(wl->elp_compl);
5945 wl->elp_compl = NULL;
5946 }
5947
5948 if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
5949 /* don't enqueue a work right now. mark it as pending */
5950 set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
5951 wl1271_debug(DEBUG_IRQ, "should not enqueue work");
5952 disable_irq_nosync(wl->irq);
5953 pm_wakeup_event(wl->dev, 0);
5954 spin_unlock_irqrestore(&wl->wl_lock, flags);
5955 return IRQ_HANDLED;
5956 }
5957 spin_unlock_irqrestore(&wl->wl_lock, flags);
5958
5959 return IRQ_WAKE_THREAD;
5960}
5961
5962static void wlcore_nvs_cb(const struct firmware *fw, void *context) 6021static void wlcore_nvs_cb(const struct firmware *fw, void *context)
5963{ 6022{
5964 struct wl1271 *wl = context; 6023 struct wl1271 *wl = context;
@@ -6000,9 +6059,8 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
6000 else 6059 else
6001 irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; 6060 irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
6002 6061
6003 ret = request_threaded_irq(wl->irq, wl12xx_hardirq, wlcore_irq, 6062 ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
6004 irqflags, 6063 irqflags, pdev->name, wl);
6005 pdev->name, wl);
6006 if (ret < 0) { 6064 if (ret < 0) {
6007 wl1271_error("request_irq() failed: %d", ret); 6065 wl1271_error("request_irq() failed: %d", ret);
6008 goto out_free_nvs; 6066 goto out_free_nvs;
diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 9b7b6e2e4fbc..9654577efd01 100644
--- a/drivers/net/wireless/ti/wlcore/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -29,6 +29,7 @@
29#define WL1271_WAKEUP_TIMEOUT 500 29#define WL1271_WAKEUP_TIMEOUT 500
30 30
31#define ELP_ENTRY_DELAY 30 31#define ELP_ENTRY_DELAY 30
32#define ELP_ENTRY_DELAY_FORCE_PS 5
32 33
33void wl1271_elp_work(struct work_struct *work) 34void wl1271_elp_work(struct work_struct *work)
34{ 35{
@@ -98,7 +99,8 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
98 return; 99 return;
99 } 100 }
100 101
101 timeout = ELP_ENTRY_DELAY; 102 timeout = wl->conf.conn.forced_ps ?
103 ELP_ENTRY_DELAY_FORCE_PS : ELP_ENTRY_DELAY;
102 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, 104 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
103 msecs_to_jiffies(timeout)); 105 msecs_to_jiffies(timeout));
104} 106}
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index ece392c54d9c..004d02e71f01 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -24,6 +24,7 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/etherdevice.h> 26#include <linux/etherdevice.h>
27#include <linux/spinlock.h>
27 28
28#include "wlcore.h" 29#include "wlcore.h"
29#include "debug.h" 30#include "debug.h"
@@ -104,7 +105,7 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
104 struct wl12xx_vif *wlvif, 105 struct wl12xx_vif *wlvif,
105 u8 hlid) 106 u8 hlid)
106{ 107{
107 bool fw_ps, single_link; 108 bool fw_ps;
108 u8 tx_pkts; 109 u8 tx_pkts;
109 110
110 if (WARN_ON(!test_bit(hlid, wlvif->links_map))) 111 if (WARN_ON(!test_bit(hlid, wlvif->links_map)))
@@ -112,15 +113,19 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
112 113
113 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 114 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
114 tx_pkts = wl->links[hlid].allocated_pkts; 115 tx_pkts = wl->links[hlid].allocated_pkts;
115 single_link = (wl->active_link_count == 1);
116 116
117 /* 117 /*
118 * if in FW PS and there is enough data in FW we can put the link 118 * if in FW PS and there is enough data in FW we can put the link
119 * into high-level PS and clean out its TX queues. 119 * into high-level PS and clean out its TX queues.
120 * Make an exception if this is the only connected link. In this 120 * Make an exception if this is the only connected link. In this
121 * case FW-memory congestion is less of a problem. 121 * case FW-memory congestion is less of a problem.
122 * Note that a single connected STA means 3 active links, since we must
123 * account for the global and broadcast AP links. The "fw_ps" check
124 * assures us the third link is a STA connected to the AP. Otherwise
125 * the FW would not set the PSM bit.
122 */ 126 */
123 if (!single_link && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) 127 if (wl->active_link_count > 3 && fw_ps &&
128 tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
124 wl12xx_ps_link_start(wl, wlvif, hlid, true); 129 wl12xx_ps_link_start(wl, wlvif, hlid, true);
125} 130}
126 131
@@ -639,6 +644,7 @@ next:
639 644
640 } 645 }
641 646
647out:
642 if (!skb && 648 if (!skb &&
643 test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { 649 test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
644 int q; 650 int q;
@@ -652,7 +658,6 @@ next:
652 spin_unlock_irqrestore(&wl->wl_lock, flags); 658 spin_unlock_irqrestore(&wl->wl_lock, flags);
653 } 659 }
654 660
655out:
656 return skb; 661 return skb;
657} 662}
658 663
@@ -928,25 +933,6 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
928 933
929 wl->stats.retry_count += result->ack_failures; 934 wl->stats.retry_count += result->ack_failures;
930 935
931 /*
932 * update sequence number only when relevant, i.e. only in
933 * sessions of TKIP, AES and GEM (not in open or WEP sessions)
934 */
935 if (info->control.hw_key &&
936 (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP ||
937 info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP ||
938 info->control.hw_key->cipher == WL1271_CIPHER_SUITE_GEM)) {
939 u8 fw_lsb = result->tx_security_sequence_number_lsb;
940 u8 cur_lsb = wlvif->tx_security_last_seq_lsb;
941
942 /*
943 * update security sequence number, taking care of potential
944 * wrap-around
945 */
946 wlvif->tx_security_seq += (fw_lsb - cur_lsb) & 0xff;
947 wlvif->tx_security_last_seq_lsb = fw_lsb;
948 }
949
950 /* remove private header from packet */ 936 /* remove private header from packet */
951 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); 937 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
952 938
@@ -1061,7 +1047,8 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1061 1047
1062 /* TX failure */ 1048 /* TX failure */
1063 for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) { 1049 for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) {
1064 if (wlvif->bss_type == BSS_TYPE_AP_BSS) { 1050 if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
1051 i != wlvif->ap.bcast_hlid && i != wlvif->ap.global_hlid) {
1065 /* this calls wl12xx_free_link */ 1052 /* this calls wl12xx_free_link */
1066 wl1271_free_sta(wl, wlvif, i); 1053 wl1271_free_sta(wl, wlvif, i);
1067 } else { 1054 } else {
@@ -1304,7 +1291,7 @@ bool wlcore_is_queue_stopped_by_reason_locked(struct wl1271 *wl,
1304{ 1291{
1305 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue); 1292 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
1306 1293
1307 WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock)); 1294 assert_spin_locked(&wl->wl_lock);
1308 return test_bit(reason, &wl->queue_stop_reasons[hwq]); 1295 return test_bit(reason, &wl->queue_stop_reasons[hwq]);
1309} 1296}
1310 1297
@@ -1313,6 +1300,6 @@ bool wlcore_is_queue_stopped_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1313{ 1300{
1314 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue); 1301 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
1315 1302
1316 WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock)); 1303 assert_spin_locked(&wl->wl_lock);
1317 return !!wl->queue_stop_reasons[hwq]; 1304 return !!wl->queue_stop_reasons[hwq];
1318} 1305}
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index af9fecaefc30..0034979e97cb 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -390,6 +390,9 @@ struct wl1271 {
390 /* number of currently active RX BA sessions */ 390 /* number of currently active RX BA sessions */
391 int ba_rx_session_count; 391 int ba_rx_session_count;
392 392
393 /* Maximum number of supported RX BA sessions */
394 int ba_rx_session_count_max;
395
393 /* AP-mode - number of currently connected stations */ 396 /* AP-mode - number of currently connected stations */
394 int active_sta_count; 397 int active_sta_count;
395 398
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 508f5b0f8a70..e5e146435fe7 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -274,6 +274,13 @@ struct wl1271_link {
274 274
275 /* The wlvif this link belongs to. Might be null for global links */ 275 /* The wlvif this link belongs to. Might be null for global links */
276 struct wl12xx_vif *wlvif; 276 struct wl12xx_vif *wlvif;
277
278 /*
279 * total freed FW packets on the link - used for tracking the
280 * AES/TKIP PN across recoveries. Re-initialized each time
281 * from the wl1271_station structure.
282 */
283 u64 total_freed_pkts;
277}; 284};
278 285
279#define WL1271_MAX_RX_FILTERS 5 286#define WL1271_MAX_RX_FILTERS 5
@@ -318,6 +325,13 @@ struct wl12xx_rx_filter {
318struct wl1271_station { 325struct wl1271_station {
319 u8 hlid; 326 u8 hlid;
320 bool in_connection; 327 bool in_connection;
328
329 /*
330 * total freed FW packets on the link to the STA - used for tracking the
331 * AES/TKIP PN across recoveries. Re-initialized each time from the
332 * wl1271_station structure.
333 */
334 u64 total_freed_pkts;
321}; 335};
322 336
323struct wl12xx_vif { 337struct wl12xx_vif {
@@ -449,16 +463,15 @@ struct wl12xx_vif {
449 */ 463 */
450 struct { 464 struct {
451 u8 persistent[0]; 465 u8 persistent[0];
466
452 /* 467 /*
453 * Security sequence number 468 * total freed FW packets on the link - used for
454 * bits 0-15: lower 16 bits part of sequence number 469 * storing the AES/TKIP PN during recovery, as this
455 * bits 16-47: higher 32 bits part of sequence number 470 * structure is not zeroed out.
456 * bits 48-63: not in use 471 * For STA this holds the PN of the link to the AP.
472 * For AP this holds the PN of the broadcast link.
457 */ 473 */
458 u64 tx_security_seq; 474 u64 total_freed_pkts;
459
460 /* 8 bits of the last sequence number in use */
461 u8 tx_security_last_seq_lsb;
462 }; 475 };
463}; 476};
464 477
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 63ff69f9d3eb..a8dc95ebf2d6 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -347,6 +347,21 @@ static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
347 return (s8)gain; 347 return (s8)gain;
348} 348}
349 349
350static void sprom_extract_r23(struct ssb_sprom *out, const u16 *in)
351{
352 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
353 SPEX(opo, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0);
354 SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0);
355 SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0);
356 SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0);
357 SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0);
358 SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0);
359 SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0);
360 SPEX(maxpwr_ah, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0);
361 SPEX(maxpwr_al, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO,
362 SSB_SPROM2_MAXP_A_LO_SHIFT);
363}
364
350static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) 365static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
351{ 366{
352 u16 loc[3]; 367 u16 loc[3];
@@ -369,6 +384,7 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
369 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); 384 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
370 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); 385 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
371 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); 386 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
387 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
372 if (out->revision == 1) 388 if (out->revision == 1)
373 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, 389 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
374 SSB_SPROM1_BINF_CCODE_SHIFT); 390 SSB_SPROM1_BINF_CCODE_SHIFT);
@@ -395,8 +411,7 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
395 SSB_SPROM1_ITSSI_A_SHIFT); 411 SSB_SPROM1_ITSSI_A_SHIFT);
396 SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0); 412 SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
397 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); 413 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
398 if (out->revision >= 2) 414
399 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
400 SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8); 415 SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8);
401 SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0); 416 SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
402 417
@@ -407,6 +422,8 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
407 out->antenna_gain.a1 = r123_extract_antgain(out->revision, in, 422 out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
408 SSB_SPROM1_AGAIN_A, 423 SSB_SPROM1_AGAIN_A,
409 SSB_SPROM1_AGAIN_A_SHIFT); 424 SSB_SPROM1_AGAIN_A_SHIFT);
425 if (out->revision >= 2)
426 sprom_extract_r23(out, in);
410} 427}
411 428
412/* Revs 4 5 and 8 have partially shared layout */ 429/* Revs 4 5 and 8 have partially shared layout */
@@ -464,6 +481,7 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
464 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, 481 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
465 SSB_SPROM4_ETHPHY_ET1A_SHIFT); 482 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
466 SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0); 483 SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
484 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
467 if (out->revision == 4) { 485 if (out->revision == 4) {
468 SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8); 486 SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8);
469 SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0); 487 SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0);
@@ -535,6 +553,7 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
535 sprom_get_mac(out->il0mac, &in[SPOFF(SSB_SPROM8_IL0MAC)]); 553 sprom_get_mac(out->il0mac, &in[SPOFF(SSB_SPROM8_IL0MAC)]);
536 554
537 SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0); 555 SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
556 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
538 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); 557 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
539 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); 558 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
540 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0); 559 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index e0ce311011c0..0ab6712fd76b 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -173,6 +173,60 @@ struct bcma_host_ops {
173#define BCMA_CHIP_ID_BCM53572 53572 173#define BCMA_CHIP_ID_BCM53572 53572
174#define BCMA_PKG_ID_BCM47188 9 174#define BCMA_PKG_ID_BCM47188 9
175 175
176/* Board types (on PCI usually equals to the subsystem dev id) */
177/* BCM4313 */
178#define BCMA_BOARD_TYPE_BCM94313BU 0X050F
179#define BCMA_BOARD_TYPE_BCM94313HM 0X0510
180#define BCMA_BOARD_TYPE_BCM94313EPA 0X0511
181#define BCMA_BOARD_TYPE_BCM94313HMG 0X051C
182/* BCM4716 */
183#define BCMA_BOARD_TYPE_BCM94716NR2 0X04CD
184/* BCM43224 */
185#define BCMA_BOARD_TYPE_BCM943224X21 0X056E
186#define BCMA_BOARD_TYPE_BCM943224X21_FCC 0X00D1
187#define BCMA_BOARD_TYPE_BCM943224X21B 0X00E9
188#define BCMA_BOARD_TYPE_BCM943224M93 0X008B
189#define BCMA_BOARD_TYPE_BCM943224M93A 0X0090
190#define BCMA_BOARD_TYPE_BCM943224X16 0X0093
191#define BCMA_BOARD_TYPE_BCM94322X9 0X008D
192#define BCMA_BOARD_TYPE_BCM94322M35E 0X008E
193/* BCM43228 */
194#define BCMA_BOARD_TYPE_BCM943228BU8 0X0540
195#define BCMA_BOARD_TYPE_BCM943228BU9 0X0541
196#define BCMA_BOARD_TYPE_BCM943228BU 0X0542
197#define BCMA_BOARD_TYPE_BCM943227HM4L 0X0543
198#define BCMA_BOARD_TYPE_BCM943227HMB 0X0544
199#define BCMA_BOARD_TYPE_BCM943228HM4L 0X0545
200#define BCMA_BOARD_TYPE_BCM943228SD 0X0573
201/* BCM4331 */
202#define BCMA_BOARD_TYPE_BCM94331X19 0X00D6
203#define BCMA_BOARD_TYPE_BCM94331X28 0X00E4
204#define BCMA_BOARD_TYPE_BCM94331X28B 0X010E
205#define BCMA_BOARD_TYPE_BCM94331PCIEBT3AX 0X00E4
206#define BCMA_BOARD_TYPE_BCM94331X12_2G 0X00EC
207#define BCMA_BOARD_TYPE_BCM94331X12_5G 0X00ED
208#define BCMA_BOARD_TYPE_BCM94331X29B 0X00EF
209#define BCMA_BOARD_TYPE_BCM94331CSAX 0X00EF
210#define BCMA_BOARD_TYPE_BCM94331X19C 0X00F5
211#define BCMA_BOARD_TYPE_BCM94331X33 0X00F4
212#define BCMA_BOARD_TYPE_BCM94331BU 0X0523
213#define BCMA_BOARD_TYPE_BCM94331S9BU 0X0524
214#define BCMA_BOARD_TYPE_BCM94331MC 0X0525
215#define BCMA_BOARD_TYPE_BCM94331MCI 0X0526
216#define BCMA_BOARD_TYPE_BCM94331PCIEBT4 0X0527
217#define BCMA_BOARD_TYPE_BCM94331HM 0X0574
218#define BCMA_BOARD_TYPE_BCM94331PCIEDUAL 0X059B
219#define BCMA_BOARD_TYPE_BCM94331MCH5 0X05A9
220#define BCMA_BOARD_TYPE_BCM94331CS 0X05C6
221#define BCMA_BOARD_TYPE_BCM94331CD 0X05DA
222/* BCM53572 */
223#define BCMA_BOARD_TYPE_BCM953572BU 0X058D
224#define BCMA_BOARD_TYPE_BCM953572NR2 0X058E
225#define BCMA_BOARD_TYPE_BCM947188NR2 0X058F
226#define BCMA_BOARD_TYPE_BCM953572SDRNR2 0X0590
227/* BCM43142 */
228#define BCMA_BOARD_TYPE_BCM943142HM 0X05E0
229
176struct bcma_device { 230struct bcma_device {
177 struct bcma_bus *bus; 231 struct bcma_bus *bus;
178 struct bcma_device_id id; 232 struct bcma_device_id id;
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 8390c474f69a..453fcc914683 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -104,6 +104,7 @@
104#define BCMA_CC_CHIPST_4706_MIPS_BENDIAN BIT(3) /* 0: little, 1: big endian */ 104#define BCMA_CC_CHIPST_4706_MIPS_BENDIAN BIT(3) /* 0: little, 1: big endian */
105#define BCMA_CC_CHIPST_4706_PCIE1_DISABLE BIT(5) /* PCIE1 enable strap pin */ 105#define BCMA_CC_CHIPST_4706_PCIE1_DISABLE BIT(5) /* PCIE1 enable strap pin */
106#define BCMA_CC_CHIPST_5357_NAND_BOOT BIT(4) /* NAND boot, valid for CC rev 38 and/or BCM5357 */ 106#define BCMA_CC_CHIPST_5357_NAND_BOOT BIT(4) /* NAND boot, valid for CC rev 38 and/or BCM5357 */
107#define BCMA_CC_CHIPST_4360_XTAL_40MZ 0x00000001
107#define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */ 108#define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */
108#define BCMA_CC_JCMD_START 0x80000000 109#define BCMA_CC_JCMD_START 0x80000000
109#define BCMA_CC_JCMD_BUSY 0x80000000 110#define BCMA_CC_JCMD_BUSY 0x80000000
@@ -607,6 +608,8 @@ void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
607 608
608extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks); 609extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks);
609 610
611extern u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc);
612
610void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value); 613void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value);
611 614
612u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask); 615u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask);
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 8b1322296fed..c64999fd1660 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -340,13 +340,61 @@ enum ssb_bustype {
340#define SSB_BOARDVENDOR_DELL 0x1028 /* Dell */ 340#define SSB_BOARDVENDOR_DELL 0x1028 /* Dell */
341#define SSB_BOARDVENDOR_HP 0x0E11 /* HP */ 341#define SSB_BOARDVENDOR_HP 0x0E11 /* HP */
342/* board_type */ 342/* board_type */
343#define SSB_BOARD_BCM94301CB 0x0406
344#define SSB_BOARD_BCM94301MP 0x0407
345#define SSB_BOARD_BU4309 0x040A
346#define SSB_BOARD_BCM94309CB 0x040B
347#define SSB_BOARD_BCM4309MP 0x040C
348#define SSB_BOARD_BU4306 0x0416
343#define SSB_BOARD_BCM94306MP 0x0418 349#define SSB_BOARD_BCM94306MP 0x0418
344#define SSB_BOARD_BCM4309G 0x0421 350#define SSB_BOARD_BCM4309G 0x0421
345#define SSB_BOARD_BCM4306CB 0x0417 351#define SSB_BOARD_BCM4306CB 0x0417
346#define SSB_BOARD_BCM4309MP 0x040C 352#define SSB_BOARD_BCM94306PC 0x0425 /* pcmcia 3.3v 4306 card */
353#define SSB_BOARD_BCM94306CBSG 0x042B /* with SiGe PA */
354#define SSB_BOARD_PCSG94306 0x042D /* with SiGe PA */
355#define SSB_BOARD_BU4704SD 0x042E /* with sdram */
356#define SSB_BOARD_BCM94704AGR 0x042F /* dual 11a/11g Router */
357#define SSB_BOARD_BCM94308MP 0x0430 /* 11a-only minipci */
358#define SSB_BOARD_BU4318 0x0447
359#define SSB_BOARD_CB4318 0x0448
360#define SSB_BOARD_MPG4318 0x0449
347#define SSB_BOARD_MP4318 0x044A 361#define SSB_BOARD_MP4318 0x044A
348#define SSB_BOARD_BU4306 0x0416 362#define SSB_BOARD_SD4318 0x044B
349#define SSB_BOARD_BU4309 0x040A 363#define SSB_BOARD_BCM94306P 0x044C /* with SiGe */
364#define SSB_BOARD_BCM94303MP 0x044E
365#define SSB_BOARD_BCM94306MPM 0x0450
366#define SSB_BOARD_BCM94306MPL 0x0453
367#define SSB_BOARD_PC4303 0x0454 /* pcmcia */
368#define SSB_BOARD_BCM94306MPLNA 0x0457
369#define SSB_BOARD_BCM94306MPH 0x045B
370#define SSB_BOARD_BCM94306PCIV 0x045C
371#define SSB_BOARD_BCM94318MPGH 0x0463
372#define SSB_BOARD_BU4311 0x0464
373#define SSB_BOARD_BCM94311MC 0x0465
374#define SSB_BOARD_BCM94311MCAG 0x0466
375/* 4321 boards */
376#define SSB_BOARD_BU4321 0x046B
377#define SSB_BOARD_BU4321E 0x047C
378#define SSB_BOARD_MP4321 0x046C
379#define SSB_BOARD_CB2_4321 0x046D
380#define SSB_BOARD_CB2_4321_AG 0x0066
381#define SSB_BOARD_MC4321 0x046E
382/* 4325 boards */
383#define SSB_BOARD_BCM94325DEVBU 0x0490
384#define SSB_BOARD_BCM94325BGABU 0x0491
385#define SSB_BOARD_BCM94325SDGWB 0x0492
386#define SSB_BOARD_BCM94325SDGMDL 0x04AA
387#define SSB_BOARD_BCM94325SDGMDL2 0x04C6
388#define SSB_BOARD_BCM94325SDGMDL3 0x04C9
389#define SSB_BOARD_BCM94325SDABGWBA 0x04E1
390/* 4322 boards */
391#define SSB_BOARD_BCM94322MC 0x04A4
392#define SSB_BOARD_BCM94322USB 0x04A8 /* dualband */
393#define SSB_BOARD_BCM94322HM 0x04B0
394#define SSB_BOARD_BCM94322USB2D 0x04Bf /* single band discrete front end */
395/* 4312 boards */
396#define SSB_BOARD_BU4312 0x048A
397#define SSB_BOARD_BCM4312MCGSG 0x04B5
350/* chip_package */ 398/* chip_package */
351#define SSB_CHIPPACK_BCM4712S 1 /* Small 200pin 4712 */ 399#define SSB_CHIPPACK_BCM4712S 1 /* Small 200pin 4712 */
352#define SSB_CHIPPACK_BCM4712M 2 /* Medium 225pin 4712 */ 400#define SSB_CHIPPACK_BCM4712M 2 /* Medium 225pin 4712 */
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index 6ecfa02ddbac..3a7256955b10 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -289,11 +289,11 @@
289#define SSB_SPROM4_ETHPHY_ET1A_SHIFT 5 289#define SSB_SPROM4_ETHPHY_ET1A_SHIFT 5
290#define SSB_SPROM4_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */ 290#define SSB_SPROM4_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */
291#define SSB_SPROM4_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */ 291#define SSB_SPROM4_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */
292#define SSB_SPROM4_ANTAVAIL 0x005D /* Antenna available bitfields */ 292#define SSB_SPROM4_ANTAVAIL 0x005C /* Antenna available bitfields */
293#define SSB_SPROM4_ANTAVAIL_A 0x00FF /* A-PHY bitfield */ 293#define SSB_SPROM4_ANTAVAIL_BG 0x00FF /* B-PHY and G-PHY bitfield */
294#define SSB_SPROM4_ANTAVAIL_A_SHIFT 0 294#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 0
295#define SSB_SPROM4_ANTAVAIL_BG 0xFF00 /* B-PHY and G-PHY bitfield */ 295#define SSB_SPROM4_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */
296#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 8 296#define SSB_SPROM4_ANTAVAIL_A_SHIFT 8
297#define SSB_SPROM4_AGAIN01 0x005E /* Antenna Gain (in dBm Q5.2) */ 297#define SSB_SPROM4_AGAIN01 0x005E /* Antenna Gain (in dBm Q5.2) */
298#define SSB_SPROM4_AGAIN0 0x00FF /* Antenna 0 */ 298#define SSB_SPROM4_AGAIN0 0x00FF /* Antenna 0 */
299#define SSB_SPROM4_AGAIN0_SHIFT 0 299#define SSB_SPROM4_AGAIN0_SHIFT 0
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 9531beee09b5..ed6e9552252e 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -232,7 +232,7 @@ struct bt_sock_list {
232}; 232};
233 233
234int bt_sock_register(int proto, const struct net_proto_family *ops); 234int bt_sock_register(int proto, const struct net_proto_family *ops);
235int bt_sock_unregister(int proto); 235void bt_sock_unregister(int proto);
236void bt_sock_link(struct bt_sock_list *l, struct sock *s); 236void bt_sock_link(struct bt_sock_list *l, struct sock *s);
237void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); 237void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
238int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, 238int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
@@ -260,12 +260,22 @@ struct l2cap_ctrl {
260 __u8 retries; 260 __u8 retries;
261}; 261};
262 262
263struct hci_dev;
264
265typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status);
266
267struct hci_req_ctrl {
268 bool start;
269 hci_req_complete_t complete;
270};
271
263struct bt_skb_cb { 272struct bt_skb_cb {
264 __u8 pkt_type; 273 __u8 pkt_type;
265 __u8 incoming; 274 __u8 incoming;
266 __u16 expect; 275 __u16 expect;
267 __u8 force_active; 276 __u8 force_active;
268 struct l2cap_ctrl control; 277 struct l2cap_ctrl control;
278 struct hci_req_ctrl req;
269}; 279};
270#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) 280#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
271 281
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 7f12c25f1fca..b3308927a0a1 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -119,10 +119,16 @@ enum {
119 HCI_CONNECTABLE, 119 HCI_CONNECTABLE,
120 HCI_DISCOVERABLE, 120 HCI_DISCOVERABLE,
121 HCI_LINK_SECURITY, 121 HCI_LINK_SECURITY,
122 HCI_PENDING_CLASS,
123 HCI_PERIODIC_INQ, 122 HCI_PERIODIC_INQ,
123 HCI_FAST_CONNECTABLE,
124}; 124};
125 125
126/* A mask for the flags that are supposed to remain when a reset happens
127 * or the HCI device is closed.
128 */
129#define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \
130 BIT(HCI_FAST_CONNECTABLE))
131
126/* HCI ioctl defines */ 132/* HCI ioctl defines */
127#define HCIDEVUP _IOW('H', 201, int) 133#define HCIDEVUP _IOW('H', 201, int)
128#define HCIDEVDOWN _IOW('H', 202, int) 134#define HCIDEVDOWN _IOW('H', 202, int)
@@ -881,12 +887,25 @@ struct hci_rp_read_data_block_size {
881 __le16 num_blocks; 887 __le16 num_blocks;
882} __packed; 888} __packed;
883 889
890#define HCI_OP_READ_PAGE_SCAN_ACTIVITY 0x0c1b
891struct hci_rp_read_page_scan_activity {
892 __u8 status;
893 __le16 interval;
894 __le16 window;
895} __packed;
896
884#define HCI_OP_WRITE_PAGE_SCAN_ACTIVITY 0x0c1c 897#define HCI_OP_WRITE_PAGE_SCAN_ACTIVITY 0x0c1c
885struct hci_cp_write_page_scan_activity { 898struct hci_cp_write_page_scan_activity {
886 __le16 interval; 899 __le16 interval;
887 __le16 window; 900 __le16 window;
888} __packed; 901} __packed;
889 902
903#define HCI_OP_READ_PAGE_SCAN_TYPE 0x0c46
904struct hci_rp_read_page_scan_type {
905 __u8 status;
906 __u8 type;
907} __packed;
908
890#define HCI_OP_WRITE_PAGE_SCAN_TYPE 0x0c47 909#define HCI_OP_WRITE_PAGE_SCAN_TYPE 0x0c47
891 #define PAGE_SCAN_TYPE_STANDARD 0x00 910 #define PAGE_SCAN_TYPE_STANDARD 0x00
892 #define PAGE_SCAN_TYPE_INTERLACED 0x01 911 #define PAGE_SCAN_TYPE_INTERLACED 0x01
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 90cf75afcb02..358a6983d3bb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -165,6 +165,10 @@ struct hci_dev {
165 __u16 voice_setting; 165 __u16 voice_setting;
166 __u8 io_capability; 166 __u8 io_capability;
167 __s8 inq_tx_power; 167 __s8 inq_tx_power;
168 __u16 page_scan_interval;
169 __u16 page_scan_window;
170 __u8 page_scan_type;
171
168 __u16 devid_source; 172 __u16 devid_source;
169 __u16 devid_vendor; 173 __u16 devid_vendor;
170 __u16 devid_product; 174 __u16 devid_product;
@@ -248,8 +252,6 @@ struct hci_dev {
248 __u32 req_status; 252 __u32 req_status;
249 __u32 req_result; 253 __u32 req_result;
250 254
251 __u16 init_last_cmd;
252
253 struct list_head mgmt_pending; 255 struct list_head mgmt_pending;
254 256
255 struct discovery_state discovery; 257 struct discovery_state discovery;
@@ -574,7 +576,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
574 return NULL; 576 return NULL;
575} 577}
576 578
577void hci_acl_disconn(struct hci_conn *conn, __u8 reason); 579void hci_disconnect(struct hci_conn *conn, __u8 reason);
578void hci_setup_sync(struct hci_conn *conn, __u16 handle); 580void hci_setup_sync(struct hci_conn *conn, __u16 handle);
579void hci_sco_setup(struct hci_conn *conn, __u8 status); 581void hci_sco_setup(struct hci_conn *conn, __u8 status);
580 582
@@ -742,8 +744,6 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
742 u8 *randomizer); 744 u8 *randomizer);
743int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); 745int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
744 746
745int hci_update_ad(struct hci_dev *hdev);
746
747void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); 747void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
748 748
749int hci_recv_frame(struct sk_buff *skb); 749int hci_recv_frame(struct sk_buff *skb);
@@ -1041,6 +1041,22 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
1041int hci_register_cb(struct hci_cb *hcb); 1041int hci_register_cb(struct hci_cb *hcb);
1042int hci_unregister_cb(struct hci_cb *hcb); 1042int hci_unregister_cb(struct hci_cb *hcb);
1043 1043
1044struct hci_request {
1045 struct hci_dev *hdev;
1046 struct sk_buff_head cmd_q;
1047
1048 /* If something goes wrong when building the HCI request, the error
1049 * value is stored in this field.
1050 */
1051 int err;
1052};
1053
1054void hci_req_init(struct hci_request *req, struct hci_dev *hdev);
1055int hci_req_run(struct hci_request *req, hci_req_complete_t complete);
1056void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param);
1057void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
1058void hci_req_cmd_status(struct hci_dev *hdev, u16 opcode, u8 status);
1059
1044int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); 1060int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
1045void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); 1061void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
1046void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); 1062void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
@@ -1153,7 +1169,7 @@ struct hci_sec_filter {
1153#define hci_req_lock(d) mutex_lock(&d->req_lock) 1169#define hci_req_lock(d) mutex_lock(&d->req_lock)
1154#define hci_req_unlock(d) mutex_unlock(&d->req_lock) 1170#define hci_req_unlock(d) mutex_unlock(&d->req_lock)
1155 1171
1156void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result); 1172void hci_update_ad(struct hci_request *req);
1157 1173
1158void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, 1174void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
1159 u16 latency, u16 to_multiplier); 1175 u16 latency, u16 to_multiplier);
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index e2e3ecad1008..7afd4199d6b6 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -158,7 +158,6 @@ struct rfcomm_session {
158 struct timer_list timer; 158 struct timer_list timer;
159 unsigned long state; 159 unsigned long state;
160 unsigned long flags; 160 unsigned long flags;
161 atomic_t refcnt;
162 int initiator; 161 int initiator;
163 162
164 /* Default DLC parameters */ 163 /* Default DLC parameters */
@@ -276,11 +275,6 @@ static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
276void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, 275void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src,
277 bdaddr_t *dst); 276 bdaddr_t *dst);
278 277
279static inline void rfcomm_session_hold(struct rfcomm_session *s)
280{
281 atomic_inc(&s->refcnt);
282}
283
284/* ---- RFCOMM sockets ---- */ 278/* ---- RFCOMM sockets ---- */
285struct sockaddr_rc { 279struct sockaddr_rc {
286 sa_family_t rc_family; 280 sa_family_t rc_family;
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index cdd7cea1fd4c..dd73b8c6746b 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -93,9 +93,11 @@ struct device;
93 * enum ieee80211_max_queues - maximum number of queues 93 * enum ieee80211_max_queues - maximum number of queues
94 * 94 *
95 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues. 95 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
96 * @IEEE80211_MAX_QUEUE_MAP: bitmap with maximum queues set
96 */ 97 */
97enum ieee80211_max_queues { 98enum ieee80211_max_queues {
98 IEEE80211_MAX_QUEUES = 16, 99 IEEE80211_MAX_QUEUES = 16,
100 IEEE80211_MAX_QUEUE_MAP = BIT(IEEE80211_MAX_QUEUES) - 1,
99}; 101};
100 102
101#define IEEE80211_INVAL_HW_QUEUE 0xff 103#define IEEE80211_INVAL_HW_QUEUE 0xff
@@ -1067,6 +1069,9 @@ enum ieee80211_vif_flags {
1067 * path needing to access it; even though the netdev carrier will always 1069 * path needing to access it; even though the netdev carrier will always
1068 * be off when it is %NULL there can still be races and packets could be 1070 * be off when it is %NULL there can still be races and packets could be
1069 * processed after it switches back to %NULL. 1071 * processed after it switches back to %NULL.
1072 * @debugfs_dir: debugfs dentry, can be used by drivers to create own per
1073 * interface debug files. Note that it will be NULL for the virtual
1074 * monitor interface (if that is requested.)
1070 * @drv_priv: data area for driver use, will always be aligned to 1075 * @drv_priv: data area for driver use, will always be aligned to
1071 * sizeof(void *). 1076 * sizeof(void *).
1072 */ 1077 */
@@ -1083,6 +1088,10 @@ struct ieee80211_vif {
1083 1088
1084 u32 driver_flags; 1089 u32 driver_flags;
1085 1090
1091#ifdef CONFIG_MAC80211_DEBUGFS
1092 struct dentry *debugfs_dir;
1093#endif
1094
1086 /* must be last */ 1095 /* must be last */
1087 u8 drv_priv[0] __aligned(sizeof(void *)); 1096 u8 drv_priv[0] __aligned(sizeof(void *));
1088}; 1097};
@@ -1946,14 +1955,14 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
1946 * filter those response frames except in the case of frames that 1955 * filter those response frames except in the case of frames that
1947 * are buffered in the driver -- those must remain buffered to avoid 1956 * are buffered in the driver -- those must remain buffered to avoid
1948 * reordering. Because it is possible that no frames are released 1957 * reordering. Because it is possible that no frames are released
1949 * in this case, the driver must call ieee80211_sta_eosp_irqsafe() 1958 * in this case, the driver must call ieee80211_sta_eosp()
1950 * to indicate to mac80211 that the service period ended anyway. 1959 * to indicate to mac80211 that the service period ended anyway.
1951 * 1960 *
1952 * Finally, if frames from multiple TIDs are released from mac80211 1961 * Finally, if frames from multiple TIDs are released from mac80211
1953 * but the driver might reorder them, it must clear & set the flags 1962 * but the driver might reorder them, it must clear & set the flags
1954 * appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP) 1963 * appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP)
1955 * and also take care of the EOSP and MORE_DATA bits in the frame. 1964 * and also take care of the EOSP and MORE_DATA bits in the frame.
1956 * The driver may also use ieee80211_sta_eosp_irqsafe() in this case. 1965 * The driver may also use ieee80211_sta_eosp() in this case.
1957 */ 1966 */
1958 1967
1959/** 1968/**
@@ -2226,18 +2235,6 @@ enum ieee80211_roc_type {
2226 * MAC address of the device going away. 2235 * MAC address of the device going away.
2227 * Hence, this callback must be implemented. It can sleep. 2236 * Hence, this callback must be implemented. It can sleep.
2228 * 2237 *
2229 * @add_interface_debugfs: Drivers can use this callback to add debugfs files
2230 * when a vif is added to mac80211. This callback and
2231 * @remove_interface_debugfs should be within a CONFIG_MAC80211_DEBUGFS
2232 * conditional. @remove_interface_debugfs must be provided for cleanup.
2233 * This callback can sleep.
2234 *
2235 * @remove_interface_debugfs: Remove the debugfs files which were added using
2236 * @add_interface_debugfs. This callback must remove all debugfs entries
2237 * that were added because mac80211 only removes interface debugfs when the
2238 * interface is destroyed, not when it is removed from the driver.
2239 * This callback can sleep.
2240 *
2241 * @config: Handler for configuration requests. IEEE 802.11 code calls this 2238 * @config: Handler for configuration requests. IEEE 802.11 code calls this
2242 * function to change hardware configuration, e.g., channel. 2239 * function to change hardware configuration, e.g., channel.
2243 * This function should never fail but returns a negative error code 2240 * This function should never fail but returns a negative error code
@@ -2259,6 +2256,9 @@ enum ieee80211_roc_type {
2259 * See the section "Frame filtering" for more information. 2256 * See the section "Frame filtering" for more information.
2260 * This callback must be implemented and can sleep. 2257 * This callback must be implemented and can sleep.
2261 * 2258 *
2259 * @set_multicast_list: Configure the device's interface specific RX multicast
2260 * filter. This callback is optional. This callback must be atomic.
2261 *
2262 * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit 2262 * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
2263 * must be set or cleared for a given STA. Must be atomic. 2263 * must be set or cleared for a given STA. Must be atomic.
2264 * 2264 *
@@ -2440,8 +2440,11 @@ enum ieee80211_roc_type {
2440 * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep. 2440 * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep.
2441 * 2441 *
2442 * @flush: Flush all pending frames from the hardware queue, making sure 2442 * @flush: Flush all pending frames from the hardware queue, making sure
2443 * that the hardware queues are empty. If the parameter @drop is set 2443 * that the hardware queues are empty. The @queues parameter is a bitmap
2444 * to %true, pending frames may be dropped. The callback can sleep. 2444 * of queues to flush, which is useful if different virtual interfaces
2445 * use different hardware queues; it may also indicate all queues.
2446 * If the parameter @drop is set to %true, pending frames may be dropped.
2447 * The callback can sleep.
2445 * 2448 *
2446 * @channel_switch: Drivers that need (or want) to offload the channel 2449 * @channel_switch: Drivers that need (or want) to offload the channel
2447 * switch operation for CSAs received from the AP may implement this 2450 * switch operation for CSAs received from the AP may implement this
@@ -2506,7 +2509,7 @@ enum ieee80211_roc_type {
2506 * setting the EOSP flag in the QoS header of the frames. Also, when the 2509 * setting the EOSP flag in the QoS header of the frames. Also, when the
2507 * service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP 2510 * service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP
2508 * on the last frame in the SP. Alternatively, it may call the function 2511 * on the last frame in the SP. Alternatively, it may call the function
2509 * ieee80211_sta_eosp_irqsafe() to inform mac80211 of the end of the SP. 2512 * ieee80211_sta_eosp() to inform mac80211 of the end of the SP.
2510 * This callback must be atomic. 2513 * This callback must be atomic.
2511 * @allow_buffered_frames: Prepare device to allow the given number of frames 2514 * @allow_buffered_frames: Prepare device to allow the given number of frames
2512 * to go out to the given station. The frames will be sent by mac80211 2515 * to go out to the given station. The frames will be sent by mac80211
@@ -2517,7 +2520,7 @@ enum ieee80211_roc_type {
2517 * them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag 2520 * them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag
2518 * on the last frame and clear it on all others and also handle the EOSP 2521 * on the last frame and clear it on all others and also handle the EOSP
2519 * bit in the QoS header correctly. Alternatively, it can also call the 2522 * bit in the QoS header correctly. Alternatively, it can also call the
2520 * ieee80211_sta_eosp_irqsafe() function. 2523 * ieee80211_sta_eosp() function.
2521 * The @tids parameter is a bitmap and tells the driver which TIDs the 2524 * The @tids parameter is a bitmap and tells the driver which TIDs the
2522 * frames will be on; it will at most have two bits set. 2525 * frames will be on; it will at most have two bits set.
2523 * This callback must be atomic. 2526 * This callback must be atomic.
@@ -2605,6 +2608,10 @@ struct ieee80211_ops {
2605 unsigned int changed_flags, 2608 unsigned int changed_flags,
2606 unsigned int *total_flags, 2609 unsigned int *total_flags,
2607 u64 multicast); 2610 u64 multicast);
2611 void (*set_multicast_list)(struct ieee80211_hw *hw,
2612 struct ieee80211_vif *vif, bool allmulti,
2613 struct netdev_hw_addr_list *mc_list);
2614
2608 int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, 2615 int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
2609 bool set); 2616 bool set);
2610 int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, 2617 int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -2651,12 +2658,6 @@ struct ieee80211_ops {
2651 struct ieee80211_vif *vif, 2658 struct ieee80211_vif *vif,
2652 struct ieee80211_sta *sta, 2659 struct ieee80211_sta *sta,
2653 struct dentry *dir); 2660 struct dentry *dir);
2654 void (*add_interface_debugfs)(struct ieee80211_hw *hw,
2655 struct ieee80211_vif *vif,
2656 struct dentry *dir);
2657 void (*remove_interface_debugfs)(struct ieee80211_hw *hw,
2658 struct ieee80211_vif *vif,
2659 struct dentry *dir);
2660#endif 2661#endif
2661 void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2662 void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2662 enum sta_notify_cmd, struct ieee80211_sta *sta); 2663 enum sta_notify_cmd, struct ieee80211_sta *sta);
@@ -2691,7 +2692,7 @@ struct ieee80211_ops {
2691 struct netlink_callback *cb, 2692 struct netlink_callback *cb,
2692 void *data, int len); 2693 void *data, int len);
2693#endif 2694#endif
2694 void (*flush)(struct ieee80211_hw *hw, bool drop); 2695 void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop);
2695 void (*channel_switch)(struct ieee80211_hw *hw, 2696 void (*channel_switch)(struct ieee80211_hw *hw,
2696 struct ieee80211_channel_switch *ch_switch); 2697 struct ieee80211_channel_switch *ch_switch);
2697 int (*napi_poll)(struct ieee80211_hw *hw, int budget); 2698 int (*napi_poll)(struct ieee80211_hw *hw, int budget);
@@ -3857,14 +3858,17 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
3857 * %IEEE80211_TX_STATUS_EOSP bit and call this function instead. 3858 * %IEEE80211_TX_STATUS_EOSP bit and call this function instead.
3858 * This applies for PS-Poll as well as uAPSD. 3859 * This applies for PS-Poll as well as uAPSD.
3859 * 3860 *
3860 * Note that there is no non-_irqsafe version right now as 3861 * Note that just like with _tx_status() and _rx() drivers must
3861 * it wasn't needed, but just like _tx_status() and _rx() 3862 * not mix calls to irqsafe/non-irqsafe versions, this function
3862 * must not be mixed in irqsafe/non-irqsafe versions, this 3863 * must not be mixed with those either. Use the all irqsafe, or
3863 * function must not be mixed with those either. Use the 3864 * all non-irqsafe, don't mix!
3864 * all irqsafe, or all non-irqsafe, don't mix! If you need 3865 *
3865 * the non-irqsafe version of this, you need to add it. 3866 * NB: the _irqsafe version of this function doesn't exist, no
3867 * driver needs it right now. Don't call this function if
3868 * you'd need the _irqsafe version, look at the git history
3869 * and restore the _irqsafe version!
3866 */ 3870 */
3867void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta); 3871void ieee80211_sta_eosp(struct ieee80211_sta *pubsta);
3868 3872
3869/** 3873/**
3870 * ieee80211_iter_keys - iterate keys programmed into the device 3874 * ieee80211_iter_keys - iterate keys programmed into the device
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index eb0f4b16ff09..17f33a62f6db 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -397,13 +397,12 @@ static int a2mp_getampassoc_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
397 if (ctrl) { 397 if (ctrl) {
398 u8 *assoc; 398 u8 *assoc;
399 399
400 assoc = kzalloc(assoc_len, GFP_KERNEL); 400 assoc = kmemdup(rsp->amp_assoc, assoc_len, GFP_KERNEL);
401 if (!assoc) { 401 if (!assoc) {
402 amp_ctrl_put(ctrl); 402 amp_ctrl_put(ctrl);
403 return -ENOMEM; 403 return -ENOMEM;
404 } 404 }
405 405
406 memcpy(assoc, rsp->amp_assoc, assoc_len);
407 ctrl->assoc = assoc; 406 ctrl->assoc = assoc;
408 ctrl->assoc_len = assoc_len; 407 ctrl->assoc_len = assoc_len;
409 ctrl->assoc_rem_len = assoc_len; 408 ctrl->assoc_rem_len = assoc_len;
@@ -472,13 +471,12 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
472 size_t assoc_len = le16_to_cpu(hdr->len) - sizeof(*req); 471 size_t assoc_len = le16_to_cpu(hdr->len) - sizeof(*req);
473 u8 *assoc; 472 u8 *assoc;
474 473
475 assoc = kzalloc(assoc_len, GFP_KERNEL); 474 assoc = kmemdup(req->amp_assoc, assoc_len, GFP_KERNEL);
476 if (!assoc) { 475 if (!assoc) {
477 amp_ctrl_put(ctrl); 476 amp_ctrl_put(ctrl);
478 return -ENOMEM; 477 return -ENOMEM;
479 } 478 }
480 479
481 memcpy(assoc, req->amp_assoc, assoc_len);
482 ctrl->assoc = assoc; 480 ctrl->assoc = assoc;
483 ctrl->assoc_len = assoc_len; 481 ctrl->assoc_len = assoc_len;
484 ctrl->assoc_rem_len = assoc_len; 482 ctrl->assoc_rem_len = assoc_len;
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index d5a973bf8a6f..e5338f787d68 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -92,23 +92,14 @@ int bt_sock_register(int proto, const struct net_proto_family *ops)
92} 92}
93EXPORT_SYMBOL(bt_sock_register); 93EXPORT_SYMBOL(bt_sock_register);
94 94
95int bt_sock_unregister(int proto) 95void bt_sock_unregister(int proto)
96{ 96{
97 int err = 0;
98
99 if (proto < 0 || proto >= BT_MAX_PROTO) 97 if (proto < 0 || proto >= BT_MAX_PROTO)
100 return -EINVAL; 98 return;
101 99
102 write_lock(&bt_proto_lock); 100 write_lock(&bt_proto_lock);
103 101 bt_proto[proto] = NULL;
104 if (!bt_proto[proto])
105 err = -ENOENT;
106 else
107 bt_proto[proto] = NULL;
108
109 write_unlock(&bt_proto_lock); 102 write_unlock(&bt_proto_lock);
110
111 return err;
112} 103}
113EXPORT_SYMBOL(bt_sock_unregister); 104EXPORT_SYMBOL(bt_sock_unregister);
114 105
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index e7154a58465f..5b1c04e28821 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -253,8 +253,6 @@ error:
253void __exit bnep_sock_cleanup(void) 253void __exit bnep_sock_cleanup(void)
254{ 254{
255 bt_procfs_cleanup(&init_net, "bnep"); 255 bt_procfs_cleanup(&init_net, "bnep");
256 if (bt_sock_unregister(BTPROTO_BNEP) < 0) 256 bt_sock_unregister(BTPROTO_BNEP);
257 BT_ERR("Can't unregister BNEP socket");
258
259 proto_unregister(&bnep_proto); 257 proto_unregister(&bnep_proto);
260} 258}
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index 1c57482112b6..58d9edebab4b 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -264,8 +264,6 @@ error:
264void cmtp_cleanup_sockets(void) 264void cmtp_cleanup_sockets(void)
265{ 265{
266 bt_procfs_cleanup(&init_net, "cmtp"); 266 bt_procfs_cleanup(&init_net, "cmtp");
267 if (bt_sock_unregister(BTPROTO_CMTP) < 0) 267 bt_sock_unregister(BTPROTO_CMTP);
268 BT_ERR("Can't unregister CMTP socket");
269
270 proto_unregister(&cmtp_proto); 268 proto_unregister(&cmtp_proto);
271} 269}
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 4925a02ae7e4..b9f90169940b 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -117,7 +117,7 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn)
117 hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp); 117 hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
118} 118}
119 119
120void hci_acl_disconn(struct hci_conn *conn, __u8 reason) 120void hci_disconnect(struct hci_conn *conn, __u8 reason)
121{ 121{
122 struct hci_cp_disconnect cp; 122 struct hci_cp_disconnect cp;
123 123
@@ -253,7 +253,7 @@ static void hci_conn_disconnect(struct hci_conn *conn)
253 hci_amp_disconn(conn, reason); 253 hci_amp_disconn(conn, reason);
254 break; 254 break;
255 default: 255 default:
256 hci_acl_disconn(conn, reason); 256 hci_disconnect(conn, reason);
257 break; 257 break;
258 } 258 }
259} 259}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 60793e7b768b..cfcad5423f1c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -57,36 +57,9 @@ static void hci_notify(struct hci_dev *hdev, int event)
57 57
58/* ---- HCI requests ---- */ 58/* ---- HCI requests ---- */
59 59
60void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) 60static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
61{ 61{
62 BT_DBG("%s command 0x%4.4x result 0x%2.2x", hdev->name, cmd, result); 62 BT_DBG("%s result 0x%2.2x", hdev->name, result);
63
64 /* If this is the init phase check if the completed command matches
65 * the last init command, and if not just return.
66 */
67 if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) {
68 struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
69 u16 opcode = __le16_to_cpu(sent->opcode);
70 struct sk_buff *skb;
71
72 /* Some CSR based controllers generate a spontaneous
73 * reset complete event during init and any pending
74 * command will never be completed. In such a case we
75 * need to resend whatever was the last sent
76 * command.
77 */
78
79 if (cmd != HCI_OP_RESET || opcode == HCI_OP_RESET)
80 return;
81
82 skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC);
83 if (skb) {
84 skb_queue_head(&hdev->cmd_q, skb);
85 queue_work(hdev->workqueue, &hdev->cmd_work);
86 }
87
88 return;
89 }
90 63
91 if (hdev->req_status == HCI_REQ_PEND) { 64 if (hdev->req_status == HCI_REQ_PEND) {
92 hdev->req_result = result; 65 hdev->req_result = result;
@@ -107,21 +80,41 @@ static void hci_req_cancel(struct hci_dev *hdev, int err)
107} 80}
108 81
109/* Execute request and wait for completion. */ 82/* Execute request and wait for completion. */
110static int __hci_request(struct hci_dev *hdev, 83static int __hci_req_sync(struct hci_dev *hdev,
111 void (*req)(struct hci_dev *hdev, unsigned long opt), 84 void (*func)(struct hci_request *req,
112 unsigned long opt, __u32 timeout) 85 unsigned long opt),
86 unsigned long opt, __u32 timeout)
113{ 87{
88 struct hci_request req;
114 DECLARE_WAITQUEUE(wait, current); 89 DECLARE_WAITQUEUE(wait, current);
115 int err = 0; 90 int err = 0;
116 91
117 BT_DBG("%s start", hdev->name); 92 BT_DBG("%s start", hdev->name);
118 93
94 hci_req_init(&req, hdev);
95
119 hdev->req_status = HCI_REQ_PEND; 96 hdev->req_status = HCI_REQ_PEND;
120 97
98 func(&req, opt);
99
100 err = hci_req_run(&req, hci_req_sync_complete);
101 if (err < 0) {
102 hdev->req_status = 0;
103
104 /* ENODATA means the HCI request command queue is empty.
105 * This can happen when a request with conditionals doesn't
106 * trigger any commands to be sent. This is normal behavior
107 * and should not trigger an error return.
108 */
109 if (err == -ENODATA)
110 return 0;
111
112 return err;
113 }
114
121 add_wait_queue(&hdev->req_wait_q, &wait); 115 add_wait_queue(&hdev->req_wait_q, &wait);
122 set_current_state(TASK_INTERRUPTIBLE); 116 set_current_state(TASK_INTERRUPTIBLE);
123 117
124 req(hdev, opt);
125 schedule_timeout(timeout); 118 schedule_timeout(timeout);
126 119
127 remove_wait_queue(&hdev->req_wait_q, &wait); 120 remove_wait_queue(&hdev->req_wait_q, &wait);
@@ -150,9 +143,10 @@ static int __hci_request(struct hci_dev *hdev,
150 return err; 143 return err;
151} 144}
152 145
153static int hci_request(struct hci_dev *hdev, 146static int hci_req_sync(struct hci_dev *hdev,
154 void (*req)(struct hci_dev *hdev, unsigned long opt), 147 void (*req)(struct hci_request *req,
155 unsigned long opt, __u32 timeout) 148 unsigned long opt),
149 unsigned long opt, __u32 timeout)
156{ 150{
157 int ret; 151 int ret;
158 152
@@ -161,75 +155,86 @@ static int hci_request(struct hci_dev *hdev,
161 155
162 /* Serialize all requests */ 156 /* Serialize all requests */
163 hci_req_lock(hdev); 157 hci_req_lock(hdev);
164 ret = __hci_request(hdev, req, opt, timeout); 158 ret = __hci_req_sync(hdev, req, opt, timeout);
165 hci_req_unlock(hdev); 159 hci_req_unlock(hdev);
166 160
167 return ret; 161 return ret;
168} 162}
169 163
170static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) 164static void hci_reset_req(struct hci_request *req, unsigned long opt)
171{ 165{
172 BT_DBG("%s %ld", hdev->name, opt); 166 BT_DBG("%s %ld", req->hdev->name, opt);
173 167
174 /* Reset device */ 168 /* Reset device */
175 set_bit(HCI_RESET, &hdev->flags); 169 set_bit(HCI_RESET, &req->hdev->flags);
176 hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 170 hci_req_add(req, HCI_OP_RESET, 0, NULL);
177} 171}
178 172
179static void bredr_init(struct hci_dev *hdev) 173static void bredr_init(struct hci_request *req)
180{ 174{
181 hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 175 req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
182 176
183 /* Read Local Supported Features */ 177 /* Read Local Supported Features */
184 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 178 hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
185 179
186 /* Read Local Version */ 180 /* Read Local Version */
187 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 181 hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
182
183 /* Read BD Address */
184 hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
188} 185}
189 186
190static void amp_init(struct hci_dev *hdev) 187static void amp_init(struct hci_request *req)
191{ 188{
192 hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 189 req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
193 190
194 /* Read Local Version */ 191 /* Read Local Version */
195 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 192 hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
196 193
197 /* Read Local AMP Info */ 194 /* Read Local AMP Info */
198 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 195 hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
199 196
200 /* Read Data Blk size */ 197 /* Read Data Blk size */
201 hci_send_cmd(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 198 hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
202} 199}
203 200
204static void hci_init_req(struct hci_dev *hdev, unsigned long opt) 201static void hci_init1_req(struct hci_request *req, unsigned long opt)
205{ 202{
203 struct hci_dev *hdev = req->hdev;
204 struct hci_request init_req;
206 struct sk_buff *skb; 205 struct sk_buff *skb;
207 206
208 BT_DBG("%s %ld", hdev->name, opt); 207 BT_DBG("%s %ld", hdev->name, opt);
209 208
210 /* Driver initialization */ 209 /* Driver initialization */
211 210
211 hci_req_init(&init_req, hdev);
212
212 /* Special commands */ 213 /* Special commands */
213 while ((skb = skb_dequeue(&hdev->driver_init))) { 214 while ((skb = skb_dequeue(&hdev->driver_init))) {
214 bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 215 bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
215 skb->dev = (void *) hdev; 216 skb->dev = (void *) hdev;
216 217
217 skb_queue_tail(&hdev->cmd_q, skb); 218 if (skb_queue_empty(&init_req.cmd_q))
218 queue_work(hdev->workqueue, &hdev->cmd_work); 219 bt_cb(skb)->req.start = true;
220
221 skb_queue_tail(&init_req.cmd_q, skb);
219 } 222 }
220 skb_queue_purge(&hdev->driver_init); 223 skb_queue_purge(&hdev->driver_init);
221 224
225 hci_req_run(&init_req, NULL);
226
222 /* Reset */ 227 /* Reset */
223 if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 228 if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
224 hci_reset_req(hdev, 0); 229 hci_reset_req(req, 0);
225 230
226 switch (hdev->dev_type) { 231 switch (hdev->dev_type) {
227 case HCI_BREDR: 232 case HCI_BREDR:
228 bredr_init(hdev); 233 bredr_init(req);
229 break; 234 break;
230 235
231 case HCI_AMP: 236 case HCI_AMP:
232 amp_init(hdev); 237 amp_init(req);
233 break; 238 break;
234 239
235 default: 240 default:
@@ -238,44 +243,327 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
238 } 243 }
239} 244}
240 245
241static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) 246static void bredr_setup(struct hci_request *req)
247{
248 struct hci_cp_delete_stored_link_key cp;
249 __le16 param;
250 __u8 flt_type;
251
252 /* Read Buffer Size (ACL mtu, max pkt, etc.) */
253 hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
254
255 /* Read Class of Device */
256 hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
257
258 /* Read Local Name */
259 hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
260
261 /* Read Voice Setting */
262 hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
263
264 /* Clear Event Filters */
265 flt_type = HCI_FLT_CLEAR_ALL;
266 hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
267
268 /* Connection accept timeout ~20 secs */
269 param = __constant_cpu_to_le16(0x7d00);
270 hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
271
272 bacpy(&cp.bdaddr, BDADDR_ANY);
273 cp.delete_all = 0x01;
274 hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
275
276 /* Read page scan parameters */
277 if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) {
278 hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
279 hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
280 }
281}
282
283static void le_setup(struct hci_request *req)
284{
285 /* Read LE Buffer Size */
286 hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
287
288 /* Read LE Local Supported Features */
289 hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
290
291 /* Read LE Advertising Channel TX Power */
292 hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
293
294 /* Read LE White List Size */
295 hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
296
297 /* Read LE Supported States */
298 hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
299}
300
301static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
302{
303 if (lmp_ext_inq_capable(hdev))
304 return 0x02;
305
306 if (lmp_inq_rssi_capable(hdev))
307 return 0x01;
308
309 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
310 hdev->lmp_subver == 0x0757)
311 return 0x01;
312
313 if (hdev->manufacturer == 15) {
314 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
315 return 0x01;
316 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
317 return 0x01;
318 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
319 return 0x01;
320 }
321
322 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
323 hdev->lmp_subver == 0x1805)
324 return 0x01;
325
326 return 0x00;
327}
328
329static void hci_setup_inquiry_mode(struct hci_request *req)
330{
331 u8 mode;
332
333 mode = hci_get_inquiry_mode(req->hdev);
334
335 hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
336}
337
338static void hci_setup_event_mask(struct hci_request *req)
339{
340 struct hci_dev *hdev = req->hdev;
341
342 /* The second byte is 0xff instead of 0x9f (two reserved bits
343 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
344 * command otherwise.
345 */
346 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
347
348 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
349 * any event mask for pre 1.2 devices.
350 */
351 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
352 return;
353
354 if (lmp_bredr_capable(hdev)) {
355 events[4] |= 0x01; /* Flow Specification Complete */
356 events[4] |= 0x02; /* Inquiry Result with RSSI */
357 events[4] |= 0x04; /* Read Remote Extended Features Complete */
358 events[5] |= 0x08; /* Synchronous Connection Complete */
359 events[5] |= 0x10; /* Synchronous Connection Changed */
360 }
361
362 if (lmp_inq_rssi_capable(hdev))
363 events[4] |= 0x02; /* Inquiry Result with RSSI */
364
365 if (lmp_sniffsubr_capable(hdev))
366 events[5] |= 0x20; /* Sniff Subrating */
367
368 if (lmp_pause_enc_capable(hdev))
369 events[5] |= 0x80; /* Encryption Key Refresh Complete */
370
371 if (lmp_ext_inq_capable(hdev))
372 events[5] |= 0x40; /* Extended Inquiry Result */
373
374 if (lmp_no_flush_capable(hdev))
375 events[7] |= 0x01; /* Enhanced Flush Complete */
376
377 if (lmp_lsto_capable(hdev))
378 events[6] |= 0x80; /* Link Supervision Timeout Changed */
379
380 if (lmp_ssp_capable(hdev)) {
381 events[6] |= 0x01; /* IO Capability Request */
382 events[6] |= 0x02; /* IO Capability Response */
383 events[6] |= 0x04; /* User Confirmation Request */
384 events[6] |= 0x08; /* User Passkey Request */
385 events[6] |= 0x10; /* Remote OOB Data Request */
386 events[6] |= 0x20; /* Simple Pairing Complete */
387 events[7] |= 0x04; /* User Passkey Notification */
388 events[7] |= 0x08; /* Keypress Notification */
389 events[7] |= 0x10; /* Remote Host Supported
390 * Features Notification
391 */
392 }
393
394 if (lmp_le_capable(hdev))
395 events[7] |= 0x20; /* LE Meta-Event */
396
397 hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
398
399 if (lmp_le_capable(hdev)) {
400 memset(events, 0, sizeof(events));
401 events[0] = 0x1f;
402 hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
403 sizeof(events), events);
404 }
405}
406
407static void hci_init2_req(struct hci_request *req, unsigned long opt)
408{
409 struct hci_dev *hdev = req->hdev;
410
411 if (lmp_bredr_capable(hdev))
412 bredr_setup(req);
413
414 if (lmp_le_capable(hdev))
415 le_setup(req);
416
417 hci_setup_event_mask(req);
418
419 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
420 hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
421
422 if (lmp_ssp_capable(hdev)) {
423 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
424 u8 mode = 0x01;
425 hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
426 sizeof(mode), &mode);
427 } else {
428 struct hci_cp_write_eir cp;
429
430 memset(hdev->eir, 0, sizeof(hdev->eir));
431 memset(&cp, 0, sizeof(cp));
432
433 hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
434 }
435 }
436
437 if (lmp_inq_rssi_capable(hdev))
438 hci_setup_inquiry_mode(req);
439
440 if (lmp_inq_tx_pwr_capable(hdev))
441 hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
442
443 if (lmp_ext_feat_capable(hdev)) {
444 struct hci_cp_read_local_ext_features cp;
445
446 cp.page = 0x01;
447 hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
448 sizeof(cp), &cp);
449 }
450
451 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
452 u8 enable = 1;
453 hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
454 &enable);
455 }
456}
457
458static void hci_setup_link_policy(struct hci_request *req)
459{
460 struct hci_dev *hdev = req->hdev;
461 struct hci_cp_write_def_link_policy cp;
462 u16 link_policy = 0;
463
464 if (lmp_rswitch_capable(hdev))
465 link_policy |= HCI_LP_RSWITCH;
466 if (lmp_hold_capable(hdev))
467 link_policy |= HCI_LP_HOLD;
468 if (lmp_sniff_capable(hdev))
469 link_policy |= HCI_LP_SNIFF;
470 if (lmp_park_capable(hdev))
471 link_policy |= HCI_LP_PARK;
472
473 cp.policy = cpu_to_le16(link_policy);
474 hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
475}
476
477static void hci_set_le_support(struct hci_request *req)
478{
479 struct hci_dev *hdev = req->hdev;
480 struct hci_cp_write_le_host_supported cp;
481
482 memset(&cp, 0, sizeof(cp));
483
484 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
485 cp.le = 0x01;
486 cp.simul = lmp_le_br_capable(hdev);
487 }
488
489 if (cp.le != lmp_host_le_capable(hdev))
490 hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
491 &cp);
492}
493
494static void hci_init3_req(struct hci_request *req, unsigned long opt)
495{
496 struct hci_dev *hdev = req->hdev;
497
498 if (hdev->commands[5] & 0x10)
499 hci_setup_link_policy(req);
500
501 if (lmp_le_capable(hdev)) {
502 hci_set_le_support(req);
503 hci_update_ad(req);
504 }
505}
506
507static int __hci_init(struct hci_dev *hdev)
508{
509 int err;
510
511 err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
512 if (err < 0)
513 return err;
514
515 /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
516 * BR/EDR/LE type controllers. AMP controllers only need the
517 * first stage init.
518 */
519 if (hdev->dev_type != HCI_BREDR)
520 return 0;
521
522 err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
523 if (err < 0)
524 return err;
525
526 return __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
527}
528
529static void hci_scan_req(struct hci_request *req, unsigned long opt)
242{ 530{
243 __u8 scan = opt; 531 __u8 scan = opt;
244 532
245 BT_DBG("%s %x", hdev->name, scan); 533 BT_DBG("%s %x", req->hdev->name, scan);
246 534
247 /* Inquiry and Page scans */ 535 /* Inquiry and Page scans */
248 hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 536 hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
249} 537}
250 538
251static void hci_auth_req(struct hci_dev *hdev, unsigned long opt) 539static void hci_auth_req(struct hci_request *req, unsigned long opt)
252{ 540{
253 __u8 auth = opt; 541 __u8 auth = opt;
254 542
255 BT_DBG("%s %x", hdev->name, auth); 543 BT_DBG("%s %x", req->hdev->name, auth);
256 544
257 /* Authentication */ 545 /* Authentication */
258 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 546 hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
259} 547}
260 548
261static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt) 549static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
262{ 550{
263 __u8 encrypt = opt; 551 __u8 encrypt = opt;
264 552
265 BT_DBG("%s %x", hdev->name, encrypt); 553 BT_DBG("%s %x", req->hdev->name, encrypt);
266 554
267 /* Encryption */ 555 /* Encryption */
268 hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 556 hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
269} 557}
270 558
271static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) 559static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
272{ 560{
273 __le16 policy = cpu_to_le16(opt); 561 __le16 policy = cpu_to_le16(opt);
274 562
275 BT_DBG("%s %x", hdev->name, policy); 563 BT_DBG("%s %x", req->hdev->name, policy);
276 564
277 /* Default link policy */ 565 /* Default link policy */
278 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 566 hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
279} 567}
280 568
281/* Get HCI device by index. 569/* Get HCI device by index.
@@ -512,9 +800,10 @@ static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
512 return copied; 800 return copied;
513} 801}
514 802
515static void hci_inq_req(struct hci_dev *hdev, unsigned long opt) 803static void hci_inq_req(struct hci_request *req, unsigned long opt)
516{ 804{
517 struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 805 struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
806 struct hci_dev *hdev = req->hdev;
518 struct hci_cp_inquiry cp; 807 struct hci_cp_inquiry cp;
519 808
520 BT_DBG("%s", hdev->name); 809 BT_DBG("%s", hdev->name);
@@ -526,7 +815,7 @@ static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
526 memcpy(&cp.lap, &ir->lap, 3); 815 memcpy(&cp.lap, &ir->lap, 3);
527 cp.length = ir->length; 816 cp.length = ir->length;
528 cp.num_rsp = ir->num_rsp; 817 cp.num_rsp = ir->num_rsp;
529 hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 818 hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
530} 819}
531 820
532int hci_inquiry(void __user *arg) 821int hci_inquiry(void __user *arg)
@@ -556,7 +845,8 @@ int hci_inquiry(void __user *arg)
556 timeo = ir.length * msecs_to_jiffies(2000); 845 timeo = ir.length * msecs_to_jiffies(2000);
557 846
558 if (do_inquiry) { 847 if (do_inquiry) {
559 err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo); 848 err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
849 timeo);
560 if (err < 0) 850 if (err < 0)
561 goto done; 851 goto done;
562 } 852 }
@@ -654,39 +944,29 @@ static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
654 return ad_len; 944 return ad_len;
655} 945}
656 946
657int hci_update_ad(struct hci_dev *hdev) 947void hci_update_ad(struct hci_request *req)
658{ 948{
949 struct hci_dev *hdev = req->hdev;
659 struct hci_cp_le_set_adv_data cp; 950 struct hci_cp_le_set_adv_data cp;
660 u8 len; 951 u8 len;
661 int err;
662 952
663 hci_dev_lock(hdev); 953 if (!lmp_le_capable(hdev))
664 954 return;
665 if (!lmp_le_capable(hdev)) {
666 err = -EINVAL;
667 goto unlock;
668 }
669 955
670 memset(&cp, 0, sizeof(cp)); 956 memset(&cp, 0, sizeof(cp));
671 957
672 len = create_ad(hdev, cp.data); 958 len = create_ad(hdev, cp.data);
673 959
674 if (hdev->adv_data_len == len && 960 if (hdev->adv_data_len == len &&
675 memcmp(cp.data, hdev->adv_data, len) == 0) { 961 memcmp(cp.data, hdev->adv_data, len) == 0)
676 err = 0; 962 return;
677 goto unlock;
678 }
679 963
680 memcpy(hdev->adv_data, cp.data, sizeof(cp.data)); 964 memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
681 hdev->adv_data_len = len; 965 hdev->adv_data_len = len;
682 966
683 cp.length = len; 967 cp.length = len;
684 err = hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
685 968
686unlock: 969 hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
687 hci_dev_unlock(hdev);
688
689 return err;
690} 970}
691 971
692/* ---- HCI ioctl helpers ---- */ 972/* ---- HCI ioctl helpers ---- */
@@ -735,10 +1015,7 @@ int hci_dev_open(__u16 dev)
735 if (!test_bit(HCI_RAW, &hdev->flags)) { 1015 if (!test_bit(HCI_RAW, &hdev->flags)) {
736 atomic_set(&hdev->cmd_cnt, 1); 1016 atomic_set(&hdev->cmd_cnt, 1);
737 set_bit(HCI_INIT, &hdev->flags); 1017 set_bit(HCI_INIT, &hdev->flags);
738 hdev->init_last_cmd = 0; 1018 ret = __hci_init(hdev);
739
740 ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
741
742 clear_bit(HCI_INIT, &hdev->flags); 1019 clear_bit(HCI_INIT, &hdev->flags);
743 } 1020 }
744 1021
@@ -746,7 +1023,6 @@ int hci_dev_open(__u16 dev)
746 hci_dev_hold(hdev); 1023 hci_dev_hold(hdev);
747 set_bit(HCI_UP, &hdev->flags); 1024 set_bit(HCI_UP, &hdev->flags);
748 hci_notify(hdev, HCI_DEV_UP); 1025 hci_notify(hdev, HCI_DEV_UP);
749 hci_update_ad(hdev);
750 if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 1026 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
751 mgmt_valid_hdev(hdev)) { 1027 mgmt_valid_hdev(hdev)) {
752 hci_dev_lock(hdev); 1028 hci_dev_lock(hdev);
@@ -828,7 +1104,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
828 if (!test_bit(HCI_RAW, &hdev->flags) && 1104 if (!test_bit(HCI_RAW, &hdev->flags) &&
829 test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 1105 test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
830 set_bit(HCI_INIT, &hdev->flags); 1106 set_bit(HCI_INIT, &hdev->flags);
831 __hci_request(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 1107 __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
832 clear_bit(HCI_INIT, &hdev->flags); 1108 clear_bit(HCI_INIT, &hdev->flags);
833 } 1109 }
834 1110
@@ -851,6 +1127,10 @@ static int hci_dev_do_close(struct hci_dev *hdev)
851 * and no tasks are scheduled. */ 1127 * and no tasks are scheduled. */
852 hdev->close(hdev); 1128 hdev->close(hdev);
853 1129
1130 /* Clear flags */
1131 hdev->flags = 0;
1132 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
1133
854 if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 1134 if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
855 mgmt_valid_hdev(hdev)) { 1135 mgmt_valid_hdev(hdev)) {
856 hci_dev_lock(hdev); 1136 hci_dev_lock(hdev);
@@ -858,9 +1138,6 @@ static int hci_dev_do_close(struct hci_dev *hdev)
858 hci_dev_unlock(hdev); 1138 hci_dev_unlock(hdev);
859 } 1139 }
860 1140
861 /* Clear flags */
862 hdev->flags = 0;
863
864 /* Controller radio is available but is currently powered down */ 1141 /* Controller radio is available but is currently powered down */
865 hdev->amp_status = 0; 1142 hdev->amp_status = 0;
866 1143
@@ -921,7 +1198,7 @@ int hci_dev_reset(__u16 dev)
921 hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 1198 hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
922 1199
923 if (!test_bit(HCI_RAW, &hdev->flags)) 1200 if (!test_bit(HCI_RAW, &hdev->flags))
924 ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 1201 ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
925 1202
926done: 1203done:
927 hci_req_unlock(hdev); 1204 hci_req_unlock(hdev);
@@ -960,8 +1237,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
960 1237
961 switch (cmd) { 1238 switch (cmd) {
962 case HCISETAUTH: 1239 case HCISETAUTH:
963 err = hci_request(hdev, hci_auth_req, dr.dev_opt, 1240 err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
964 HCI_INIT_TIMEOUT); 1241 HCI_INIT_TIMEOUT);
965 break; 1242 break;
966 1243
967 case HCISETENCRYPT: 1244 case HCISETENCRYPT:
@@ -972,24 +1249,24 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
972 1249
973 if (!test_bit(HCI_AUTH, &hdev->flags)) { 1250 if (!test_bit(HCI_AUTH, &hdev->flags)) {
974 /* Auth must be enabled first */ 1251 /* Auth must be enabled first */
975 err = hci_request(hdev, hci_auth_req, dr.dev_opt, 1252 err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
976 HCI_INIT_TIMEOUT); 1253 HCI_INIT_TIMEOUT);
977 if (err) 1254 if (err)
978 break; 1255 break;
979 } 1256 }
980 1257
981 err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, 1258 err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
982 HCI_INIT_TIMEOUT); 1259 HCI_INIT_TIMEOUT);
983 break; 1260 break;
984 1261
985 case HCISETSCAN: 1262 case HCISETSCAN:
986 err = hci_request(hdev, hci_scan_req, dr.dev_opt, 1263 err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
987 HCI_INIT_TIMEOUT); 1264 HCI_INIT_TIMEOUT);
988 break; 1265 break;
989 1266
990 case HCISETLINKPOL: 1267 case HCISETLINKPOL:
991 err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, 1268 err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
992 HCI_INIT_TIMEOUT); 1269 HCI_INIT_TIMEOUT);
993 break; 1270 break;
994 1271
995 case HCISETLINKMODE: 1272 case HCISETLINKMODE:
@@ -1566,7 +1843,7 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1566 return mgmt_device_unblocked(hdev, bdaddr, type); 1843 return mgmt_device_unblocked(hdev, bdaddr, type);
1567} 1844}
1568 1845
1569static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt) 1846static void le_scan_param_req(struct hci_request *req, unsigned long opt)
1570{ 1847{
1571 struct le_scan_params *param = (struct le_scan_params *) opt; 1848 struct le_scan_params *param = (struct le_scan_params *) opt;
1572 struct hci_cp_le_set_scan_param cp; 1849 struct hci_cp_le_set_scan_param cp;
@@ -1576,10 +1853,10 @@ static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
1576 cp.interval = cpu_to_le16(param->interval); 1853 cp.interval = cpu_to_le16(param->interval);
1577 cp.window = cpu_to_le16(param->window); 1854 cp.window = cpu_to_le16(param->window);
1578 1855
1579 hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); 1856 hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
1580} 1857}
1581 1858
1582static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt) 1859static void le_scan_enable_req(struct hci_request *req, unsigned long opt)
1583{ 1860{
1584 struct hci_cp_le_set_scan_enable cp; 1861 struct hci_cp_le_set_scan_enable cp;
1585 1862
@@ -1587,7 +1864,7 @@ static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
1587 cp.enable = 1; 1864 cp.enable = 1;
1588 cp.filter_dup = 1; 1865 cp.filter_dup = 1;
1589 1866
1590 hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 1867 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
1591} 1868}
1592 1869
1593static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, 1870static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
@@ -1608,10 +1885,10 @@ static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
1608 1885
1609 hci_req_lock(hdev); 1886 hci_req_lock(hdev);
1610 1887
1611 err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param, 1888 err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) &param,
1612 timeo); 1889 timeo);
1613 if (!err) 1890 if (!err)
1614 err = __hci_request(hdev, le_scan_enable_req, 0, timeo); 1891 err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo);
1615 1892
1616 hci_req_unlock(hdev); 1893 hci_req_unlock(hdev);
1617 1894
@@ -2160,20 +2437,55 @@ static int hci_send_frame(struct sk_buff *skb)
2160 return hdev->send(skb); 2437 return hdev->send(skb);
2161} 2438}
2162 2439
2163/* Send HCI command */ 2440void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
2164int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) 2441{
2442 skb_queue_head_init(&req->cmd_q);
2443 req->hdev = hdev;
2444 req->err = 0;
2445}
2446
2447int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
2448{
2449 struct hci_dev *hdev = req->hdev;
2450 struct sk_buff *skb;
2451 unsigned long flags;
2452
2453 BT_DBG("length %u", skb_queue_len(&req->cmd_q));
2454
2455 /* If an error occured during request building, remove all HCI
2456 * commands queued on the HCI request queue.
2457 */
2458 if (req->err) {
2459 skb_queue_purge(&req->cmd_q);
2460 return req->err;
2461 }
2462
2463 /* Do not allow empty requests */
2464 if (skb_queue_empty(&req->cmd_q))
2465 return -ENODATA;
2466
2467 skb = skb_peek_tail(&req->cmd_q);
2468 bt_cb(skb)->req.complete = complete;
2469
2470 spin_lock_irqsave(&hdev->cmd_q.lock, flags);
2471 skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
2472 spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
2473
2474 queue_work(hdev->workqueue, &hdev->cmd_work);
2475
2476 return 0;
2477}
2478
2479static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
2480 u32 plen, void *param)
2165{ 2481{
2166 int len = HCI_COMMAND_HDR_SIZE + plen; 2482 int len = HCI_COMMAND_HDR_SIZE + plen;
2167 struct hci_command_hdr *hdr; 2483 struct hci_command_hdr *hdr;
2168 struct sk_buff *skb; 2484 struct sk_buff *skb;
2169 2485
2170 BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
2171
2172 skb = bt_skb_alloc(len, GFP_ATOMIC); 2486 skb = bt_skb_alloc(len, GFP_ATOMIC);
2173 if (!skb) { 2487 if (!skb)
2174 BT_ERR("%s no memory for command", hdev->name); 2488 return NULL;
2175 return -ENOMEM;
2176 }
2177 2489
2178 hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2490 hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2179 hdr->opcode = cpu_to_le16(opcode); 2491 hdr->opcode = cpu_to_le16(opcode);
@@ -2187,8 +2499,26 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
2187 bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 2499 bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
2188 skb->dev = (void *) hdev; 2500 skb->dev = (void *) hdev;
2189 2501
2190 if (test_bit(HCI_INIT, &hdev->flags)) 2502 return skb;
2191 hdev->init_last_cmd = opcode; 2503}
2504
2505/* Send HCI command */
2506int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
2507{
2508 struct sk_buff *skb;
2509
2510 BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
2511
2512 skb = hci_prepare_cmd(hdev, opcode, plen, param);
2513 if (!skb) {
2514 BT_ERR("%s no memory for command", hdev->name);
2515 return -ENOMEM;
2516 }
2517
2518 /* Stand-alone HCI commands must be flaged as
2519 * single-command requests.
2520 */
2521 bt_cb(skb)->req.start = true;
2192 2522
2193 skb_queue_tail(&hdev->cmd_q, skb); 2523 skb_queue_tail(&hdev->cmd_q, skb);
2194 queue_work(hdev->workqueue, &hdev->cmd_work); 2524 queue_work(hdev->workqueue, &hdev->cmd_work);
@@ -2196,6 +2526,34 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
2196 return 0; 2526 return 0;
2197} 2527}
2198 2528
2529/* Queue a command to an asynchronous HCI request */
2530void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param)
2531{
2532 struct hci_dev *hdev = req->hdev;
2533 struct sk_buff *skb;
2534
2535 BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
2536
2537 /* If an error occured during request building, there is no point in
2538 * queueing the HCI command. We can simply return.
2539 */
2540 if (req->err)
2541 return;
2542
2543 skb = hci_prepare_cmd(hdev, opcode, plen, param);
2544 if (!skb) {
2545 BT_ERR("%s no memory for command (opcode 0x%4.4x)",
2546 hdev->name, opcode);
2547 req->err = -ENOMEM;
2548 return;
2549 }
2550
2551 if (skb_queue_empty(&req->cmd_q))
2552 bt_cb(skb)->req.start = true;
2553
2554 skb_queue_tail(&req->cmd_q, skb);
2555}
2556
2199/* Get data from the previously sent command */ 2557/* Get data from the previously sent command */
2200void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 2558void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
2201{ 2559{
@@ -2398,7 +2756,7 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
2398 if (c->type == type && c->sent) { 2756 if (c->type == type && c->sent) {
2399 BT_ERR("%s killing stalled connection %pMR", 2757 BT_ERR("%s killing stalled connection %pMR",
2400 hdev->name, &c->dst); 2758 hdev->name, &c->dst);
2401 hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM); 2759 hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
2402 } 2760 }
2403 } 2761 }
2404 2762
@@ -2860,6 +3218,123 @@ static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
2860 kfree_skb(skb); 3218 kfree_skb(skb);
2861} 3219}
2862 3220
3221static bool hci_req_is_complete(struct hci_dev *hdev)
3222{
3223 struct sk_buff *skb;
3224
3225 skb = skb_peek(&hdev->cmd_q);
3226 if (!skb)
3227 return true;
3228
3229 return bt_cb(skb)->req.start;
3230}
3231
3232static void hci_resend_last(struct hci_dev *hdev)
3233{
3234 struct hci_command_hdr *sent;
3235 struct sk_buff *skb;
3236 u16 opcode;
3237
3238 if (!hdev->sent_cmd)
3239 return;
3240
3241 sent = (void *) hdev->sent_cmd->data;
3242 opcode = __le16_to_cpu(sent->opcode);
3243 if (opcode == HCI_OP_RESET)
3244 return;
3245
3246 skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
3247 if (!skb)
3248 return;
3249
3250 skb_queue_head(&hdev->cmd_q, skb);
3251 queue_work(hdev->workqueue, &hdev->cmd_work);
3252}
3253
3254void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
3255{
3256 hci_req_complete_t req_complete = NULL;
3257 struct sk_buff *skb;
3258 unsigned long flags;
3259
3260 BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
3261
3262 /* If the completed command doesn't match the last one that was
3263 * sent we need to do special handling of it.
3264 */
3265 if (!hci_sent_cmd_data(hdev, opcode)) {
3266 /* Some CSR based controllers generate a spontaneous
3267 * reset complete event during init and any pending
3268 * command will never be completed. In such a case we
3269 * need to resend whatever was the last sent
3270 * command.
3271 */
3272 if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
3273 hci_resend_last(hdev);
3274
3275 return;
3276 }
3277
3278 /* If the command succeeded and there's still more commands in
3279 * this request the request is not yet complete.
3280 */
3281 if (!status && !hci_req_is_complete(hdev))
3282 return;
3283
3284 /* If this was the last command in a request the complete
3285 * callback would be found in hdev->sent_cmd instead of the
3286 * command queue (hdev->cmd_q).
3287 */
3288 if (hdev->sent_cmd) {
3289 req_complete = bt_cb(hdev->sent_cmd)->req.complete;
3290 if (req_complete)
3291 goto call_complete;
3292 }
3293
3294 /* Remove all pending commands belonging to this request */
3295 spin_lock_irqsave(&hdev->cmd_q.lock, flags);
3296 while ((skb = __skb_dequeue(&hdev->cmd_q))) {
3297 if (bt_cb(skb)->req.start) {
3298 __skb_queue_head(&hdev->cmd_q, skb);
3299 break;
3300 }
3301
3302 req_complete = bt_cb(skb)->req.complete;
3303 kfree_skb(skb);
3304 }
3305 spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
3306
3307call_complete:
3308 if (req_complete)
3309 req_complete(hdev, status);
3310}
3311
3312void hci_req_cmd_status(struct hci_dev *hdev, u16 opcode, u8 status)
3313{
3314 hci_req_complete_t req_complete = NULL;
3315
3316 BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
3317
3318 if (status) {
3319 hci_req_cmd_complete(hdev, opcode, status);
3320 return;
3321 }
3322
3323 /* No need to handle success status if there are more commands */
3324 if (!hci_req_is_complete(hdev))
3325 return;
3326
3327 if (hdev->sent_cmd)
3328 req_complete = bt_cb(hdev->sent_cmd)->req.complete;
3329
3330 /* If the request doesn't have a complete callback or there
3331 * are other commands/requests in the hdev queue we consider
3332 * this request as completed.
3333 */
3334 if (!req_complete || !skb_queue_empty(&hdev->cmd_q))
3335 hci_req_cmd_complete(hdev, opcode, status);
3336}
3337
2863static void hci_rx_work(struct work_struct *work) 3338static void hci_rx_work(struct work_struct *work)
2864{ 3339{
2865 struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 3340 struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 477726a63512..138580745c2c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -53,7 +53,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
53 hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 53 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
54 hci_dev_unlock(hdev); 54 hci_dev_unlock(hdev);
55 55
56 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); 56 hci_req_cmd_complete(hdev, HCI_OP_INQUIRY, status);
57 57
58 hci_conn_check_pending(hdev); 58 hci_conn_check_pending(hdev);
59} 59}
@@ -183,8 +183,6 @@ static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
183 183
184 if (!status) 184 if (!status)
185 hdev->link_policy = get_unaligned_le16(sent); 185 hdev->link_policy = get_unaligned_le16(sent);
186
187 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
188} 186}
189 187
190static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) 188static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
@@ -195,11 +193,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
195 193
196 clear_bit(HCI_RESET, &hdev->flags); 194 clear_bit(HCI_RESET, &hdev->flags);
197 195
198 hci_req_complete(hdev, HCI_OP_RESET, status);
199
200 /* Reset all non-persistent flags */ 196 /* Reset all non-persistent flags */
201 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS) | 197 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
202 BIT(HCI_PERIODIC_INQ));
203 198
204 hdev->discovery.state = DISCOVERY_STOPPED; 199 hdev->discovery.state = DISCOVERY_STOPPED;
205 hdev->inq_tx_power = HCI_TX_POWER_INVALID; 200 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
@@ -228,11 +223,6 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
228 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 223 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
229 224
230 hci_dev_unlock(hdev); 225 hci_dev_unlock(hdev);
231
232 if (!status && !test_bit(HCI_INIT, &hdev->flags))
233 hci_update_ad(hdev);
234
235 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
236} 226}
237 227
238static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 228static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -270,8 +260,6 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
270 260
271 if (test_bit(HCI_MGMT, &hdev->dev_flags)) 261 if (test_bit(HCI_MGMT, &hdev->dev_flags))
272 mgmt_auth_enable_complete(hdev, status); 262 mgmt_auth_enable_complete(hdev, status);
273
274 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
275} 263}
276 264
277static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) 265static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
@@ -293,8 +281,6 @@ static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
293 else 281 else
294 clear_bit(HCI_ENCRYPT, &hdev->flags); 282 clear_bit(HCI_ENCRYPT, &hdev->flags);
295 } 283 }
296
297 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
298} 284}
299 285
300static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) 286static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
@@ -343,7 +329,6 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
343 329
344done: 330done:
345 hci_dev_unlock(hdev); 331 hci_dev_unlock(hdev);
346 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
347} 332}
348 333
349static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 334static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
@@ -435,15 +420,6 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev,
435 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 420 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
436} 421}
437 422
438static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
439{
440 __u8 status = *((__u8 *) skb->data);
441
442 BT_DBG("%s status 0x%2.2x", hdev->name, status);
443
444 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
445}
446
447static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 423static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
448{ 424{
449 __u8 status = *((__u8 *) skb->data); 425 __u8 status = *((__u8 *) skb->data);
@@ -472,211 +448,6 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
472 } 448 }
473} 449}
474 450
475static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
476{
477 if (lmp_ext_inq_capable(hdev))
478 return 2;
479
480 if (lmp_inq_rssi_capable(hdev))
481 return 1;
482
483 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
484 hdev->lmp_subver == 0x0757)
485 return 1;
486
487 if (hdev->manufacturer == 15) {
488 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
489 return 1;
490 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
491 return 1;
492 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
493 return 1;
494 }
495
496 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
497 hdev->lmp_subver == 0x1805)
498 return 1;
499
500 return 0;
501}
502
503static void hci_setup_inquiry_mode(struct hci_dev *hdev)
504{
505 u8 mode;
506
507 mode = hci_get_inquiry_mode(hdev);
508
509 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
510}
511
512static void hci_setup_event_mask(struct hci_dev *hdev)
513{
514 /* The second byte is 0xff instead of 0x9f (two reserved bits
515 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
516 * command otherwise */
517 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
518
519 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
520 * any event mask for pre 1.2 devices */
521 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
522 return;
523
524 if (lmp_bredr_capable(hdev)) {
525 events[4] |= 0x01; /* Flow Specification Complete */
526 events[4] |= 0x02; /* Inquiry Result with RSSI */
527 events[4] |= 0x04; /* Read Remote Extended Features Complete */
528 events[5] |= 0x08; /* Synchronous Connection Complete */
529 events[5] |= 0x10; /* Synchronous Connection Changed */
530 }
531
532 if (lmp_inq_rssi_capable(hdev))
533 events[4] |= 0x02; /* Inquiry Result with RSSI */
534
535 if (lmp_sniffsubr_capable(hdev))
536 events[5] |= 0x20; /* Sniff Subrating */
537
538 if (lmp_pause_enc_capable(hdev))
539 events[5] |= 0x80; /* Encryption Key Refresh Complete */
540
541 if (lmp_ext_inq_capable(hdev))
542 events[5] |= 0x40; /* Extended Inquiry Result */
543
544 if (lmp_no_flush_capable(hdev))
545 events[7] |= 0x01; /* Enhanced Flush Complete */
546
547 if (lmp_lsto_capable(hdev))
548 events[6] |= 0x80; /* Link Supervision Timeout Changed */
549
550 if (lmp_ssp_capable(hdev)) {
551 events[6] |= 0x01; /* IO Capability Request */
552 events[6] |= 0x02; /* IO Capability Response */
553 events[6] |= 0x04; /* User Confirmation Request */
554 events[6] |= 0x08; /* User Passkey Request */
555 events[6] |= 0x10; /* Remote OOB Data Request */
556 events[6] |= 0x20; /* Simple Pairing Complete */
557 events[7] |= 0x04; /* User Passkey Notification */
558 events[7] |= 0x08; /* Keypress Notification */
559 events[7] |= 0x10; /* Remote Host Supported
560 * Features Notification */
561 }
562
563 if (lmp_le_capable(hdev))
564 events[7] |= 0x20; /* LE Meta-Event */
565
566 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
567
568 if (lmp_le_capable(hdev)) {
569 memset(events, 0, sizeof(events));
570 events[0] = 0x1f;
571 hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK,
572 sizeof(events), events);
573 }
574}
575
576static void bredr_setup(struct hci_dev *hdev)
577{
578 struct hci_cp_delete_stored_link_key cp;
579 __le16 param;
580 __u8 flt_type;
581
582 /* Read Buffer Size (ACL mtu, max pkt, etc.) */
583 hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
584
585 /* Read Class of Device */
586 hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
587
588 /* Read Local Name */
589 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
590
591 /* Read Voice Setting */
592 hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
593
594 /* Clear Event Filters */
595 flt_type = HCI_FLT_CLEAR_ALL;
596 hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
597
598 /* Connection accept timeout ~20 secs */
599 param = __constant_cpu_to_le16(0x7d00);
600 hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
601
602 bacpy(&cp.bdaddr, BDADDR_ANY);
603 cp.delete_all = 1;
604 hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
605}
606
607static void le_setup(struct hci_dev *hdev)
608{
609 /* Read LE Buffer Size */
610 hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
611
612 /* Read LE Local Supported Features */
613 hci_send_cmd(hdev, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
614
615 /* Read LE Advertising Channel TX Power */
616 hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
617
618 /* Read LE White List Size */
619 hci_send_cmd(hdev, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
620
621 /* Read LE Supported States */
622 hci_send_cmd(hdev, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
623}
624
625static void hci_setup(struct hci_dev *hdev)
626{
627 if (hdev->dev_type != HCI_BREDR)
628 return;
629
630 /* Read BD Address */
631 hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
632
633 if (lmp_bredr_capable(hdev))
634 bredr_setup(hdev);
635
636 if (lmp_le_capable(hdev))
637 le_setup(hdev);
638
639 hci_setup_event_mask(hdev);
640
641 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
642 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
643
644 if (lmp_ssp_capable(hdev)) {
645 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
646 u8 mode = 0x01;
647 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
648 sizeof(mode), &mode);
649 } else {
650 struct hci_cp_write_eir cp;
651
652 memset(hdev->eir, 0, sizeof(hdev->eir));
653 memset(&cp, 0, sizeof(cp));
654
655 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
656 }
657 }
658
659 if (lmp_inq_rssi_capable(hdev))
660 hci_setup_inquiry_mode(hdev);
661
662 if (lmp_inq_tx_pwr_capable(hdev))
663 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
664
665 if (lmp_ext_feat_capable(hdev)) {
666 struct hci_cp_read_local_ext_features cp;
667
668 cp.page = 0x01;
669 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp),
670 &cp);
671 }
672
673 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
674 u8 enable = 1;
675 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
676 &enable);
677 }
678}
679
680static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 451static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
681{ 452{
682 struct hci_rp_read_local_version *rp = (void *) skb->data; 453 struct hci_rp_read_local_version *rp = (void *) skb->data;
@@ -684,7 +455,7 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
684 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 455 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
685 456
686 if (rp->status) 457 if (rp->status)
687 goto done; 458 return;
688 459
689 hdev->hci_ver = rp->hci_ver; 460 hdev->hci_ver = rp->hci_ver;
690 hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 461 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
@@ -694,30 +465,6 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
694 465
695 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name, 466 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
696 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev); 467 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
697
698 if (test_bit(HCI_INIT, &hdev->flags))
699 hci_setup(hdev);
700
701done:
702 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
703}
704
705static void hci_setup_link_policy(struct hci_dev *hdev)
706{
707 struct hci_cp_write_def_link_policy cp;
708 u16 link_policy = 0;
709
710 if (lmp_rswitch_capable(hdev))
711 link_policy |= HCI_LP_RSWITCH;
712 if (lmp_hold_capable(hdev))
713 link_policy |= HCI_LP_HOLD;
714 if (lmp_sniff_capable(hdev))
715 link_policy |= HCI_LP_SNIFF;
716 if (lmp_park_capable(hdev))
717 link_policy |= HCI_LP_PARK;
718
719 cp.policy = cpu_to_le16(link_policy);
720 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
721} 468}
722 469
723static void hci_cc_read_local_commands(struct hci_dev *hdev, 470static void hci_cc_read_local_commands(struct hci_dev *hdev,
@@ -727,16 +474,8 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev,
727 474
728 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 475 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
729 476
730 if (rp->status) 477 if (!rp->status)
731 goto done; 478 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
732
733 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
734
735 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
736 hci_setup_link_policy(hdev);
737
738done:
739 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
740} 479}
741 480
742static void hci_cc_read_local_features(struct hci_dev *hdev, 481static void hci_cc_read_local_features(struct hci_dev *hdev,
@@ -795,22 +534,6 @@ static void hci_cc_read_local_features(struct hci_dev *hdev,
795 hdev->features[6], hdev->features[7]); 534 hdev->features[6], hdev->features[7]);
796} 535}
797 536
798static void hci_set_le_support(struct hci_dev *hdev)
799{
800 struct hci_cp_write_le_host_supported cp;
801
802 memset(&cp, 0, sizeof(cp));
803
804 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
805 cp.le = 1;
806 cp.simul = lmp_le_br_capable(hdev);
807 }
808
809 if (cp.le != lmp_host_le_capable(hdev))
810 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
811 &cp);
812}
813
814static void hci_cc_read_local_ext_features(struct hci_dev *hdev, 537static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
815 struct sk_buff *skb) 538 struct sk_buff *skb)
816{ 539{
@@ -819,7 +542,7 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
819 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 542 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
820 543
821 if (rp->status) 544 if (rp->status)
822 goto done; 545 return;
823 546
824 switch (rp->page) { 547 switch (rp->page) {
825 case 0: 548 case 0:
@@ -829,12 +552,6 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
829 memcpy(hdev->host_features, rp->features, 8); 552 memcpy(hdev->host_features, rp->features, 8);
830 break; 553 break;
831 } 554 }
832
833 if (test_bit(HCI_INIT, &hdev->flags) && lmp_le_capable(hdev))
834 hci_set_le_support(hdev);
835
836done:
837 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
838} 555}
839 556
840static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, 557static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
@@ -844,12 +561,8 @@ static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
844 561
845 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 562 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
846 563
847 if (rp->status) 564 if (!rp->status)
848 return; 565 hdev->flow_ctl_mode = rp->mode;
849
850 hdev->flow_ctl_mode = rp->mode;
851
852 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
853} 566}
854 567
855static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 568static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
@@ -886,8 +599,65 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
886 599
887 if (!rp->status) 600 if (!rp->status)
888 bacpy(&hdev->bdaddr, &rp->bdaddr); 601 bacpy(&hdev->bdaddr, &rp->bdaddr);
602}
603
604static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
605 struct sk_buff *skb)
606{
607 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
608
609 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
610
611 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
612 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
613 hdev->page_scan_window = __le16_to_cpu(rp->window);
614 }
615}
616
617static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
618 struct sk_buff *skb)
619{
620 u8 status = *((u8 *) skb->data);
621 struct hci_cp_write_page_scan_activity *sent;
622
623 BT_DBG("%s status 0x%2.2x", hdev->name, status);
624
625 if (status)
626 return;
627
628 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
629 if (!sent)
630 return;
631
632 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
633 hdev->page_scan_window = __le16_to_cpu(sent->window);
634}
635
636static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
637 struct sk_buff *skb)
638{
639 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
640
641 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
642
643 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
644 hdev->page_scan_type = rp->type;
645}
646
647static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
648 struct sk_buff *skb)
649{
650 u8 status = *((u8 *) skb->data);
651 u8 *type;
889 652
890 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status); 653 BT_DBG("%s status 0x%2.2x", hdev->name, status);
654
655 if (status)
656 return;
657
658 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
659 if (type)
660 hdev->page_scan_type = *type;
891} 661}
892 662
893static void hci_cc_read_data_block_size(struct hci_dev *hdev, 663static void hci_cc_read_data_block_size(struct hci_dev *hdev,
@@ -908,17 +678,6 @@ static void hci_cc_read_data_block_size(struct hci_dev *hdev,
908 678
909 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 679 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
910 hdev->block_cnt, hdev->block_len); 680 hdev->block_cnt, hdev->block_len);
911
912 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
913}
914
915static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
916{
917 __u8 status = *((__u8 *) skb->data);
918
919 BT_DBG("%s status 0x%2.2x", hdev->name, status);
920
921 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
922} 681}
923 682
924static void hci_cc_read_local_amp_info(struct hci_dev *hdev, 683static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
@@ -942,8 +701,6 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
942 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 701 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
943 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 702 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
944 703
945 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
946
947a2mp_rsp: 704a2mp_rsp:
948 a2mp_send_getinfo_rsp(hdev); 705 a2mp_send_getinfo_rsp(hdev);
949} 706}
@@ -985,35 +742,6 @@ a2mp_rsp:
985 a2mp_send_create_phy_link_req(hdev, rp->status); 742 a2mp_send_create_phy_link_req(hdev, rp->status);
986} 743}
987 744
988static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
989 struct sk_buff *skb)
990{
991 __u8 status = *((__u8 *) skb->data);
992
993 BT_DBG("%s status 0x%2.2x", hdev->name, status);
994
995 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
996}
997
998static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
999{
1000 __u8 status = *((__u8 *) skb->data);
1001
1002 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1003
1004 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
1005}
1006
1007static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
1008 struct sk_buff *skb)
1009{
1010 __u8 status = *((__u8 *) skb->data);
1011
1012 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1013
1014 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
1015}
1016
1017static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, 745static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
1018 struct sk_buff *skb) 746 struct sk_buff *skb)
1019{ 747{
@@ -1023,17 +751,6 @@ static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
1023 751
1024 if (!rp->status) 752 if (!rp->status)
1025 hdev->inq_tx_power = rp->tx_power; 753 hdev->inq_tx_power = rp->tx_power;
1026
1027 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, rp->status);
1028}
1029
1030static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
1031{
1032 __u8 status = *((__u8 *) skb->data);
1033
1034 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1035
1036 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
1037} 754}
1038 755
1039static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) 756static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1095,8 +812,6 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
1095 hdev->le_cnt = hdev->le_pkts; 812 hdev->le_cnt = hdev->le_pkts;
1096 813
1097 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 814 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
1098
1099 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
1100} 815}
1101 816
1102static void hci_cc_le_read_local_features(struct hci_dev *hdev, 817static void hci_cc_le_read_local_features(struct hci_dev *hdev,
@@ -1108,8 +823,6 @@ static void hci_cc_le_read_local_features(struct hci_dev *hdev,
1108 823
1109 if (!rp->status) 824 if (!rp->status)
1110 memcpy(hdev->le_features, rp->features, 8); 825 memcpy(hdev->le_features, rp->features, 8);
1111
1112 hci_req_complete(hdev, HCI_OP_LE_READ_LOCAL_FEATURES, rp->status);
1113} 826}
1114 827
1115static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, 828static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
@@ -1119,22 +832,8 @@ static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
1119 832
1120 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 833 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1121 834
1122 if (!rp->status) { 835 if (!rp->status)
1123 hdev->adv_tx_power = rp->tx_power; 836 hdev->adv_tx_power = rp->tx_power;
1124 if (!test_bit(HCI_INIT, &hdev->flags))
1125 hci_update_ad(hdev);
1126 }
1127
1128 hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status);
1129}
1130
1131static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
1132{
1133 __u8 status = *((__u8 *) skb->data);
1134
1135 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1136
1137 hci_req_complete(hdev, HCI_OP_LE_SET_EVENT_MASK, status);
1138} 837}
1139 838
1140static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) 839static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1231,12 +930,15 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
1231 clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags); 930 clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
1232 } 931 }
1233 932
1234 hci_dev_unlock(hdev); 933 if (!test_bit(HCI_INIT, &hdev->flags)) {
934 struct hci_request req;
1235 935
1236 if (!test_bit(HCI_INIT, &hdev->flags)) 936 hci_req_init(&req, hdev);
1237 hci_update_ad(hdev); 937 hci_update_ad(&req);
938 hci_req_run(&req, NULL);
939 }
1238 940
1239 hci_req_complete(hdev, HCI_OP_LE_SET_ADV_ENABLE, status); 941 hci_dev_unlock(hdev);
1240} 942}
1241 943
1242static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) 944static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1245,8 +947,6 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1245 947
1246 BT_DBG("%s status 0x%2.2x", hdev->name, status); 948 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1247 949
1248 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
1249
1250 if (status) { 950 if (status) {
1251 hci_dev_lock(hdev); 951 hci_dev_lock(hdev);
1252 mgmt_start_discovery_failed(hdev, status); 952 mgmt_start_discovery_failed(hdev, status);
@@ -1269,8 +969,6 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1269 969
1270 switch (cp->enable) { 970 switch (cp->enable) {
1271 case LE_SCANNING_ENABLED: 971 case LE_SCANNING_ENABLED:
1272 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1273
1274 if (status) { 972 if (status) {
1275 hci_dev_lock(hdev); 973 hci_dev_lock(hdev);
1276 mgmt_start_discovery_failed(hdev, status); 974 mgmt_start_discovery_failed(hdev, status);
@@ -1321,32 +1019,6 @@ static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1321 1019
1322 if (!rp->status) 1020 if (!rp->status)
1323 hdev->le_white_list_size = rp->size; 1021 hdev->le_white_list_size = rp->size;
1324
1325 hci_req_complete(hdev, HCI_OP_LE_READ_WHITE_LIST_SIZE, rp->status);
1326}
1327
1328static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1329{
1330 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1331
1332 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1333
1334 if (rp->status)
1335 return;
1336
1337 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1338}
1339
1340static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1341{
1342 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1343
1344 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1345
1346 if (rp->status)
1347 return;
1348
1349 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1350} 1022}
1351 1023
1352static void hci_cc_le_read_supported_states(struct hci_dev *hdev, 1024static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
@@ -1358,8 +1030,6 @@ static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1358 1030
1359 if (!rp->status) 1031 if (!rp->status)
1360 memcpy(hdev->le_states, rp->le_states, 8); 1032 memcpy(hdev->le_states, rp->le_states, 8);
1361
1362 hci_req_complete(hdev, HCI_OP_LE_READ_SUPPORTED_STATES, rp->status);
1363} 1033}
1364 1034
1365static void hci_cc_write_le_host_supported(struct hci_dev *hdev, 1035static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
@@ -1389,8 +1059,6 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1389 if (test_bit(HCI_MGMT, &hdev->dev_flags) && 1059 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
1390 !test_bit(HCI_INIT, &hdev->flags)) 1060 !test_bit(HCI_INIT, &hdev->flags))
1391 mgmt_le_enable_complete(hdev, sent->le, status); 1061 mgmt_le_enable_complete(hdev, sent->le, status);
1392
1393 hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
1394} 1062}
1395 1063
1396static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, 1064static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
@@ -1412,7 +1080,6 @@ static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1412 BT_DBG("%s status 0x%2.2x", hdev->name, status); 1080 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1413 1081
1414 if (status) { 1082 if (status) {
1415 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
1416 hci_conn_check_pending(hdev); 1083 hci_conn_check_pending(hdev);
1417 hci_dev_lock(hdev); 1084 hci_dev_lock(hdev);
1418 if (test_bit(HCI_MGMT, &hdev->dev_flags)) 1085 if (test_bit(HCI_MGMT, &hdev->dev_flags))
@@ -1884,11 +1551,6 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1884 } 1551 }
1885} 1552}
1886 1553
1887static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1888{
1889 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1890}
1891
1892static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) 1554static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1893{ 1555{
1894 struct hci_cp_create_phy_link *cp; 1556 struct hci_cp_create_phy_link *cp;
@@ -1930,11 +1592,6 @@ static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1930 amp_write_remote_assoc(hdev, cp->phy_handle); 1592 amp_write_remote_assoc(hdev, cp->phy_handle);
1931} 1593}
1932 1594
1933static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status)
1934{
1935 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1936}
1937
1938static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1595static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1939{ 1596{
1940 __u8 status = *((__u8 *) skb->data); 1597 __u8 status = *((__u8 *) skb->data);
@@ -1943,7 +1600,7 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1943 1600
1944 BT_DBG("%s status 0x%2.2x", hdev->name, status); 1601 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1945 1602
1946 hci_req_complete(hdev, HCI_OP_INQUIRY, status); 1603 hci_req_cmd_complete(hdev, HCI_OP_INQUIRY, status);
1947 1604
1948 hci_conn_check_pending(hdev); 1605 hci_conn_check_pending(hdev);
1949 1606
@@ -2399,7 +2056,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2399 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2056 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2400 2057
2401 if (ev->status && conn->state == BT_CONNECTED) { 2058 if (ev->status && conn->state == BT_CONNECTED) {
2402 hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE); 2059 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2403 hci_conn_put(conn); 2060 hci_conn_put(conn);
2404 goto unlock; 2061 goto unlock;
2405 } 2062 }
@@ -2491,20 +2148,10 @@ unlock:
2491 hci_dev_unlock(hdev); 2148 hci_dev_unlock(hdev);
2492} 2149}
2493 2150
2494static void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2495{
2496 BT_DBG("%s", hdev->name);
2497}
2498
2499static void hci_qos_setup_complete_evt(struct hci_dev *hdev,
2500 struct sk_buff *skb)
2501{
2502 BT_DBG("%s", hdev->name);
2503}
2504
2505static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2151static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2506{ 2152{
2507 struct hci_ev_cmd_complete *ev = (void *) skb->data; 2153 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2154 u8 status = skb->data[sizeof(*ev)];
2508 __u16 opcode; 2155 __u16 opcode;
2509 2156
2510 skb_pull(skb, sizeof(*ev)); 2157 skb_pull(skb, sizeof(*ev));
@@ -2588,10 +2235,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2588 hci_cc_write_voice_setting(hdev, skb); 2235 hci_cc_write_voice_setting(hdev, skb);
2589 break; 2236 break;
2590 2237
2591 case HCI_OP_HOST_BUFFER_SIZE:
2592 hci_cc_host_buffer_size(hdev, skb);
2593 break;
2594
2595 case HCI_OP_WRITE_SSP_MODE: 2238 case HCI_OP_WRITE_SSP_MODE:
2596 hci_cc_write_ssp_mode(hdev, skb); 2239 hci_cc_write_ssp_mode(hdev, skb);
2597 break; 2240 break;
@@ -2620,46 +2263,42 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2620 hci_cc_read_bd_addr(hdev, skb); 2263 hci_cc_read_bd_addr(hdev, skb);
2621 break; 2264 break;
2622 2265
2623 case HCI_OP_READ_DATA_BLOCK_SIZE: 2266 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2624 hci_cc_read_data_block_size(hdev, skb); 2267 hci_cc_read_page_scan_activity(hdev, skb);
2625 break; 2268 break;
2626 2269
2627 case HCI_OP_WRITE_CA_TIMEOUT: 2270 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2628 hci_cc_write_ca_timeout(hdev, skb); 2271 hci_cc_write_page_scan_activity(hdev, skb);
2629 break; 2272 break;
2630 2273
2631 case HCI_OP_READ_FLOW_CONTROL_MODE: 2274 case HCI_OP_READ_PAGE_SCAN_TYPE:
2632 hci_cc_read_flow_control_mode(hdev, skb); 2275 hci_cc_read_page_scan_type(hdev, skb);
2633 break; 2276 break;
2634 2277
2635 case HCI_OP_READ_LOCAL_AMP_INFO: 2278 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2636 hci_cc_read_local_amp_info(hdev, skb); 2279 hci_cc_write_page_scan_type(hdev, skb);
2637 break; 2280 break;
2638 2281
2639 case HCI_OP_READ_LOCAL_AMP_ASSOC: 2282 case HCI_OP_READ_DATA_BLOCK_SIZE:
2640 hci_cc_read_local_amp_assoc(hdev, skb); 2283 hci_cc_read_data_block_size(hdev, skb);
2641 break; 2284 break;
2642 2285
2643 case HCI_OP_DELETE_STORED_LINK_KEY: 2286 case HCI_OP_READ_FLOW_CONTROL_MODE:
2644 hci_cc_delete_stored_link_key(hdev, skb); 2287 hci_cc_read_flow_control_mode(hdev, skb);
2645 break; 2288 break;
2646 2289
2647 case HCI_OP_SET_EVENT_MASK: 2290 case HCI_OP_READ_LOCAL_AMP_INFO:
2648 hci_cc_set_event_mask(hdev, skb); 2291 hci_cc_read_local_amp_info(hdev, skb);
2649 break; 2292 break;
2650 2293
2651 case HCI_OP_WRITE_INQUIRY_MODE: 2294 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2652 hci_cc_write_inquiry_mode(hdev, skb); 2295 hci_cc_read_local_amp_assoc(hdev, skb);
2653 break; 2296 break;
2654 2297
2655 case HCI_OP_READ_INQ_RSP_TX_POWER: 2298 case HCI_OP_READ_INQ_RSP_TX_POWER:
2656 hci_cc_read_inq_rsp_tx_power(hdev, skb); 2299 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2657 break; 2300 break;
2658 2301
2659 case HCI_OP_SET_EVENT_FLT:
2660 hci_cc_set_event_flt(hdev, skb);
2661 break;
2662
2663 case HCI_OP_PIN_CODE_REPLY: 2302 case HCI_OP_PIN_CODE_REPLY:
2664 hci_cc_pin_code_reply(hdev, skb); 2303 hci_cc_pin_code_reply(hdev, skb);
2665 break; 2304 break;
@@ -2684,10 +2323,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2684 hci_cc_le_read_adv_tx_power(hdev, skb); 2323 hci_cc_le_read_adv_tx_power(hdev, skb);
2685 break; 2324 break;
2686 2325
2687 case HCI_OP_LE_SET_EVENT_MASK:
2688 hci_cc_le_set_event_mask(hdev, skb);
2689 break;
2690
2691 case HCI_OP_USER_CONFIRM_REPLY: 2326 case HCI_OP_USER_CONFIRM_REPLY:
2692 hci_cc_user_confirm_reply(hdev, skb); 2327 hci_cc_user_confirm_reply(hdev, skb);
2693 break; 2328 break;
@@ -2720,14 +2355,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2720 hci_cc_le_read_white_list_size(hdev, skb); 2355 hci_cc_le_read_white_list_size(hdev, skb);
2721 break; 2356 break;
2722 2357
2723 case HCI_OP_LE_LTK_REPLY:
2724 hci_cc_le_ltk_reply(hdev, skb);
2725 break;
2726
2727 case HCI_OP_LE_LTK_NEG_REPLY:
2728 hci_cc_le_ltk_neg_reply(hdev, skb);
2729 break;
2730
2731 case HCI_OP_LE_READ_SUPPORTED_STATES: 2358 case HCI_OP_LE_READ_SUPPORTED_STATES:
2732 hci_cc_le_read_supported_states(hdev, skb); 2359 hci_cc_le_read_supported_states(hdev, skb);
2733 break; 2360 break;
@@ -2745,9 +2372,11 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2745 break; 2372 break;
2746 } 2373 }
2747 2374
2748 if (ev->opcode != HCI_OP_NOP) 2375 if (opcode != HCI_OP_NOP)
2749 del_timer(&hdev->cmd_timer); 2376 del_timer(&hdev->cmd_timer);
2750 2377
2378 hci_req_cmd_complete(hdev, opcode, status);
2379
2751 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2380 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
2752 atomic_set(&hdev->cmd_cnt, 1); 2381 atomic_set(&hdev->cmd_cnt, 1);
2753 if (!skb_queue_empty(&hdev->cmd_q)) 2382 if (!skb_queue_empty(&hdev->cmd_q))
@@ -2817,10 +2446,6 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2817 hci_cs_le_create_conn(hdev, ev->status); 2446 hci_cs_le_create_conn(hdev, ev->status);
2818 break; 2447 break;
2819 2448
2820 case HCI_OP_LE_START_ENC:
2821 hci_cs_le_start_enc(hdev, ev->status);
2822 break;
2823
2824 case HCI_OP_CREATE_PHY_LINK: 2449 case HCI_OP_CREATE_PHY_LINK:
2825 hci_cs_create_phylink(hdev, ev->status); 2450 hci_cs_create_phylink(hdev, ev->status);
2826 break; 2451 break;
@@ -2829,18 +2454,16 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2829 hci_cs_accept_phylink(hdev, ev->status); 2454 hci_cs_accept_phylink(hdev, ev->status);
2830 break; 2455 break;
2831 2456
2832 case HCI_OP_CREATE_LOGICAL_LINK:
2833 hci_cs_create_logical_link(hdev, ev->status);
2834 break;
2835
2836 default: 2457 default:
2837 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 2458 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
2838 break; 2459 break;
2839 } 2460 }
2840 2461
2841 if (ev->opcode != HCI_OP_NOP) 2462 if (opcode != HCI_OP_NOP)
2842 del_timer(&hdev->cmd_timer); 2463 del_timer(&hdev->cmd_timer);
2843 2464
2465 hci_req_cmd_status(hdev, opcode, ev->status);
2466
2844 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2467 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
2845 atomic_set(&hdev->cmd_cnt, 1); 2468 atomic_set(&hdev->cmd_cnt, 1);
2846 if (!skb_queue_empty(&hdev->cmd_q)) 2469 if (!skb_queue_empty(&hdev->cmd_q))
@@ -3391,18 +3014,6 @@ unlock:
3391 hci_dev_unlock(hdev); 3014 hci_dev_unlock(hdev);
3392} 3015}
3393 3016
3394static void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
3395{
3396 BT_DBG("%s", hdev->name);
3397}
3398
3399static void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
3400{
3401 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
3402
3403 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3404}
3405
3406static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, 3017static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3407 struct sk_buff *skb) 3018 struct sk_buff *skb)
3408{ 3019{
@@ -3472,7 +3083,7 @@ static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3472 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 3083 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3473 3084
3474 if (ev->status && conn->state == BT_CONNECTED) { 3085 if (ev->status && conn->state == BT_CONNECTED) {
3475 hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE); 3086 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
3476 hci_conn_put(conn); 3087 hci_conn_put(conn);
3477 goto unlock; 3088 goto unlock;
3478 } 3089 }
@@ -4130,14 +3741,6 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
4130 hci_remote_features_evt(hdev, skb); 3741 hci_remote_features_evt(hdev, skb);
4131 break; 3742 break;
4132 3743
4133 case HCI_EV_REMOTE_VERSION:
4134 hci_remote_version_evt(hdev, skb);
4135 break;
4136
4137 case HCI_EV_QOS_SETUP_COMPLETE:
4138 hci_qos_setup_complete_evt(hdev, skb);
4139 break;
4140
4141 case HCI_EV_CMD_COMPLETE: 3744 case HCI_EV_CMD_COMPLETE:
4142 hci_cmd_complete_evt(hdev, skb); 3745 hci_cmd_complete_evt(hdev, skb);
4143 break; 3746 break;
@@ -4194,14 +3797,6 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
4194 hci_sync_conn_complete_evt(hdev, skb); 3797 hci_sync_conn_complete_evt(hdev, skb);
4195 break; 3798 break;
4196 3799
4197 case HCI_EV_SYNC_CONN_CHANGED:
4198 hci_sync_conn_changed_evt(hdev, skb);
4199 break;
4200
4201 case HCI_EV_SNIFF_SUBRATE:
4202 hci_sniff_subrate_evt(hdev, skb);
4203 break;
4204
4205 case HCI_EV_EXTENDED_INQUIRY_RESULT: 3800 case HCI_EV_EXTENDED_INQUIRY_RESULT:
4206 hci_extended_inquiry_result_evt(hdev, skb); 3801 hci_extended_inquiry_result_evt(hdev, skb);
4207 break; 3802 break;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 6a93614f2c49..aa4354fca77c 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -854,6 +854,11 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
854 skb_queue_tail(&hdev->raw_q, skb); 854 skb_queue_tail(&hdev->raw_q, skb);
855 queue_work(hdev->workqueue, &hdev->tx_work); 855 queue_work(hdev->workqueue, &hdev->tx_work);
856 } else { 856 } else {
857 /* Stand-alone HCI commands must be flaged as
858 * single-command requests.
859 */
860 bt_cb(skb)->req.start = true;
861
857 skb_queue_tail(&hdev->cmd_q, skb); 862 skb_queue_tail(&hdev->cmd_q, skb);
858 queue_work(hdev->workqueue, &hdev->cmd_work); 863 queue_work(hdev->workqueue, &hdev->cmd_work);
859 } 864 }
@@ -1121,8 +1126,6 @@ error:
1121void hci_sock_cleanup(void) 1126void hci_sock_cleanup(void)
1122{ 1127{
1123 bt_procfs_cleanup(&init_net, "hci"); 1128 bt_procfs_cleanup(&init_net, "hci");
1124 if (bt_sock_unregister(BTPROTO_HCI) < 0) 1129 bt_sock_unregister(BTPROTO_HCI);
1125 BT_ERR("HCI socket unregistration failed");
1126
1127 proto_unregister(&hci_sk_proto); 1130 proto_unregister(&hci_sk_proto);
1128} 1131}
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 23b4e242a31a..ff38561385de 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -590,10 +590,8 @@ int __init bt_sysfs_init(void)
590 bt_debugfs = debugfs_create_dir("bluetooth", NULL); 590 bt_debugfs = debugfs_create_dir("bluetooth", NULL);
591 591
592 bt_class = class_create(THIS_MODULE, "bluetooth"); 592 bt_class = class_create(THIS_MODULE, "bluetooth");
593 if (IS_ERR(bt_class))
594 return PTR_ERR(bt_class);
595 593
596 return 0; 594 return PTR_RET(bt_class);
597} 595}
598 596
599void bt_sysfs_cleanup(void) 597void bt_sysfs_cleanup(void)
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index a7352ff3fd1e..2342327f3335 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -311,6 +311,9 @@ static int hidp_get_raw_report(struct hid_device *hid,
311 int numbered_reports = hid->report_enum[report_type].numbered; 311 int numbered_reports = hid->report_enum[report_type].numbered;
312 int ret; 312 int ret;
313 313
314 if (atomic_read(&session->terminate))
315 return -EIO;
316
314 switch (report_type) { 317 switch (report_type) {
315 case HID_FEATURE_REPORT: 318 case HID_FEATURE_REPORT:
316 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_FEATURE; 319 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_FEATURE;
@@ -722,6 +725,7 @@ static int hidp_session(void *arg)
722 set_current_state(TASK_INTERRUPTIBLE); 725 set_current_state(TASK_INTERRUPTIBLE);
723 } 726 }
724 set_current_state(TASK_RUNNING); 727 set_current_state(TASK_RUNNING);
728 atomic_inc(&session->terminate);
725 remove_wait_queue(sk_sleep(intr_sk), &intr_wait); 729 remove_wait_queue(sk_sleep(intr_sk), &intr_wait);
726 remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); 730 remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait);
727 731
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index 82a829d90b0f..5d0f1ca0a314 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -304,8 +304,6 @@ error:
304void __exit hidp_cleanup_sockets(void) 304void __exit hidp_cleanup_sockets(void)
305{ 305{
306 bt_procfs_cleanup(&init_net, "hidp"); 306 bt_procfs_cleanup(&init_net, "hidp");
307 if (bt_sock_unregister(BTPROTO_HIDP) < 0) 307 bt_sock_unregister(BTPROTO_HIDP);
308 BT_ERR("Can't unregister HIDP socket");
309
310 proto_unregister(&hidp_proto); 308 proto_unregister(&hidp_proto);
311} 309}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 1bcfb8422fdc..7f9704993b74 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1312,8 +1312,6 @@ error:
1312void l2cap_cleanup_sockets(void) 1312void l2cap_cleanup_sockets(void)
1313{ 1313{
1314 bt_procfs_cleanup(&init_net, "l2cap"); 1314 bt_procfs_cleanup(&init_net, "l2cap");
1315 if (bt_sock_unregister(BTPROTO_L2CAP) < 0) 1315 bt_sock_unregister(BTPROTO_L2CAP);
1316 BT_ERR("L2CAP socket unregistration failed");
1317
1318 proto_unregister(&l2cap_proto); 1316 proto_unregister(&l2cap_proto);
1319} 1317}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 39395c7144aa..03e7e732215f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -384,7 +384,8 @@ static u32 get_supported_settings(struct hci_dev *hdev)
384 384
385 if (lmp_bredr_capable(hdev)) { 385 if (lmp_bredr_capable(hdev)) {
386 settings |= MGMT_SETTING_CONNECTABLE; 386 settings |= MGMT_SETTING_CONNECTABLE;
387 settings |= MGMT_SETTING_FAST_CONNECTABLE; 387 if (hdev->hci_ver >= BLUETOOTH_VER_1_2)
388 settings |= MGMT_SETTING_FAST_CONNECTABLE;
388 settings |= MGMT_SETTING_DISCOVERABLE; 389 settings |= MGMT_SETTING_DISCOVERABLE;
389 settings |= MGMT_SETTING_BREDR; 390 settings |= MGMT_SETTING_BREDR;
390 settings |= MGMT_SETTING_LINK_SECURITY; 391 settings |= MGMT_SETTING_LINK_SECURITY;
@@ -409,6 +410,9 @@ static u32 get_current_settings(struct hci_dev *hdev)
409 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) 410 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
410 settings |= MGMT_SETTING_CONNECTABLE; 411 settings |= MGMT_SETTING_CONNECTABLE;
411 412
413 if (test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags))
414 settings |= MGMT_SETTING_FAST_CONNECTABLE;
415
412 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) 416 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
413 settings |= MGMT_SETTING_DISCOVERABLE; 417 settings |= MGMT_SETTING_DISCOVERABLE;
414 418
@@ -591,32 +595,33 @@ static void create_eir(struct hci_dev *hdev, u8 *data)
591 ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); 595 ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
592} 596}
593 597
594static int update_eir(struct hci_dev *hdev) 598static void update_eir(struct hci_request *req)
595{ 599{
600 struct hci_dev *hdev = req->hdev;
596 struct hci_cp_write_eir cp; 601 struct hci_cp_write_eir cp;
597 602
598 if (!hdev_is_powered(hdev)) 603 if (!hdev_is_powered(hdev))
599 return 0; 604 return;
600 605
601 if (!lmp_ext_inq_capable(hdev)) 606 if (!lmp_ext_inq_capable(hdev))
602 return 0; 607 return;
603 608
604 if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) 609 if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
605 return 0; 610 return;
606 611
607 if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 612 if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
608 return 0; 613 return;
609 614
610 memset(&cp, 0, sizeof(cp)); 615 memset(&cp, 0, sizeof(cp));
611 616
612 create_eir(hdev, cp.data); 617 create_eir(hdev, cp.data);
613 618
614 if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0) 619 if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
615 return 0; 620 return;
616 621
617 memcpy(hdev->eir, cp.data, sizeof(cp.data)); 622 memcpy(hdev->eir, cp.data, sizeof(cp.data));
618 623
619 return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 624 hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
620} 625}
621 626
622static u8 get_service_classes(struct hci_dev *hdev) 627static u8 get_service_classes(struct hci_dev *hdev)
@@ -630,47 +635,48 @@ static u8 get_service_classes(struct hci_dev *hdev)
630 return val; 635 return val;
631} 636}
632 637
633static int update_class(struct hci_dev *hdev) 638static void update_class(struct hci_request *req)
634{ 639{
640 struct hci_dev *hdev = req->hdev;
635 u8 cod[3]; 641 u8 cod[3];
636 int err;
637 642
638 BT_DBG("%s", hdev->name); 643 BT_DBG("%s", hdev->name);
639 644
640 if (!hdev_is_powered(hdev)) 645 if (!hdev_is_powered(hdev))
641 return 0; 646 return;
642 647
643 if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 648 if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
644 return 0; 649 return;
645 650
646 cod[0] = hdev->minor_class; 651 cod[0] = hdev->minor_class;
647 cod[1] = hdev->major_class; 652 cod[1] = hdev->major_class;
648 cod[2] = get_service_classes(hdev); 653 cod[2] = get_service_classes(hdev);
649 654
650 if (memcmp(cod, hdev->dev_class, 3) == 0) 655 if (memcmp(cod, hdev->dev_class, 3) == 0)
651 return 0; 656 return;
652
653 err = hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
654 if (err == 0)
655 set_bit(HCI_PENDING_CLASS, &hdev->dev_flags);
656 657
657 return err; 658 hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
658} 659}
659 660
660static void service_cache_off(struct work_struct *work) 661static void service_cache_off(struct work_struct *work)
661{ 662{
662 struct hci_dev *hdev = container_of(work, struct hci_dev, 663 struct hci_dev *hdev = container_of(work, struct hci_dev,
663 service_cache.work); 664 service_cache.work);
665 struct hci_request req;
664 666
665 if (!test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 667 if (!test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
666 return; 668 return;
667 669
670 hci_req_init(&req, hdev);
671
668 hci_dev_lock(hdev); 672 hci_dev_lock(hdev);
669 673
670 update_eir(hdev); 674 update_eir(&req);
671 update_class(hdev); 675 update_class(&req);
672 676
673 hci_dev_unlock(hdev); 677 hci_dev_unlock(hdev);
678
679 hci_req_run(&req, NULL);
674} 680}
675 681
676static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev) 682static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
@@ -994,11 +1000,64 @@ failed:
994 return err; 1000 return err;
995} 1001}
996 1002
1003static void write_fast_connectable(struct hci_request *req, bool enable)
1004{
1005 struct hci_dev *hdev = req->hdev;
1006 struct hci_cp_write_page_scan_activity acp;
1007 u8 type;
1008
1009 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
1010 return;
1011
1012 if (enable) {
1013 type = PAGE_SCAN_TYPE_INTERLACED;
1014
1015 /* 160 msec page scan interval */
1016 acp.interval = __constant_cpu_to_le16(0x0100);
1017 } else {
1018 type = PAGE_SCAN_TYPE_STANDARD; /* default */
1019
1020 /* default 1.28 sec page scan */
1021 acp.interval = __constant_cpu_to_le16(0x0800);
1022 }
1023
1024 acp.window = __constant_cpu_to_le16(0x0012);
1025
1026 if (__cpu_to_le16(hdev->page_scan_interval) != acp.interval ||
1027 __cpu_to_le16(hdev->page_scan_window) != acp.window)
1028 hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
1029 sizeof(acp), &acp);
1030
1031 if (hdev->page_scan_type != type)
1032 hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
1033}
1034
1035static void set_connectable_complete(struct hci_dev *hdev, u8 status)
1036{
1037 struct pending_cmd *cmd;
1038
1039 BT_DBG("status 0x%02x", status);
1040
1041 hci_dev_lock(hdev);
1042
1043 cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
1044 if (!cmd)
1045 goto unlock;
1046
1047 send_settings_rsp(cmd->sk, MGMT_OP_SET_CONNECTABLE, hdev);
1048
1049 mgmt_pending_remove(cmd);
1050
1051unlock:
1052 hci_dev_unlock(hdev);
1053}
1054
997static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, 1055static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
998 u16 len) 1056 u16 len)
999{ 1057{
1000 struct mgmt_mode *cp = data; 1058 struct mgmt_mode *cp = data;
1001 struct pending_cmd *cmd; 1059 struct pending_cmd *cmd;
1060 struct hci_request req;
1002 u8 scan; 1061 u8 scan;
1003 int err; 1062 int err;
1004 1063
@@ -1065,7 +1124,20 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
1065 cancel_delayed_work(&hdev->discov_off); 1124 cancel_delayed_work(&hdev->discov_off);
1066 } 1125 }
1067 1126
1068 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 1127 hci_req_init(&req, hdev);
1128
1129 hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
1130
1131 /* If we're going from non-connectable to connectable or
1132 * vice-versa when fast connectable is enabled ensure that fast
1133 * connectable gets disabled. write_fast_connectable won't do
1134 * anything if the page scan parameters are already what they
1135 * should be.
1136 */
1137 if (cp->val || test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags))
1138 write_fast_connectable(&req, false);
1139
1140 err = hci_req_run(&req, set_connectable_complete);
1069 if (err < 0) 1141 if (err < 0)
1070 mgmt_pending_remove(cmd); 1142 mgmt_pending_remove(cmd);
1071 1143
@@ -1332,6 +1404,29 @@ unlock:
1332 return err; 1404 return err;
1333} 1405}
1334 1406
1407/* This is a helper function to test for pending mgmt commands that can
1408 * cause CoD or EIR HCI commands. We can only allow one such pending
1409 * mgmt command at a time since otherwise we cannot easily track what
1410 * the current values are, will be, and based on that calculate if a new
1411 * HCI command needs to be sent and if yes with what value.
1412 */
1413static bool pending_eir_or_class(struct hci_dev *hdev)
1414{
1415 struct pending_cmd *cmd;
1416
1417 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
1418 switch (cmd->opcode) {
1419 case MGMT_OP_ADD_UUID:
1420 case MGMT_OP_REMOVE_UUID:
1421 case MGMT_OP_SET_DEV_CLASS:
1422 case MGMT_OP_SET_POWERED:
1423 return true;
1424 }
1425 }
1426
1427 return false;
1428}
1429
1335static const u8 bluetooth_base_uuid[] = { 1430static const u8 bluetooth_base_uuid[] = {
1336 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 1431 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
1337 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1432 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -1351,10 +1446,37 @@ static u8 get_uuid_size(const u8 *uuid)
1351 return 16; 1446 return 16;
1352} 1447}
1353 1448
1449static void mgmt_class_complete(struct hci_dev *hdev, u16 mgmt_op, u8 status)
1450{
1451 struct pending_cmd *cmd;
1452
1453 hci_dev_lock(hdev);
1454
1455 cmd = mgmt_pending_find(mgmt_op, hdev);
1456 if (!cmd)
1457 goto unlock;
1458
1459 cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status),
1460 hdev->dev_class, 3);
1461
1462 mgmt_pending_remove(cmd);
1463
1464unlock:
1465 hci_dev_unlock(hdev);
1466}
1467
1468static void add_uuid_complete(struct hci_dev *hdev, u8 status)
1469{
1470 BT_DBG("status 0x%02x", status);
1471
1472 mgmt_class_complete(hdev, MGMT_OP_ADD_UUID, status);
1473}
1474
1354static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) 1475static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1355{ 1476{
1356 struct mgmt_cp_add_uuid *cp = data; 1477 struct mgmt_cp_add_uuid *cp = data;
1357 struct pending_cmd *cmd; 1478 struct pending_cmd *cmd;
1479 struct hci_request req;
1358 struct bt_uuid *uuid; 1480 struct bt_uuid *uuid;
1359 int err; 1481 int err;
1360 1482
@@ -1362,7 +1484,7 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1362 1484
1363 hci_dev_lock(hdev); 1485 hci_dev_lock(hdev);
1364 1486
1365 if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { 1487 if (pending_eir_or_class(hdev)) {
1366 err = cmd_status(sk, hdev->id, MGMT_OP_ADD_UUID, 1488 err = cmd_status(sk, hdev->id, MGMT_OP_ADD_UUID,
1367 MGMT_STATUS_BUSY); 1489 MGMT_STATUS_BUSY);
1368 goto failed; 1490 goto failed;
@@ -1380,23 +1502,28 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1380 1502
1381 list_add_tail(&uuid->list, &hdev->uuids); 1503 list_add_tail(&uuid->list, &hdev->uuids);
1382 1504
1383 err = update_class(hdev); 1505 hci_req_init(&req, hdev);
1384 if (err < 0)
1385 goto failed;
1386 1506
1387 err = update_eir(hdev); 1507 update_class(&req);
1388 if (err < 0) 1508 update_eir(&req);
1389 goto failed; 1509
1510 err = hci_req_run(&req, add_uuid_complete);
1511 if (err < 0) {
1512 if (err != -ENODATA)
1513 goto failed;
1390 1514
1391 if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) {
1392 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_UUID, 0, 1515 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_UUID, 0,
1393 hdev->dev_class, 3); 1516 hdev->dev_class, 3);
1394 goto failed; 1517 goto failed;
1395 } 1518 }
1396 1519
1397 cmd = mgmt_pending_add(sk, MGMT_OP_ADD_UUID, hdev, data, len); 1520 cmd = mgmt_pending_add(sk, MGMT_OP_ADD_UUID, hdev, data, len);
1398 if (!cmd) 1521 if (!cmd) {
1399 err = -ENOMEM; 1522 err = -ENOMEM;
1523 goto failed;
1524 }
1525
1526 err = 0;
1400 1527
1401failed: 1528failed:
1402 hci_dev_unlock(hdev); 1529 hci_dev_unlock(hdev);
@@ -1417,6 +1544,13 @@ static bool enable_service_cache(struct hci_dev *hdev)
1417 return false; 1544 return false;
1418} 1545}
1419 1546
1547static void remove_uuid_complete(struct hci_dev *hdev, u8 status)
1548{
1549 BT_DBG("status 0x%02x", status);
1550
1551 mgmt_class_complete(hdev, MGMT_OP_REMOVE_UUID, status);
1552}
1553
1420static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, 1554static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
1421 u16 len) 1555 u16 len)
1422{ 1556{
@@ -1424,13 +1558,14 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
1424 struct pending_cmd *cmd; 1558 struct pending_cmd *cmd;
1425 struct bt_uuid *match, *tmp; 1559 struct bt_uuid *match, *tmp;
1426 u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1560 u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1561 struct hci_request req;
1427 int err, found; 1562 int err, found;
1428 1563
1429 BT_DBG("request for %s", hdev->name); 1564 BT_DBG("request for %s", hdev->name);
1430 1565
1431 hci_dev_lock(hdev); 1566 hci_dev_lock(hdev);
1432 1567
1433 if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { 1568 if (pending_eir_or_class(hdev)) {
1434 err = cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID, 1569 err = cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID,
1435 MGMT_STATUS_BUSY); 1570 MGMT_STATUS_BUSY);
1436 goto unlock; 1571 goto unlock;
@@ -1466,34 +1601,47 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
1466 } 1601 }
1467 1602
1468update_class: 1603update_class:
1469 err = update_class(hdev); 1604 hci_req_init(&req, hdev);
1470 if (err < 0)
1471 goto unlock;
1472 1605
1473 err = update_eir(hdev); 1606 update_class(&req);
1474 if (err < 0) 1607 update_eir(&req);
1475 goto unlock; 1608
1609 err = hci_req_run(&req, remove_uuid_complete);
1610 if (err < 0) {
1611 if (err != -ENODATA)
1612 goto unlock;
1476 1613
1477 if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) {
1478 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, 0, 1614 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, 0,
1479 hdev->dev_class, 3); 1615 hdev->dev_class, 3);
1480 goto unlock; 1616 goto unlock;
1481 } 1617 }
1482 1618
1483 cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_UUID, hdev, data, len); 1619 cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_UUID, hdev, data, len);
1484 if (!cmd) 1620 if (!cmd) {
1485 err = -ENOMEM; 1621 err = -ENOMEM;
1622 goto unlock;
1623 }
1624
1625 err = 0;
1486 1626
1487unlock: 1627unlock:
1488 hci_dev_unlock(hdev); 1628 hci_dev_unlock(hdev);
1489 return err; 1629 return err;
1490} 1630}
1491 1631
1632static void set_class_complete(struct hci_dev *hdev, u8 status)
1633{
1634 BT_DBG("status 0x%02x", status);
1635
1636 mgmt_class_complete(hdev, MGMT_OP_SET_DEV_CLASS, status);
1637}
1638
1492static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data, 1639static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
1493 u16 len) 1640 u16 len)
1494{ 1641{
1495 struct mgmt_cp_set_dev_class *cp = data; 1642 struct mgmt_cp_set_dev_class *cp = data;
1496 struct pending_cmd *cmd; 1643 struct pending_cmd *cmd;
1644 struct hci_request req;
1497 int err; 1645 int err;
1498 1646
1499 BT_DBG("request for %s", hdev->name); 1647 BT_DBG("request for %s", hdev->name);
@@ -1502,15 +1650,19 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
1502 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 1650 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
1503 MGMT_STATUS_NOT_SUPPORTED); 1651 MGMT_STATUS_NOT_SUPPORTED);
1504 1652
1505 if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) 1653 hci_dev_lock(hdev);
1506 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
1507 MGMT_STATUS_BUSY);
1508 1654
1509 if ((cp->minor & 0x03) != 0 || (cp->major & 0xe0) != 0) 1655 if (pending_eir_or_class(hdev)) {
1510 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 1656 err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
1511 MGMT_STATUS_INVALID_PARAMS); 1657 MGMT_STATUS_BUSY);
1658 goto unlock;
1659 }
1512 1660
1513 hci_dev_lock(hdev); 1661 if ((cp->minor & 0x03) != 0 || (cp->major & 0xe0) != 0) {
1662 err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
1663 MGMT_STATUS_INVALID_PARAMS);
1664 goto unlock;
1665 }
1514 1666
1515 hdev->major_class = cp->major; 1667 hdev->major_class = cp->major;
1516 hdev->minor_class = cp->minor; 1668 hdev->minor_class = cp->minor;
@@ -1521,26 +1673,34 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
1521 goto unlock; 1673 goto unlock;
1522 } 1674 }
1523 1675
1676 hci_req_init(&req, hdev);
1677
1524 if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) { 1678 if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) {
1525 hci_dev_unlock(hdev); 1679 hci_dev_unlock(hdev);
1526 cancel_delayed_work_sync(&hdev->service_cache); 1680 cancel_delayed_work_sync(&hdev->service_cache);
1527 hci_dev_lock(hdev); 1681 hci_dev_lock(hdev);
1528 update_eir(hdev); 1682 update_eir(&req);
1529 } 1683 }
1530 1684
1531 err = update_class(hdev); 1685 update_class(&req);
1532 if (err < 0) 1686
1533 goto unlock; 1687 err = hci_req_run(&req, set_class_complete);
1688 if (err < 0) {
1689 if (err != -ENODATA)
1690 goto unlock;
1534 1691
1535 if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) {
1536 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0, 1692 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0,
1537 hdev->dev_class, 3); 1693 hdev->dev_class, 3);
1538 goto unlock; 1694 goto unlock;
1539 } 1695 }
1540 1696
1541 cmd = mgmt_pending_add(sk, MGMT_OP_SET_DEV_CLASS, hdev, data, len); 1697 cmd = mgmt_pending_add(sk, MGMT_OP_SET_DEV_CLASS, hdev, data, len);
1542 if (!cmd) 1698 if (!cmd) {
1543 err = -ENOMEM; 1699 err = -ENOMEM;
1700 goto unlock;
1701 }
1702
1703 err = 0;
1544 1704
1545unlock: 1705unlock:
1546 hci_dev_unlock(hdev); 1706 hci_dev_unlock(hdev);
@@ -2140,7 +2300,7 @@ unlock:
2140} 2300}
2141 2301
2142static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev, 2302static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
2143 bdaddr_t *bdaddr, u8 type, u16 mgmt_op, 2303 struct mgmt_addr_info *addr, u16 mgmt_op,
2144 u16 hci_op, __le32 passkey) 2304 u16 hci_op, __le32 passkey)
2145{ 2305{
2146 struct pending_cmd *cmd; 2306 struct pending_cmd *cmd;
@@ -2150,37 +2310,41 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
2150 hci_dev_lock(hdev); 2310 hci_dev_lock(hdev);
2151 2311
2152 if (!hdev_is_powered(hdev)) { 2312 if (!hdev_is_powered(hdev)) {
2153 err = cmd_status(sk, hdev->id, mgmt_op, 2313 err = cmd_complete(sk, hdev->id, mgmt_op,
2154 MGMT_STATUS_NOT_POWERED); 2314 MGMT_STATUS_NOT_POWERED, addr,
2315 sizeof(*addr));
2155 goto done; 2316 goto done;
2156 } 2317 }
2157 2318
2158 if (type == BDADDR_BREDR) 2319 if (addr->type == BDADDR_BREDR)
2159 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, bdaddr); 2320 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &addr->bdaddr);
2160 else 2321 else
2161 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr); 2322 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &addr->bdaddr);
2162 2323
2163 if (!conn) { 2324 if (!conn) {
2164 err = cmd_status(sk, hdev->id, mgmt_op, 2325 err = cmd_complete(sk, hdev->id, mgmt_op,
2165 MGMT_STATUS_NOT_CONNECTED); 2326 MGMT_STATUS_NOT_CONNECTED, addr,
2327 sizeof(*addr));
2166 goto done; 2328 goto done;
2167 } 2329 }
2168 2330
2169 if (type == BDADDR_LE_PUBLIC || type == BDADDR_LE_RANDOM) { 2331 if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
2170 /* Continue with pairing via SMP */ 2332 /* Continue with pairing via SMP */
2171 err = smp_user_confirm_reply(conn, mgmt_op, passkey); 2333 err = smp_user_confirm_reply(conn, mgmt_op, passkey);
2172 2334
2173 if (!err) 2335 if (!err)
2174 err = cmd_status(sk, hdev->id, mgmt_op, 2336 err = cmd_complete(sk, hdev->id, mgmt_op,
2175 MGMT_STATUS_SUCCESS); 2337 MGMT_STATUS_SUCCESS, addr,
2338 sizeof(*addr));
2176 else 2339 else
2177 err = cmd_status(sk, hdev->id, mgmt_op, 2340 err = cmd_complete(sk, hdev->id, mgmt_op,
2178 MGMT_STATUS_FAILED); 2341 MGMT_STATUS_FAILED, addr,
2342 sizeof(*addr));
2179 2343
2180 goto done; 2344 goto done;
2181 } 2345 }
2182 2346
2183 cmd = mgmt_pending_add(sk, mgmt_op, hdev, bdaddr, sizeof(*bdaddr)); 2347 cmd = mgmt_pending_add(sk, mgmt_op, hdev, addr, sizeof(*addr));
2184 if (!cmd) { 2348 if (!cmd) {
2185 err = -ENOMEM; 2349 err = -ENOMEM;
2186 goto done; 2350 goto done;
@@ -2190,11 +2354,12 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
2190 if (hci_op == HCI_OP_USER_PASSKEY_REPLY) { 2354 if (hci_op == HCI_OP_USER_PASSKEY_REPLY) {
2191 struct hci_cp_user_passkey_reply cp; 2355 struct hci_cp_user_passkey_reply cp;
2192 2356
2193 bacpy(&cp.bdaddr, bdaddr); 2357 bacpy(&cp.bdaddr, &addr->bdaddr);
2194 cp.passkey = passkey; 2358 cp.passkey = passkey;
2195 err = hci_send_cmd(hdev, hci_op, sizeof(cp), &cp); 2359 err = hci_send_cmd(hdev, hci_op, sizeof(cp), &cp);
2196 } else 2360 } else
2197 err = hci_send_cmd(hdev, hci_op, sizeof(*bdaddr), bdaddr); 2361 err = hci_send_cmd(hdev, hci_op, sizeof(addr->bdaddr),
2362 &addr->bdaddr);
2198 2363
2199 if (err < 0) 2364 if (err < 0)
2200 mgmt_pending_remove(cmd); 2365 mgmt_pending_remove(cmd);
@@ -2211,7 +2376,7 @@ static int pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev,
2211 2376
2212 BT_DBG(""); 2377 BT_DBG("");
2213 2378
2214 return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type, 2379 return user_pairing_resp(sk, hdev, &cp->addr,
2215 MGMT_OP_PIN_CODE_NEG_REPLY, 2380 MGMT_OP_PIN_CODE_NEG_REPLY,
2216 HCI_OP_PIN_CODE_NEG_REPLY, 0); 2381 HCI_OP_PIN_CODE_NEG_REPLY, 0);
2217} 2382}
@@ -2227,7 +2392,7 @@ static int user_confirm_reply(struct sock *sk, struct hci_dev *hdev, void *data,
2227 return cmd_status(sk, hdev->id, MGMT_OP_USER_CONFIRM_REPLY, 2392 return cmd_status(sk, hdev->id, MGMT_OP_USER_CONFIRM_REPLY,
2228 MGMT_STATUS_INVALID_PARAMS); 2393 MGMT_STATUS_INVALID_PARAMS);
2229 2394
2230 return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type, 2395 return user_pairing_resp(sk, hdev, &cp->addr,
2231 MGMT_OP_USER_CONFIRM_REPLY, 2396 MGMT_OP_USER_CONFIRM_REPLY,
2232 HCI_OP_USER_CONFIRM_REPLY, 0); 2397 HCI_OP_USER_CONFIRM_REPLY, 0);
2233} 2398}
@@ -2239,7 +2404,7 @@ static int user_confirm_neg_reply(struct sock *sk, struct hci_dev *hdev,
2239 2404
2240 BT_DBG(""); 2405 BT_DBG("");
2241 2406
2242 return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type, 2407 return user_pairing_resp(sk, hdev, &cp->addr,
2243 MGMT_OP_USER_CONFIRM_NEG_REPLY, 2408 MGMT_OP_USER_CONFIRM_NEG_REPLY,
2244 HCI_OP_USER_CONFIRM_NEG_REPLY, 0); 2409 HCI_OP_USER_CONFIRM_NEG_REPLY, 0);
2245} 2410}
@@ -2251,7 +2416,7 @@ static int user_passkey_reply(struct sock *sk, struct hci_dev *hdev, void *data,
2251 2416
2252 BT_DBG(""); 2417 BT_DBG("");
2253 2418
2254 return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type, 2419 return user_pairing_resp(sk, hdev, &cp->addr,
2255 MGMT_OP_USER_PASSKEY_REPLY, 2420 MGMT_OP_USER_PASSKEY_REPLY,
2256 HCI_OP_USER_PASSKEY_REPLY, cp->passkey); 2421 HCI_OP_USER_PASSKEY_REPLY, cp->passkey);
2257} 2422}
@@ -2263,18 +2428,47 @@ static int user_passkey_neg_reply(struct sock *sk, struct hci_dev *hdev,
2263 2428
2264 BT_DBG(""); 2429 BT_DBG("");
2265 2430
2266 return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type, 2431 return user_pairing_resp(sk, hdev, &cp->addr,
2267 MGMT_OP_USER_PASSKEY_NEG_REPLY, 2432 MGMT_OP_USER_PASSKEY_NEG_REPLY,
2268 HCI_OP_USER_PASSKEY_NEG_REPLY, 0); 2433 HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
2269} 2434}
2270 2435
2271static int update_name(struct hci_dev *hdev, const char *name) 2436static void update_name(struct hci_request *req)
2272{ 2437{
2438 struct hci_dev *hdev = req->hdev;
2273 struct hci_cp_write_local_name cp; 2439 struct hci_cp_write_local_name cp;
2274 2440
2275 memcpy(cp.name, name, sizeof(cp.name)); 2441 memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
2442
2443 hci_req_add(req, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
2444}
2445
2446static void set_name_complete(struct hci_dev *hdev, u8 status)
2447{
2448 struct mgmt_cp_set_local_name *cp;
2449 struct pending_cmd *cmd;
2450
2451 BT_DBG("status 0x%02x", status);
2452
2453 hci_dev_lock(hdev);
2454
2455 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev);
2456 if (!cmd)
2457 goto unlock;
2458
2459 cp = cmd->param;
2276 2460
2277 return hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp); 2461 if (status)
2462 cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
2463 mgmt_status(status));
2464 else
2465 cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
2466 cp, sizeof(*cp));
2467
2468 mgmt_pending_remove(cmd);
2469
2470unlock:
2471 hci_dev_unlock(hdev);
2278} 2472}
2279 2473
2280static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data, 2474static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
@@ -2282,12 +2476,24 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
2282{ 2476{
2283 struct mgmt_cp_set_local_name *cp = data; 2477 struct mgmt_cp_set_local_name *cp = data;
2284 struct pending_cmd *cmd; 2478 struct pending_cmd *cmd;
2479 struct hci_request req;
2285 int err; 2480 int err;
2286 2481
2287 BT_DBG(""); 2482 BT_DBG("");
2288 2483
2289 hci_dev_lock(hdev); 2484 hci_dev_lock(hdev);
2290 2485
2486 /* If the old values are the same as the new ones just return a
2487 * direct command complete event.
2488 */
2489 if (!memcmp(hdev->dev_name, cp->name, sizeof(hdev->dev_name)) &&
2490 !memcmp(hdev->short_name, cp->short_name,
2491 sizeof(hdev->short_name))) {
2492 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
2493 data, len);
2494 goto failed;
2495 }
2496
2291 memcpy(hdev->short_name, cp->short_name, sizeof(hdev->short_name)); 2497 memcpy(hdev->short_name, cp->short_name, sizeof(hdev->short_name));
2292 2498
2293 if (!hdev_is_powered(hdev)) { 2499 if (!hdev_is_powered(hdev)) {
@@ -2310,7 +2516,19 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
2310 goto failed; 2516 goto failed;
2311 } 2517 }
2312 2518
2313 err = update_name(hdev, cp->name); 2519 memcpy(hdev->dev_name, cp->name, sizeof(hdev->dev_name));
2520
2521 hci_req_init(&req, hdev);
2522
2523 if (lmp_bredr_capable(hdev)) {
2524 update_name(&req);
2525 update_eir(&req);
2526 }
2527
2528 if (lmp_le_capable(hdev))
2529 hci_update_ad(&req);
2530
2531 err = hci_req_run(&req, set_name_complete);
2314 if (err < 0) 2532 if (err < 0)
2315 mgmt_pending_remove(cmd); 2533 mgmt_pending_remove(cmd);
2316 2534
@@ -2698,6 +2916,7 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
2698 u16 len) 2916 u16 len)
2699{ 2917{
2700 struct mgmt_cp_set_device_id *cp = data; 2918 struct mgmt_cp_set_device_id *cp = data;
2919 struct hci_request req;
2701 int err; 2920 int err;
2702 __u16 source; 2921 __u16 source;
2703 2922
@@ -2718,24 +2937,59 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
2718 2937
2719 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, 0, NULL, 0); 2938 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, 0, NULL, 0);
2720 2939
2721 update_eir(hdev); 2940 hci_req_init(&req, hdev);
2941 update_eir(&req);
2942 hci_req_run(&req, NULL);
2722 2943
2723 hci_dev_unlock(hdev); 2944 hci_dev_unlock(hdev);
2724 2945
2725 return err; 2946 return err;
2726} 2947}
2727 2948
2949static void fast_connectable_complete(struct hci_dev *hdev, u8 status)
2950{
2951 struct pending_cmd *cmd;
2952
2953 BT_DBG("status 0x%02x", status);
2954
2955 hci_dev_lock(hdev);
2956
2957 cmd = mgmt_pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev);
2958 if (!cmd)
2959 goto unlock;
2960
2961 if (status) {
2962 cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2963 mgmt_status(status));
2964 } else {
2965 struct mgmt_mode *cp = cmd->param;
2966
2967 if (cp->val)
2968 set_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags);
2969 else
2970 clear_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags);
2971
2972 send_settings_rsp(cmd->sk, MGMT_OP_SET_FAST_CONNECTABLE, hdev);
2973 new_settings(hdev, cmd->sk);
2974 }
2975
2976 mgmt_pending_remove(cmd);
2977
2978unlock:
2979 hci_dev_unlock(hdev);
2980}
2981
2728static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, 2982static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
2729 void *data, u16 len) 2983 void *data, u16 len)
2730{ 2984{
2731 struct mgmt_mode *cp = data; 2985 struct mgmt_mode *cp = data;
2732 struct hci_cp_write_page_scan_activity acp; 2986 struct pending_cmd *cmd;
2733 u8 type; 2987 struct hci_request req;
2734 int err; 2988 int err;
2735 2989
2736 BT_DBG("%s", hdev->name); 2990 BT_DBG("%s", hdev->name);
2737 2991
2738 if (!lmp_bredr_capable(hdev)) 2992 if (!lmp_bredr_capable(hdev) || hdev->hci_ver < BLUETOOTH_VER_1_2)
2739 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, 2993 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2740 MGMT_STATUS_NOT_SUPPORTED); 2994 MGMT_STATUS_NOT_SUPPORTED);
2741 2995
@@ -2753,40 +3007,39 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
2753 3007
2754 hci_dev_lock(hdev); 3008 hci_dev_lock(hdev);
2755 3009
2756 if (cp->val) { 3010 if (mgmt_pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev)) {
2757 type = PAGE_SCAN_TYPE_INTERLACED; 3011 err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
3012 MGMT_STATUS_BUSY);
3013 goto unlock;
3014 }
2758 3015
2759 /* 160 msec page scan interval */ 3016 if (!!cp->val == test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags)) {
2760 acp.interval = __constant_cpu_to_le16(0x0100); 3017 err = send_settings_rsp(sk, MGMT_OP_SET_FAST_CONNECTABLE,
2761 } else { 3018 hdev);
2762 type = PAGE_SCAN_TYPE_STANDARD; /* default */ 3019 goto unlock;
3020 }
2763 3021
2764 /* default 1.28 sec page scan */ 3022 cmd = mgmt_pending_add(sk, MGMT_OP_SET_FAST_CONNECTABLE, hdev,
2765 acp.interval = __constant_cpu_to_le16(0x0800); 3023 data, len);
3024 if (!cmd) {
3025 err = -ENOMEM;
3026 goto unlock;
2766 } 3027 }
2767 3028
2768 /* default 11.25 msec page scan window */ 3029 hci_req_init(&req, hdev);
2769 acp.window = __constant_cpu_to_le16(0x0012);
2770 3030
2771 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, sizeof(acp), 3031 write_fast_connectable(&req, cp->val);
2772 &acp);
2773 if (err < 0) {
2774 err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2775 MGMT_STATUS_FAILED);
2776 goto done;
2777 }
2778 3032
2779 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type); 3033 err = hci_req_run(&req, fast_connectable_complete);
2780 if (err < 0) { 3034 if (err < 0) {
2781 err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, 3035 err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2782 MGMT_STATUS_FAILED); 3036 MGMT_STATUS_FAILED);
2783 goto done; 3037 mgmt_pending_remove(cmd);
2784 } 3038 }
2785 3039
2786 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, 0, 3040unlock:
2787 NULL, 0);
2788done:
2789 hci_dev_unlock(hdev); 3041 hci_dev_unlock(hdev);
3042
2790 return err; 3043 return err;
2791} 3044}
2792 3045
@@ -3043,79 +3296,115 @@ static void settings_rsp(struct pending_cmd *cmd, void *data)
3043 mgmt_pending_free(cmd); 3296 mgmt_pending_free(cmd);
3044} 3297}
3045 3298
3046static int set_bredr_scan(struct hci_dev *hdev) 3299static void set_bredr_scan(struct hci_request *req)
3047{ 3300{
3301 struct hci_dev *hdev = req->hdev;
3048 u8 scan = 0; 3302 u8 scan = 0;
3049 3303
3304 /* Ensure that fast connectable is disabled. This function will
3305 * not do anything if the page scan parameters are already what
3306 * they should be.
3307 */
3308 write_fast_connectable(req, false);
3309
3050 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) 3310 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
3051 scan |= SCAN_PAGE; 3311 scan |= SCAN_PAGE;
3052 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) 3312 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
3053 scan |= SCAN_INQUIRY; 3313 scan |= SCAN_INQUIRY;
3054 3314
3055 if (!scan) 3315 if (scan)
3056 return 0; 3316 hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
3057
3058 return hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
3059} 3317}
3060 3318
3061int mgmt_powered(struct hci_dev *hdev, u8 powered) 3319static void powered_complete(struct hci_dev *hdev, u8 status)
3062{ 3320{
3063 struct cmd_lookup match = { NULL, hdev }; 3321 struct cmd_lookup match = { NULL, hdev };
3064 int err;
3065 3322
3066 if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 3323 BT_DBG("status 0x%02x", status);
3067 return 0; 3324
3325 hci_dev_lock(hdev);
3068 3326
3069 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); 3327 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
3070 3328
3071 if (powered) { 3329 new_settings(hdev, match.sk);
3072 u8 link_sec;
3073 3330
3074 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && 3331 hci_dev_unlock(hdev);
3075 !lmp_host_ssp_capable(hdev)) {
3076 u8 ssp = 1;
3077 3332
3078 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &ssp); 3333 if (match.sk)
3079 } 3334 sock_put(match.sk);
3335}
3080 3336
3081 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 3337static int powered_update_hci(struct hci_dev *hdev)
3082 struct hci_cp_write_le_host_supported cp; 3338{
3339 struct hci_request req;
3340 u8 link_sec;
3083 3341
3084 cp.le = 1; 3342 hci_req_init(&req, hdev);
3085 cp.simul = lmp_le_br_capable(hdev);
3086 3343
3087 /* Check first if we already have the right 3344 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
3088 * host state (host features set) 3345 !lmp_host_ssp_capable(hdev)) {
3089 */ 3346 u8 ssp = 1;
3090 if (cp.le != lmp_host_le_capable(hdev) ||
3091 cp.simul != lmp_host_le_br_capable(hdev))
3092 hci_send_cmd(hdev,
3093 HCI_OP_WRITE_LE_HOST_SUPPORTED,
3094 sizeof(cp), &cp);
3095 }
3096 3347
3097 link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags); 3348 hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, 1, &ssp);
3098 if (link_sec != test_bit(HCI_AUTH, &hdev->flags)) 3349 }
3099 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
3100 sizeof(link_sec), &link_sec);
3101 3350
3102 if (lmp_bredr_capable(hdev)) { 3351 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
3103 set_bredr_scan(hdev); 3352 struct hci_cp_write_le_host_supported cp;
3104 update_class(hdev);
3105 update_name(hdev, hdev->dev_name);
3106 update_eir(hdev);
3107 }
3108 } else {
3109 u8 status = MGMT_STATUS_NOT_POWERED;
3110 u8 zero_cod[] = { 0, 0, 0 };
3111 3353
3112 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); 3354 cp.le = 1;
3355 cp.simul = lmp_le_br_capable(hdev);
3113 3356
3114 if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) 3357 /* Check first if we already have the right
3115 mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, 3358 * host state (host features set)
3116 zero_cod, sizeof(zero_cod), NULL); 3359 */
3360 if (cp.le != lmp_host_le_capable(hdev) ||
3361 cp.simul != lmp_host_le_br_capable(hdev))
3362 hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED,
3363 sizeof(cp), &cp);
3117 } 3364 }
3118 3365
3366 link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
3367 if (link_sec != test_bit(HCI_AUTH, &hdev->flags))
3368 hci_req_add(&req, HCI_OP_WRITE_AUTH_ENABLE,
3369 sizeof(link_sec), &link_sec);
3370
3371 if (lmp_bredr_capable(hdev)) {
3372 set_bredr_scan(&req);
3373 update_class(&req);
3374 update_name(&req);
3375 update_eir(&req);
3376 }
3377
3378 return hci_req_run(&req, powered_complete);
3379}
3380
3381int mgmt_powered(struct hci_dev *hdev, u8 powered)
3382{
3383 struct cmd_lookup match = { NULL, hdev };
3384 u8 status_not_powered = MGMT_STATUS_NOT_POWERED;
3385 u8 zero_cod[] = { 0, 0, 0 };
3386 int err;
3387
3388 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
3389 return 0;
3390
3391 if (powered) {
3392 if (powered_update_hci(hdev) == 0)
3393 return 0;
3394
3395 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp,
3396 &match);
3397 goto new_settings;
3398 }
3399
3400 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
3401 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status_not_powered);
3402
3403 if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0)
3404 mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
3405 zero_cod, sizeof(zero_cod), NULL);
3406
3407new_settings:
3119 err = new_settings(hdev, match.sk); 3408 err = new_settings(hdev, match.sk);
3120 3409
3121 if (match.sk) 3410 if (match.sk)
@@ -3152,7 +3441,7 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
3152 3441
3153int mgmt_connectable(struct hci_dev *hdev, u8 connectable) 3442int mgmt_connectable(struct hci_dev *hdev, u8 connectable)
3154{ 3443{
3155 struct cmd_lookup match = { NULL, hdev }; 3444 struct pending_cmd *cmd;
3156 bool changed = false; 3445 bool changed = false;
3157 int err = 0; 3446 int err = 0;
3158 3447
@@ -3164,14 +3453,10 @@ int mgmt_connectable(struct hci_dev *hdev, u8 connectable)
3164 changed = true; 3453 changed = true;
3165 } 3454 }
3166 3455
3167 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, settings_rsp, 3456 cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
3168 &match);
3169 3457
3170 if (changed) 3458 if (changed)
3171 err = new_settings(hdev, match.sk); 3459 err = new_settings(hdev, cmd ? cmd->sk : NULL);
3172
3173 if (match.sk)
3174 sock_put(match.sk);
3175 3460
3176 return err; 3461 return err;
3177} 3462}
@@ -3555,23 +3840,25 @@ int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
3555 return err; 3840 return err;
3556} 3841}
3557 3842
3558static int clear_eir(struct hci_dev *hdev) 3843static void clear_eir(struct hci_request *req)
3559{ 3844{
3845 struct hci_dev *hdev = req->hdev;
3560 struct hci_cp_write_eir cp; 3846 struct hci_cp_write_eir cp;
3561 3847
3562 if (!lmp_ext_inq_capable(hdev)) 3848 if (!lmp_ext_inq_capable(hdev))
3563 return 0; 3849 return;
3564 3850
3565 memset(hdev->eir, 0, sizeof(hdev->eir)); 3851 memset(hdev->eir, 0, sizeof(hdev->eir));
3566 3852
3567 memset(&cp, 0, sizeof(cp)); 3853 memset(&cp, 0, sizeof(cp));
3568 3854
3569 return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 3855 hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
3570} 3856}
3571 3857
3572int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) 3858int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
3573{ 3859{
3574 struct cmd_lookup match = { NULL, hdev }; 3860 struct cmd_lookup match = { NULL, hdev };
3861 struct hci_request req;
3575 bool changed = false; 3862 bool changed = false;
3576 int err = 0; 3863 int err = 0;
3577 3864
@@ -3604,29 +3891,26 @@ int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
3604 if (match.sk) 3891 if (match.sk)
3605 sock_put(match.sk); 3892 sock_put(match.sk);
3606 3893
3894 hci_req_init(&req, hdev);
3895
3607 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) 3896 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
3608 update_eir(hdev); 3897 update_eir(&req);
3609 else 3898 else
3610 clear_eir(hdev); 3899 clear_eir(&req);
3900
3901 hci_req_run(&req, NULL);
3611 3902
3612 return err; 3903 return err;
3613} 3904}
3614 3905
3615static void class_rsp(struct pending_cmd *cmd, void *data) 3906static void sk_lookup(struct pending_cmd *cmd, void *data)
3616{ 3907{
3617 struct cmd_lookup *match = data; 3908 struct cmd_lookup *match = data;
3618 3909
3619 cmd_complete(cmd->sk, cmd->index, cmd->opcode, match->mgmt_status,
3620 match->hdev->dev_class, 3);
3621
3622 list_del(&cmd->list);
3623
3624 if (match->sk == NULL) { 3910 if (match->sk == NULL) {
3625 match->sk = cmd->sk; 3911 match->sk = cmd->sk;
3626 sock_hold(match->sk); 3912 sock_hold(match->sk);
3627 } 3913 }
3628
3629 mgmt_pending_free(cmd);
3630} 3914}
3631 3915
3632int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, 3916int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
@@ -3635,11 +3919,9 @@ int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
3635 struct cmd_lookup match = { NULL, hdev, mgmt_status(status) }; 3919 struct cmd_lookup match = { NULL, hdev, mgmt_status(status) };
3636 int err = 0; 3920 int err = 0;
3637 3921
3638 clear_bit(HCI_PENDING_CLASS, &hdev->dev_flags); 3922 mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match);
3639 3923 mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match);
3640 mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, class_rsp, &match); 3924 mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match);
3641 mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, class_rsp, &match);
3642 mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, class_rsp, &match);
3643 3925
3644 if (!status) 3926 if (!status)
3645 err = mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, 3927 err = mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class,
@@ -3653,55 +3935,29 @@ int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
3653 3935
3654int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) 3936int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
3655{ 3937{
3656 struct pending_cmd *cmd;
3657 struct mgmt_cp_set_local_name ev; 3938 struct mgmt_cp_set_local_name ev;
3658 bool changed = false; 3939 struct pending_cmd *cmd;
3659 int err = 0;
3660 3940
3661 if (memcmp(name, hdev->dev_name, sizeof(hdev->dev_name)) != 0) { 3941 if (status)
3662 memcpy(hdev->dev_name, name, sizeof(hdev->dev_name)); 3942 return 0;
3663 changed = true;
3664 }
3665 3943
3666 memset(&ev, 0, sizeof(ev)); 3944 memset(&ev, 0, sizeof(ev));
3667 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); 3945 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
3668 memcpy(ev.short_name, hdev->short_name, HCI_MAX_SHORT_NAME_LENGTH); 3946 memcpy(ev.short_name, hdev->short_name, HCI_MAX_SHORT_NAME_LENGTH);
3669 3947
3670 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev); 3948 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev);
3671 if (!cmd) 3949 if (!cmd) {
3672 goto send_event; 3950 memcpy(hdev->dev_name, name, sizeof(hdev->dev_name));
3673
3674 /* Always assume that either the short or the complete name has
3675 * changed if there was a pending mgmt command */
3676 changed = true;
3677 3951
3678 if (status) { 3952 /* If this is a HCI command related to powering on the
3679 err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 3953 * HCI dev don't send any mgmt signals.
3680 mgmt_status(status)); 3954 */
3681 goto failed; 3955 if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
3956 return 0;
3682 } 3957 }
3683 3958
3684 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, &ev, 3959 return mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev),
3685 sizeof(ev)); 3960 cmd ? cmd->sk : NULL);
3686 if (err < 0)
3687 goto failed;
3688
3689send_event:
3690 if (changed)
3691 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev,
3692 sizeof(ev), cmd ? cmd->sk : NULL);
3693
3694 /* EIR is taken care of separately when powering on the
3695 * adapter so only update them here if this is a name change
3696 * unrelated to power on.
3697 */
3698 if (!test_bit(HCI_INIT, &hdev->flags))
3699 update_eir(hdev);
3700
3701failed:
3702 if (cmd)
3703 mgmt_pending_remove(cmd);
3704 return err;
3705} 3961}
3706 3962
3707int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, 3963int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index b23e2713fea8..ca957d34b0c8 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -69,7 +69,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
69 u8 sec_level, 69 u8 sec_level,
70 int *err); 70 int *err);
71static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst); 71static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
72static void rfcomm_session_del(struct rfcomm_session *s); 72static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s);
73 73
74/* ---- RFCOMM frame parsing macros ---- */ 74/* ---- RFCOMM frame parsing macros ---- */
75#define __get_dlci(b) ((b & 0xfc) >> 2) 75#define __get_dlci(b) ((b & 0xfc) >> 2)
@@ -108,12 +108,6 @@ static void rfcomm_schedule(void)
108 wake_up_process(rfcomm_thread); 108 wake_up_process(rfcomm_thread);
109} 109}
110 110
111static void rfcomm_session_put(struct rfcomm_session *s)
112{
113 if (atomic_dec_and_test(&s->refcnt))
114 rfcomm_session_del(s);
115}
116
117/* ---- RFCOMM FCS computation ---- */ 111/* ---- RFCOMM FCS computation ---- */
118 112
119/* reversed, 8-bit, poly=0x07 */ 113/* reversed, 8-bit, poly=0x07 */
@@ -249,16 +243,14 @@ static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout)
249{ 243{
250 BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout); 244 BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout);
251 245
252 if (!mod_timer(&s->timer, jiffies + timeout)) 246 mod_timer(&s->timer, jiffies + timeout);
253 rfcomm_session_hold(s);
254} 247}
255 248
256static void rfcomm_session_clear_timer(struct rfcomm_session *s) 249static void rfcomm_session_clear_timer(struct rfcomm_session *s)
257{ 250{
258 BT_DBG("session %p state %ld", s, s->state); 251 BT_DBG("session %p state %ld", s, s->state);
259 252
260 if (del_timer(&s->timer)) 253 del_timer_sync(&s->timer);
261 rfcomm_session_put(s);
262} 254}
263 255
264/* ---- RFCOMM DLCs ---- */ 256/* ---- RFCOMM DLCs ---- */
@@ -336,8 +328,6 @@ static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
336{ 328{
337 BT_DBG("dlc %p session %p", d, s); 329 BT_DBG("dlc %p session %p", d, s);
338 330
339 rfcomm_session_hold(s);
340
341 rfcomm_session_clear_timer(s); 331 rfcomm_session_clear_timer(s);
342 rfcomm_dlc_hold(d); 332 rfcomm_dlc_hold(d);
343 list_add(&d->list, &s->dlcs); 333 list_add(&d->list, &s->dlcs);
@@ -356,8 +346,6 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
356 346
357 if (list_empty(&s->dlcs)) 347 if (list_empty(&s->dlcs))
358 rfcomm_session_set_timer(s, RFCOMM_IDLE_TIMEOUT); 348 rfcomm_session_set_timer(s, RFCOMM_IDLE_TIMEOUT);
359
360 rfcomm_session_put(s);
361} 349}
362 350
363static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci) 351static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
@@ -493,12 +481,34 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
493 481
494int rfcomm_dlc_close(struct rfcomm_dlc *d, int err) 482int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
495{ 483{
496 int r; 484 int r = 0;
485 struct rfcomm_dlc *d_list;
486 struct rfcomm_session *s, *s_list;
487
488 BT_DBG("dlc %p state %ld dlci %d err %d", d, d->state, d->dlci, err);
497 489
498 rfcomm_lock(); 490 rfcomm_lock();
499 491
500 r = __rfcomm_dlc_close(d, err); 492 s = d->session;
493 if (!s)
494 goto no_session;
495
496 /* after waiting on the mutex check the session still exists
497 * then check the dlc still exists
498 */
499 list_for_each_entry(s_list, &session_list, list) {
500 if (s_list == s) {
501 list_for_each_entry(d_list, &s->dlcs, list) {
502 if (d_list == d) {
503 r = __rfcomm_dlc_close(d, err);
504 break;
505 }
506 }
507 break;
508 }
509 }
501 510
511no_session:
502 rfcomm_unlock(); 512 rfcomm_unlock();
503 return r; 513 return r;
504} 514}
@@ -609,7 +619,7 @@ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
609 return s; 619 return s;
610} 620}
611 621
612static void rfcomm_session_del(struct rfcomm_session *s) 622static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s)
613{ 623{
614 int state = s->state; 624 int state = s->state;
615 625
@@ -617,15 +627,14 @@ static void rfcomm_session_del(struct rfcomm_session *s)
617 627
618 list_del(&s->list); 628 list_del(&s->list);
619 629
620 if (state == BT_CONNECTED)
621 rfcomm_send_disc(s, 0);
622
623 rfcomm_session_clear_timer(s); 630 rfcomm_session_clear_timer(s);
624 sock_release(s->sock); 631 sock_release(s->sock);
625 kfree(s); 632 kfree(s);
626 633
627 if (state != BT_LISTEN) 634 if (state != BT_LISTEN)
628 module_put(THIS_MODULE); 635 module_put(THIS_MODULE);
636
637 return NULL;
629} 638}
630 639
631static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst) 640static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
@@ -644,17 +653,16 @@ static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
644 return NULL; 653 return NULL;
645} 654}
646 655
647static void rfcomm_session_close(struct rfcomm_session *s, int err) 656static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s,
657 int err)
648{ 658{
649 struct rfcomm_dlc *d; 659 struct rfcomm_dlc *d;
650 struct list_head *p, *n; 660 struct list_head *p, *n;
651 661
652 BT_DBG("session %p state %ld err %d", s, s->state, err);
653
654 rfcomm_session_hold(s);
655
656 s->state = BT_CLOSED; 662 s->state = BT_CLOSED;
657 663
664 BT_DBG("session %p state %ld err %d", s, s->state, err);
665
658 /* Close all dlcs */ 666 /* Close all dlcs */
659 list_for_each_safe(p, n, &s->dlcs) { 667 list_for_each_safe(p, n, &s->dlcs) {
660 d = list_entry(p, struct rfcomm_dlc, list); 668 d = list_entry(p, struct rfcomm_dlc, list);
@@ -663,7 +671,7 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err)
663 } 671 }
664 672
665 rfcomm_session_clear_timer(s); 673 rfcomm_session_clear_timer(s);
666 rfcomm_session_put(s); 674 return rfcomm_session_del(s);
667} 675}
668 676
669static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, 677static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
@@ -715,8 +723,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
715 if (*err == 0 || *err == -EINPROGRESS) 723 if (*err == 0 || *err == -EINPROGRESS)
716 return s; 724 return s;
717 725
718 rfcomm_session_del(s); 726 return rfcomm_session_del(s);
719 return NULL;
720 727
721failed: 728failed:
722 sock_release(sock); 729 sock_release(sock);
@@ -1105,7 +1112,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
1105} 1112}
1106 1113
1107/* ---- RFCOMM frame reception ---- */ 1114/* ---- RFCOMM frame reception ---- */
1108static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) 1115static struct rfcomm_session *rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
1109{ 1116{
1110 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); 1117 BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
1111 1118
@@ -1114,7 +1121,7 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
1114 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci); 1121 struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
1115 if (!d) { 1122 if (!d) {
1116 rfcomm_send_dm(s, dlci); 1123 rfcomm_send_dm(s, dlci);
1117 return 0; 1124 return s;
1118 } 1125 }
1119 1126
1120 switch (d->state) { 1127 switch (d->state) {
@@ -1150,25 +1157,14 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
1150 break; 1157 break;
1151 1158
1152 case BT_DISCONN: 1159 case BT_DISCONN:
1153 /* rfcomm_session_put is called later so don't do 1160 s = rfcomm_session_close(s, ECONNRESET);
1154 * anything here otherwise we will mess up the session
1155 * reference counter:
1156 *
1157 * (a) when we are the initiator dlc_unlink will drive
1158 * the reference counter to 0 (there is no initial put
1159 * after session_add)
1160 *
1161 * (b) when we are not the initiator rfcomm_rx_process
1162 * will explicitly call put to balance the initial hold
1163 * done after session add.
1164 */
1165 break; 1161 break;
1166 } 1162 }
1167 } 1163 }
1168 return 0; 1164 return s;
1169} 1165}
1170 1166
1171static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci) 1167static struct rfcomm_session *rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
1172{ 1168{
1173 int err = 0; 1169 int err = 0;
1174 1170
@@ -1192,13 +1188,13 @@ static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
1192 else 1188 else
1193 err = ECONNRESET; 1189 err = ECONNRESET;
1194 1190
1195 s->state = BT_CLOSED; 1191 s = rfcomm_session_close(s, err);
1196 rfcomm_session_close(s, err);
1197 } 1192 }
1198 return 0; 1193 return s;
1199} 1194}
1200 1195
1201static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci) 1196static struct rfcomm_session *rfcomm_recv_disc(struct rfcomm_session *s,
1197 u8 dlci)
1202{ 1198{
1203 int err = 0; 1199 int err = 0;
1204 1200
@@ -1227,11 +1223,9 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
1227 else 1223 else
1228 err = ECONNRESET; 1224 err = ECONNRESET;
1229 1225
1230 s->state = BT_CLOSED; 1226 s = rfcomm_session_close(s, err);
1231 rfcomm_session_close(s, err);
1232 } 1227 }
1233 1228 return s;
1234 return 0;
1235} 1229}
1236 1230
1237void rfcomm_dlc_accept(struct rfcomm_dlc *d) 1231void rfcomm_dlc_accept(struct rfcomm_dlc *d)
@@ -1652,11 +1646,18 @@ drop:
1652 return 0; 1646 return 0;
1653} 1647}
1654 1648
1655static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb) 1649static struct rfcomm_session *rfcomm_recv_frame(struct rfcomm_session *s,
1650 struct sk_buff *skb)
1656{ 1651{
1657 struct rfcomm_hdr *hdr = (void *) skb->data; 1652 struct rfcomm_hdr *hdr = (void *) skb->data;
1658 u8 type, dlci, fcs; 1653 u8 type, dlci, fcs;
1659 1654
1655 if (!s) {
1656 /* no session, so free socket data */
1657 kfree_skb(skb);
1658 return s;
1659 }
1660
1660 dlci = __get_dlci(hdr->addr); 1661 dlci = __get_dlci(hdr->addr);
1661 type = __get_type(hdr->ctrl); 1662 type = __get_type(hdr->ctrl);
1662 1663
@@ -1667,7 +1668,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
1667 if (__check_fcs(skb->data, type, fcs)) { 1668 if (__check_fcs(skb->data, type, fcs)) {
1668 BT_ERR("bad checksum in packet"); 1669 BT_ERR("bad checksum in packet");
1669 kfree_skb(skb); 1670 kfree_skb(skb);
1670 return -EILSEQ; 1671 return s;
1671 } 1672 }
1672 1673
1673 if (__test_ea(hdr->len)) 1674 if (__test_ea(hdr->len))
@@ -1683,22 +1684,23 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
1683 1684
1684 case RFCOMM_DISC: 1685 case RFCOMM_DISC:
1685 if (__test_pf(hdr->ctrl)) 1686 if (__test_pf(hdr->ctrl))
1686 rfcomm_recv_disc(s, dlci); 1687 s = rfcomm_recv_disc(s, dlci);
1687 break; 1688 break;
1688 1689
1689 case RFCOMM_UA: 1690 case RFCOMM_UA:
1690 if (__test_pf(hdr->ctrl)) 1691 if (__test_pf(hdr->ctrl))
1691 rfcomm_recv_ua(s, dlci); 1692 s = rfcomm_recv_ua(s, dlci);
1692 break; 1693 break;
1693 1694
1694 case RFCOMM_DM: 1695 case RFCOMM_DM:
1695 rfcomm_recv_dm(s, dlci); 1696 s = rfcomm_recv_dm(s, dlci);
1696 break; 1697 break;
1697 1698
1698 case RFCOMM_UIH: 1699 case RFCOMM_UIH:
1699 if (dlci) 1700 if (dlci) {
1700 return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb); 1701 rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
1701 1702 return s;
1703 }
1702 rfcomm_recv_mcc(s, skb); 1704 rfcomm_recv_mcc(s, skb);
1703 break; 1705 break;
1704 1706
@@ -1707,7 +1709,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
1707 break; 1709 break;
1708 } 1710 }
1709 kfree_skb(skb); 1711 kfree_skb(skb);
1710 return 0; 1712 return s;
1711} 1713}
1712 1714
1713/* ---- Connection and data processing ---- */ 1715/* ---- Connection and data processing ---- */
@@ -1844,7 +1846,7 @@ static void rfcomm_process_dlcs(struct rfcomm_session *s)
1844 } 1846 }
1845} 1847}
1846 1848
1847static void rfcomm_process_rx(struct rfcomm_session *s) 1849static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s)
1848{ 1850{
1849 struct socket *sock = s->sock; 1851 struct socket *sock = s->sock;
1850 struct sock *sk = sock->sk; 1852 struct sock *sk = sock->sk;
@@ -1856,17 +1858,15 @@ static void rfcomm_process_rx(struct rfcomm_session *s)
1856 while ((skb = skb_dequeue(&sk->sk_receive_queue))) { 1858 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
1857 skb_orphan(skb); 1859 skb_orphan(skb);
1858 if (!skb_linearize(skb)) 1860 if (!skb_linearize(skb))
1859 rfcomm_recv_frame(s, skb); 1861 s = rfcomm_recv_frame(s, skb);
1860 else 1862 else
1861 kfree_skb(skb); 1863 kfree_skb(skb);
1862 } 1864 }
1863 1865
1864 if (sk->sk_state == BT_CLOSED) { 1866 if (s && (sk->sk_state == BT_CLOSED))
1865 if (!s->initiator) 1867 s = rfcomm_session_close(s, sk->sk_err);
1866 rfcomm_session_put(s);
1867 1868
1868 rfcomm_session_close(s, sk->sk_err); 1869 return s;
1869 }
1870} 1870}
1871 1871
1872static void rfcomm_accept_connection(struct rfcomm_session *s) 1872static void rfcomm_accept_connection(struct rfcomm_session *s)
@@ -1891,8 +1891,6 @@ static void rfcomm_accept_connection(struct rfcomm_session *s)
1891 1891
1892 s = rfcomm_session_add(nsock, BT_OPEN); 1892 s = rfcomm_session_add(nsock, BT_OPEN);
1893 if (s) { 1893 if (s) {
1894 rfcomm_session_hold(s);
1895
1896 /* We should adjust MTU on incoming sessions. 1894 /* We should adjust MTU on incoming sessions.
1897 * L2CAP MTU minus UIH header and FCS. */ 1895 * L2CAP MTU minus UIH header and FCS. */
1898 s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu, 1896 s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu,
@@ -1903,7 +1901,7 @@ static void rfcomm_accept_connection(struct rfcomm_session *s)
1903 sock_release(nsock); 1901 sock_release(nsock);
1904} 1902}
1905 1903
1906static void rfcomm_check_connection(struct rfcomm_session *s) 1904static struct rfcomm_session *rfcomm_check_connection(struct rfcomm_session *s)
1907{ 1905{
1908 struct sock *sk = s->sock->sk; 1906 struct sock *sk = s->sock->sk;
1909 1907
@@ -1921,10 +1919,10 @@ static void rfcomm_check_connection(struct rfcomm_session *s)
1921 break; 1919 break;
1922 1920
1923 case BT_CLOSED: 1921 case BT_CLOSED:
1924 s->state = BT_CLOSED; 1922 s = rfcomm_session_close(s, sk->sk_err);
1925 rfcomm_session_close(s, sk->sk_err);
1926 break; 1923 break;
1927 } 1924 }
1925 return s;
1928} 1926}
1929 1927
1930static void rfcomm_process_sessions(void) 1928static void rfcomm_process_sessions(void)
@@ -1940,7 +1938,6 @@ static void rfcomm_process_sessions(void)
1940 if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) { 1938 if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
1941 s->state = BT_DISCONN; 1939 s->state = BT_DISCONN;
1942 rfcomm_send_disc(s, 0); 1940 rfcomm_send_disc(s, 0);
1943 rfcomm_session_put(s);
1944 continue; 1941 continue;
1945 } 1942 }
1946 1943
@@ -1949,21 +1946,18 @@ static void rfcomm_process_sessions(void)
1949 continue; 1946 continue;
1950 } 1947 }
1951 1948
1952 rfcomm_session_hold(s);
1953
1954 switch (s->state) { 1949 switch (s->state) {
1955 case BT_BOUND: 1950 case BT_BOUND:
1956 rfcomm_check_connection(s); 1951 s = rfcomm_check_connection(s);
1957 break; 1952 break;
1958 1953
1959 default: 1954 default:
1960 rfcomm_process_rx(s); 1955 s = rfcomm_process_rx(s);
1961 break; 1956 break;
1962 } 1957 }
1963 1958
1964 rfcomm_process_dlcs(s); 1959 if (s)
1965 1960 rfcomm_process_dlcs(s);
1966 rfcomm_session_put(s);
1967 } 1961 }
1968 1962
1969 rfcomm_unlock(); 1963 rfcomm_unlock();
@@ -2010,10 +2004,11 @@ static int rfcomm_add_listener(bdaddr_t *ba)
2010 2004
2011 /* Add listening session */ 2005 /* Add listening session */
2012 s = rfcomm_session_add(sock, BT_LISTEN); 2006 s = rfcomm_session_add(sock, BT_LISTEN);
2013 if (!s) 2007 if (!s) {
2008 err = -ENOMEM;
2014 goto failed; 2009 goto failed;
2010 }
2015 2011
2016 rfcomm_session_hold(s);
2017 return 0; 2012 return 0;
2018failed: 2013failed:
2019 sock_release(sock); 2014 sock_release(sock);
@@ -2071,8 +2066,6 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
2071 if (!s) 2066 if (!s)
2072 return; 2067 return;
2073 2068
2074 rfcomm_session_hold(s);
2075
2076 list_for_each_safe(p, n, &s->dlcs) { 2069 list_for_each_safe(p, n, &s->dlcs) {
2077 d = list_entry(p, struct rfcomm_dlc, list); 2070 d = list_entry(p, struct rfcomm_dlc, list);
2078 2071
@@ -2104,8 +2097,6 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
2104 set_bit(RFCOMM_AUTH_REJECT, &d->flags); 2097 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
2105 } 2098 }
2106 2099
2107 rfcomm_session_put(s);
2108
2109 rfcomm_schedule(); 2100 rfcomm_schedule();
2110} 2101}
2111 2102
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 7c9224bcce17..a8638b58c4bf 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -1066,8 +1066,7 @@ void __exit rfcomm_cleanup_sockets(void)
1066 1066
1067 debugfs_remove(rfcomm_sock_debugfs); 1067 debugfs_remove(rfcomm_sock_debugfs);
1068 1068
1069 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) 1069 bt_sock_unregister(BTPROTO_RFCOMM);
1070 BT_ERR("RFCOMM socket layer unregistration failed");
1071 1070
1072 proto_unregister(&rfcomm_proto); 1071 proto_unregister(&rfcomm_proto);
1073} 1072}
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index fb6192c9812e..2c8055350510 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -1113,8 +1113,7 @@ void __exit sco_exit(void)
1113 1113
1114 debugfs_remove(sco_debugfs); 1114 debugfs_remove(sco_debugfs);
1115 1115
1116 if (bt_sock_unregister(BTPROTO_SCO) < 0) 1116 bt_sock_unregister(BTPROTO_SCO);
1117 BT_ERR("SCO socket unregistration failed");
1118 1117
1119 proto_unregister(&sco_proto); 1118 proto_unregister(&sco_proto);
1120} 1119}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c34e6d78a592..c50c19402588 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -175,7 +175,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
175 * add it to the device after the station. 175 * add it to the device after the station.
176 */ 176 */
177 if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) { 177 if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
178 ieee80211_key_free(sdata->local, key); 178 ieee80211_key_free_unused(key);
179 err = -ENOENT; 179 err = -ENOENT;
180 goto out_unlock; 180 goto out_unlock;
181 } 181 }
@@ -214,8 +214,6 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
214 } 214 }
215 215
216 err = ieee80211_key_link(key, sdata, sta); 216 err = ieee80211_key_link(key, sdata, sta);
217 if (err)
218 ieee80211_key_free(sdata->local, key);
219 217
220 out_unlock: 218 out_unlock:
221 mutex_unlock(&sdata->local->sta_mtx); 219 mutex_unlock(&sdata->local->sta_mtx);
@@ -254,7 +252,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
254 goto out_unlock; 252 goto out_unlock;
255 } 253 }
256 254
257 __ieee80211_key_free(key, true); 255 ieee80211_key_free(key, true);
258 256
259 ret = 0; 257 ret = 0;
260 out_unlock: 258 out_unlock:
@@ -445,12 +443,14 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
445 struct ieee80211_sub_if_data *sdata = sta->sdata; 443 struct ieee80211_sub_if_data *sdata = sta->sdata;
446 struct ieee80211_local *local = sdata->local; 444 struct ieee80211_local *local = sdata->local;
447 struct timespec uptime; 445 struct timespec uptime;
446 u64 packets = 0;
447 int ac;
448 448
449 sinfo->generation = sdata->local->sta_generation; 449 sinfo->generation = sdata->local->sta_generation;
450 450
451 sinfo->filled = STATION_INFO_INACTIVE_TIME | 451 sinfo->filled = STATION_INFO_INACTIVE_TIME |
452 STATION_INFO_RX_BYTES | 452 STATION_INFO_RX_BYTES64 |
453 STATION_INFO_TX_BYTES | 453 STATION_INFO_TX_BYTES64 |
454 STATION_INFO_RX_PACKETS | 454 STATION_INFO_RX_PACKETS |
455 STATION_INFO_TX_PACKETS | 455 STATION_INFO_TX_PACKETS |
456 STATION_INFO_TX_RETRIES | 456 STATION_INFO_TX_RETRIES |
@@ -467,10 +467,14 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
467 sinfo->connected_time = uptime.tv_sec - sta->last_connected; 467 sinfo->connected_time = uptime.tv_sec - sta->last_connected;
468 468
469 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 469 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
470 sinfo->tx_bytes = 0;
471 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
472 sinfo->tx_bytes += sta->tx_bytes[ac];
473 packets += sta->tx_packets[ac];
474 }
475 sinfo->tx_packets = packets;
470 sinfo->rx_bytes = sta->rx_bytes; 476 sinfo->rx_bytes = sta->rx_bytes;
471 sinfo->tx_bytes = sta->tx_bytes;
472 sinfo->rx_packets = sta->rx_packets; 477 sinfo->rx_packets = sta->rx_packets;
473 sinfo->tx_packets = sta->tx_packets;
474 sinfo->tx_retries = sta->tx_retry_count; 478 sinfo->tx_retries = sta->tx_retry_count;
475 sinfo->tx_failed = sta->tx_retry_failed; 479 sinfo->tx_failed = sta->tx_retry_failed;
476 sinfo->rx_dropped_misc = sta->rx_dropped; 480 sinfo->rx_dropped_misc = sta->rx_dropped;
@@ -598,8 +602,8 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
598 data[i++] += sta->rx_fragments; \ 602 data[i++] += sta->rx_fragments; \
599 data[i++] += sta->rx_dropped; \ 603 data[i++] += sta->rx_dropped; \
600 \ 604 \
601 data[i++] += sta->tx_packets; \ 605 data[i++] += sinfo.tx_packets; \
602 data[i++] += sta->tx_bytes; \ 606 data[i++] += sinfo.tx_bytes; \
603 data[i++] += sta->tx_fragments; \ 607 data[i++] += sta->tx_fragments; \
604 data[i++] += sta->tx_filtered_count; \ 608 data[i++] += sta->tx_filtered_count; \
605 data[i++] += sta->tx_retry_failed; \ 609 data[i++] += sta->tx_retry_failed; \
@@ -621,13 +625,14 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
621 if (!(sta && !WARN_ON(sta->sdata->dev != dev))) 625 if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
622 goto do_survey; 626 goto do_survey;
623 627
628 sinfo.filled = 0;
629 sta_set_sinfo(sta, &sinfo);
630
624 i = 0; 631 i = 0;
625 ADD_STA_STATS(sta); 632 ADD_STA_STATS(sta);
626 633
627 data[i++] = sta->sta_state; 634 data[i++] = sta->sta_state;
628 635
629 sinfo.filled = 0;
630 sta_set_sinfo(sta, &sinfo);
631 636
632 if (sinfo.filled & STATION_INFO_TX_BITRATE) 637 if (sinfo.filled & STATION_INFO_TX_BITRATE)
633 data[i] = 100000 * 638 data[i] = 100000 *
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index c3a3082b72e5..1521cabad3d6 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -295,7 +295,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
295 char buf[50]; 295 char buf[50];
296 struct ieee80211_key *key; 296 struct ieee80211_key *key;
297 297
298 if (!sdata->debugfs.dir) 298 if (!sdata->vif.debugfs_dir)
299 return; 299 return;
300 300
301 lockdep_assert_held(&sdata->local->key_mtx); 301 lockdep_assert_held(&sdata->local->key_mtx);
@@ -311,7 +311,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
311 sprintf(buf, "../keys/%d", key->debugfs.cnt); 311 sprintf(buf, "../keys/%d", key->debugfs.cnt);
312 sdata->debugfs.default_unicast_key = 312 sdata->debugfs.default_unicast_key =
313 debugfs_create_symlink("default_unicast_key", 313 debugfs_create_symlink("default_unicast_key",
314 sdata->debugfs.dir, buf); 314 sdata->vif.debugfs_dir, buf);
315 } 315 }
316 316
317 if (sdata->debugfs.default_multicast_key) { 317 if (sdata->debugfs.default_multicast_key) {
@@ -325,7 +325,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
325 sprintf(buf, "../keys/%d", key->debugfs.cnt); 325 sprintf(buf, "../keys/%d", key->debugfs.cnt);
326 sdata->debugfs.default_multicast_key = 326 sdata->debugfs.default_multicast_key =
327 debugfs_create_symlink("default_multicast_key", 327 debugfs_create_symlink("default_multicast_key",
328 sdata->debugfs.dir, buf); 328 sdata->vif.debugfs_dir, buf);
329 } 329 }
330} 330}
331 331
@@ -334,7 +334,7 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
334 char buf[50]; 334 char buf[50];
335 struct ieee80211_key *key; 335 struct ieee80211_key *key;
336 336
337 if (!sdata->debugfs.dir) 337 if (!sdata->vif.debugfs_dir)
338 return; 338 return;
339 339
340 key = key_mtx_dereference(sdata->local, 340 key = key_mtx_dereference(sdata->local,
@@ -343,7 +343,7 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
343 sprintf(buf, "../keys/%d", key->debugfs.cnt); 343 sprintf(buf, "../keys/%d", key->debugfs.cnt);
344 sdata->debugfs.default_mgmt_key = 344 sdata->debugfs.default_mgmt_key =
345 debugfs_create_symlink("default_mgmt_key", 345 debugfs_create_symlink("default_mgmt_key",
346 sdata->debugfs.dir, buf); 346 sdata->vif.debugfs_dir, buf);
347 } else 347 } else
348 ieee80211_debugfs_key_remove_mgmt_default(sdata); 348 ieee80211_debugfs_key_remove_mgmt_default(sdata);
349} 349}
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 059bbb82e84f..ddb426867904 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -521,7 +521,7 @@ IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration,
521#endif 521#endif
522 522
523#define DEBUGFS_ADD_MODE(name, mode) \ 523#define DEBUGFS_ADD_MODE(name, mode) \
524 debugfs_create_file(#name, mode, sdata->debugfs.dir, \ 524 debugfs_create_file(#name, mode, sdata->vif.debugfs_dir, \
525 sdata, &name##_ops); 525 sdata, &name##_ops);
526 526
527#define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400) 527#define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400)
@@ -577,7 +577,7 @@ static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
577static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) 577static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
578{ 578{
579 struct dentry *dir = debugfs_create_dir("mesh_stats", 579 struct dentry *dir = debugfs_create_dir("mesh_stats",
580 sdata->debugfs.dir); 580 sdata->vif.debugfs_dir);
581#define MESHSTATS_ADD(name)\ 581#define MESHSTATS_ADD(name)\
582 debugfs_create_file(#name, 0400, dir, sdata, &name##_ops); 582 debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);
583 583
@@ -594,7 +594,7 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
594static void add_mesh_config(struct ieee80211_sub_if_data *sdata) 594static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
595{ 595{
596 struct dentry *dir = debugfs_create_dir("mesh_config", 596 struct dentry *dir = debugfs_create_dir("mesh_config",
597 sdata->debugfs.dir); 597 sdata->vif.debugfs_dir);
598 598
599#define MESHPARAMS_ADD(name) \ 599#define MESHPARAMS_ADD(name) \
600 debugfs_create_file(#name, 0600, dir, sdata, &name##_ops); 600 debugfs_create_file(#name, 0600, dir, sdata, &name##_ops);
@@ -631,7 +631,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
631 631
632static void add_files(struct ieee80211_sub_if_data *sdata) 632static void add_files(struct ieee80211_sub_if_data *sdata)
633{ 633{
634 if (!sdata->debugfs.dir) 634 if (!sdata->vif.debugfs_dir)
635 return; 635 return;
636 636
637 DEBUGFS_ADD(flags); 637 DEBUGFS_ADD(flags);
@@ -673,21 +673,21 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
673 char buf[10+IFNAMSIZ]; 673 char buf[10+IFNAMSIZ];
674 674
675 sprintf(buf, "netdev:%s", sdata->name); 675 sprintf(buf, "netdev:%s", sdata->name);
676 sdata->debugfs.dir = debugfs_create_dir(buf, 676 sdata->vif.debugfs_dir = debugfs_create_dir(buf,
677 sdata->local->hw.wiphy->debugfsdir); 677 sdata->local->hw.wiphy->debugfsdir);
678 if (sdata->debugfs.dir) 678 if (sdata->vif.debugfs_dir)
679 sdata->debugfs.subdir_stations = debugfs_create_dir("stations", 679 sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
680 sdata->debugfs.dir); 680 sdata->vif.debugfs_dir);
681 add_files(sdata); 681 add_files(sdata);
682} 682}
683 683
684void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) 684void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
685{ 685{
686 if (!sdata->debugfs.dir) 686 if (!sdata->vif.debugfs_dir)
687 return; 687 return;
688 688
689 debugfs_remove_recursive(sdata->debugfs.dir); 689 debugfs_remove_recursive(sdata->vif.debugfs_dir);
690 sdata->debugfs.dir = NULL; 690 sdata->vif.debugfs_dir = NULL;
691} 691}
692 692
693void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) 693void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
@@ -695,7 +695,7 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
695 struct dentry *dir; 695 struct dentry *dir;
696 char buf[10 + IFNAMSIZ]; 696 char buf[10 + IFNAMSIZ];
697 697
698 dir = sdata->debugfs.dir; 698 dir = sdata->vif.debugfs_dir;
699 699
700 if (!dir) 700 if (!dir)
701 return; 701 return;
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 832acea4a5cb..169664c122e2 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -241,6 +241,22 @@ static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
241 return ret; 241 return ret;
242} 242}
243 243
244static inline void drv_set_multicast_list(struct ieee80211_local *local,
245 struct ieee80211_sub_if_data *sdata,
246 struct netdev_hw_addr_list *mc_list)
247{
248 bool allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI;
249
250 trace_drv_set_multicast_list(local, sdata, mc_list->count);
251
252 check_sdata_in_driver(sdata);
253
254 if (local->ops->set_multicast_list)
255 local->ops->set_multicast_list(&local->hw, &sdata->vif,
256 allmulti, mc_list);
257 trace_drv_return_void(local);
258}
259
244static inline void drv_configure_filter(struct ieee80211_local *local, 260static inline void drv_configure_filter(struct ieee80211_local *local,
245 unsigned int changed_flags, 261 unsigned int changed_flags,
246 unsigned int *total_flags, 262 unsigned int *total_flags,
@@ -531,43 +547,6 @@ static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
531 local->ops->sta_remove_debugfs(&local->hw, &sdata->vif, 547 local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
532 sta, dir); 548 sta, dir);
533} 549}
534
535static inline
536void drv_add_interface_debugfs(struct ieee80211_local *local,
537 struct ieee80211_sub_if_data *sdata)
538{
539 might_sleep();
540
541 check_sdata_in_driver(sdata);
542
543 if (!local->ops->add_interface_debugfs)
544 return;
545
546 local->ops->add_interface_debugfs(&local->hw, &sdata->vif,
547 sdata->debugfs.dir);
548}
549
550static inline
551void drv_remove_interface_debugfs(struct ieee80211_local *local,
552 struct ieee80211_sub_if_data *sdata)
553{
554 might_sleep();
555
556 check_sdata_in_driver(sdata);
557
558 if (!local->ops->remove_interface_debugfs)
559 return;
560
561 local->ops->remove_interface_debugfs(&local->hw, &sdata->vif,
562 sdata->debugfs.dir);
563}
564#else
565static inline
566void drv_add_interface_debugfs(struct ieee80211_local *local,
567 struct ieee80211_sub_if_data *sdata) {}
568static inline
569void drv_remove_interface_debugfs(struct ieee80211_local *local,
570 struct ieee80211_sub_if_data *sdata) {}
571#endif 550#endif
572 551
573static inline __must_check 552static inline __must_check
@@ -741,13 +720,14 @@ static inline void drv_rfkill_poll(struct ieee80211_local *local)
741 local->ops->rfkill_poll(&local->hw); 720 local->ops->rfkill_poll(&local->hw);
742} 721}
743 722
744static inline void drv_flush(struct ieee80211_local *local, bool drop) 723static inline void drv_flush(struct ieee80211_local *local,
724 u32 queues, bool drop)
745{ 725{
746 might_sleep(); 726 might_sleep();
747 727
748 trace_drv_flush(local, drop); 728 trace_drv_flush(local, queues, drop);
749 if (local->ops->flush) 729 if (local->ops->flush)
750 local->ops->flush(&local->hw, drop); 730 local->ops->flush(&local->hw, queues, drop);
751 trace_drv_return_void(local); 731 trace_drv_return_void(local);
752} 732}
753 733
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e140184c28ce..0b09716d22ad 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -759,7 +759,6 @@ struct ieee80211_sub_if_data {
759 759
760#ifdef CONFIG_MAC80211_DEBUGFS 760#ifdef CONFIG_MAC80211_DEBUGFS
761 struct { 761 struct {
762 struct dentry *dir;
763 struct dentry *subdir_stations; 762 struct dentry *subdir_stations;
764 struct dentry *default_unicast_key; 763 struct dentry *default_unicast_key;
765 struct dentry *default_multicast_key; 764 struct dentry *default_multicast_key;
@@ -801,11 +800,6 @@ enum sdata_queue_type {
801enum { 800enum {
802 IEEE80211_RX_MSG = 1, 801 IEEE80211_RX_MSG = 1,
803 IEEE80211_TX_STATUS_MSG = 2, 802 IEEE80211_TX_STATUS_MSG = 2,
804 IEEE80211_EOSP_MSG = 3,
805};
806
807struct skb_eosp_msg_data {
808 u8 sta[ETH_ALEN], iface[ETH_ALEN];
809}; 803};
810 804
811enum queue_stop_reason { 805enum queue_stop_reason {
@@ -816,6 +810,7 @@ enum queue_stop_reason {
816 IEEE80211_QUEUE_STOP_REASON_SUSPEND, 810 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
817 IEEE80211_QUEUE_STOP_REASON_SKB_ADD, 811 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
818 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, 812 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
813 IEEE80211_QUEUE_STOP_REASON_FLUSH,
819}; 814};
820 815
821#ifdef CONFIG_MAC80211_LEDS 816#ifdef CONFIG_MAC80211_LEDS
@@ -1530,8 +1525,10 @@ void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1530 struct ieee80211_hdr *hdr, bool ack); 1525 struct ieee80211_hdr *hdr, bool ack);
1531 1526
1532void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1527void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
1528 unsigned long queues,
1533 enum queue_stop_reason reason); 1529 enum queue_stop_reason reason);
1534void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 1530void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
1531 unsigned long queues,
1535 enum queue_stop_reason reason); 1532 enum queue_stop_reason reason);
1536void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 1533void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
1537 enum queue_stop_reason reason); 1534 enum queue_stop_reason reason);
@@ -1548,6 +1545,8 @@ static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local,
1548{ 1545{
1549 ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); 1546 ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
1550} 1547}
1548void ieee80211_flush_queues(struct ieee80211_local *local,
1549 struct ieee80211_sub_if_data *sdata);
1551 1550
1552void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1551void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1553 u16 transaction, u16 auth_alg, u16 status, 1552 u16 transaction, u16 auth_alg, u16 status,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index a2b5e17036bb..69aaba79a9f7 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -92,7 +92,7 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local)
92 if (local->hw.conf.flags & IEEE80211_CONF_IDLE) 92 if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
93 return 0; 93 return 0;
94 94
95 drv_flush(local, false); 95 ieee80211_flush_queues(local, NULL);
96 96
97 local->hw.conf.flags |= IEEE80211_CONF_IDLE; 97 local->hw.conf.flags |= IEEE80211_CONF_IDLE;
98 return IEEE80211_CONF_CHANGE_IDLE; 98 return IEEE80211_CONF_CHANGE_IDLE;
@@ -560,8 +560,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
560 goto err_del_interface; 560 goto err_del_interface;
561 } 561 }
562 562
563 drv_add_interface_debugfs(local, sdata);
564
565 if (sdata->vif.type == NL80211_IFTYPE_AP) { 563 if (sdata->vif.type == NL80211_IFTYPE_AP) {
566 local->fif_pspoll++; 564 local->fif_pspoll++;
567 local->fif_probe_req++; 565 local->fif_probe_req++;
@@ -849,8 +847,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
849 case NL80211_IFTYPE_AP: 847 case NL80211_IFTYPE_AP:
850 skb_queue_purge(&sdata->skb_queue); 848 skb_queue_purge(&sdata->skb_queue);
851 849
852 drv_remove_interface_debugfs(local, sdata);
853
854 if (going_down) 850 if (going_down)
855 drv_remove_interface(local, sdata); 851 drv_remove_interface(local, sdata);
856 } 852 }
@@ -922,6 +918,17 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
922 atomic_dec(&local->iff_promiscs); 918 atomic_dec(&local->iff_promiscs);
923 sdata->flags ^= IEEE80211_SDATA_PROMISC; 919 sdata->flags ^= IEEE80211_SDATA_PROMISC;
924 } 920 }
921
922 /*
923 * TODO: If somebody needs this on AP interfaces,
924 * it can be enabled easily but multicast
925 * addresses from VLANs need to be synced.
926 */
927 if (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
928 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
929 sdata->vif.type != NL80211_IFTYPE_AP)
930 drv_set_multicast_list(local, sdata, &dev->mc);
931
925 spin_lock_bh(&local->filter_lock); 932 spin_lock_bh(&local->filter_lock);
926 __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); 933 __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
927 spin_unlock_bh(&local->filter_lock); 934 spin_unlock_bh(&local->filter_lock);
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 99e9f6ae6a54..67059b88fea5 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -248,11 +248,11 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
248} 248}
249 249
250 250
251static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, 251static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
252 struct sta_info *sta, 252 struct sta_info *sta,
253 bool pairwise, 253 bool pairwise,
254 struct ieee80211_key *old, 254 struct ieee80211_key *old,
255 struct ieee80211_key *new) 255 struct ieee80211_key *new)
256{ 256{
257 int idx; 257 int idx;
258 bool defunikey, defmultikey, defmgmtkey; 258 bool defunikey, defmultikey, defmgmtkey;
@@ -397,25 +397,21 @@ 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_free_common(struct ieee80211_key *key)
401{
402 if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
403 ieee80211_aes_key_free(key->u.ccmp.tfm);
404 if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
405 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
406 kfree(key);
407}
408
400static void __ieee80211_key_destroy(struct ieee80211_key *key, 409static void __ieee80211_key_destroy(struct ieee80211_key *key,
401 bool delay_tailroom) 410 bool delay_tailroom)
402{ 411{
403 if (!key)
404 return;
405
406 /*
407 * Synchronize so the TX path can no longer be using
408 * this key before we free/remove it.
409 */
410 synchronize_net();
411
412 if (key->local) 412 if (key->local)
413 ieee80211_key_disable_hw_accel(key); 413 ieee80211_key_disable_hw_accel(key);
414 414
415 if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
416 ieee80211_aes_key_free(key->u.ccmp.tfm);
417 if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
418 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
419 if (key->local) { 415 if (key->local) {
420 struct ieee80211_sub_if_data *sdata = key->sdata; 416 struct ieee80211_sub_if_data *sdata = key->sdata;
421 417
@@ -431,7 +427,28 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key,
431 } 427 }
432 } 428 }
433 429
434 kfree(key); 430 ieee80211_key_free_common(key);
431}
432
433static void ieee80211_key_destroy(struct ieee80211_key *key,
434 bool delay_tailroom)
435{
436 if (!key)
437 return;
438
439 /*
440 * Synchronize so the TX path can no longer be using
441 * this key before we free/remove it.
442 */
443 synchronize_net();
444
445 __ieee80211_key_destroy(key, delay_tailroom);
446}
447
448void ieee80211_key_free_unused(struct ieee80211_key *key)
449{
450 WARN_ON(key->sdata || key->local);
451 ieee80211_key_free_common(key);
435} 452}
436 453
437int ieee80211_key_link(struct ieee80211_key *key, 454int ieee80211_key_link(struct ieee80211_key *key,
@@ -462,19 +479,22 @@ int ieee80211_key_link(struct ieee80211_key *key,
462 479
463 increment_tailroom_need_count(sdata); 480 increment_tailroom_need_count(sdata);
464 481
465 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key); 482 ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
466 __ieee80211_key_destroy(old_key, true); 483 ieee80211_key_destroy(old_key, true);
467 484
468 ieee80211_debugfs_key_add(key); 485 ieee80211_debugfs_key_add(key);
469 486
470 ret = ieee80211_key_enable_hw_accel(key); 487 ret = ieee80211_key_enable_hw_accel(key);
471 488
489 if (ret)
490 ieee80211_key_free(key, true);
491
472 mutex_unlock(&sdata->local->key_mtx); 492 mutex_unlock(&sdata->local->key_mtx);
473 493
474 return ret; 494 return ret;
475} 495}
476 496
477void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom) 497void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
478{ 498{
479 if (!key) 499 if (!key)
480 return; 500 return;
@@ -483,18 +503,10 @@ void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
483 * Replace key with nothingness if it was ever used. 503 * Replace key with nothingness if it was ever used.
484 */ 504 */
485 if (key->sdata) 505 if (key->sdata)
486 __ieee80211_key_replace(key->sdata, key->sta, 506 ieee80211_key_replace(key->sdata, key->sta,
487 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, 507 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
488 key, NULL); 508 key, NULL);
489 __ieee80211_key_destroy(key, delay_tailroom); 509 ieee80211_key_destroy(key, delay_tailroom);
490}
491
492void ieee80211_key_free(struct ieee80211_local *local,
493 struct ieee80211_key *key)
494{
495 mutex_lock(&local->key_mtx);
496 __ieee80211_key_free(key, true);
497 mutex_unlock(&local->key_mtx);
498} 510}
499 511
500void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) 512void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
@@ -554,6 +566,7 @@ EXPORT_SYMBOL(ieee80211_iter_keys);
554void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) 566void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
555{ 567{
556 struct ieee80211_key *key, *tmp; 568 struct ieee80211_key *key, *tmp;
569 LIST_HEAD(keys);
557 570
558 cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk); 571 cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk);
559 572
@@ -565,17 +578,65 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
565 578
566 ieee80211_debugfs_key_remove_mgmt_default(sdata); 579 ieee80211_debugfs_key_remove_mgmt_default(sdata);
567 580
568 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) 581 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) {
569 __ieee80211_key_free(key, false); 582 ieee80211_key_replace(key->sdata, key->sta,
583 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
584 key, NULL);
585 list_add_tail(&key->list, &keys);
586 }
570 587
571 ieee80211_debugfs_key_update_default(sdata); 588 ieee80211_debugfs_key_update_default(sdata);
572 589
590 if (!list_empty(&keys)) {
591 synchronize_net();
592 list_for_each_entry_safe(key, tmp, &keys, list)
593 __ieee80211_key_destroy(key, false);
594 }
595
573 WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || 596 WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
574 sdata->crypto_tx_tailroom_pending_dec); 597 sdata->crypto_tx_tailroom_pending_dec);
575 598
576 mutex_unlock(&sdata->local->key_mtx); 599 mutex_unlock(&sdata->local->key_mtx);
577} 600}
578 601
602void ieee80211_free_sta_keys(struct ieee80211_local *local,
603 struct sta_info *sta)
604{
605 struct ieee80211_key *key, *tmp;
606 LIST_HEAD(keys);
607 int i;
608
609 mutex_lock(&local->key_mtx);
610 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
611 key = key_mtx_dereference(local, sta->gtk[i]);
612 if (!key)
613 continue;
614 ieee80211_key_replace(key->sdata, key->sta,
615 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
616 key, NULL);
617 list_add(&key->list, &keys);
618 }
619
620 key = key_mtx_dereference(local, sta->ptk);
621 if (key) {
622 ieee80211_key_replace(key->sdata, key->sta,
623 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
624 key, NULL);
625 list_add(&key->list, &keys);
626 }
627
628 /*
629 * NB: the station code relies on this being
630 * done even if there aren't any keys
631 */
632 synchronize_net();
633
634 list_for_each_entry_safe(key, tmp, &keys, list)
635 __ieee80211_key_destroy(key, true);
636
637 mutex_unlock(&local->key_mtx);
638}
639
579void ieee80211_delayed_tailroom_dec(struct work_struct *wk) 640void ieee80211_delayed_tailroom_dec(struct work_struct *wk)
580{ 641{
581 struct ieee80211_sub_if_data *sdata; 642 struct ieee80211_sub_if_data *sdata;
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 2a682d81cee9..e8de3e6d7804 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -129,19 +129,20 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
129 size_t seq_len, const u8 *seq); 129 size_t seq_len, const u8 *seq);
130/* 130/*
131 * Insert a key into data structures (sdata, sta if necessary) 131 * Insert a key into data structures (sdata, sta if necessary)
132 * to make it used, free old key. 132 * to make it used, free old key. On failure, also free the new key.
133 */ 133 */
134int __must_check ieee80211_key_link(struct ieee80211_key *key, 134int 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, bool delay_tailroom); 137void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom);
138void ieee80211_key_free(struct ieee80211_local *local, 138void ieee80211_key_free_unused(struct ieee80211_key *key);
139 struct ieee80211_key *key);
140void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, 139void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
141 bool uni, bool multi); 140 bool uni, bool multi);
142void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 141void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
143 int idx); 142 int idx);
144void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); 143void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
144void ieee80211_free_sta_keys(struct ieee80211_local *local,
145 struct sta_info *sta);
145void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); 146void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
146 147
147#define key_mtx_dereference(local, ref) \ 148#define key_mtx_dereference(local, ref) \
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 5a53aa5ede80..c6f81ecc36a1 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -100,7 +100,6 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
100 int power; 100 int power;
101 enum nl80211_channel_type channel_type; 101 enum nl80211_channel_type channel_type;
102 u32 offchannel_flag; 102 u32 offchannel_flag;
103 bool scanning = false;
104 103
105 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 104 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
106 if (local->scan_channel) { 105 if (local->scan_channel) {
@@ -147,9 +146,6 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
147 changed |= IEEE80211_CONF_CHANGE_SMPS; 146 changed |= IEEE80211_CONF_CHANGE_SMPS;
148 } 147 }
149 148
150 scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
151 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
152 test_bit(SCAN_HW_SCANNING, &local->scanning);
153 power = chan->max_power; 149 power = chan->max_power;
154 150
155 rcu_read_lock(); 151 rcu_read_lock();
@@ -226,8 +222,6 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
226static void ieee80211_tasklet_handler(unsigned long data) 222static void ieee80211_tasklet_handler(unsigned long data)
227{ 223{
228 struct ieee80211_local *local = (struct ieee80211_local *) data; 224 struct ieee80211_local *local = (struct ieee80211_local *) data;
229 struct sta_info *sta, *tmp;
230 struct skb_eosp_msg_data *eosp_data;
231 struct sk_buff *skb; 225 struct sk_buff *skb;
232 226
233 while ((skb = skb_dequeue(&local->skb_queue)) || 227 while ((skb = skb_dequeue(&local->skb_queue)) ||
@@ -243,18 +237,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
243 skb->pkt_type = 0; 237 skb->pkt_type = 0;
244 ieee80211_tx_status(&local->hw, skb); 238 ieee80211_tx_status(&local->hw, skb);
245 break; 239 break;
246 case IEEE80211_EOSP_MSG:
247 eosp_data = (void *)skb->cb;
248 for_each_sta_info(local, eosp_data->sta, sta, tmp) {
249 /* skip wrong virtual interface */
250 if (memcmp(eosp_data->iface,
251 sta->sdata->vif.addr, ETH_ALEN))
252 continue;
253 clear_sta_flag(sta, WLAN_STA_SP);
254 break;
255 }
256 dev_kfree_skb(skb);
257 break;
258 default: 240 default:
259 WARN(1, "mac80211: Packet is of unknown type %d\n", 241 WARN(1, "mac80211: Packet is of unknown type %d\n",
260 skb->pkt_type); 242 skb->pkt_type);
@@ -295,8 +277,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
295 "Hardware restart was requested\n"); 277 "Hardware restart was requested\n");
296 278
297 /* use this reason, ieee80211_reconfig will unblock it */ 279 /* use this reason, ieee80211_reconfig will unblock it */
298 ieee80211_stop_queues_by_reason(hw, 280 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
299 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 281 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
300 282
301 /* 283 /*
302 * Stop all Rx during the reconfig. We don't want state changes 284 * Stop all Rx during the reconfig. We don't want state changes
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 77b5710db241..123a300cef57 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -699,10 +699,8 @@ out_free:
699static int 699static int
700ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh) 700ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh)
701{ 701{
702 struct ieee80211_sub_if_data *sdata;
703 struct beacon_data *old_bcn; 702 struct beacon_data *old_bcn;
704 int ret; 703 int ret;
705 sdata = container_of(ifmsh, struct ieee80211_sub_if_data, u.mesh);
706 704
707 mutex_lock(&ifmsh->mtx); 705 mutex_lock(&ifmsh->mtx);
708 706
@@ -833,9 +831,8 @@ ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata,
833 struct ieee80211_mgmt *hdr; 831 struct ieee80211_mgmt *hdr;
834 struct ieee802_11_elems elems; 832 struct ieee802_11_elems elems;
835 size_t baselen; 833 size_t baselen;
836 u8 *pos, *end; 834 u8 *pos;
837 835
838 end = ((u8 *) mgmt) + len;
839 pos = mgmt->u.probe_req.variable; 836 pos = mgmt->u.probe_req.variable;
840 baselen = (u8 *) pos - (u8 *) mgmt; 837 baselen = (u8 *) pos - (u8 *) mgmt;
841 if (baselen > len) 838 if (baselen > len)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 167158646593..e06dbbf8cb4c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1009,6 +1009,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
1009 1009
1010 /* XXX: wait for a beacon first? */ 1010 /* XXX: wait for a beacon first? */
1011 ieee80211_wake_queues_by_reason(&sdata->local->hw, 1011 ieee80211_wake_queues_by_reason(&sdata->local->hw,
1012 IEEE80211_MAX_QUEUE_MAP,
1012 IEEE80211_QUEUE_STOP_REASON_CSA); 1013 IEEE80211_QUEUE_STOP_REASON_CSA);
1013 out: 1014 out:
1014 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 1015 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
@@ -1108,6 +1109,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1108 1109
1109 if (sw_elem->mode) 1110 if (sw_elem->mode)
1110 ieee80211_stop_queues_by_reason(&sdata->local->hw, 1111 ieee80211_stop_queues_by_reason(&sdata->local->hw,
1112 IEEE80211_MAX_QUEUE_MAP,
1111 IEEE80211_QUEUE_STOP_REASON_CSA); 1113 IEEE80211_QUEUE_STOP_REASON_CSA);
1112 1114
1113 if (sdata->local->ops->channel_switch) { 1115 if (sdata->local->ops->channel_switch) {
@@ -1375,6 +1377,7 @@ void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
1375 } 1377 }
1376 1378
1377 ieee80211_wake_queues_by_reason(&local->hw, 1379 ieee80211_wake_queues_by_reason(&local->hw,
1380 IEEE80211_MAX_QUEUE_MAP,
1378 IEEE80211_QUEUE_STOP_REASON_PS); 1381 IEEE80211_QUEUE_STOP_REASON_PS);
1379} 1382}
1380 1383
@@ -1436,7 +1439,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
1436 else { 1439 else {
1437 ieee80211_send_nullfunc(local, sdata, 1); 1440 ieee80211_send_nullfunc(local, sdata, 1);
1438 /* Flush to get the tx status of nullfunc frame */ 1441 /* Flush to get the tx status of nullfunc frame */
1439 drv_flush(local, false); 1442 ieee80211_flush_queues(local, sdata);
1440 } 1443 }
1441 } 1444 }
1442 1445
@@ -1767,7 +1770,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1767 1770
1768 /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ 1771 /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */
1769 if (tx) 1772 if (tx)
1770 drv_flush(local, false); 1773 ieee80211_flush_queues(local, sdata);
1771 1774
1772 /* deauthenticate/disassociate now */ 1775 /* deauthenticate/disassociate now */
1773 if (tx || frame_buf) 1776 if (tx || frame_buf)
@@ -1776,7 +1779,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1776 1779
1777 /* flush out frame */ 1780 /* flush out frame */
1778 if (tx) 1781 if (tx)
1779 drv_flush(local, false); 1782 ieee80211_flush_queues(local, sdata);
1780 1783
1781 /* clear bssid only after building the needed mgmt frames */ 1784 /* clear bssid only after building the needed mgmt frames */
1782 memset(ifmgd->bssid, 0, ETH_ALEN); 1785 memset(ifmgd->bssid, 0, ETH_ALEN);
@@ -1948,7 +1951,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1948 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); 1951 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
1949 run_again(ifmgd, ifmgd->probe_timeout); 1952 run_again(ifmgd, ifmgd->probe_timeout);
1950 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 1953 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
1951 drv_flush(sdata->local, false); 1954 ieee80211_flush_queues(sdata->local, sdata);
1952} 1955}
1953 1956
1954static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, 1957static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
@@ -2071,6 +2074,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2071 true, frame_buf); 2074 true, frame_buf);
2072 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 2075 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
2073 ieee80211_wake_queues_by_reason(&sdata->local->hw, 2076 ieee80211_wake_queues_by_reason(&sdata->local->hw,
2077 IEEE80211_MAX_QUEUE_MAP,
2074 IEEE80211_QUEUE_STOP_REASON_CSA); 2078 IEEE80211_QUEUE_STOP_REASON_CSA);
2075 mutex_unlock(&ifmgd->mtx); 2079 mutex_unlock(&ifmgd->mtx);
2076 2080
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 950c95bec13d..cce795871ab1 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -118,9 +118,9 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
118 * Stop queues and transmit all frames queued by the driver 118 * Stop queues and transmit all frames queued by the driver
119 * before sending nullfunc to enable powersave at the AP. 119 * before sending nullfunc to enable powersave at the AP.
120 */ 120 */
121 ieee80211_stop_queues_by_reason(&local->hw, 121 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); 122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL);
123 drv_flush(local, false); 123 ieee80211_flush_queues(local, NULL);
124 124
125 mutex_lock(&local->iflist_mtx); 125 mutex_lock(&local->iflist_mtx);
126 list_for_each_entry(sdata, &local->interfaces, list) { 126 list_for_each_entry(sdata, &local->interfaces, list) {
@@ -181,7 +181,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local)
181 } 181 }
182 mutex_unlock(&local->iflist_mtx); 182 mutex_unlock(&local->iflist_mtx);
183 183
184 ieee80211_wake_queues_by_reason(&local->hw, 184 ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
185 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); 185 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL);
186} 186}
187 187
@@ -382,7 +382,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
382 ieee80211_roc_notify_destroy(roc, !roc->abort); 382 ieee80211_roc_notify_destroy(roc, !roc->abort);
383 383
384 if (started) { 384 if (started) {
385 drv_flush(local, false); 385 ieee80211_flush_queues(local, NULL);
386 386
387 local->tmp_channel = NULL; 387 local->tmp_channel = NULL;
388 ieee80211_hw_config(local, 0); 388 ieee80211_hw_config(local, 0);
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index b471a67f224d..3d16f4e61743 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -30,12 +30,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
30 } 30 }
31 31
32 ieee80211_stop_queues_by_reason(hw, 32 ieee80211_stop_queues_by_reason(hw,
33 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 33 IEEE80211_MAX_QUEUE_MAP,
34 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
34 35
35 /* flush out all packets */ 36 /* flush out all packets */
36 synchronize_net(); 37 synchronize_net();
37 38
38 drv_flush(local, false); 39 ieee80211_flush_queues(local, NULL);
39 40
40 local->quiescing = true; 41 local->quiescing = true;
41 /* make quiescing visible to timers everywhere */ 42 /* make quiescing visible to timers everywhere */
@@ -68,6 +69,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
68 mutex_unlock(&local->sta_mtx); 69 mutex_unlock(&local->sta_mtx);
69 } 70 }
70 ieee80211_wake_queues_by_reason(hw, 71 ieee80211_wake_queues_by_reason(hw,
72 IEEE80211_MAX_QUEUE_MAP,
71 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 73 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
72 return err; 74 return err;
73 } else if (err > 0) { 75 } else if (err > 0) {
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 749552bdcfe1..d2b264d1311d 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -202,14 +202,23 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
202 struct minstrel_rate_stats *mr; 202 struct minstrel_rate_stats *mr;
203 unsigned int nsecs = 0; 203 unsigned int nsecs = 0;
204 unsigned int tp; 204 unsigned int tp;
205 unsigned int prob;
205 206
206 mr = &mi->groups[group].rates[rate]; 207 mr = &mi->groups[group].rates[rate];
208 prob = mr->probability;
207 209
208 if (mr->probability < MINSTREL_FRAC(1, 10)) { 210 if (prob < MINSTREL_FRAC(1, 10)) {
209 mr->cur_tp = 0; 211 mr->cur_tp = 0;
210 return; 212 return;
211 } 213 }
212 214
215 /*
216 * For the throughput calculation, limit the probability value to 90% to
217 * account for collision related packet error rate fluctuation
218 */
219 if (prob > MINSTREL_FRAC(9, 10))
220 prob = MINSTREL_FRAC(9, 10);
221
213 if (group != MINSTREL_CCK_GROUP) 222 if (group != MINSTREL_CCK_GROUP)
214 nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); 223 nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
215 224
@@ -639,15 +648,18 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
639 /* 648 /*
640 * Sampling might add some overhead (RTS, no aggregation) 649 * Sampling might add some overhead (RTS, no aggregation)
641 * to the frame. Hence, don't use sampling for the currently 650 * to the frame. Hence, don't use sampling for the currently
642 * used max TP rate. 651 * used rates.
643 */ 652 */
644 if (sample_idx == mi->max_tp_rate) 653 if (sample_idx == mi->max_tp_rate ||
654 sample_idx == mi->max_tp_rate2 ||
655 sample_idx == mi->max_prob_rate)
645 return -1; 656 return -1;
657
646 /* 658 /*
647 * When not using MRR, do not sample if the probability is already 659 * Do not sample if the probability is already higher than 95%
648 * higher than 95% to avoid wasting airtime 660 * to avoid wasting airtime.
649 */ 661 */
650 if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100))) 662 if (mr->probability > MINSTREL_FRAC(95, 100))
651 return -1; 663 return -1;
652 664
653 /* 665 /*
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 43a45cf00e06..cb34cbbaa20c 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -153,7 +153,6 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
153 u8 *elements; 153 u8 *elements;
154 struct ieee80211_channel *channel; 154 struct ieee80211_channel *channel;
155 size_t baselen; 155 size_t baselen;
156 bool beacon;
157 struct ieee802_11_elems elems; 156 struct ieee802_11_elems elems;
158 157
159 if (skb->len < 24 || 158 if (skb->len < 24 ||
@@ -175,11 +174,9 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
175 174
176 elements = mgmt->u.probe_resp.variable; 175 elements = mgmt->u.probe_resp.variable;
177 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); 176 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
178 beacon = false;
179 } else { 177 } else {
180 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); 178 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
181 elements = mgmt->u.beacon.variable; 179 elements = mgmt->u.beacon.variable;
182 beacon = true;
183 } 180 }
184 181
185 if (baselen > skb->len) 182 if (baselen > skb->len)
@@ -335,7 +332,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
335 ieee80211_offchannel_stop_vifs(local); 332 ieee80211_offchannel_stop_vifs(local);
336 333
337 /* ensure nullfunc is transmitted before leaving operating channel */ 334 /* ensure nullfunc is transmitted before leaving operating channel */
338 drv_flush(local, false); 335 ieee80211_flush_queues(local, NULL);
339 336
340 ieee80211_configure_filter(local); 337 ieee80211_configure_filter(local);
341 338
@@ -671,7 +668,7 @@ static void ieee80211_scan_state_resume(struct ieee80211_local *local,
671 ieee80211_offchannel_stop_vifs(local); 668 ieee80211_offchannel_stop_vifs(local);
672 669
673 if (local->ops->flush) { 670 if (local->ops->flush) {
674 drv_flush(local, false); 671 ieee80211_flush_queues(local, NULL);
675 *next_delay = 0; 672 *next_delay = 0;
676 } else 673 } else
677 *next_delay = HZ / 10; 674 *next_delay = HZ / 10;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 85458a28ffa0..11216bc13b27 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -556,6 +556,15 @@ static inline void __bss_tim_clear(u8 *tim, u16 id)
556 tim[id / 8] &= ~(1 << (id % 8)); 556 tim[id / 8] &= ~(1 << (id % 8));
557} 557}
558 558
559static inline bool __bss_tim_get(u8 *tim, u16 id)
560{
561 /*
562 * This format has been mandated by the IEEE specifications,
563 * so this line may not be changed to use the test_bit() format.
564 */
565 return tim[id / 8] & (1 << (id % 8));
566}
567
559static unsigned long ieee80211_tids_for_ac(int ac) 568static unsigned long ieee80211_tids_for_ac(int ac)
560{ 569{
561 /* If we ever support TIDs > 7, this obviously needs to be adjusted */ 570 /* If we ever support TIDs > 7, this obviously needs to be adjusted */
@@ -636,6 +645,9 @@ void sta_info_recalc_tim(struct sta_info *sta)
636 done: 645 done:
637 spin_lock_bh(&local->tim_lock); 646 spin_lock_bh(&local->tim_lock);
638 647
648 if (indicate_tim == __bss_tim_get(ps->tim, id))
649 goto out_unlock;
650
639 if (indicate_tim) 651 if (indicate_tim)
640 __bss_tim_set(ps->tim, id); 652 __bss_tim_set(ps->tim, id);
641 else 653 else
@@ -647,6 +659,7 @@ void sta_info_recalc_tim(struct sta_info *sta)
647 local->tim_in_locked_section = false; 659 local->tim_in_locked_section = false;
648 } 660 }
649 661
662out_unlock:
650 spin_unlock_bh(&local->tim_lock); 663 spin_unlock_bh(&local->tim_lock);
651} 664}
652 665
@@ -770,8 +783,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
770{ 783{
771 struct ieee80211_local *local; 784 struct ieee80211_local *local;
772 struct ieee80211_sub_if_data *sdata; 785 struct ieee80211_sub_if_data *sdata;
773 int ret, i; 786 int ret;
774 bool have_key = false;
775 787
776 might_sleep(); 788 might_sleep();
777 789
@@ -798,22 +810,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
798 810
799 list_del_rcu(&sta->list); 811 list_del_rcu(&sta->list);
800 812
801 mutex_lock(&local->key_mtx); 813 /* this always calls synchronize_net() */
802 for (i = 0; i < NUM_DEFAULT_KEYS; i++) { 814 ieee80211_free_sta_keys(local, sta);
803 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]),
804 true);
805 have_key = true;
806 }
807 if (sta->ptk) {
808 __ieee80211_key_free(key_mtx_dereference(local, sta->ptk),
809 true);
810 have_key = true;
811 }
812
813 mutex_unlock(&local->key_mtx);
814
815 if (!have_key)
816 synchronize_net();
817 815
818 sta->dead = true; 816 sta->dead = true;
819 817
@@ -1399,30 +1397,16 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
1399} 1397}
1400EXPORT_SYMBOL(ieee80211_sta_block_awake); 1398EXPORT_SYMBOL(ieee80211_sta_block_awake);
1401 1399
1402void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta) 1400void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)
1403{ 1401{
1404 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 1402 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
1405 struct ieee80211_local *local = sta->local; 1403 struct ieee80211_local *local = sta->local;
1406 struct sk_buff *skb;
1407 struct skb_eosp_msg_data *data;
1408 1404
1409 trace_api_eosp(local, pubsta); 1405 trace_api_eosp(local, pubsta);
1410 1406
1411 skb = alloc_skb(0, GFP_ATOMIC); 1407 clear_sta_flag(sta, WLAN_STA_SP);
1412 if (!skb) {
1413 /* too bad ... but race is better than loss */
1414 clear_sta_flag(sta, WLAN_STA_SP);
1415 return;
1416 }
1417
1418 data = (void *)skb->cb;
1419 memcpy(data->sta, pubsta->addr, ETH_ALEN);
1420 memcpy(data->iface, sta->sdata->vif.addr, ETH_ALEN);
1421 skb->pkt_type = IEEE80211_EOSP_MSG;
1422 skb_queue_tail(&local->skb_queue, skb);
1423 tasklet_schedule(&local->tasklet);
1424} 1408}
1425EXPORT_SYMBOL(ieee80211_sta_eosp_irqsafe); 1409EXPORT_SYMBOL(ieee80211_sta_eosp);
1426 1410
1427void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, 1411void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
1428 u8 tid, bool buffered) 1412 u8 tid, bool buffered)
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index e5868c32d1a3..adc30045f99e 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -333,7 +333,8 @@ struct sta_info {
333 unsigned long driver_buffered_tids; 333 unsigned long driver_buffered_tids;
334 334
335 /* Updated from RX path only, no locking requirements */ 335 /* Updated from RX path only, no locking requirements */
336 unsigned long rx_packets, rx_bytes; 336 unsigned long rx_packets;
337 u64 rx_bytes;
337 unsigned long wep_weak_iv_count; 338 unsigned long wep_weak_iv_count;
338 unsigned long last_rx; 339 unsigned long last_rx;
339 long last_connected; 340 long last_connected;
@@ -353,9 +354,9 @@ struct sta_info {
353 unsigned int fail_avg; 354 unsigned int fail_avg;
354 355
355 /* Updated from TX path only, no locking requirements */ 356 /* Updated from TX path only, no locking requirements */
356 unsigned long tx_packets; 357 u32 tx_fragments;
357 unsigned long tx_bytes; 358 u64 tx_packets[IEEE80211_NUM_ACS];
358 unsigned long tx_fragments; 359 u64 tx_bytes[IEEE80211_NUM_ACS];
359 struct ieee80211_tx_rate last_tx_rate; 360 struct ieee80211_tx_rate last_tx_rate;
360 int last_rx_rate_idx; 361 int last_rx_rate_idx;
361 u32 last_rx_rate_flag; 362 u32 last_rx_rate_flag;
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index e7db2b804e0c..c5899797a8d4 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -431,6 +431,30 @@ TRACE_EVENT(drv_prepare_multicast,
431 ) 431 )
432); 432);
433 433
434TRACE_EVENT(drv_set_multicast_list,
435 TP_PROTO(struct ieee80211_local *local,
436 struct ieee80211_sub_if_data *sdata, int mc_count),
437
438 TP_ARGS(local, sdata, mc_count),
439
440 TP_STRUCT__entry(
441 LOCAL_ENTRY
442 __field(bool, allmulti)
443 __field(int, mc_count)
444 ),
445
446 TP_fast_assign(
447 LOCAL_ASSIGN;
448 __entry->allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI;
449 __entry->mc_count = mc_count;
450 ),
451
452 TP_printk(
453 LOCAL_PR_FMT " configure mc filter, count=%d, allmulti=%d",
454 LOCAL_PR_ARG, __entry->mc_count, __entry->allmulti
455 )
456);
457
434TRACE_EVENT(drv_configure_filter, 458TRACE_EVENT(drv_configure_filter,
435 TP_PROTO(struct ieee80211_local *local, 459 TP_PROTO(struct ieee80211_local *local,
436 unsigned int changed_flags, 460 unsigned int changed_flags,
@@ -940,23 +964,26 @@ TRACE_EVENT(drv_get_survey,
940); 964);
941 965
942TRACE_EVENT(drv_flush, 966TRACE_EVENT(drv_flush,
943 TP_PROTO(struct ieee80211_local *local, bool drop), 967 TP_PROTO(struct ieee80211_local *local,
968 u32 queues, bool drop),
944 969
945 TP_ARGS(local, drop), 970 TP_ARGS(local, queues, drop),
946 971
947 TP_STRUCT__entry( 972 TP_STRUCT__entry(
948 LOCAL_ENTRY 973 LOCAL_ENTRY
949 __field(bool, drop) 974 __field(bool, drop)
975 __field(u32, queues)
950 ), 976 ),
951 977
952 TP_fast_assign( 978 TP_fast_assign(
953 LOCAL_ASSIGN; 979 LOCAL_ASSIGN;
954 __entry->drop = drop; 980 __entry->drop = drop;
981 __entry->queues = queues;
955 ), 982 ),
956 983
957 TP_printk( 984 TP_printk(
958 LOCAL_PR_FMT " drop:%d", 985 LOCAL_PR_FMT " queues:0x%x drop:%d",
959 LOCAL_PR_ARG, __entry->drop 986 LOCAL_PR_ARG, __entry->queues, __entry->drop
960 ) 987 )
961); 988);
962 989
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 4e8a86163fc7..9e67cc97b87b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -233,6 +233,7 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
233 233
234 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 234 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
235 ieee80211_stop_queues_by_reason(&local->hw, 235 ieee80211_stop_queues_by_reason(&local->hw,
236 IEEE80211_MAX_QUEUE_MAP,
236 IEEE80211_QUEUE_STOP_REASON_PS); 237 IEEE80211_QUEUE_STOP_REASON_PS);
237 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 238 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
238 ieee80211_queue_work(&local->hw, 239 ieee80211_queue_work(&local->hw,
@@ -991,15 +992,18 @@ static ieee80211_tx_result debug_noinline
991ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) 992ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
992{ 993{
993 struct sk_buff *skb; 994 struct sk_buff *skb;
995 int ac = -1;
994 996
995 if (!tx->sta) 997 if (!tx->sta)
996 return TX_CONTINUE; 998 return TX_CONTINUE;
997 999
998 tx->sta->tx_packets++;
999 skb_queue_walk(&tx->skbs, skb) { 1000 skb_queue_walk(&tx->skbs, skb) {
1001 ac = skb_get_queue_mapping(skb);
1000 tx->sta->tx_fragments++; 1002 tx->sta->tx_fragments++;
1001 tx->sta->tx_bytes += skb->len; 1003 tx->sta->tx_bytes[ac] += skb->len;
1002 } 1004 }
1005 if (ac >= 0)
1006 tx->sta->tx_packets[ac]++;
1003 1007
1004 return TX_CONTINUE; 1008 return TX_CONTINUE;
1005} 1009}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index b7a856e3281b..a7368870c8ee 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -453,7 +453,8 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
453} 453}
454 454
455void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 455void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
456 enum queue_stop_reason reason) 456 unsigned long queues,
457 enum queue_stop_reason reason)
457{ 458{
458 struct ieee80211_local *local = hw_to_local(hw); 459 struct ieee80211_local *local = hw_to_local(hw);
459 unsigned long flags; 460 unsigned long flags;
@@ -461,7 +462,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
461 462
462 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 463 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
463 464
464 for (i = 0; i < hw->queues; i++) 465 for_each_set_bit(i, &queues, hw->queues)
465 __ieee80211_stop_queue(hw, i, reason); 466 __ieee80211_stop_queue(hw, i, reason);
466 467
467 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 468 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
@@ -469,7 +470,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
469 470
470void ieee80211_stop_queues(struct ieee80211_hw *hw) 471void ieee80211_stop_queues(struct ieee80211_hw *hw)
471{ 472{
472 ieee80211_stop_queues_by_reason(hw, 473 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
473 IEEE80211_QUEUE_STOP_REASON_DRIVER); 474 IEEE80211_QUEUE_STOP_REASON_DRIVER);
474} 475}
475EXPORT_SYMBOL(ieee80211_stop_queues); 476EXPORT_SYMBOL(ieee80211_stop_queues);
@@ -491,6 +492,7 @@ int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
491EXPORT_SYMBOL(ieee80211_queue_stopped); 492EXPORT_SYMBOL(ieee80211_queue_stopped);
492 493
493void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 494void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
495 unsigned long queues,
494 enum queue_stop_reason reason) 496 enum queue_stop_reason reason)
495{ 497{
496 struct ieee80211_local *local = hw_to_local(hw); 498 struct ieee80211_local *local = hw_to_local(hw);
@@ -499,7 +501,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
499 501
500 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 502 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
501 503
502 for (i = 0; i < hw->queues; i++) 504 for_each_set_bit(i, &queues, hw->queues)
503 __ieee80211_wake_queue(hw, i, reason); 505 __ieee80211_wake_queue(hw, i, reason);
504 506
505 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 507 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
@@ -507,10 +509,42 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
507 509
508void ieee80211_wake_queues(struct ieee80211_hw *hw) 510void ieee80211_wake_queues(struct ieee80211_hw *hw)
509{ 511{
510 ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER); 512 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
513 IEEE80211_QUEUE_STOP_REASON_DRIVER);
511} 514}
512EXPORT_SYMBOL(ieee80211_wake_queues); 515EXPORT_SYMBOL(ieee80211_wake_queues);
513 516
517void ieee80211_flush_queues(struct ieee80211_local *local,
518 struct ieee80211_sub_if_data *sdata)
519{
520 u32 queues;
521
522 if (!local->ops->flush)
523 return;
524
525 if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) {
526 int ac;
527
528 queues = 0;
529
530 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
531 queues |= BIT(sdata->vif.hw_queue[ac]);
532 if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE)
533 queues |= BIT(sdata->vif.cab_queue);
534 } else {
535 /* all queues */
536 queues = BIT(local->hw.queues) - 1;
537 }
538
539 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
540 IEEE80211_QUEUE_STOP_REASON_FLUSH);
541
542 drv_flush(local, queues, false);
543
544 ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
545 IEEE80211_QUEUE_STOP_REASON_FLUSH);
546}
547
514void ieee80211_iterate_active_interfaces( 548void ieee80211_iterate_active_interfaces(
515 struct ieee80211_hw *hw, u32 iter_flags, 549 struct ieee80211_hw *hw, u32 iter_flags,
516 void (*iterator)(void *data, u8 *mac, 550 void (*iterator)(void *data, u8 *mac,
@@ -1651,8 +1685,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1651 mutex_unlock(&local->sta_mtx); 1685 mutex_unlock(&local->sta_mtx);
1652 } 1686 }
1653 1687
1654 ieee80211_wake_queues_by_reason(hw, 1688 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
1655 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 1689 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
1656 1690
1657 /* 1691 /*
1658 * If this is for hw restart things are still running. 1692 * If this is for hw restart things are still running.
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 00be55530a32..84c9ad7e1dca 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1126,8 +1126,10 @@ static int __init cfg80211_init(void)
1126 goto out_fail_reg; 1126 goto out_fail_reg;
1127 1127
1128 cfg80211_wq = create_singlethread_workqueue("cfg80211"); 1128 cfg80211_wq = create_singlethread_workqueue("cfg80211");
1129 if (!cfg80211_wq) 1129 if (!cfg80211_wq) {
1130 err = -ENOMEM;
1130 goto out_fail_wq; 1131 goto out_fail_wq;
1132 }
1131 1133
1132 return 0; 1134 return 0;
1133 1135
diff --git a/net/wireless/core.h b/net/wireless/core.h
index b5174f65cc9a..124e5e773fbc 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -500,14 +500,12 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
500void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, 500void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
501 enum nl80211_iftype iftype, int num); 501 enum nl80211_iftype iftype, int num);
502 502
503
504void cfg80211_leave(struct cfg80211_registered_device *rdev, 503void cfg80211_leave(struct cfg80211_registered_device *rdev,
505 struct wireless_dev *wdev); 504 struct wireless_dev *wdev);
506 505
507void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, 506void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
508 struct wireless_dev *wdev); 507 struct wireless_dev *wdev);
509 508
510
511#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 509#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
512 510
513#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 511#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index ff6f7ae35586..a9dc5c736df0 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -228,6 +228,7 @@ void cfg80211_conn_work(struct work_struct *work)
228 rtnl_lock(); 228 rtnl_lock();
229 cfg80211_lock_rdev(rdev); 229 cfg80211_lock_rdev(rdev);
230 mutex_lock(&rdev->devlist_mtx); 230 mutex_lock(&rdev->devlist_mtx);
231 mutex_lock(&rdev->sched_scan_mtx);
231 232
232 list_for_each_entry(wdev, &rdev->wdev_list, list) { 233 list_for_each_entry(wdev, &rdev->wdev_list, list) {
233 wdev_lock(wdev); 234 wdev_lock(wdev);
@@ -235,7 +236,7 @@ void cfg80211_conn_work(struct work_struct *work)
235 wdev_unlock(wdev); 236 wdev_unlock(wdev);
236 continue; 237 continue;
237 } 238 }
238 if (wdev->sme_state != CFG80211_SME_CONNECTING) { 239 if (wdev->sme_state != CFG80211_SME_CONNECTING || !wdev->conn) {
239 wdev_unlock(wdev); 240 wdev_unlock(wdev);
240 continue; 241 continue;
241 } 242 }
@@ -252,6 +253,7 @@ void cfg80211_conn_work(struct work_struct *work)
252 wdev_unlock(wdev); 253 wdev_unlock(wdev);
253 } 254 }
254 255
256 mutex_unlock(&rdev->sched_scan_mtx);
255 mutex_unlock(&rdev->devlist_mtx); 257 mutex_unlock(&rdev->devlist_mtx);
256 cfg80211_unlock_rdev(rdev); 258 cfg80211_unlock_rdev(rdev);
257 rtnl_unlock(); 259 rtnl_unlock();