summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2024-10-29 18:50:57 -0700
committerJakub Kicinski <kuba@kernel.org>2024-10-29 18:50:58 -0700
commit71e0ad345163c150ea15434b37036b0678d5f6f4 (patch)
treedd29b61a1aed768be35fba13e55e94e1acea7cd0
parentef0ed88af8007f7afa7a6f6bbf2fc4b8b032eeb1 (diff)
parenteaed5fc0c322d75cfcdbc7a16c0c5023d9e4f6fe (diff)
Merge tag 'wireless-next-2024-10-25' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next
Kalle Valo says: ==================== wireless-next patches for v6.13 The first -next "new features" pull request for v6.13. This is a big one as we have not been able to send one earlier. We have also some patches affecting other subsystems: in staging we deleted the rtl8192e driver and in debugfs added a new interface to save struct file_operations memory; both were acked by GregKH. Because of the lib80211/libipw move there were quite a lot of conflicts and to solve those we decided to merge net-next into wireless-next. Major changes: cfg80211/mac80211 * stop exporting wext symbols * new mac80211 op to indicate that a new interface is to be added * support radio separation of multi-band devices Wireless Extensions * move wext spy implementation to libiw * remove iw_public_data from struct net_device brcmfmac * optional LPO clock support ipw2x00 * move remaining lib80211 code into libiw wilc1000 * WILC3000 support rtw89 * RTL8852BE and RTL8852BE-VT BT-coexistence improvements * tag 'wireless-next-2024-10-25' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (126 commits) mac80211: Remove NOP call to ieee80211_hw_config wifi: iwlwifi: work around -Wenum-compare-conditional warning wifi: mac80211: re-order assigning channel in activate links wifi: mac80211: convert debugfs files to short fops debugfs: add small file operations for most files wifi: mac80211: remove misleading j_0 construction parts wifi: mac80211_hwsim: use hrtimer_active() wifi: mac80211: refactor BW limitation check for CSA parsing wifi: mac80211: filter on monitor interfaces based on configured channel wifi: mac80211: refactor ieee80211_rx_monitor wifi: mac80211: add support for the monitor SKIP_TX flag wifi: cfg80211: add monitor SKIP_TX flag wifi: mac80211: add flag to opt out of virtual monitor support wifi: cfg80211: pass net_device to .set_monitor_channel wifi: mac80211: remove status->ampdu_delimiter_crc wifi: cfg80211: report per wiphy radio antenna mask wifi: mac80211: use vif radio mask to limit creating chanctx wifi: mac80211: use vif radio mask to limit ibss scan frequencies wifi: cfg80211: add option for vif allowed radios wifi: iwlwifi: allow IWL_FW_CHECK() with just a string ... ==================== Link: https://patch.msgid.link/20241025170705.5F6B2C4CEC3@smtp.kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml9
-rw-r--r--Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml6
-rw-r--r--Documentation/networking/net_cachelines/net_device.rst1
-rw-r--r--drivers/net/ethernet/toshiba/ps3_gelic_wireless.c1
-rw-r--r--drivers/net/ethernet/toshiba/ps3_gelic_wireless.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c5
-rw-r--r--drivers/net/wireless/ath/ath11k/mac.c5
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c1
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c4
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c7
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h1
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c26
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h9
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c55
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c22
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c5
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h1
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h2
-rw-r--r--drivers/net/wireless/intel/ipw2x00/Kconfig11
-rw-r--r--drivers/net/wireless/intel/ipw2x00/Makefile7
-rw-r--r--drivers/net/wireless/intel/ipw2x00/ipw2100.c9
-rw-r--r--drivers/net/wireless/intel/ipw2x00/ipw2100.h2
-rw-r--r--drivers/net/wireless/intel/ipw2x00/ipw2200.c25
-rw-r--r--drivers/net/wireless/intel/ipw2x00/ipw2200.h4
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw.h114
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_crypto.c246
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c (renamed from net/wireless/lib80211_crypt_ccmp.c)76
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c (renamed from net/wireless/lib80211_crypt_tkip.c)106
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c (renamed from net/wireless/lib80211_crypt_wep.c)73
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_module.c36
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_rx.c11
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_spy.c (renamed from net/wireless/wext-spy.c)63
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_tx.c4
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_wx.c43
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/bz.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/sc.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h32
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.h9
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dump.c22
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/constants.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/d3.c34
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/link.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c13
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c45
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c75
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h17
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c13
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c8
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx.c4
-rw-r--r--drivers/net/wireless/intersil/p54/p54spi.c4
-rw-r--r--drivers/net/wireless/marvell/libertas/Kconfig1
-rw-r--r--drivers/net/wireless/marvell/libertas/cfg.c1
-rw-r--r--drivers/net/wireless/marvell/libertas/mesh.h1
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cmdevt.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/fw.h2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/ioctl.h2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/join.c11
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.c4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.h4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sta_event.c6
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sta_ioctl.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/tdls.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/util.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/main.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/main.c5
-rw-r--r--drivers/net/wireless/microchip/wilc1000/cfg80211.c113
-rw-r--r--drivers/net/wireless/microchip/wilc1000/cfg80211.h2
-rw-r--r--drivers/net/wireless/microchip/wilc1000/netdev.c37
-rw-r--r--drivers/net/wireless/microchip/wilc1000/sdio.c99
-rw-r--r--drivers/net/wireless/microchip/wilc1000/spi.c8
-rw-r--r--drivers/net/wireless/microchip/wilc1000/wlan.c444
-rw-r--r--drivers/net/wireless/microchip/wilc1000/wlan.h53
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/commands.c2
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/core.h1
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800lib.c2
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/core.c6
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c18
-rw-r--r--drivers/net/wireless/realtek/rtw88/fw.c2
-rw-r--r--drivers/net/wireless/realtek/rtw88/mac.c4
-rw-r--r--drivers/net/wireless/realtek/rtw88/mac80211.c6
-rw-r--r--drivers/net/wireless/realtek/rtw88/main.h13
-rw-r--r--drivers/net/wireless/realtek/rtw88/pci.c2
-rw-r--r--drivers/net/wireless/realtek/rtw88/phy.c2
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8703b.c62
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8723d.c49
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821c.c65
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8822b.c53
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8822c.c54
-rw-r--r--drivers/net/wireless/realtek/rtw88/rx.c70
-rw-r--r--drivers/net/wireless/realtek/rtw88/rx.h64
-rw-r--r--drivers/net/wireless/realtek/rtw88/sdio.c9
-rw-r--r--drivers/net/wireless/realtek/rtw88/usb.c9
-rw-r--r--drivers/net/wireless/realtek/rtw89/cam.c259
-rw-r--r--drivers/net/wireless/realtek/rtw89/cam.h24
-rw-r--r--drivers/net/wireless/realtek/rtw89/chan.c215
-rw-r--r--drivers/net/wireless/realtek/rtw89/chan.h15
-rw-r--r--drivers/net/wireless/realtek/rtw89/coex.c383
-rw-r--r--drivers/net/wireless/realtek/rtw89/coex.h6
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.c927
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.h450
-rw-r--r--drivers/net/wireless/realtek/rtw89/debug.c134
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.c706
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.h261
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.c721
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.h115
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac80211.c660
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac_be.c71
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.c68
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.h24
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci_be.c77
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.c668
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.h13
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy_be.c12
-rw-r--r--drivers/net/wireless/realtek/rtw89/ps.c109
-rw-r--r--drivers/net/wireless/realtek/rtw89/ps.h14
-rw-r--r--drivers/net/wireless/realtek/rtw89/regd.c79
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8851b.c13
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a.c12
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b.c13
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852bt.c13
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c.c12
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922a.c33
-rw-r--r--drivers/net/wireless/realtek/rtw89/ser.c37
-rw-r--r--drivers/net/wireless/realtek/rtw89/wow.c217
-rw-r--r--drivers/net/wireless/realtek/rtw89/wow.h10
-rw-r--r--drivers/net/wireless/st/cw1200/queue.c27
-rw-r--r--drivers/net/wireless/st/cw1200/queue.h1
-rw-r--r--drivers/net/wireless/ti/wl1251/sdio.c4
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c5
-rw-r--r--drivers/net/wireless/ti/wlcore/sdio.c13
-rw-r--r--drivers/net/wireless/virtual/mac80211_hwsim.c12
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/rtl8192e/Kconfig61
-rw-r--r--drivers/staging/rtl8192e/Makefile19
-rw-r--r--drivers/staging/rtl8192e/TODO18
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/Kconfig10
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/Makefile19
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8190P_def.h266
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c198
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.h17
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c79
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h12
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c1915
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h34
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c189
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h52
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h244
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c1110
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h55
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h773
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_cam.c123
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_cam.h25
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_core.c2016
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_core.h402
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_dm.c1856
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_dm.h155
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c84
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.h12
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_ethtool.c37
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_pci.c79
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_pci.h20
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_pm.c89
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_pm.h16
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_ps.c230
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_ps.h31
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_wx.c867
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_wx.h13
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/table.c543
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/table.h27
-rw-r--r--drivers/staging/rtl8192e/rtl819x_BA.h60
-rw-r--r--drivers/staging/rtl8192e/rtl819x_BAProc.c544
-rw-r--r--drivers/staging/rtl8192e/rtl819x_HT.h223
-rw-r--r--drivers/staging/rtl8192e/rtl819x_HTProc.c699
-rw-r--r--drivers/staging/rtl8192e/rtl819x_Qos.h43
-rw-r--r--drivers/staging/rtl8192e/rtl819x_TS.h50
-rw-r--r--drivers/staging/rtl8192e/rtl819x_TSProc.c450
-rw-r--r--drivers/staging/rtl8192e/rtllib.h1799
-rw-r--r--drivers/staging/rtl8192e/rtllib_crypt_ccmp.c411
-rw-r--r--drivers/staging/rtl8192e/rtllib_crypt_tkip.c706
-rw-r--r--drivers/staging/rtl8192e/rtllib_crypt_wep.c242
-rw-r--r--drivers/staging/rtl8192e/rtllib_module.c179
-rw-r--r--drivers/staging/rtl8192e/rtllib_rx.c2564
-rw-r--r--drivers/staging/rtl8192e/rtllib_softmac.c2309
-rw-r--r--drivers/staging/rtl8192e/rtllib_softmac_wx.c534
-rw-r--r--drivers/staging/rtl8192e/rtllib_tx.c901
-rw-r--r--drivers/staging/rtl8192e/rtllib_wx.c752
-rw-r--r--drivers/staging/rtl8712/TODO1
-rw-r--r--drivers/staging/rtl8723bs/TODO1
-rw-r--r--drivers/staging/vt6655/TODO1
-rw-r--r--drivers/staging/vt6656/TODO1
-rw-r--r--fs/debugfs/file.c100
-rw-r--r--fs/debugfs/inode.c63
-rw-r--r--fs/debugfs/internal.h6
-rw-r--r--include/linux/debugfs.h62
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--include/linux/wireless.h5
-rw-r--r--include/net/cfg80211.h23
-rw-r--r--include/net/iw_handler.h41
-rw-r--r--include/net/lib80211.h122
-rw-r--r--include/net/mac80211.h78
-rw-r--r--include/uapi/linux/nl80211.h10
-rw-r--r--net/mac80211/agg-tx.c2
-rw-r--r--net/mac80211/cfg.c174
-rw-r--r--net/mac80211/chan.c65
-rw-r--r--net/mac80211/debugfs.c28
-rw-r--r--net/mac80211/debugfs_key.c9
-rw-r--r--net/mac80211/debugfs_netdev.c3
-rw-r--r--net/mac80211/debugfs_sta.c9
-rw-r--r--net/mac80211/driver-ops.c16
-rw-r--r--net/mac80211/driver-ops.h18
-rw-r--r--net/mac80211/eht.c21
-rw-r--r--net/mac80211/ibss.c7
-rw-r--r--net/mac80211/ieee80211_i.h16
-rw-r--r--net/mac80211/iface.c52
-rw-r--r--net/mac80211/link.c54
-rw-r--r--net/mac80211/mesh.c2
-rw-r--r--net/mac80211/mesh_hwmp.c6
-rw-r--r--net/mac80211/mesh_pathtbl.c10
-rw-r--r--net/mac80211/mesh_plink.c7
-rw-r--r--net/mac80211/mesh_sync.c2
-rw-r--r--net/mac80211/mlme.c118
-rw-r--r--net/mac80211/ocb.c4
-rw-r--r--net/mac80211/rate.c35
-rw-r--r--net/mac80211/rate.h10
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c2
-rw-r--r--net/mac80211/rx.c75
-rw-r--r--net/mac80211/scan.c22
-rw-r--r--net/mac80211/spectmgmt.c9
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/status.c5
-rw-r--r--net/mac80211/tdls.c3
-rw-r--r--net/mac80211/tkip.c2
-rw-r--r--net/mac80211/trace.h34
-rw-r--r--net/mac80211/tx.c8
-rw-r--r--net/mac80211/util.c20
-rw-r--r--net/mac80211/vht.c29
-rw-r--r--net/mac80211/wpa.c3
-rw-r--r--net/wireless/Kconfig45
-rw-r--r--net/wireless/Makefile5
-rw-r--r--net/wireless/chan.c5
-rw-r--r--net/wireless/core.c66
-rw-r--r--net/wireless/core.h1
-rw-r--r--net/wireless/lib80211.c257
-rw-r--r--net/wireless/nl80211.c104
-rw-r--r--net/wireless/radiotap.c2
-rw-r--r--net/wireless/rdev-ops.h5
-rw-r--r--net/wireless/reg.c2
-rw-r--r--net/wireless/scan.c12
-rw-r--r--net/wireless/trace.h10
-rw-r--r--net/wireless/util.c31
-rw-r--r--net/wireless/wext-compat.c13
-rw-r--r--net/wireless/wext-compat.h6
-rw-r--r--net/wireless/wext-core.c2
261 files changed, 6916 insertions, 28251 deletions
diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml
index e564f20d8f41..a3607d55ef36 100644
--- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml
+++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml
@@ -53,6 +53,7 @@ properties:
- pci14e4,4488 # BCM4377
- pci14e4,4425 # BCM4378
- pci14e4,4433 # BCM4387
+ - pci14e4,449d # BCM43752
reg:
description: SDIO function number for the device (for most cases
@@ -121,6 +122,14 @@ properties:
NVRAM. This would normally be filled in by the bootloader from platform
configuration data.
+ clocks:
+ items:
+ - description: External Low Power Clock input (32.768KHz)
+
+ clock-names:
+ items:
+ - const: lpo
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml
index 2460ccc08237..5d40f22765bb 100644
--- a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml
+++ b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml
@@ -16,7 +16,11 @@ description:
properties:
compatible:
- const: microchip,wilc1000
+ oneOf:
+ - items:
+ - const: microchip,wilc3000
+ - const: microchip,wilc1000
+ - const: microchip,wilc1000
reg: true
diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst
index db6192b2bb50..ade50d4e67cf 100644
--- a/Documentation/networking/net_cachelines/net_device.rst
+++ b/Documentation/networking/net_cachelines/net_device.rst
@@ -52,7 +52,6 @@ struct net_device_core_stats* core_stats
atomic_t carrier_up_count
atomic_t carrier_down_count
struct iw_handler_def* wireless_handlers
-struct iw_public_data* wireless_data
struct ethtool_ops* ethtool_ops
struct l3mdev_ops* l3mdev_ops
struct ndisc_ops* ndisc_ops
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
index 44488c153ea2..4fbe4b7cd12a 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
@@ -2566,7 +2566,6 @@ static void gelic_wl_setup_netdev_ops(struct net_device *netdev)
netdev->ethtool_ops = &gelic_wl_ethtool_ops;
netdev->netdev_ops = &gelic_wl_netdevice_ops;
- netdev->wireless_data = &wl->wireless_data;
netdev->wireless_handlers = &gelic_wl_wext_handler_def;
}
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h
index 1f203d1ae8db..dbabf538e10a 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h
@@ -276,7 +276,6 @@ struct gelic_wl_info {
u8 active_bssid[ETH_ALEN]; /* associated bssid */
unsigned int essid_len;
- struct iw_public_data wireless_data;
struct iw_statistics iwstat;
};
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 646e1737d4c4..41ab83c3d3f7 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -8507,9 +8507,10 @@ exit:
static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
+ struct ieee80211_link_sta *link_sta,
u32 changed)
{
+ struct ieee80211_sta *sta = link_sta->sta;
struct ath10k *ar = hw->priv;
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
struct ath10k_vif *arvif = (void *)vif->drv_priv;
@@ -9450,7 +9451,7 @@ static const struct ieee80211_ops ath10k_ops = {
.reconfig_complete = ath10k_reconfig_complete,
.get_survey = ath10k_get_survey,
.set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
- .sta_rc_update = ath10k_sta_rc_update,
+ .link_sta_rc_update = ath10k_sta_rc_update,
.offset_tsf = ath10k_offset_tsf,
.ampdu_action = ath10k_ampdu_action,
.get_et_sset_count = ath10k_debug_get_et_sset_count,
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index f8068d2e848c..e6acbff06749 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5079,9 +5079,10 @@ static void ath11k_mac_op_sta_set_4addr(struct ieee80211_hw *hw,
static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
+ struct ieee80211_link_sta *link_sta,
u32 changed)
{
+ struct ieee80211_sta *sta = link_sta->sta;
struct ath11k *ar = hw->priv;
struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
@@ -9708,7 +9709,7 @@ static const struct ieee80211_ops ath11k_ops = {
.sta_state = ath11k_mac_op_sta_state,
.sta_set_4addr = ath11k_mac_op_sta_set_4addr,
.sta_set_txpwr = ath11k_mac_op_sta_set_txpwr,
- .sta_rc_update = ath11k_mac_op_sta_rc_update,
+ .link_sta_rc_update = ath11k_mac_op_sta_rc_update,
.conf_tx = ath11k_mac_op_conf_tx,
.set_antenna = ath11k_mac_op_set_antenna,
.get_antenna = ath11k_mac_op_get_antenna,
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 137394c36460..acf5628adda5 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -4737,9 +4737,10 @@ out:
static void ath12k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
+ struct ieee80211_link_sta *link_sta,
u32 changed)
{
+ struct ieee80211_sta *sta = link_sta->sta;
struct ath12k *ar;
struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta);
struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
@@ -8681,7 +8682,7 @@ static const struct ieee80211_ops ath12k_ops = {
.set_rekey_data = ath12k_mac_op_set_rekey_data,
.sta_state = ath12k_mac_op_sta_state,
.sta_set_txpwr = ath12k_mac_op_sta_set_txpwr,
- .sta_rc_update = ath12k_mac_op_sta_rc_update,
+ .link_sta_rc_update = ath12k_mac_op_sta_rc_update,
.conf_tx = ath12k_mac_op_conf_tx,
.set_antenna = ath12k_mac_op_set_antenna,
.get_antenna = ath12k_mac_op_get_antenna,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 8a03bcc2789e..57094bd45d98 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1357,8 +1357,10 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, u32 changed)
+ struct ieee80211_link_sta *link_sta,
+ u32 changed)
{
+ struct ieee80211_sta *sta = link_sta->sta;
struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
@@ -1883,7 +1885,7 @@ struct ieee80211_ops ath9k_htc_ops = {
.sta_add = ath9k_htc_sta_add,
.sta_remove = ath9k_htc_sta_remove,
.conf_tx = ath9k_htc_conf_tx,
- .sta_rc_update = ath9k_htc_sta_rc_update,
+ .link_sta_rc_update = ath9k_htc_sta_rc_update,
.bss_info_changed = ath9k_htc_bss_info_changed,
.set_key = ath9k_htc_set_key,
.get_tsf = ath9k_htc_get_tsf,
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index e8f1d30a8d73..a1a0a9223e74 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1493,6 +1493,7 @@ out:
}
static int wil_cfg80211_set_channel(struct wiphy *wiphy,
+ struct net_device *dev,
struct cfg80211_chan_def *chandef)
{
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index d35262335eaf..17f6b33beabd 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -947,8 +947,8 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
/* try to attach to the target device */
sdiodev->bus = brcmf_sdio_probe(sdiodev);
- if (!sdiodev->bus) {
- ret = -ENODEV;
+ if (IS_ERR(sdiodev->bus)) {
+ ret = PTR_ERR(sdiodev->bus);
goto out;
}
brcmf_sdiod_host_fixup(sdiodev->func2->card->host);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 349aa3439502..297a7c738c01 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -7820,13 +7820,6 @@ s32 brcmf_cfg80211_down(struct net_device *ndev)
return err;
}
-enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
-{
- struct wireless_dev *wdev = &ifp->vif->wdev;
-
- return wdev->iftype;
-}
-
bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
unsigned long state)
{
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index dc3a6a537507..2abae8894614 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -443,7 +443,6 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
s32 brcmf_cfg80211_up(struct net_device *ndev);
s32 brcmf_cfg80211_down(struct net_device *ndev);
struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings);
-enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
enum nl80211_iftype type);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index b24faae35873..58d50918dd17 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -561,7 +561,8 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
if (!found) {
/* No platform data for this device, try OF and DMI data */
brcmf_dmi_probe(settings, chip, chiprev);
- brcmf_of_probe(dev, bus_type, settings);
+ if (brcmf_of_probe(dev, bus_type, settings) == -EPROBE_DEFER)
+ return ERR_PTR(-EPROBE_DEFER);
brcmf_acpi_probe(dev, bus_type, settings);
}
return settings;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
index fe4f65756105..ae98e371dbfd 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -6,6 +6,7 @@
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_net.h>
+#include <linux/clk.h>
#include <defs.h>
#include "debug.h"
@@ -65,12 +66,13 @@ static int brcmf_of_get_country_codes(struct device *dev,
return 0;
}
-void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
- struct brcmf_mp_device *settings)
+int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
+ struct brcmf_mp_device *settings)
{
struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
struct device_node *root, *np = dev->of_node;
struct of_phandle_args oirq;
+ struct clk *clk;
const char *prop;
int irq;
int err;
@@ -106,7 +108,7 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);
if (!board_type) {
of_node_put(root);
- return;
+ return 0;
}
strreplace(board_type, '/', '-');
settings->board_type = board_type;
@@ -114,8 +116,14 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
of_node_put(root);
}
+ clk = devm_clk_get_optional_enabled_with_rate(dev, "lpo", 32768);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ brcmf_dbg(INFO, "%s LPO clock\n", clk ? "enable" : "no");
+
if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
- return;
+ return 0;
err = brcmf_of_get_country_codes(dev, settings);
if (err)
@@ -124,23 +132,25 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
of_get_mac_address(np, settings->mac);
if (bus_type != BRCMF_BUSTYPE_SDIO)
- return;
+ return 0;
if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
sdio->drive_strength = val;
/* make sure there are interrupts defined in the node */
if (of_irq_parse_one(np, 0, &oirq))
- return;
+ return 0;
irq = irq_create_of_mapping(&oirq);
if (!irq) {
brcmf_err("interrupt could not be mapped\n");
- return;
+ return 0;
}
- irqf = irqd_get_trigger_type(irq_get_irq_data(irq));
+ irqf = irq_get_trigger_type(irq);
sdio->oob_irq_supported = true;
sdio->oob_irq_nr = irq;
sdio->oob_irq_flags = irqf;
+
+ return 0;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
index 10bf52253337..ae124c73fc3b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
@@ -3,11 +3,12 @@
* Copyright (c) 2014 Broadcom Corporation
*/
#ifdef CONFIG_OF
-void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
- struct brcmf_mp_device *settings);
+int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
+ struct brcmf_mp_device *settings);
#else
-static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
- struct brcmf_mp_device *settings)
+static int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
+ struct brcmf_mp_device *settings)
{
+ return 0;
}
#endif /* CONFIG_OF */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 5dee54819fbd..e4395b1f8c11 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -66,6 +66,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie");
BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie");
BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
+BRCMF_FW_CLM_DEF(43752, "brcmfmac43752-pcie");
BRCMF_FW_CLM_DEF(4377B3, "brcmfmac4377b3-pcie");
BRCMF_FW_CLM_DEF(4378B1, "brcmfmac4378b1-pcie");
BRCMF_FW_CLM_DEF(4378B3, "brcmfmac4378b3-pcie");
@@ -104,6 +105,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
+ BRCMF_FW_ENTRY(BRCM_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752),
BRCMF_FW_ENTRY(BRCM_CC_4377_CHIP_ID, 0xFFFFFFFF, 4377B3), /* revision ID 4 */
BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0x0000000F, 4378B1), /* revision ID 3 */
BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFE0, 4378B3), /* revision ID 5 */
@@ -353,6 +355,7 @@ struct brcmf_pciedev_info {
u16 value);
struct brcmf_mp_device *settings;
struct brcmf_otp_params otp;
+ bool fwseed;
#ifdef DEBUG
u32 console_interval;
bool console_active;
@@ -1715,14 +1718,14 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
memcpy_toio(devinfo->tcm + address, nvram, nvram_len);
brcmf_fw_nvram_free(nvram);
- if (devinfo->otp.valid) {
+ if (devinfo->fwseed) {
size_t rand_len = BRCMF_RANDOM_SEED_LENGTH;
struct brcmf_random_seed_footer footer = {
.length = cpu_to_le32(rand_len),
.magic = cpu_to_le32(BRCMF_RANDOM_SEED_MAGIC),
};
- /* Some Apple chips/firmwares expect a buffer of random
+ /* Some chips/firmwares expect a buffer of random
* data to be present before NVRAM
*/
brcmf_dbg(PCIE, "Download random seed\n");
@@ -2394,6 +2397,37 @@ static void brcmf_pcie_debugfs_create(struct device *dev)
}
#endif
+struct brcmf_pcie_drvdata {
+ enum brcmf_fwvendor vendor;
+ bool fw_seed;
+};
+
+enum {
+ BRCMF_DRVDATA_CYW,
+ BRCMF_DRVDATA_BCA,
+ BRCMF_DRVDATA_WCC,
+ BRCMF_DRVDATA_WCC_SEED,
+};
+
+static const struct brcmf_pcie_drvdata drvdata[] = {
+ [BRCMF_DRVDATA_CYW] = {
+ .vendor = BRCMF_FWVENDOR_CYW,
+ .fw_seed = false,
+ },
+ [BRCMF_DRVDATA_BCA] = {
+ .vendor = BRCMF_FWVENDOR_BCA,
+ .fw_seed = false,
+ },
+ [BRCMF_DRVDATA_WCC] = {
+ .vendor = BRCMF_FWVENDOR_WCC,
+ .fw_seed = false,
+ },
+ [BRCMF_DRVDATA_WCC_SEED] = {
+ .vendor = BRCMF_FWVENDOR_WCC,
+ .fw_seed = true,
+ },
+};
+
/* Forward declaration for pci_match_id() call */
static const struct pci_device_id brcmf_pcie_devid_table[];
@@ -2452,6 +2486,9 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ret = -ENOMEM;
goto fail;
}
+ ret = PTR_ERR_OR_ZERO(devinfo->settings);
+ if (ret < 0)
+ goto fail;
bus = kzalloc(sizeof(*bus), GFP_KERNEL);
if (!bus) {
@@ -2472,9 +2509,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
bus->bus_priv.pcie = pcie_bus_dev;
bus->ops = &brcmf_pcie_bus_ops;
bus->proto_type = BRCMF_PROTO_MSGBUF;
- bus->fwvid = id->driver_data;
bus->chip = devinfo->coreid;
bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot);
+ bus->fwvid = drvdata[id->driver_data].vendor;
+ devinfo->fwseed = drvdata[id->driver_data].fw_seed;
dev_set_drvdata(&pdev->dev, bus);
ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings);
@@ -2660,14 +2698,14 @@ static const struct dev_pm_ops brcmf_pciedrvr_pm = {
BRCM_PCIE_VENDOR_ID_BROADCOM, (dev_id), \
PCI_ANY_ID, PCI_ANY_ID, \
PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, \
- BRCMF_FWVENDOR_ ## fw_vend \
+ BRCMF_DRVDATA_ ## fw_vend \
}
#define BRCMF_PCIE_DEVICE_SUB(dev_id, subvend, subdev, fw_vend) \
{ \
BRCM_PCIE_VENDOR_ID_BROADCOM, (dev_id), \
(subvend), (subdev), \
PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, \
- BRCMF_FWVENDOR_ ## fw_vend \
+ BRCMF_DRVDATA_ ## fw_vend \
}
static const struct pci_device_id brcmf_pcie_devid_table[] = {
@@ -2695,9 +2733,10 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID, BCA),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID, WCC),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43596_DEVICE_ID, CYW),
- BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC),
- BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC),
- BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC_SEED),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC_SEED),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC_SEED),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43752_DEVICE_ID, WCC_SEED),
{ /* end: all zeroes */ }
};
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 7b936668c1b6..b1727f35217b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3943,7 +3943,7 @@ static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
.write32 = brcmf_sdio_buscore_write32,
};
-static bool
+static int
brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
{
struct brcmf_sdio_dev *sdiodev;
@@ -3953,6 +3953,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
u32 reg_val;
u32 drivestrength;
u32 enum_base;
+ int ret = -EBADE;
sdiodev = bus->sdiodev;
sdio_claim_host(sdiodev->func1);
@@ -4001,8 +4002,9 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
BRCMF_BUSTYPE_SDIO,
bus->ci->chip,
bus->ci->chiprev);
- if (!sdiodev->settings) {
+ if (IS_ERR_OR_NULL(sdiodev->settings)) {
brcmf_err("Failed to get device parameters\n");
+ ret = PTR_ERR_OR_ZERO(sdiodev->settings);
goto fail;
}
/* platform specific configuration:
@@ -4071,7 +4073,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
/* allocate header buffer */
bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL);
if (!bus->hdrbuf)
- return false;
+ return -ENOMEM;
/* Locate an appropriately-aligned portion of hdrbuf */
bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
bus->head_align);
@@ -4082,11 +4084,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
if (bus->poll)
bus->pollrate = 1;
- return true;
+ return 0;
fail:
sdio_release_host(sdiodev->func1);
- return false;
+ return ret;
}
static int
@@ -4451,8 +4453,10 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
/* Allocate private bus interface state */
bus = kzalloc(sizeof(*bus), GFP_ATOMIC);
- if (!bus)
+ if (!bus) {
+ ret = -ENOMEM;
goto fail;
+ }
bus->sdiodev = sdiodev;
sdiodev->bus = bus;
@@ -4467,6 +4471,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
dev_name(&sdiodev->func1->dev));
if (!wq) {
brcmf_err("insufficient memory to create txworkqueue\n");
+ ret = -ENOMEM;
goto fail;
}
brcmf_sdiod_freezer_count(sdiodev);
@@ -4474,7 +4479,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
bus->brcmf_wq = wq;
/* attempt to attach to the dongle */
- if (!(brcmf_sdio_probe_attach(bus))) {
+ ret = brcmf_sdio_probe_attach(bus);
+ if (ret < 0) {
brcmf_err("brcmf_sdio_probe_attach failed\n");
goto fail;
}
@@ -4546,7 +4552,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
fail:
brcmf_sdio_remove(bus);
- return NULL;
+ return ERR_PTR(ret);
}
/* Detach and free everything */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 8afbf529c745..2821c27f317e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -1272,6 +1272,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,
ret = -ENOMEM;
goto fail;
}
+ ret = PTR_ERR_OR_ZERO(devinfo->settings);
+ if (ret < 0)
+ goto fail;
if (!brcmf_usb_dlneeded(devinfo)) {
ret = brcmf_alloc(devinfo->dev, devinfo->settings);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c
index 6d776ef6ff54..81df41c7fbb5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c
@@ -56,11 +56,6 @@ void brcms_debugfs_detach(struct brcms_pub *drvr)
debugfs_remove_recursive(drvr->dbgfs_dir);
}
-struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr)
-{
- return drvr->dbgfs_dir;
-}
-
static
int brcms_debugfs_hardware_read(struct seq_file *s, void *data)
{
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h
index 56898e6d789d..d30a9fa30f1b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h
@@ -70,7 +70,6 @@ void brcms_debugfs_init(void);
void brcms_debugfs_exit(void);
void brcms_debugfs_attach(struct brcms_pub *drvr);
void brcms_debugfs_detach(struct brcms_pub *drvr);
-struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr);
void brcms_debugfs_create_files(struct brcms_pub *drvr);
#endif /* _BRCMS_DEBUG_H_ */
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index 44684bf1b9ac..c1e22c589d85 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -52,6 +52,7 @@
#define BRCM_CC_43664_CHIP_ID 43664
#define BRCM_CC_43666_CHIP_ID 43666
#define BRCM_CC_4371_CHIP_ID 0x4371
+#define BRCM_CC_43752_CHIP_ID 43752
#define BRCM_CC_4377_CHIP_ID 0x4377
#define BRCM_CC_4378_CHIP_ID 0x4378
#define BRCM_CC_4387_CHIP_ID 0x4387
@@ -94,6 +95,7 @@
#define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5
#define BRCM_PCIE_4371_DEVICE_ID 0x440d
#define BRCM_PCIE_43596_DEVICE_ID 0x4415
+#define BRCM_PCIE_43752_DEVICE_ID 0x449d
#define BRCM_PCIE_4377_DEVICE_ID 0x4488
#define BRCM_PCIE_4378_DEVICE_ID 0x4425
#define BRCM_PCIE_4387_DEVICE_ID 0x4433
diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig
index 1650d5865aa0..b92df91adb3a 100644
--- a/drivers/net/wireless/intel/ipw2x00/Kconfig
+++ b/drivers/net/wireless/intel/ipw2x00/Kconfig
@@ -7,10 +7,8 @@ config IPW2100
tristate "Intel PRO/Wireless 2100 Network Connection"
depends on PCI && CFG80211
select WIRELESS_EXT
- select WEXT_SPY
select WEXT_PRIV
select FW_LOADER
- select LIB80211
select LIBIPW
help
A driver for the Intel PRO/Wireless 2100 Network
@@ -67,12 +65,9 @@ config IPW2100_DEBUG
config IPW2200
tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
depends on PCI && CFG80211
- select CFG80211_WEXT_EXPORT
select WIRELESS_EXT
- select WEXT_SPY
select WEXT_PRIV
select FW_LOADER
- select LIB80211
select LIBIPW
help
A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
@@ -158,14 +153,10 @@ config LIBIPW
tristate
depends on PCI && CFG80211
select WIRELESS_EXT
- select WEXT_SPY
select CRYPTO
select CRYPTO_MICHAEL_MIC
+ select CRYPTO_LIB_ARC4
select CRC32
- select LIB80211
- select LIB80211_CRYPT_WEP
- select LIB80211_CRYPT_TKIP
- select LIB80211_CRYPT_CCMP
help
This option enables the hardware independent IEEE 802.11
networking stack. This component is deprecated in favor of the
diff --git a/drivers/net/wireless/intel/ipw2x00/Makefile b/drivers/net/wireless/intel/ipw2x00/Makefile
index e1ec50359dff..91e6091c4ebf 100644
--- a/drivers/net/wireless/intel/ipw2x00/Makefile
+++ b/drivers/net/wireless/intel/ipw2x00/Makefile
@@ -12,4 +12,9 @@ libipw-objs := \
libipw_tx.o \
libipw_rx.o \
libipw_wx.o \
- libipw_geo.o
+ libipw_geo.o \
+ libipw_spy.o \
+ libipw_crypto.o \
+ libipw_crypto_ccmp.o \
+ libipw_crypto_tkip.o \
+ libipw_crypto_wep.o
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
index b6636002c7d2..15bf35f2de2a 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
@@ -148,9 +148,6 @@ that only one external action is invoked at a time.
#include <linux/acpi.h>
#include <linux/ctype.h>
#include <linux/pm_qos.h>
-
-#include <net/lib80211.h>
-
#include "ipw2100.h"
#include "ipw.h"
@@ -6025,8 +6022,6 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
dev->netdev_ops = &ipw2100_netdev_ops;
dev->ethtool_ops = &ipw2100_ethtool_ops;
dev->wireless_handlers = &ipw2100_wx_handler_def;
- priv->wireless_data.libipw = priv->ieee;
- dev->wireless_data = &priv->wireless_data;
dev->watchdog_timeo = 3 * HZ;
dev->irq = 0;
dev->min_mtu = 68;
@@ -7571,7 +7566,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
struct ipw2100_priv *priv = libipw_priv(dev);
struct libipw_device *ieee = priv->ieee;
struct iw_param *param = &wrqu->param;
- struct lib80211_crypt_data *crypt;
+ struct libipw_crypt_data *crypt;
unsigned long flags;
int ret = 0;
@@ -7663,7 +7658,7 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
{
struct ipw2100_priv *priv = libipw_priv(dev);
struct libipw_device *ieee = priv->ieee;
- struct lib80211_crypt_data *crypt;
+ struct libipw_crypt_data *crypt;
struct iw_param *param = &wrqu->param;
switch (param->flags & IW_AUTH_INDEX) {
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.h b/drivers/net/wireless/intel/ipw2x00/ipw2100.h
index b34085ade3aa..6f81f509b9cb 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.h
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.h
@@ -554,8 +554,6 @@ struct ipw2100_priv {
struct net_device *net_dev;
struct iw_statistics wstats;
- struct iw_public_data wireless_data;
-
struct tasklet_struct irq_tasklet;
struct delayed_work reset_work;
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index eed9ef17bc29..be1d971b3d32 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -6463,6 +6463,14 @@ static int ipw_set_rsn_capa(struct ipw_priv *priv,
* WE-18 support
*/
+static int ipw_wx_get_name(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ strcpy(wrqu->name, "IEEE 802.11");
+ return 0;
+}
+
/* SIOCSIWGENIE */
static int ipw_wx_set_genie(struct net_device *dev,
struct iw_request_info *info,
@@ -6549,7 +6557,7 @@ static int ipw_wx_set_auth(struct net_device *dev,
struct ipw_priv *priv = libipw_priv(dev);
struct libipw_device *ieee = priv->ieee;
struct iw_param *param = &wrqu->param;
- struct lib80211_crypt_data *crypt;
+ struct libipw_crypt_data *crypt;
unsigned long flags;
int ret = 0;
@@ -6648,7 +6656,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
{
struct ipw_priv *priv = libipw_priv(dev);
struct libipw_device *ieee = priv->ieee;
- struct lib80211_crypt_data *crypt;
+ struct libipw_crypt_data *crypt;
struct iw_param *param = &wrqu->param;
switch (param->flags & IW_AUTH_INDEX) {
@@ -9826,7 +9834,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
/* Rebase the WE IOCTLs to zero for the handler array */
static iw_handler ipw_wx_handlers[] = {
- IW_HANDLER(SIOCGIWNAME, cfg80211_wext_giwname),
+ IW_HANDLER(SIOCGIWNAME, ipw_wx_get_name),
IW_HANDLER(SIOCSIWFREQ, ipw_wx_set_freq),
IW_HANDLER(SIOCGIWFREQ, ipw_wx_get_freq),
IW_HANDLER(SIOCSIWMODE, ipw_wx_set_mode),
@@ -9856,10 +9864,10 @@ static iw_handler ipw_wx_handlers[] = {
IW_HANDLER(SIOCGIWENCODE, ipw_wx_get_encode),
IW_HANDLER(SIOCSIWPOWER, ipw_wx_set_power),
IW_HANDLER(SIOCGIWPOWER, ipw_wx_get_power),
- IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
- IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
- IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
- IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
+ IW_HANDLER(SIOCSIWSPY, ipw_wx_set_spy),
+ IW_HANDLER(SIOCGIWSPY, ipw_wx_get_spy),
+ IW_HANDLER(SIOCSIWTHRSPY, ipw_wx_set_thrspy),
+ IW_HANDLER(SIOCGIWTHRSPY, ipw_wx_get_thrspy),
IW_HANDLER(SIOCSIWGENIE, ipw_wx_set_genie),
IW_HANDLER(SIOCGIWGENIE, ipw_wx_get_genie),
IW_HANDLER(SIOCSIWMLME, ipw_wx_set_mlme),
@@ -11636,8 +11644,7 @@ static int ipw_pci_probe(struct pci_dev *pdev,
priv->ieee->worst_rssi = -85;
net_dev->netdev_ops = &ipw_netdev_ops;
- priv->wireless_data.spy_data = &priv->ieee->spy_data;
- net_dev->wireless_data = &priv->wireless_data;
+ priv->ieee->spy_enabled = true;
net_dev->wireless_handlers = &ipw_wx_handler_def;
net_dev->ethtool_ops = &ipw_ethtool_ops;
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.h b/drivers/net/wireless/intel/ipw2x00/ipw2200.h
index 8ebf09121e17..d3db54e6d37c 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.h
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.h
@@ -31,8 +31,6 @@
#include <linux/wireless.h>
#include <linux/jiffies.h>
#include <asm/io.h>
-
-#include <net/lib80211.h>
#include <net/ieee80211_radiotap.h>
#define DRV_NAME "ipw2200"
@@ -1276,8 +1274,6 @@ struct ipw_priv {
struct iw_statistics wstats;
- struct iw_public_data wireless_data;
-
int user_requested_scan;
u8 direct_scan_ssid[IW_ESSID_MAX_SIZE];
u8 direct_scan_ssid_len;
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw.h b/drivers/net/wireless/intel/ipw2x00/libipw.h
index bad080d33c07..3c20353e5a41 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw.h
+++ b/drivers/net/wireless/intel/ipw2x00/libipw.h
@@ -25,8 +25,6 @@
#include <linux/kernel.h> /* ARRAY_SIZE */
#include <linux/wireless.h>
#include <linux/ieee80211.h>
-
-#include <net/lib80211.h>
#include <net/cfg80211.h>
#define LIBIPW_VERSION "git-1.1.13"
@@ -699,6 +697,76 @@ struct libipw_geo {
struct libipw_channel a[LIBIPW_52GHZ_CHANNELS];
};
+#define NUM_WEP_KEYS 4
+
+enum {
+ IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
+};
+
+struct module;
+
+struct libipw_crypto_ops {
+ const char *name;
+ struct list_head list;
+
+ /* init new crypto context (e.g., allocate private data space,
+ * select IV, etc.); returns NULL on failure or pointer to allocated
+ * private data on success */
+ void *(*init) (int keyidx);
+
+ /* deinitialize crypto context and free allocated private data */
+ void (*deinit) (void *priv);
+
+ /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
+ * value from decrypt_mpdu is passed as the keyidx value for
+ * decrypt_msdu. skb must have enough head and tail room for the
+ * encryption; if not, error will be returned; these functions are
+ * called for all MPDUs (i.e., fragments).
+ */
+ int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
+ int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
+
+ /* These functions are called for full MSDUs, i.e. full frames.
+ * These can be NULL if full MSDU operations are not needed. */
+ int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
+ int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
+ void *priv);
+
+ int (*set_key) (void *key, int len, u8 * seq, void *priv);
+ int (*get_key) (void *key, int len, u8 * seq, void *priv);
+
+ /* procfs handler for printing out key information and possible
+ * statistics */
+ void (*print_stats) (struct seq_file *m, void *priv);
+
+ /* Crypto specific flag get/set for configuration settings */
+ unsigned long (*get_flags) (void *priv);
+ unsigned long (*set_flags) (unsigned long flags, void *priv);
+
+ /* maximum number of bytes added by encryption; encrypt buf is
+ * allocated with extra_prefix_len bytes, copy of in_buf, and
+ * extra_postfix_len; encrypt need not use all this space, but
+ * the result must start at the beginning of the buffer and correct
+ * length must be returned */
+ int extra_mpdu_prefix_len, extra_mpdu_postfix_len;
+ int extra_msdu_prefix_len, extra_msdu_postfix_len;
+
+ struct module *owner;
+};
+
+struct libipw_crypt_info {
+ char *name;
+ /* Most clients will already have a lock,
+ so just point to that. */
+ spinlock_t *lock;
+
+ struct libipw_crypt_data *crypt[NUM_WEP_KEYS];
+ int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+ struct list_head crypt_deinit_list;
+ struct timer_list crypt_deinit_timer;
+ int crypt_quiesced;
+};
+
struct libipw_device {
struct net_device *dev;
struct wireless_dev wdev;
@@ -720,6 +788,7 @@ struct libipw_device {
int iw_mode; /* operating mode (IW_MODE_*) */
struct iw_spy_data spy_data; /* iwspy support */
+ bool spy_enabled;
spinlock_t lock;
@@ -751,7 +820,7 @@ struct libipw_device {
size_t wpa_ie_len;
u8 *wpa_ie;
- struct lib80211_crypt_info crypt_info;
+ struct libipw_crypt_info crypt_info;
int bcrx_sta_key; /* use individual keys to override default keys even
* with RX of broad/multicast frames */
@@ -988,4 +1057,43 @@ static inline int libipw_get_scans(struct libipw_device *ieee)
return ieee->scans;
}
+struct libipw_crypt_data {
+ struct list_head list; /* delayed deletion list */
+ const struct libipw_crypto_ops *ops;
+ void *priv;
+ atomic_t refcnt;
+};
+
+int libipw_crypt_info_init(struct libipw_crypt_info *info, char *name,
+ spinlock_t *lock);
+void libipw_crypt_info_free(struct libipw_crypt_info *info);
+int libipw_register_crypto_ops(const struct libipw_crypto_ops *ops);
+int libipw_unregister_crypto_ops(const struct libipw_crypto_ops *ops);
+const struct libipw_crypto_ops *libipw_get_crypto_ops(const char *name);
+void libipw_crypt_delayed_deinit(struct libipw_crypt_info *info,
+ struct libipw_crypt_data **crypt);
+
+/* must be called in the listed order */
+int libipw_crypto_init(void);
+int libipw_crypto_ccmp_init(void);
+int libipw_crypto_tkip_init(void);
+int libipw_crypto_wep_init(void);
+
+void libipw_crypto_wep_exit(void);
+void libipw_crypto_tkip_exit(void);
+void libipw_crypto_ccmp_exit(void);
+void libipw_crypto_exit(void);
+
+
+int ipw_wx_set_spy(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+int ipw_wx_get_spy(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+int ipw_wx_set_thrspy(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+int ipw_wx_get_thrspy(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+void libipw_spy_update(struct net_device *dev, unsigned char *address,
+ struct iw_quality *wstats);
+
#endif /* LIBIPW_H */
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c
new file mode 100644
index 000000000000..32639e0e8430
--- /dev/null
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * libipw -- common bits for IPW drivers
+ *
+ * Copyright(c) 2008 John W. Linville <linville@tuxdriver.com>
+ *
+ * Portions copied from old ieee80211 component, w/ original copyright
+ * notices below:
+ *
+ * Host AP crypto routines
+ *
+ * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
+ * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/ieee80211.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include "libipw.h"
+
+struct libipw_crypto_alg {
+ struct list_head list;
+ const struct libipw_crypto_ops *ops;
+};
+
+static LIST_HEAD(libipw_crypto_algs);
+static DEFINE_SPINLOCK(libipw_crypto_lock);
+
+static void libipw_crypt_deinit_entries(struct libipw_crypt_info *info,
+ int force);
+static void libipw_crypt_quiescing(struct libipw_crypt_info *info);
+static void libipw_crypt_deinit_handler(struct timer_list *t);
+
+int libipw_crypt_info_init(struct libipw_crypt_info *info, char *name,
+ spinlock_t *lock)
+{
+ memset(info, 0, sizeof(*info));
+
+ info->name = name;
+ info->lock = lock;
+
+ INIT_LIST_HEAD(&info->crypt_deinit_list);
+ timer_setup(&info->crypt_deinit_timer, libipw_crypt_deinit_handler,
+ 0);
+
+ return 0;
+}
+EXPORT_SYMBOL(libipw_crypt_info_init);
+
+void libipw_crypt_info_free(struct libipw_crypt_info *info)
+{
+ int i;
+
+ libipw_crypt_quiescing(info);
+ del_timer_sync(&info->crypt_deinit_timer);
+ libipw_crypt_deinit_entries(info, 1);
+
+ for (i = 0; i < NUM_WEP_KEYS; i++) {
+ struct libipw_crypt_data *crypt = info->crypt[i];
+ if (crypt) {
+ if (crypt->ops) {
+ crypt->ops->deinit(crypt->priv);
+ module_put(crypt->ops->owner);
+ }
+ kfree(crypt);
+ info->crypt[i] = NULL;
+ }
+ }
+}
+EXPORT_SYMBOL(libipw_crypt_info_free);
+
+static void libipw_crypt_deinit_entries(struct libipw_crypt_info *info,
+ int force)
+{
+ struct libipw_crypt_data *entry, *next;
+ unsigned long flags;
+
+ spin_lock_irqsave(info->lock, flags);
+ list_for_each_entry_safe(entry, next, &info->crypt_deinit_list, list) {
+ if (atomic_read(&entry->refcnt) != 0 && !force)
+ continue;
+
+ list_del(&entry->list);
+
+ if (entry->ops) {
+ entry->ops->deinit(entry->priv);
+ module_put(entry->ops->owner);
+ }
+ kfree(entry);
+ }
+ spin_unlock_irqrestore(info->lock, flags);
+}
+
+/* After this, crypt_deinit_list won't accept new members */
+static void libipw_crypt_quiescing(struct libipw_crypt_info *info)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(info->lock, flags);
+ info->crypt_quiesced = 1;
+ spin_unlock_irqrestore(info->lock, flags);
+}
+
+static void libipw_crypt_deinit_handler(struct timer_list *t)
+{
+ struct libipw_crypt_info *info = from_timer(info, t,
+ crypt_deinit_timer);
+ unsigned long flags;
+
+ libipw_crypt_deinit_entries(info, 0);
+
+ spin_lock_irqsave(info->lock, flags);
+ if (!list_empty(&info->crypt_deinit_list) && !info->crypt_quiesced) {
+ printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
+ "deletion list\n", info->name);
+ info->crypt_deinit_timer.expires = jiffies + HZ;
+ add_timer(&info->crypt_deinit_timer);
+ }
+ spin_unlock_irqrestore(info->lock, flags);
+}
+
+void libipw_crypt_delayed_deinit(struct libipw_crypt_info *info,
+ struct libipw_crypt_data **crypt)
+{
+ struct libipw_crypt_data *tmp;
+ unsigned long flags;
+
+ if (*crypt == NULL)
+ return;
+
+ tmp = *crypt;
+ *crypt = NULL;
+
+ /* must not run ops->deinit() while there may be pending encrypt or
+ * decrypt operations. Use a list of delayed deinits to avoid needing
+ * locking. */
+
+ spin_lock_irqsave(info->lock, flags);
+ if (!info->crypt_quiesced) {
+ list_add(&tmp->list, &info->crypt_deinit_list);
+ if (!timer_pending(&info->crypt_deinit_timer)) {
+ info->crypt_deinit_timer.expires = jiffies + HZ;
+ add_timer(&info->crypt_deinit_timer);
+ }
+ }
+ spin_unlock_irqrestore(info->lock, flags);
+}
+EXPORT_SYMBOL(libipw_crypt_delayed_deinit);
+
+int libipw_register_crypto_ops(const struct libipw_crypto_ops *ops)
+{
+ unsigned long flags;
+ struct libipw_crypto_alg *alg;
+
+ alg = kzalloc(sizeof(*alg), GFP_KERNEL);
+ if (alg == NULL)
+ return -ENOMEM;
+
+ alg->ops = ops;
+
+ spin_lock_irqsave(&libipw_crypto_lock, flags);
+ list_add(&alg->list, &libipw_crypto_algs);
+ spin_unlock_irqrestore(&libipw_crypto_lock, flags);
+
+ printk(KERN_DEBUG "libipw_crypt: registered algorithm '%s'\n",
+ ops->name);
+
+ return 0;
+}
+EXPORT_SYMBOL(libipw_register_crypto_ops);
+
+int libipw_unregister_crypto_ops(const struct libipw_crypto_ops *ops)
+{
+ struct libipw_crypto_alg *alg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&libipw_crypto_lock, flags);
+ list_for_each_entry(alg, &libipw_crypto_algs, list) {
+ if (alg->ops == ops)
+ goto found;
+ }
+ spin_unlock_irqrestore(&libipw_crypto_lock, flags);
+ return -EINVAL;
+
+ found:
+ printk(KERN_DEBUG "libipw_crypt: unregistered algorithm '%s'\n",
+ ops->name);
+ list_del(&alg->list);
+ spin_unlock_irqrestore(&libipw_crypto_lock, flags);
+ kfree(alg);
+ return 0;
+}
+EXPORT_SYMBOL(libipw_unregister_crypto_ops);
+
+const struct libipw_crypto_ops *libipw_get_crypto_ops(const char *name)
+{
+ struct libipw_crypto_alg *alg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&libipw_crypto_lock, flags);
+ list_for_each_entry(alg, &libipw_crypto_algs, list) {
+ if (strcmp(alg->ops->name, name) == 0)
+ goto found;
+ }
+ spin_unlock_irqrestore(&libipw_crypto_lock, flags);
+ return NULL;
+
+ found:
+ spin_unlock_irqrestore(&libipw_crypto_lock, flags);
+ return alg->ops;
+}
+EXPORT_SYMBOL(libipw_get_crypto_ops);
+
+static void *libipw_crypt_null_init(int keyidx)
+{
+ return (void *)1;
+}
+
+static void libipw_crypt_null_deinit(void *priv)
+{
+}
+
+static const struct libipw_crypto_ops libipw_crypt_null = {
+ .name = "NULL",
+ .init = libipw_crypt_null_init,
+ .deinit = libipw_crypt_null_deinit,
+ .owner = THIS_MODULE,
+};
+
+int __init libipw_crypto_init(void)
+{
+ return libipw_register_crypto_ops(&libipw_crypt_null);
+}
+
+void libipw_crypto_exit(void)
+{
+ libipw_unregister_crypto_ops(&libipw_crypt_null);
+ BUG_ON(!list_empty(&libipw_crypto_algs));
+}
diff --git a/net/wireless/lib80211_crypt_ccmp.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c
index 5aad139130e1..bf900d8c8ad3 100644
--- a/net/wireless/lib80211_crypt_ccmp.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * lib80211 crypt: host-based CCMP encryption implementation for lib80211
+ * libipw crypt: host-based CCMP encryption implementation for libipw
*
* Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
* Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
@@ -18,17 +18,10 @@
#include <linux/if_arp.h>
#include <asm/string.h>
#include <linux/wireless.h>
-
#include <linux/ieee80211.h>
-
#include <linux/crypto.h>
#include <crypto/aead.h>
-
-#include <net/lib80211.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: CCMP");
-MODULE_LICENSE("GPL");
+#include "libipw.h"
#define AES_BLOCK_LEN 16
#define CCMP_HDR_LEN 8
@@ -36,7 +29,7 @@ MODULE_LICENSE("GPL");
#define CCMP_TK_LEN 16
#define CCMP_PN_LEN 6
-struct lib80211_ccmp_data {
+struct libipw_ccmp_data {
u8 key[CCMP_TK_LEN];
int key_set;
@@ -56,9 +49,9 @@ struct lib80211_ccmp_data {
u8 rx_aad[2 * AES_BLOCK_LEN];
};
-static void *lib80211_ccmp_init(int key_idx)
+static void *libipw_ccmp_init(int key_idx)
{
- struct lib80211_ccmp_data *priv;
+ struct libipw_ccmp_data *priv;
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
if (priv == NULL)
@@ -83,9 +76,9 @@ static void *lib80211_ccmp_init(int key_idx)
return NULL;
}
-static void lib80211_ccmp_deinit(void *priv)
+static void libipw_ccmp_deinit(void *priv)
{
- struct lib80211_ccmp_data *_priv = priv;
+ struct libipw_ccmp_data *_priv = priv;
if (_priv && _priv->tfm)
crypto_free_aead(_priv->tfm);
kfree(priv);
@@ -150,10 +143,10 @@ static int ccmp_init_iv_and_aad(const struct ieee80211_hdr *hdr,
return aad_len;
}
-static int lib80211_ccmp_hdr(struct sk_buff *skb, int hdr_len,
+static int libipw_ccmp_hdr(struct sk_buff *skb, int hdr_len,
u8 *aeskey, int keylen, void *priv)
{
- struct lib80211_ccmp_data *key = priv;
+ struct libipw_ccmp_data *key = priv;
int i;
u8 *pos;
@@ -187,9 +180,9 @@ static int lib80211_ccmp_hdr(struct sk_buff *skb, int hdr_len,
return CCMP_HDR_LEN;
}
-static int lib80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static int libipw_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
- struct lib80211_ccmp_data *key = priv;
+ struct libipw_ccmp_data *key = priv;
struct ieee80211_hdr *hdr;
struct aead_request *req;
struct scatterlist sg[2];
@@ -202,7 +195,7 @@ static int lib80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
return -1;
data_len = skb->len - hdr_len;
- len = lib80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv);
+ len = libipw_ccmp_hdr(skb, hdr_len, NULL, 0, priv);
if (len < 0)
return -1;
@@ -251,9 +244,9 @@ static inline int ccmp_replay_check(u8 *pn_n, u8 *pn_o)
return 0;
}
-static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static int libipw_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
- struct lib80211_ccmp_data *key = priv;
+ struct libipw_ccmp_data *key = priv;
u8 keyidx, *pos;
struct ieee80211_hdr *hdr;
struct aead_request *req;
@@ -299,7 +292,7 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
pos += 8;
if (ccmp_replay_check(pn, key->rx_pn)) {
-#ifdef CONFIG_LIB80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
net_dbg_ratelimited("CCMP: replay detected: STA=%pM previous PN %02x%02x%02x%02x%02x%02x received PN %02x%02x%02x%02x%02x%02x\n",
hdr->addr2,
key->rx_pn[0], key->rx_pn[1], key->rx_pn[2],
@@ -344,9 +337,9 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return keyidx;
}
-static int lib80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
+static int libipw_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
{
- struct lib80211_ccmp_data *data = priv;
+ struct libipw_ccmp_data *data = priv;
int keyidx;
struct crypto_aead *tfm = data->tfm;
@@ -376,9 +369,9 @@ static int lib80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
return 0;
}
-static int lib80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
+static int libipw_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
{
- struct lib80211_ccmp_data *data = priv;
+ struct libipw_ccmp_data *data = priv;
if (len < CCMP_TK_LEN)
return -1;
@@ -399,9 +392,9 @@ static int lib80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
return CCMP_TK_LEN;
}
-static void lib80211_ccmp_print_stats(struct seq_file *m, void *priv)
+static void libipw_ccmp_print_stats(struct seq_file *m, void *priv)
{
- struct lib80211_ccmp_data *ccmp = priv;
+ struct libipw_ccmp_data *ccmp = priv;
seq_printf(m,
"key[%d] alg=CCMP key_set=%d "
@@ -418,31 +411,28 @@ static void lib80211_ccmp_print_stats(struct seq_file *m, void *priv)
ccmp->dot11RSNAStatsCCMPDecryptErrors);
}
-static const struct lib80211_crypto_ops lib80211_crypt_ccmp = {
+static const struct libipw_crypto_ops libipw_crypt_ccmp = {
.name = "CCMP",
- .init = lib80211_ccmp_init,
- .deinit = lib80211_ccmp_deinit,
- .encrypt_mpdu = lib80211_ccmp_encrypt,
- .decrypt_mpdu = lib80211_ccmp_decrypt,
+ .init = libipw_ccmp_init,
+ .deinit = libipw_ccmp_deinit,
+ .encrypt_mpdu = libipw_ccmp_encrypt,
+ .decrypt_mpdu = libipw_ccmp_decrypt,
.encrypt_msdu = NULL,
.decrypt_msdu = NULL,
- .set_key = lib80211_ccmp_set_key,
- .get_key = lib80211_ccmp_get_key,
- .print_stats = lib80211_ccmp_print_stats,
+ .set_key = libipw_ccmp_set_key,
+ .get_key = libipw_ccmp_get_key,
+ .print_stats = libipw_ccmp_print_stats,
.extra_mpdu_prefix_len = CCMP_HDR_LEN,
.extra_mpdu_postfix_len = CCMP_MIC_LEN,
.owner = THIS_MODULE,
};
-static int __init lib80211_crypto_ccmp_init(void)
+int __init libipw_crypto_ccmp_init(void)
{
- return lib80211_register_crypto_ops(&lib80211_crypt_ccmp);
+ return libipw_register_crypto_ops(&libipw_crypt_ccmp);
}
-static void __exit lib80211_crypto_ccmp_exit(void)
+void libipw_crypto_ccmp_exit(void)
{
- lib80211_unregister_crypto_ops(&lib80211_crypt_ccmp);
+ libipw_unregister_crypto_ops(&libipw_crypt_ccmp);
}
-
-module_init(lib80211_crypto_ccmp_init);
-module_exit(lib80211_crypto_ccmp_exit);
diff --git a/net/wireless/lib80211_crypt_tkip.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c
index 63e68e5e121e..32288697da4f 100644
--- a/net/wireless/lib80211_crypt_tkip.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * lib80211 crypt: host-based TKIP encryption implementation for lib80211
+ * libipw crypt: host-based TKIP encryption implementation for libipw
*
* Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
* Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
@@ -21,25 +21,18 @@
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <asm/string.h>
-
#include <linux/wireless.h>
#include <linux/ieee80211.h>
#include <net/iw_handler.h>
-
#include <crypto/arc4.h>
#include <crypto/hash.h>
#include <linux/crypto.h>
#include <linux/crc32.h>
-
-#include <net/lib80211.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("lib80211 crypt: TKIP");
-MODULE_LICENSE("GPL");
+#include "libipw.h"
#define TKIP_HDR_LEN 8
-struct lib80211_tkip_data {
+struct libipw_tkip_data {
#define TKIP_KEY_LEN 32
u8 key[TKIP_KEY_LEN];
int key_set;
@@ -73,23 +66,23 @@ struct lib80211_tkip_data {
unsigned long flags;
};
-static unsigned long lib80211_tkip_set_flags(unsigned long flags, void *priv)
+static unsigned long libipw_tkip_set_flags(unsigned long flags, void *priv)
{
- struct lib80211_tkip_data *_priv = priv;
+ struct libipw_tkip_data *_priv = priv;
unsigned long old_flags = _priv->flags;
_priv->flags = flags;
return old_flags;
}
-static unsigned long lib80211_tkip_get_flags(void *priv)
+static unsigned long libipw_tkip_get_flags(void *priv)
{
- struct lib80211_tkip_data *_priv = priv;
+ struct libipw_tkip_data *_priv = priv;
return _priv->flags;
}
-static void *lib80211_tkip_init(int key_idx)
+static void *libipw_tkip_init(int key_idx)
{
- struct lib80211_tkip_data *priv;
+ struct libipw_tkip_data *priv;
if (fips_enabled)
return NULL;
@@ -124,9 +117,9 @@ static void *lib80211_tkip_init(int key_idx)
return NULL;
}
-static void lib80211_tkip_deinit(void *priv)
+static void libipw_tkip_deinit(void *priv)
{
- struct lib80211_tkip_data *_priv = priv;
+ struct libipw_tkip_data *_priv = priv;
if (_priv) {
crypto_free_shash(_priv->tx_tfm_michael);
crypto_free_shash(_priv->rx_tfm_michael);
@@ -280,10 +273,10 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
#endif
}
-static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
+static int libipw_tkip_hdr(struct sk_buff *skb, int hdr_len,
u8 * rc4key, int keylen, void *priv)
{
- struct lib80211_tkip_data *tkey = priv;
+ struct libipw_tkip_data *tkey = priv;
u8 *pos;
struct ieee80211_hdr *hdr;
@@ -324,9 +317,9 @@ static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
return TKIP_HDR_LEN;
}
-static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static int libipw_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
- struct lib80211_tkip_data *tkey = priv;
+ struct libipw_tkip_data *tkey = priv;
int len;
u8 rc4key[16], *pos, *icv;
u32 crc;
@@ -344,7 +337,7 @@ static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
len = skb->len - hdr_len;
pos = skb->data + hdr_len;
- if ((lib80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
+ if ((libipw_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
return -1;
crc = ~crc32_le(~0, pos, len);
@@ -373,9 +366,9 @@ static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
return 0;
}
-static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static int libipw_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
- struct lib80211_tkip_data *tkey = priv;
+ struct libipw_tkip_data *tkey = priv;
u8 rc4key[16];
u8 keyidx, *pos;
u32 iv32;
@@ -419,7 +412,7 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
pos += TKIP_HDR_LEN;
if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
-#ifdef CONFIG_LIB80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
net_dbg_ratelimited("TKIP: replay detected: STA=%pM previous TSC %08x%04x received TSC %08x%04x\n",
hdr->addr2, tkey->rx_iv32, tkey->rx_iv16,
iv32, iv16);
@@ -450,7 +443,7 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
* it needs to be recalculated for the next packet. */
tkey->rx_phase1_done = 0;
}
-#ifdef CONFIG_LIB80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
net_dbg_ratelimited("TKIP: ICV error detected: STA=%pM\n",
hdr->addr2);
#endif
@@ -538,10 +531,10 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
}
-static int lib80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
+static int libipw_michael_mic_add(struct sk_buff *skb, int hdr_len,
void *priv)
{
- struct lib80211_tkip_data *tkey = priv;
+ struct libipw_tkip_data *tkey = priv;
u8 *pos;
if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
@@ -560,7 +553,7 @@ static int lib80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
return 0;
}
-static void lib80211_michael_mic_failure(struct net_device *dev,
+static void libipw_michael_mic_failure(struct net_device *dev,
struct ieee80211_hdr *hdr,
int keyidx)
{
@@ -581,10 +574,10 @@ static void lib80211_michael_mic_failure(struct net_device *dev,
wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
}
-static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
+static int libipw_michael_mic_verify(struct sk_buff *skb, int keyidx,
int hdr_len, void *priv)
{
- struct lib80211_tkip_data *tkey = priv;
+ struct libipw_tkip_data *tkey = priv;
u8 mic[8];
if (!tkey->key_set)
@@ -602,7 +595,7 @@ static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
skb->dev ? skb->dev->name : "N/A", hdr->addr2,
keyidx);
if (skb->dev)
- lib80211_michael_mic_failure(skb->dev, hdr, keyidx);
+ libipw_michael_mic_failure(skb->dev, hdr, keyidx);
tkey->dot11RSNAStatsTKIPLocalMICFailures++;
return -1;
}
@@ -617,9 +610,9 @@ static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
return 0;
}
-static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
+static int libipw_tkip_set_key(void *key, int len, u8 * seq, void *priv)
{
- struct lib80211_tkip_data *tkey = priv;
+ struct libipw_tkip_data *tkey = priv;
int keyidx;
struct crypto_shash *tfm = tkey->tx_tfm_michael;
struct arc4_ctx *tfm2 = &tkey->tx_ctx_arc4;
@@ -650,9 +643,9 @@ static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
return 0;
}
-static int lib80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
+static int libipw_tkip_get_key(void *key, int len, u8 * seq, void *priv)
{
- struct lib80211_tkip_data *tkey = priv;
+ struct libipw_tkip_data *tkey = priv;
if (len < TKIP_KEY_LEN)
return -1;
@@ -679,9 +672,9 @@ static int lib80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
return TKIP_KEY_LEN;
}
-static void lib80211_tkip_print_stats(struct seq_file *m, void *priv)
+static void libipw_tkip_print_stats(struct seq_file *m, void *priv)
{
- struct lib80211_tkip_data *tkip = priv;
+ struct libipw_tkip_data *tkip = priv;
seq_printf(m,
"key[%d] alg=TKIP key_set=%d "
"tx_pn=%02x%02x%02x%02x%02x%02x "
@@ -705,34 +698,31 @@ static void lib80211_tkip_print_stats(struct seq_file *m, void *priv)
tkip->dot11RSNAStatsTKIPLocalMICFailures);
}
-static const struct lib80211_crypto_ops lib80211_crypt_tkip = {
+static const struct libipw_crypto_ops libipw_crypt_tkip = {
.name = "TKIP",
- .init = lib80211_tkip_init,
- .deinit = lib80211_tkip_deinit,
- .encrypt_mpdu = lib80211_tkip_encrypt,
- .decrypt_mpdu = lib80211_tkip_decrypt,
- .encrypt_msdu = lib80211_michael_mic_add,
- .decrypt_msdu = lib80211_michael_mic_verify,
- .set_key = lib80211_tkip_set_key,
- .get_key = lib80211_tkip_get_key,
- .print_stats = lib80211_tkip_print_stats,
+ .init = libipw_tkip_init,
+ .deinit = libipw_tkip_deinit,
+ .encrypt_mpdu = libipw_tkip_encrypt,
+ .decrypt_mpdu = libipw_tkip_decrypt,
+ .encrypt_msdu = libipw_michael_mic_add,
+ .decrypt_msdu = libipw_michael_mic_verify,
+ .set_key = libipw_tkip_set_key,
+ .get_key = libipw_tkip_get_key,
+ .print_stats = libipw_tkip_print_stats,
.extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
.extra_mpdu_postfix_len = 4, /* ICV */
.extra_msdu_postfix_len = 8, /* MIC */
- .get_flags = lib80211_tkip_get_flags,
- .set_flags = lib80211_tkip_set_flags,
+ .get_flags = libipw_tkip_get_flags,
+ .set_flags = libipw_tkip_set_flags,
.owner = THIS_MODULE,
};
-static int __init lib80211_crypto_tkip_init(void)
+int __init libipw_crypto_tkip_init(void)
{
- return lib80211_register_crypto_ops(&lib80211_crypt_tkip);
+ return libipw_register_crypto_ops(&libipw_crypt_tkip);
}
-static void __exit lib80211_crypto_tkip_exit(void)
+void libipw_crypto_tkip_exit(void)
{
- lib80211_unregister_crypto_ops(&lib80211_crypt_tkip);
+ libipw_unregister_crypto_ops(&libipw_crypt_tkip);
}
-
-module_init(lib80211_crypto_tkip_init);
-module_exit(lib80211_crypto_tkip_exit);
diff --git a/net/wireless/lib80211_crypt_wep.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c
index 3b148c7bef85..c3a4ccb9de17 100644
--- a/net/wireless/lib80211_crypt_wep.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * lib80211 crypt: host-based WEP encryption implementation for lib80211
+ * libipw crypt: host-based WEP encryption implementation for libipw
*
* Copyright (c) 2002-2004, Jouni Malinen <j@w1.fi>
* Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
@@ -16,17 +16,11 @@
#include <linux/skbuff.h>
#include <linux/mm.h>
#include <asm/string.h>
-
-#include <net/lib80211.h>
-
#include <crypto/arc4.h>
#include <linux/crc32.h>
+#include "libipw.h"
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("lib80211 crypt: WEP");
-MODULE_LICENSE("GPL");
-
-struct lib80211_wep_data {
+struct libipw_wep_data {
u32 iv;
#define WEP_KEY_LEN 13
u8 key[WEP_KEY_LEN + 1];
@@ -36,9 +30,9 @@ struct lib80211_wep_data {
struct arc4_ctx rx_ctx;
};
-static void *lib80211_wep_init(int keyidx)
+static void *libipw_wep_init(int keyidx)
{
- struct lib80211_wep_data *priv;
+ struct libipw_wep_data *priv;
if (fips_enabled)
return NULL;
@@ -54,16 +48,16 @@ static void *lib80211_wep_init(int keyidx)
return priv;
}
-static void lib80211_wep_deinit(void *priv)
+static void libipw_wep_deinit(void *priv)
{
kfree_sensitive(priv);
}
/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */
-static int lib80211_wep_build_iv(struct sk_buff *skb, int hdr_len,
+static int libipw_wep_build_iv(struct sk_buff *skb, int hdr_len,
u8 *key, int keylen, void *priv)
{
- struct lib80211_wep_data *wep = priv;
+ struct libipw_wep_data *wep = priv;
u32 klen;
u8 *pos;
@@ -102,19 +96,19 @@ static int lib80211_wep_build_iv(struct sk_buff *skb, int hdr_len,
*
* WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
*/
-static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static int libipw_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
- struct lib80211_wep_data *wep = priv;
+ struct libipw_wep_data *wep = priv;
u32 crc, klen, len;
u8 *pos, *icv;
u8 key[WEP_KEY_LEN + 3];
- /* other checks are in lib80211_wep_build_iv */
+ /* other checks are in libipw_wep_build_iv */
if (skb_tailroom(skb) < 4)
return -1;
/* add the IV to the frame */
- if (lib80211_wep_build_iv(skb, hdr_len, NULL, 0, priv))
+ if (libipw_wep_build_iv(skb, hdr_len, NULL, 0, priv))
return -1;
/* Copy the IV into the first 3 bytes of the key */
@@ -148,9 +142,9 @@ static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
* Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
* failure. If frame is OK, IV and ICV will be removed.
*/
-static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static int libipw_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
- struct lib80211_wep_data *wep = priv;
+ struct libipw_wep_data *wep = priv;
u32 crc, klen, plen;
u8 key[WEP_KEY_LEN + 3];
u8 keyidx, *pos, icv[4];
@@ -195,9 +189,9 @@ static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return 0;
}
-static int lib80211_wep_set_key(void *key, int len, u8 * seq, void *priv)
+static int libipw_wep_set_key(void *key, int len, u8 * seq, void *priv)
{
- struct lib80211_wep_data *wep = priv;
+ struct libipw_wep_data *wep = priv;
if (len < 0 || len > WEP_KEY_LEN)
return -1;
@@ -208,9 +202,9 @@ static int lib80211_wep_set_key(void *key, int len, u8 * seq, void *priv)
return 0;
}
-static int lib80211_wep_get_key(void *key, int len, u8 * seq, void *priv)
+static int libipw_wep_get_key(void *key, int len, u8 * seq, void *priv)
{
- struct lib80211_wep_data *wep = priv;
+ struct libipw_wep_data *wep = priv;
if (len < wep->key_len)
return -1;
@@ -220,37 +214,34 @@ static int lib80211_wep_get_key(void *key, int len, u8 * seq, void *priv)
return wep->key_len;
}
-static void lib80211_wep_print_stats(struct seq_file *m, void *priv)
+static void libipw_wep_print_stats(struct seq_file *m, void *priv)
{
- struct lib80211_wep_data *wep = priv;
+ struct libipw_wep_data *wep = priv;
seq_printf(m, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
}
-static const struct lib80211_crypto_ops lib80211_crypt_wep = {
+static const struct libipw_crypto_ops libipw_crypt_wep = {
.name = "WEP",
- .init = lib80211_wep_init,
- .deinit = lib80211_wep_deinit,
- .encrypt_mpdu = lib80211_wep_encrypt,
- .decrypt_mpdu = lib80211_wep_decrypt,
+ .init = libipw_wep_init,
+ .deinit = libipw_wep_deinit,
+ .encrypt_mpdu = libipw_wep_encrypt,
+ .decrypt_mpdu = libipw_wep_decrypt,
.encrypt_msdu = NULL,
.decrypt_msdu = NULL,
- .set_key = lib80211_wep_set_key,
- .get_key = lib80211_wep_get_key,
- .print_stats = lib80211_wep_print_stats,
+ .set_key = libipw_wep_set_key,
+ .get_key = libipw_wep_get_key,
+ .print_stats = libipw_wep_print_stats,
.extra_mpdu_prefix_len = 4, /* IV */
.extra_mpdu_postfix_len = 4, /* ICV */
.owner = THIS_MODULE,
};
-static int __init lib80211_crypto_wep_init(void)
+int __init libipw_crypto_wep_init(void)
{
- return lib80211_register_crypto_ops(&lib80211_crypt_wep);
+ return libipw_register_crypto_ops(&libipw_crypt_wep);
}
-static void __exit lib80211_crypto_wep_exit(void)
+void __exit libipw_crypto_wep_exit(void)
{
- lib80211_unregister_crypto_ops(&lib80211_crypt_wep);
+ libipw_unregister_crypto_ops(&libipw_crypt_wep);
}
-
-module_init(lib80211_crypto_wep_init);
-module_exit(lib80211_crypto_wep_exit);
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_module.c b/drivers/net/wireless/intel/ipw2x00/libipw_module.c
index 43bab92a4148..0a16127bfd68 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_module.c
@@ -169,7 +169,7 @@ struct net_device *alloc_libipw(int sizeof_priv, int monitor)
spin_lock_init(&ieee->lock);
- lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
+ libipw_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
ieee->wpa_enabled = 0;
ieee->drop_unencrypted = 0;
@@ -191,7 +191,7 @@ void free_libipw(struct net_device *dev, int monitor)
{
struct libipw_device *ieee = netdev_priv(dev);
- lib80211_crypt_info_free(&ieee->crypt_info);
+ libipw_crypt_info_free(&ieee->crypt_info);
libipw_networks_free(ieee);
@@ -251,6 +251,7 @@ static const struct proc_ops debug_level_proc_ops = {
static int __init libipw_init(void)
{
+ int err;
#ifdef CONFIG_LIBIPW_DEBUG
struct proc_dir_entry *e;
@@ -273,7 +274,33 @@ static int __init libipw_init(void)
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
+ err = libipw_crypto_init();
+ if (err)
+ goto remove_debugfs;
+ err = libipw_crypto_ccmp_init();
+ if (err)
+ goto uninit_crypto;
+ err = libipw_crypto_tkip_init();
+ if (err)
+ goto uninit_crypto_ccmp;
+ err = libipw_crypto_wep_init();
+ if (err)
+ goto uninit_crypto_tkip;
+
return 0;
+uninit_crypto_tkip:
+ libipw_crypto_tkip_exit();
+uninit_crypto_ccmp:
+ libipw_crypto_ccmp_exit();
+uninit_crypto:
+ libipw_crypto_exit();
+remove_debugfs:
+#ifdef CONFIG_LIBIPW_DEBUG
+ remove_proc_entry("debug_level", libipw_proc);
+ remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
+ libipw_proc = NULL;
+#endif
+ return err;
}
static void __exit libipw_exit(void)
@@ -285,6 +312,11 @@ static void __exit libipw_exit(void)
libipw_proc = NULL;
}
#endif /* CONFIG_LIBIPW_DEBUG */
+
+ libipw_crypto_ccmp_exit();
+ libipw_crypto_tkip_exit();
+ libipw_crypto_wep_exit();
+ libipw_crypto_exit();
}
#ifdef CONFIG_LIBIPW_DEBUG
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
index 48d6870bbf4e..7e41cb7bbfe0 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
@@ -27,9 +27,6 @@
#include <linux/etherdevice.h>
#include <linux/uaccess.h>
#include <linux/ctype.h>
-
-#include <net/lib80211.h>
-
#include "libipw.h"
static void libipw_monitor_rx(struct libipw_device *ieee,
@@ -266,7 +263,7 @@ static int libipw_is_eapol_frame(struct libipw_device *ieee,
/* Called only as a tasklet (software IRQ), by libipw_rx */
static int
libipw_rx_frame_decrypt(struct libipw_device *ieee, struct sk_buff *skb,
- struct lib80211_crypt_data *crypt)
+ struct libipw_crypt_data *crypt)
{
struct libipw_hdr_3addr *hdr;
int res, hdrlen;
@@ -298,7 +295,7 @@ libipw_rx_frame_decrypt(struct libipw_device *ieee, struct sk_buff *skb,
static int
libipw_rx_frame_decrypt_msdu(struct libipw_device *ieee,
struct sk_buff *skb, int keyidx,
- struct lib80211_crypt_data *crypt)
+ struct libipw_crypt_data *crypt)
{
struct libipw_hdr_3addr *hdr;
int res, hdrlen;
@@ -345,7 +342,7 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb,
#endif
u8 dst[ETH_ALEN];
u8 src[ETH_ALEN];
- struct lib80211_crypt_data *crypt = NULL;
+ struct libipw_crypt_data *crypt = NULL;
int keyidx = 0;
int can_be_decrypted = 0;
@@ -396,7 +393,7 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb,
wstats.updated |= IW_QUAL_QUAL_INVALID;
/* Update spy records */
- wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
+ libipw_spy_update(ieee->dev, hdr->addr2, &wstats);
}
#endif /* IW_WIRELESS_SPY */
#endif /* CONFIG_WIRELESS_EXT */
diff --git a/net/wireless/wext-spy.c b/drivers/net/wireless/intel/ipw2x00/libipw_spy.c
index b379a0371653..ba876e92f7f6 100644
--- a/net/wireless/wext-spy.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_spy.c
@@ -14,19 +14,21 @@
#include <net/iw_handler.h>
#include <net/arp.h>
#include <net/wext.h>
+#include "libipw.h"
-static inline struct iw_spy_data *get_spydata(struct net_device *dev)
+static struct iw_spy_data *get_spydata(struct net_device *dev)
{
- /* This is the new way */
- if (dev->wireless_data)
- return dev->wireless_data->spy_data;
+ struct libipw_device *ieee = netdev_priv(dev);
+
+ if (ieee->spy_enabled)
+ return &ieee->spy_data;
return NULL;
}
-int iw_handler_set_spy(struct net_device * dev,
- struct iw_request_info * info,
- union iwreq_data * wrqu,
- char * extra)
+int ipw_wx_set_spy(struct net_device * dev,
+ struct iw_request_info * info,
+ union iwreq_data * wrqu,
+ char * extra)
{
struct iw_spy_data * spydata = get_spydata(dev);
struct sockaddr * address = (struct sockaddr *) extra;
@@ -36,15 +38,15 @@ int iw_handler_set_spy(struct net_device * dev,
return -EOPNOTSUPP;
/* Disable spy collection while we copy the addresses.
- * While we copy addresses, any call to wireless_spy_update()
+ * While we copy addresses, any call to libipw_spy_update()
* will NOP. This is OK, as anyway the addresses are changing. */
spydata->spy_number = 0;
- /* We want to operate without locking, because wireless_spy_update()
+ /* We want to operate without locking, because libipw_spy_update()
* most likely will happen in the interrupt handler, and therefore
* have its own locking constraints and needs performance.
* The rtnl_lock() make sure we don't race with the other iw_handlers.
- * This make sure wireless_spy_update() "see" that the spy list
+ * This make sure libipw_spy_update() "see" that the spy list
* is temporarily disabled. */
smp_wmb();
@@ -69,12 +71,12 @@ int iw_handler_set_spy(struct net_device * dev,
return 0;
}
-EXPORT_SYMBOL(iw_handler_set_spy);
+EXPORT_SYMBOL(ipw_wx_set_spy);
-int iw_handler_get_spy(struct net_device * dev,
- struct iw_request_info * info,
- union iwreq_data * wrqu,
- char * extra)
+int ipw_wx_get_spy(struct net_device * dev,
+ struct iw_request_info * info,
+ union iwreq_data * wrqu,
+ char * extra)
{
struct iw_spy_data * spydata = get_spydata(dev);
struct sockaddr * address = (struct sockaddr *) extra;
@@ -101,16 +103,16 @@ int iw_handler_get_spy(struct net_device * dev,
spydata->spy_stat[i].updated &= ~IW_QUAL_ALL_UPDATED;
return 0;
}
-EXPORT_SYMBOL(iw_handler_get_spy);
+EXPORT_SYMBOL(ipw_wx_get_spy);
/*------------------------------------------------------------------*/
/*
* Standard Wireless Handler : set spy threshold
*/
-int iw_handler_set_thrspy(struct net_device * dev,
- struct iw_request_info *info,
- union iwreq_data * wrqu,
- char * extra)
+int ipw_wx_set_thrspy(struct net_device * dev,
+ struct iw_request_info * info,
+ union iwreq_data * wrqu,
+ char * extra)
{
struct iw_spy_data * spydata = get_spydata(dev);
struct iw_thrspy * threshold = (struct iw_thrspy *) extra;
@@ -128,16 +130,16 @@ int iw_handler_set_thrspy(struct net_device * dev,
return 0;
}
-EXPORT_SYMBOL(iw_handler_set_thrspy);
+EXPORT_SYMBOL(ipw_wx_set_thrspy);
/*------------------------------------------------------------------*/
/*
* Standard Wireless Handler : get spy threshold
*/
-int iw_handler_get_thrspy(struct net_device * dev,
- struct iw_request_info *info,
- union iwreq_data * wrqu,
- char * extra)
+int ipw_wx_get_thrspy(struct net_device * dev,
+ struct iw_request_info * info,
+ union iwreq_data * wrqu,
+ char * extra)
{
struct iw_spy_data * spydata = get_spydata(dev);
struct iw_thrspy * threshold = (struct iw_thrspy *) extra;
@@ -152,7 +154,7 @@ int iw_handler_get_thrspy(struct net_device * dev,
return 0;
}
-EXPORT_SYMBOL(iw_handler_get_thrspy);
+EXPORT_SYMBOL(ipw_wx_get_thrspy);
/*------------------------------------------------------------------*/
/*
@@ -189,9 +191,9 @@ static void iw_send_thrspy_event(struct net_device * dev,
* small, this is good enough. If we wanted to support larger number of
* spy addresses, we should use something more efficient...
*/
-void wireless_spy_update(struct net_device * dev,
- unsigned char * address,
- struct iw_quality * wstats)
+void libipw_spy_update(struct net_device * dev,
+ unsigned char * address,
+ struct iw_quality * wstats)
{
struct iw_spy_data * spydata = get_spydata(dev);
int i;
@@ -229,4 +231,3 @@ void wireless_spy_update(struct net_device * dev,
}
}
}
-EXPORT_SYMBOL(wireless_spy_update);
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_tx.c b/drivers/net/wireless/intel/ipw2x00/libipw_tx.c
index e22a6732a4c3..80edaa3dea9c 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_tx.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_tx.c
@@ -138,7 +138,7 @@ static int libipw_copy_snap(u8 * data, __be16 h_proto)
static int libipw_encrypt_fragment(struct libipw_device *ieee,
struct sk_buff *frag, int hdr_len)
{
- struct lib80211_crypt_data *crypt =
+ struct libipw_crypt_data *crypt =
ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
int res;
@@ -255,7 +255,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
.qos_ctl = 0
};
u8 dest[ETH_ALEN], src[ETH_ALEN];
- struct lib80211_crypt_data *crypt;
+ struct libipw_crypt_data *crypt;
int priority = skb->priority;
int snapped = 0;
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_wx.c b/drivers/net/wireless/intel/ipw2x00/libipw_wx.c
index dbc7153d0a3d..db71d81b0d4f 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_wx.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_wx.c
@@ -21,10 +21,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/jiffies.h>
-
-#include <net/lib80211.h>
#include <linux/wireless.h>
-
#include "libipw.h"
static const char *libipw_modes[] = {
@@ -303,7 +300,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
.flags = 0
};
int i, key, key_provided, len;
- struct lib80211_crypt_data **crypt;
+ struct libipw_crypt_data **crypt;
int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
LIBIPW_DEBUG_WX("SET_ENCODE\n");
@@ -328,7 +325,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
if (key_provided && *crypt) {
LIBIPW_DEBUG_WX("Disabling encryption on key %d.\n",
key);
- lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
+ libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt);
} else
LIBIPW_DEBUG_WX("Disabling encryption.\n");
@@ -338,7 +335,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
if (ieee->crypt_info.crypt[i] != NULL) {
if (key_provided)
break;
- lib80211_crypt_delayed_deinit(&ieee->crypt_info,
+ libipw_crypt_delayed_deinit(&ieee->crypt_info,
&ieee->crypt_info.crypt[i]);
}
}
@@ -361,21 +358,21 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
strcmp((*crypt)->ops->name, "WEP") != 0) {
/* changing to use WEP; deinit previously used algorithm
* on this key */
- lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
+ libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt);
}
if (*crypt == NULL && host_crypto) {
- struct lib80211_crypt_data *new_crypt;
+ struct libipw_crypt_data *new_crypt;
/* take WEP into use */
- new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
+ new_crypt = kzalloc(sizeof(struct libipw_crypt_data),
GFP_KERNEL);
if (new_crypt == NULL)
return -ENOMEM;
- new_crypt->ops = lib80211_get_crypto_ops("WEP");
+ new_crypt->ops = libipw_get_crypto_ops("WEP");
if (!new_crypt->ops) {
- request_module("lib80211_crypt_wep");
- new_crypt->ops = lib80211_get_crypto_ops("WEP");
+ request_module("libipw_crypt_wep");
+ new_crypt->ops = libipw_get_crypto_ops("WEP");
}
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
@@ -386,7 +383,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
new_crypt = NULL;
printk(KERN_WARNING "%s: could not initialize WEP: "
- "load module lib80211_crypt_wep\n", dev->name);
+ "load module libipw_crypt_wep\n", dev->name);
return -EOPNOTSUPP;
}
*crypt = new_crypt;
@@ -509,8 +506,8 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
int i, idx, ret = 0;
int group_key = 0;
const char *alg, *module;
- const struct lib80211_crypto_ops *ops;
- struct lib80211_crypt_data **crypt;
+ const struct libipw_crypto_ops *ops;
+ struct libipw_crypt_data **crypt;
struct libipw_security sec = {
.flags = 0,
@@ -541,7 +538,7 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
if ((encoding->flags & IW_ENCODE_DISABLED) ||
ext->alg == IW_ENCODE_ALG_NONE) {
if (*crypt)
- lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
+ libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt);
for (i = 0; i < WEP_KEYS; i++)
if (ieee->crypt_info.crypt[i] != NULL)
@@ -567,15 +564,15 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
switch (ext->alg) {
case IW_ENCODE_ALG_WEP:
alg = "WEP";
- module = "lib80211_crypt_wep";
+ module = "libipw_crypt_wep";
break;
case IW_ENCODE_ALG_TKIP:
alg = "TKIP";
- module = "lib80211_crypt_tkip";
+ module = "libipw_crypt_tkip";
break;
case IW_ENCODE_ALG_CCMP:
alg = "CCMP";
- module = "lib80211_crypt_ccmp";
+ module = "libipw_crypt_ccmp";
break;
default:
LIBIPW_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -584,10 +581,10 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
goto done;
}
- ops = lib80211_get_crypto_ops(alg);
+ ops = libipw_get_crypto_ops(alg);
if (ops == NULL) {
request_module(module);
- ops = lib80211_get_crypto_ops(alg);
+ ops = libipw_get_crypto_ops(alg);
}
if (ops == NULL) {
LIBIPW_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -597,9 +594,9 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
}
if (*crypt == NULL || (*crypt)->ops != ops) {
- struct lib80211_crypt_data *new_crypt;
+ struct libipw_crypt_data *new_crypt;
- lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
+ libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt);
new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
if (new_crypt == NULL) {
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c
index fa1be8c54d3c..ea40d402681d 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c
@@ -10,7 +10,7 @@
#include "fw/api/txq.h"
/* Highest firmware API version supported */
-#define IWL_BZ_UCODE_API_MAX 93
+#define IWL_BZ_UCODE_API_MAX 94
/* Lowest firmware API version supported */
#define IWL_BZ_UCODE_API_MIN 90
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
index f1dd1c29f305..635fed641c19 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
@@ -10,7 +10,7 @@
#include "fw/api/txq.h"
/* Highest firmware API version supported */
-#define IWL_SC_UCODE_API_MAX 93
+#define IWL_SC_UCODE_API_MAX 94
/* Lowest firmware API version supported */
#define IWL_SC_UCODE_API_MIN 90
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
index c46e24fc6a1e..b23d5fc4bbe6 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
@@ -382,6 +382,8 @@ struct iwl_mac_config_cmd {
* @LINK_CONTEXT_MODIFY_EHT_PARAMS: covers iwl_link_ctx_cfg_cmd::puncture_mask.
* This flag can be set only if the MAC that this link relates to has
* eht_support set to true. No longer used since _VER_3 of this command.
+ * @LINK_CONTEXT_MODIFY_BANDWIDTH: Covers iwl_link_ctx_cfg_cmd::modify_bandwidth.
+ * Request RX OMI to the AP to modify bandwidth of this link.
* @LINK_CONTEXT_MODIFY_ALL: set all above flags
*/
enum iwl_link_ctx_modify_flags {
@@ -393,6 +395,7 @@ enum iwl_link_ctx_modify_flags {
LINK_CONTEXT_MODIFY_HE_PARAMS = BIT(5),
LINK_CONTEXT_MODIFY_BSS_COLOR_DISABLE = BIT(6),
LINK_CONTEXT_MODIFY_EHT_PARAMS = BIT(7),
+ LINK_CONTEXT_MODIFY_BANDWIDTH = BIT(8),
LINK_CONTEXT_MODIFY_ALL = 0xff,
}; /* LINK_CONTEXT_MODIFY_MASK_E_VER_1 */
@@ -434,6 +437,22 @@ enum iwl_link_ctx_flags {
}; /* LINK_CONTEXT_FLAG_E_VER_1 */
/**
+ * enum iwl_link_modify_bandwidth - link modify (RX OMI) bandwidth
+ * @IWL_LINK_MODIFY_BW_20: request 20 MHz
+ * @IWL_LINK_MODIFY_BW_40: request 40 MHz
+ * @IWL_LINK_MODIFY_BW_80: request 80 MHz
+ * @IWL_LINK_MODIFY_BW_160: request 160 MHz
+ * @IWL_LINK_MODIFY_BW_320: request 320 MHz
+ */
+enum iwl_link_modify_bandwidth {
+ IWL_LINK_MODIFY_BW_20,
+ IWL_LINK_MODIFY_BW_40,
+ IWL_LINK_MODIFY_BW_80,
+ IWL_LINK_MODIFY_BW_160,
+ IWL_LINK_MODIFY_BW_320,
+};
+
+/**
* struct iwl_link_config_cmd - command structure to configure the LINK context
* in MLD API
* ( LINK_CONFIG_CMD =0x9 )
@@ -457,6 +476,8 @@ enum iwl_link_ctx_flags {
* @block_tx: tell the firmware that this link can't Tx. This should be used
* only when a link is de-activated because of CSA with mode = 1.
* Available since version 5.
+ * @modify_bandwidth: bandwidth request value for RX OMI (see also
+ * %LINK_CONTEXT_MODIFY_BANDWIDTH), from &enum iwl_link_modify_bandwidth.
* @reserved1: in version 2, listen_lmac became reserved
* @cck_rates: basic rates available for CCK
* @ofdm_rates: basic rates available for OFDM
@@ -500,10 +521,11 @@ struct iwl_link_config_cmd {
__le32 modify_mask;
__le32 active;
union {
- __le32 listen_lmac;
+ __le32 listen_lmac; /* only _VER_1 */
struct {
- u8 block_tx;
- u8 reserved1[3];
+ u8 block_tx; /* since _VER_5 */
+ u8 modify_bandwidth; /* since _VER_6 */
+ u8 reserved1[2];
};
};
__le32 cck_rates;
@@ -524,7 +546,7 @@ struct iwl_link_config_cmd {
__le16 puncture_mask; /* removed in _VER_3 */
__le16 frame_time_rts_th;
__le32 flags;
- __le32 flags_mask;
+ __le32 flags_mask; /* removed in _VER_6 */
/* The below fields are for multi-bssid */
u8 ref_bssid_addr[6];
__le16 reserved_for_ref_bssid_addr;
@@ -535,7 +557,7 @@ struct iwl_link_config_cmd {
u8 ibss_bssid_addr[6];
__le16 reserved_for_ibss_bssid_addr;
__le32 reserved3[8];
-} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5 */
+} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5, _VER_6 */
/* Currently FW supports link ids in the range 0-3 and can have
* at most two active links for each vif.
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 98d56e778d99..f4803b55adb9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2005-2014, 2018-2019, 2021-2023 Intel Corporation
+ * Copyright (C) 2005-2014, 2018-2019, 2021-2024 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH
*/
@@ -327,18 +327,19 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt);
void iwl_send_dbg_dump_complete_cmd(struct iwl_fw_runtime *fwrt,
u32 timepoint,
u32 timepoint_data);
+bool iwl_fwrt_read_err_table(struct iwl_trans *trans, u32 base, u32 *err_id);
void iwl_fw_disable_dbg_asserts(struct iwl_fw_runtime *fwrt);
void iwl_fw_dbg_clear_monitor_buf(struct iwl_fw_runtime *fwrt);
-#define IWL_FW_CHECK_FAILED(_obj, _fmt, ...) \
- IWL_ERR_LIMIT(_obj, _fmt, __VA_ARGS__)
+#define IWL_FW_CHECK_FAILED(_obj, ...) \
+ IWL_ERR_LIMIT(_obj, __VA_ARGS__)
#define IWL_FW_CHECK(_obj, _cond, _fmt, ...) \
({ \
bool __cond = (_cond); \
\
if (unlikely(__cond)) \
- IWL_FW_CHECK_FAILED(_obj, _fmt, __VA_ARGS__); \
+ IWL_FW_CHECK_FAILED(_obj, _fmt, ##__VA_ARGS__); \
\
unlikely(__cond); \
})
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dump.c b/drivers/net/wireless/intel/iwlwifi/fw/dump.c
index 8f107ceec407..3cabdeb53e99 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dump.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dump.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2012-2014, 2018-2023 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2024 Intel Corporation
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH
*/
@@ -530,3 +530,23 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)
}
}
IWL_EXPORT_SYMBOL(iwl_fwrt_dump_error_logs);
+
+bool iwl_fwrt_read_err_table(struct iwl_trans *trans, u32 base, u32 *err_id)
+{
+ struct error_table_start {
+ /* cf. struct iwl_error_event_table */
+ u32 valid;
+ __le32 err_id;
+ } err_info;
+
+ if (!base)
+ return false;
+
+ iwl_trans_read_mem_bytes(trans, base,
+ &err_info, sizeof(err_info));
+ if (err_info.valid && err_id)
+ *err_id = le32_to_cpu(err_info.err_id);
+
+ return !!err_info.valid;
+}
+IWL_EXPORT_SYMBOL(iwl_fwrt_read_err_table);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
index ddf484027d4f..795a166ed63a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
@@ -17,7 +17,8 @@
#define IWL_MVM_TRIGGER_LINK_SEL_TIME_SEC 30
#define IWL_MVM_TPT_COUNT_WINDOW_SEC 5
#define IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS 5
-#define IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH 11
+#define IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH 15
+#define IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_BSS_PARAM_CHANGED 11
#define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
@@ -57,7 +58,6 @@
#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0
#define IWL_MVM_RS_80_20_FAR_RANGE_TWEAK 1
#define IWL_MVM_TOF_IS_RESPONDER 0
-#define IWL_MVM_HW_CSUM_DISABLE 0
#define IWL_MVM_ADWELL_ENABLE 1
#define IWL_MVM_ADWELL_MAX_BUDGET 0
#define IWL_MVM_TCM_LOAD_MEDIUM_THRESH 10 /* percentage */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 49a6aff42376..9f41b9af5269 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -3024,24 +3024,6 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
ieee80211_resume_disconnect(vif);
}
-static bool iwl_mvm_rt_status(struct iwl_trans *trans, u32 base, u32 *err_id)
-{
- struct error_table_start {
- /* cf. struct iwl_error_event_table */
- u32 valid;
- __le32 err_id;
- } err_info;
-
- if (!base)
- return false;
-
- iwl_trans_read_mem_bytes(trans, base,
- &err_info, sizeof(err_info));
- if (err_info.valid && err_id)
- *err_id = le32_to_cpu(err_info.err_id);
-
- return !!err_info.valid;
-}
static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
@@ -3049,9 +3031,9 @@ static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
u32 err_id;
/* check for lmac1 error */
- if (iwl_mvm_rt_status(mvm->trans,
- mvm->trans->dbg.lmac_error_event_table[0],
- &err_id)) {
+ if (iwl_fwrt_read_err_table(mvm->trans,
+ mvm->trans->dbg.lmac_error_event_table[0],
+ &err_id)) {
if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN && vif) {
struct cfg80211_wowlan_wakeup wakeup = {
.rfkill_release = true,
@@ -3063,13 +3045,15 @@ static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
}
/* check if we have lmac2 set and check for error */
- if (iwl_mvm_rt_status(mvm->trans,
- mvm->trans->dbg.lmac_error_event_table[1], NULL))
+ if (iwl_fwrt_read_err_table(mvm->trans,
+ mvm->trans->dbg.lmac_error_event_table[1],
+ NULL))
return true;
/* check for umac error */
- if (iwl_mvm_rt_status(mvm->trans,
- mvm->trans->dbg.umac_error_event_table, NULL))
+ if (iwl_fwrt_read_err_table(mvm->trans,
+ mvm->trans->dbg.umac_error_event_table,
+ NULL))
return true;
return false;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c
index 2b0652168002..628baf67b208 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c
@@ -12,6 +12,7 @@
HOW(BLOCKED_FW) \
HOW(BLOCKED_NON_BSS) \
HOW(BLOCKED_ROC) \
+ HOW(BLOCKED_TMP_NON_BSS) \
HOW(EXIT_MISSED_BEACON) \
HOW(EXIT_LOW_RSSI) \
HOW(EXIT_COEX) \
@@ -360,7 +361,8 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
send_cmd:
cmd.modify_mask = cpu_to_le32(changes);
cmd.flags = cpu_to_le32(flags);
- cmd.flags_mask = cpu_to_le32(flags_mask);
+ if (cmd_ver < 6)
+ cmd.flags_mask = cpu_to_le32(flags_mask);
cmd.spec_link_id = link_conf->link_id;
if (cmd_ver < 2)
cmd.listen_lmac = cpu_to_le32(link_info->listen_lmac);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index a7a10e716e65..9a43df49493f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -1605,6 +1605,7 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
0);
u8 new_notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP,
MISSED_BEACONS_NOTIF, 0);
+ struct ieee80211_bss_conf *bss_conf;
/* If the firmware uses the new notification (from MAC_CONF_GROUP),
* refer to that notification's version.
@@ -1617,9 +1618,9 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
/* before version four the ID in the notification refers to mac ID */
if (notif_ver < 4) {
vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, false);
+ bss_conf = &vif->bss_conf;
} else {
- struct ieee80211_bss_conf *bss_conf =
- iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, id, false);
+ bss_conf = iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, id, false);
if (!bss_conf)
return;
@@ -1664,6 +1665,8 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
rx_missed_bcon, rx_missed_bcon_since_rx);
}
} else if (link_id >= 0 && hweight16(vif->active_links) > 1) {
+ u32 bss_param_ch_cnt_link_id =
+ bss_conf->bss_param_ch_cnt_link_id;
u32 scnd_lnk_bcn_lost = 0;
if (notif_ver >= 5 &&
@@ -1677,10 +1680,14 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
/* Exit EMLSR if we lost more than
* IWL_MVM_MISSED_BEACONS_EXIT_ESR_THRESH beacons on boths links
* OR more than IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH on any link.
+ * OR more than IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_BSS_PARAM_CHANGED
+ * and the link's bss_param_ch_count has changed.
*/
if ((rx_missed_bcon >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS &&
scnd_lnk_bcn_lost >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS) ||
- rx_missed_bcon >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH)
+ rx_missed_bcon >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH ||
+ (bss_param_ch_cnt_link_id != link_id &&
+ rx_missed_bcon >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_BSS_PARAM_CHANGED))
iwl_mvm_exit_esr(mvm, vif,
IWL_MVM_ESR_EXIT_MISSED_BEACON,
iwl_mvm_get_primary_link(vif));
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index a327893c6dce..4db7c3ee6bf5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1336,6 +1336,8 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
* of packets the FW sent out, so we must reconnect.
*/
iwl_mvm_teardown_tdls_peers(mvm);
+
+ IWL_INFO(mvm, "restart completed\n");
}
void iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
@@ -1466,15 +1468,16 @@ struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
return NULL;
}
-int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+int iwl_mvm_set_tx_power(struct iwl_mvm *mvm,
+ struct ieee80211_bss_conf *link_conf,
s16 tx_power)
{
u32 cmd_id = REDUCE_TX_POWER_CMD;
+ u32 mac_id = iwl_mvm_vif_from_mac80211(link_conf->vif)->id;
int len;
struct iwl_dev_tx_power_cmd_v3_v8 cmd = {
.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC),
- .common.mac_context_id =
- cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id),
+ .common.mac_context_id = cpu_to_le32(mac_id),
};
struct iwl_dev_tx_power_cmd cmd_v9_v10;
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 3);
@@ -1487,8 +1490,7 @@ int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if (cmd_ver > 8) {
/* Those fields sit on the same place for v9 and v10 */
cmd_v9_v10.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC);
- cmd_v9_v10.common.mac_context_id =
- cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id);
+ cmd_v9_v10.common.mac_context_id = cpu_to_le32(mac_id);
cmd_v9_v10.common.pwr_restriction = cpu_to_le16(u_tx_power);
cmd_data = &cmd_v9_v10;
}
@@ -1731,6 +1733,21 @@ static void iwl_mvm_unblock_esr_tpt(struct wiphy *wiphy, struct wiphy_work *wk)
iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_TPT);
}
+static void iwl_mvm_unblock_esr_tmp_non_bss(struct wiphy *wiphy,
+ struct wiphy_work *wk)
+{
+ struct iwl_mvm_vif *mvmvif =
+ container_of(wk, struct iwl_mvm_vif,
+ unblock_esr_tmp_non_bss_wk.work);
+ struct iwl_mvm *mvm = mvmvif->mvm;
+ struct ieee80211_vif *vif =
+ container_of((void *)mvmvif, struct ieee80211_vif, drv_priv);
+
+ mutex_lock(&mvm->mutex);
+ iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_TMP_NON_BSS);
+ mutex_unlock(&mvm->mutex);
+}
+
void iwl_mvm_mac_init_mvmvif(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif)
{
lockdep_assert_held(&mvm->mutex);
@@ -1749,6 +1766,9 @@ void iwl_mvm_mac_init_mvmvif(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif)
wiphy_work_init(&mvmvif->unblock_esr_tpt_wk,
iwl_mvm_unblock_esr_tpt);
+
+ wiphy_delayed_work_init(&mvmvif->unblock_esr_tmp_non_bss_wk,
+ iwl_mvm_unblock_esr_tmp_non_bss);
}
static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
@@ -1899,6 +1919,8 @@ void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
&mvmvif->mlo_int_scan_wk);
wiphy_work_cancel(mvm->hw->wiphy, &mvmvif->unblock_esr_tpt_wk);
+ wiphy_delayed_work_cancel(mvm->hw->wiphy,
+ &mvmvif->unblock_esr_tmp_non_bss_wk);
cancel_delayed_work_sync(&mvmvif->csa_work);
}
@@ -3303,7 +3325,7 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
if (changes & BSS_CHANGED_TXPOWER) {
IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d dBm\n",
bss_conf->txpower);
- iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
+ iwl_mvm_set_tx_power(mvm, bss_conf, bss_conf->txpower);
}
}
@@ -4075,6 +4097,8 @@ iwl_mvm_sta_state_authorized_to_assoc(struct iwl_mvm *mvm,
&mvmvif->mlo_int_scan_wk);
wiphy_work_cancel(mvm->hw->wiphy, &mvmvif->unblock_esr_tpt_wk);
+ wiphy_delayed_work_cancel(mvm->hw->wiphy,
+ &mvmvif->unblock_esr_tmp_non_bss_wk);
/* No need for the periodic statistics anymore */
if (ieee80211_vif_is_mld(vif) && mvmvif->esr_active)
@@ -4236,8 +4260,9 @@ int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
}
void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, u32 changed)
+ struct ieee80211_link_sta *link_sta, u32 changed)
{
+ struct ieee80211_sta *sta = link_sta->sta;
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
if (changed & (IEEE80211_RC_BW_CHANGED |
@@ -5067,7 +5092,7 @@ void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
(changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
IEEE80211_CHANCTX_CHANGE_RADAR |
- IEEE80211_CHANCTX_CHANGE_MIN_WIDTH)),
+ IEEE80211_CHANCTX_CHANGE_MIN_DEF)),
"Cannot change PHY. Ref=%d, changed=0x%X\n",
phy_ctxt->ref, changed))
return;
@@ -5075,7 +5100,7 @@ void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
guard(mvm)(mvm);
/* we are only changing the min_width, may be a noop */
- if (changed == IEEE80211_CHANCTX_CHANGE_MIN_WIDTH) {
+ if (changed == IEEE80211_CHANCTX_CHANGE_MIN_DEF) {
if (phy_ctxt->width == def->width)
return;
@@ -6562,7 +6587,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
.allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
.release_buffered_frames = iwl_mvm_mac_release_buffered_frames,
.set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
- .sta_rc_update = iwl_mvm_sta_rc_update,
+ .link_sta_rc_update = iwl_mvm_sta_rc_update,
.conf_tx = iwl_mvm_mac_conf_tx,
.mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
.mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
index f2378e0fb2fb..a5c38f389c69 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
@@ -331,23 +331,18 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
if (ret)
goto out;
- /* Initialize rate control for the AP station, since we might be
- * doing a link switch here - we cannot initialize it before since
- * this needs the phy context assigned (and in FW?), and we cannot
- * do it later because it needs to be initialized as soon as we're
- * able to TX on the link, i.e. when active.
+ /*
+ * if link switching (link not active yet) we'll activate it in
+ * firmware later on link-info change, which mac80211 guarantees
+ * for link switch after the stations are set up
*/
- if (mvmvif->ap_sta) {
- struct ieee80211_link_sta *link_sta;
-
- rcu_read_lock();
- link_sta = rcu_dereference(mvmvif->ap_sta->link[link_id]);
-
- if (!WARN_ON_ONCE(!link_sta))
- iwl_mvm_rs_rate_init(mvm, vif, mvmvif->ap_sta,
- link_conf, link_sta,
- phy_ctxt->channel->band);
- rcu_read_unlock();
+ if (ieee80211_vif_link_active(vif, link_conf->link_id)) {
+ ret = iwl_mvm_link_changed(mvm, vif, link_conf,
+ LINK_CONTEXT_MODIFY_ACTIVE |
+ LINK_CONTEXT_MODIFY_RATES_INFO,
+ true);
+ if (ret)
+ goto out;
}
if (vif->type == NL80211_IFTYPE_STATION)
@@ -355,14 +350,6 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
link_conf,
false);
- /* then activate */
- ret = iwl_mvm_link_changed(mvm, vif, link_conf,
- LINK_CONTEXT_MODIFY_ACTIVE |
- LINK_CONTEXT_MODIFY_RATES_INFO,
- true);
- if (ret)
- goto out;
-
/*
* Power state must be updated before quotas,
* otherwise fw will complain.
@@ -775,6 +762,11 @@ iwl_mvm_mld_link_info_changed_station(struct iwl_mvm *mvm,
if (WARN_ON_ONCE(!mvmvif->link[link_conf->link_id]))
return;
+ /* not yet marked active in vif means during link switch */
+ if (!ieee80211_vif_link_active(vif, link_conf->link_id) &&
+ vif->cfg.assoc && mvmvif->link[link_conf->link_id]->phy_ctxt)
+ link_changes |= LINK_CONTEXT_MODIFY_ACTIVE;
+
has_he = link_conf->he_support && !iwlwifi_mod_params.disable_11ax;
has_eht = link_conf->eht_support && !iwlwifi_mod_params.disable_11be;
@@ -1038,7 +1030,7 @@ static void iwl_mvm_mld_link_info_changed(struct ieee80211_hw *hw,
if (changes & BSS_CHANGED_TXPOWER) {
IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d dBm\n",
link_conf->txpower);
- iwl_mvm_set_tx_power(mvm, vif, link_conf->txpower);
+ iwl_mvm_set_tx_power(mvm, link_conf, link_conf->txpower);
}
}
@@ -1376,6 +1368,36 @@ iwl_mvm_mld_mac_pre_channel_switch(struct ieee80211_hw *hw,
return ret;
}
+#define IWL_MVM_MLD_UNBLOCK_ESR_NON_BSS_TIMEOUT (5 * HZ)
+
+static void iwl_mvm_mld_prep_add_interface(struct ieee80211_hw *hw,
+ enum nl80211_iftype type)
+{
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ struct ieee80211_vif *bss_vif = iwl_mvm_get_bss_vif(mvm);
+ struct iwl_mvm_vif *mvmvif;
+ int ret;
+
+ IWL_DEBUG_MAC80211(mvm, "prep_add_interface: type=%u\n",
+ type);
+
+ if (IS_ERR_OR_NULL(bss_vif) ||
+ !(type == NL80211_IFTYPE_AP ||
+ type == NL80211_IFTYPE_P2P_GO ||
+ type == NL80211_IFTYPE_P2P_CLIENT))
+ return;
+
+ mvmvif = iwl_mvm_vif_from_mac80211(bss_vif);
+ ret = iwl_mvm_block_esr_sync(mvm, bss_vif,
+ IWL_MVM_ESR_BLOCKED_TMP_NON_BSS);
+ if (ret)
+ return;
+
+ wiphy_delayed_work_queue(mvmvif->mvm->hw->wiphy,
+ &mvmvif->unblock_esr_tmp_non_bss_wk,
+ IWL_MVM_MLD_UNBLOCK_ESR_NON_BSS_TIMEOUT);
+}
+
const struct ieee80211_ops iwl_mvm_mld_hw_ops = {
.tx = iwl_mvm_mac_tx,
.wake_tx_queue = iwl_mvm_mac_wake_tx_queue,
@@ -1401,7 +1423,7 @@ const struct ieee80211_ops iwl_mvm_mld_hw_ops = {
.allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
.release_buffered_frames = iwl_mvm_mac_release_buffered_frames,
.set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
- .sta_rc_update = iwl_mvm_sta_rc_update,
+ .link_sta_rc_update = iwl_mvm_sta_rc_update,
.conf_tx = iwl_mvm_mld_mac_conf_tx,
.mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
.mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx,
@@ -1472,4 +1494,5 @@ const struct ieee80211_ops iwl_mvm_mld_hw_ops = {
.change_sta_links = iwl_mvm_mld_change_sta_links,
.can_activate_links = iwl_mvm_mld_can_activate_links,
.can_neg_ttlm = iwl_mvm_mld_can_neg_ttlm,
+ .prep_add_interface = iwl_mvm_mld_prep_add_interface,
};
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
index 28a9d90ad1cd..99eb1e1db1bb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
@@ -1182,6 +1182,9 @@ int iwl_mvm_mld_update_sta_links(struct iwl_mvm *mvm,
link_sta_added_to_fw |= BIT(link_id);
iwl_mvm_rs_add_sta_link(mvm, mvm_sta_link);
+
+ iwl_mvm_rs_rate_init(mvm, vif, sta, link_conf, link_sta,
+ link_conf->chanreq.oper.chan->band);
}
if (sta_mask_added) {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index ef07cff203b0..5aa48c77b054 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -361,6 +361,9 @@ struct iwl_mvm_vif_link_info {
* @IWL_MVM_ESR_BLOCKED_NON_BSS: An active non-BSS interface's link is
* preventing EMLSR
* @IWL_MVM_ESR_BLOCKED_ROC: remain-on-channel is preventing EMLSR
+ * @IWL_MVM_ESR_BLOCKED_TMP_NON_BSS: An expected active non-BSS interface's link
+ * is preventing EMLSR. This is a temporary blocking that is set when there
+ * is an indication that a non-BSS interface is to be added.
* @IWL_MVM_ESR_EXIT_MISSED_BEACON: exited EMLSR due to missed beacons
* @IWL_MVM_ESR_EXIT_LOW_RSSI: link is deactivated/not allowed for EMLSR
* due to low RSSI.
@@ -379,6 +382,7 @@ enum iwl_mvm_esr_state {
IWL_MVM_ESR_BLOCKED_FW = 0x8,
IWL_MVM_ESR_BLOCKED_NON_BSS = 0x10,
IWL_MVM_ESR_BLOCKED_ROC = 0x20,
+ IWL_MVM_ESR_BLOCKED_TMP_NON_BSS = 0x40,
IWL_MVM_ESR_EXIT_MISSED_BEACON = 0x10000,
IWL_MVM_ESR_EXIT_LOW_RSSI = 0x20000,
IWL_MVM_ESR_EXIT_COEX = 0x40000,
@@ -452,6 +456,8 @@ struct iwl_mvm_esr_exit {
* @prevent_esr_done_wk: work that should be done when esr prevention ends.
* @mlo_int_scan_wk: work for the internal MLO scan.
* @unblock_esr_tpt_wk: work for unblocking EMLSR when tpt is high enough.
+ * @unblock_esr_tmp_non_bss_wk: work for removing the
+ * IWL_MVM_ESR_BLOCKED_TMP_NON_BSS blocking for EMLSR.
* @roc_activity: currently running ROC activity for this vif (or
* ROC_NUM_ACTIVITIES if no activity is running).
* @session_prot_connection_loss: the connection was lost due to session
@@ -588,6 +594,7 @@ struct iwl_mvm_vif {
struct wiphy_delayed_work prevent_esr_done_wk;
struct wiphy_delayed_work mlo_int_scan_wk;
struct wiphy_work unblock_esr_tpt_wk;
+ struct wiphy_delayed_work unblock_esr_tmp_non_bss_wk;
struct iwl_mvm_vif_link_info deflink;
struct iwl_mvm_vif_link_info *link[IEEE80211_MLD_MAX_NUM_LINKS];
@@ -773,7 +780,6 @@ struct iwl_mvm_tcm {
* @head_sn: reorder window head sn
* @num_stored: number of mpdus stored in the buffer
* @queue: queue of this reorder buffer
- * @last_amsdu: track last ASMDU SN for duplication detection
* @valid: reordering is valid for this queue
* @lock: protect reorder buffer internal state
*/
@@ -781,7 +787,6 @@ struct iwl_mvm_reorder_buffer {
u16 head_sn;
u16 num_stored;
int queue;
- u16 last_amsdu;
bool valid;
spinlock_t lock;
} ____cacheline_aligned_in_smp;
@@ -1584,8 +1589,7 @@ static inline bool iwl_mvm_bt_is_rrc_supported(struct iwl_mvm *mvm)
static inline bool iwl_mvm_is_csum_supported(struct iwl_mvm *mvm)
{
return fw_has_capa(&mvm->fw->ucode_capa,
- IWL_UCODE_TLV_CAPA_CSUM_SUPPORT) &&
- !IWL_MVM_HW_CSUM_DISABLE;
+ IWL_UCODE_TLV_CAPA_CSUM_SUPPORT);
}
static inline bool iwl_mvm_is_mplut_supported(struct iwl_mvm *mvm)
@@ -2914,7 +2918,7 @@ iwl_mvm_mac_release_buffered_frames(struct ieee80211_hw *hw,
bool more_data);
int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, u32 changed);
+ struct ieee80211_link_sta *link_sta, u32 changed);
void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_prep_tx_info *info);
@@ -2982,7 +2986,8 @@ void iwl_mvm_abort_pmsr(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
bool iwl_mvm_have_links_same_channel(struct iwl_mvm_vif *vif1,
struct iwl_mvm_vif *vif2);
bool iwl_mvm_vif_is_active(struct iwl_mvm_vif *mvmvif);
-int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+int iwl_mvm_set_tx_power(struct iwl_mvm *mvm,
+ struct ieee80211_bss_conf *bss_conf,
s16 tx_power);
int iwl_mvm_set_hw_timestamp(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
index 05715e5af6ab..de5ac000272e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
@@ -440,12 +440,6 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
mvmsta = iwl_mvm_sta_from_mac80211(sta);
- if (!mvmsta) {
- IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n",
- notif->sta_id);
- goto out;
- }
-
flags = le32_to_cpu(notif->flags);
mvm_link_sta = rcu_dereference(mvmsta->link[link_sta->link_id]);
@@ -615,11 +609,8 @@ void iwl_mvm_rs_fw_rate_init(struct iwl_mvm *mvm,
int cmd_ver;
int ret;
- /* Enable external EHT LTF only for GL device and if there's
- * mutual support by AP and client
- */
- if (CSR_HW_REV_TYPE(mvm->trans->hw_rev) == IWL_CFG_MAC_TYPE_GL &&
- sband_eht_cap &&
+ /* Enable extra EHT LTF if there's mutual support by AP and client */
+ if (sband_eht_cap &&
sband_eht_cap->eht_cap_elem.phy_cap_info[5] &
IEEE80211_EHT_PHY_CAP5_SUPP_EXTRA_EHT_LTF &&
link_sta->eht_cap.has_eht &&
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 65f8933c34b4..a2f16bfaec44 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -773,9 +773,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
return false;
}
- rcu_read_lock();
sta_mask = iwl_mvm_sta_fw_id_mask(mvm, sta, -1);
- rcu_read_unlock();
if (IWL_FW_CHECK(mvm,
tid != baid_data->tid ||
@@ -814,7 +812,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
if (!buffer->num_stored && ieee80211_sn_less(sn, nssn)) {
if (!amsdu || last_subframe)
buffer->head_sn = nssn;
- /* No need to update AMSDU last SN - we are moving the head */
+
spin_unlock_bh(&buffer->lock);
return false;
}
@@ -831,7 +829,6 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
if (!amsdu || last_subframe)
buffer->head_sn = ieee80211_sn_inc(buffer->head_sn);
- /* No need to update AMSDU last SN - we are moving the head */
spin_unlock_bh(&buffer->lock);
return false;
}
@@ -841,9 +838,6 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
__skb_queue_tail(&entries[index].frames, skb);
buffer->num_stored++;
- if (amsdu)
- buffer->last_amsdu = sn;
-
/*
* We cannot trust NSSN for AMSDU sub-frames that are not the last.
* The reason is that NSSN advances on the first sub-frame, and may
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index b6c99cd6d9e5..9d05c344d967 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -4328,7 +4328,10 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
unsigned int wdg_timeout =
iwl_mvm_get_wd_timeout(mvm, vif);
bool mld = iwl_mvm_has_mld_api(mvm->fw);
- u32 type = mld ? STATION_TYPE_PEER : IWL_STA_LINK;
+ u32 type = IWL_STA_LINK;
+
+ if (mld)
+ type = STATION_TYPE_PEER;
ret = iwl_mvm_allocate_int_sta(mvm, sta, 0,
NL80211_IFTYPE_UNSPECIFIED, type);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 9fe050f0ddc1..1ef14340953c 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -2351,6 +2351,10 @@ void iwl_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
txq_write_ptr = txq->write_ptr;
spin_unlock(&txq->lock);
+ /* There is nothing to do if we are flushing an empty queue */
+ if (is_flush && txq_write_ptr == txq_read_ptr)
+ goto out;
+
read_ptr = iwl_txq_get_cmd_index(txq, txq_read_ptr);
if (!test_bit(txq_id, trans_pcie->txqs.queue_used)) {
diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c
index d33a994906a7..27f44a9f0bc1 100644
--- a/drivers/net/wireless/intersil/p54/p54spi.c
+++ b/drivers/net/wireless/intersil/p54/p54spi.c
@@ -624,7 +624,7 @@ static int p54spi_probe(struct spi_device *spi)
gpio_direction_input(p54spi_gpio_irq);
ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
- p54spi_interrupt, 0, "p54spi",
+ p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi",
priv->spi);
if (ret < 0) {
dev_err(&priv->spi->dev, "request_irq() failed");
@@ -633,8 +633,6 @@ static int p54spi_probe(struct spi_device *spi)
irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
- disable_irq(gpio_to_irq(p54spi_gpio_irq));
-
INIT_WORK(&priv->work, p54spi_work);
init_completion(&priv->fw_comp);
INIT_LIST_HEAD(&priv->tx_pending);
diff --git a/drivers/net/wireless/marvell/libertas/Kconfig b/drivers/net/wireless/marvell/libertas/Kconfig
index 36b234bc5be8..caf8bc231b2e 100644
--- a/drivers/net/wireless/marvell/libertas/Kconfig
+++ b/drivers/net/wireless/marvell/libertas/Kconfig
@@ -3,7 +3,6 @@ config LIBERTAS
tristate "Marvell 8xxx Libertas WLAN driver support"
depends on USB || MMC || SPI
depends on CFG80211
- select LIB80211
select FW_LOADER
help
A library for Marvell Libertas 8xxx devices.
diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/marvell/libertas/cfg.c
index afe9bcd3ad46..2e2c193716d9 100644
--- a/drivers/net/wireless/marvell/libertas/cfg.c
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
@@ -486,6 +486,7 @@ static int lbs_add_wps_enrollee_tlv(u8 *tlv, const u8 *ie, size_t ie_len)
*/
static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
+ struct net_device *dev,
struct cfg80211_chan_def *chandef)
{
struct lbs_private *priv = wiphy_priv(wiphy);
diff --git a/drivers/net/wireless/marvell/libertas/mesh.h b/drivers/net/wireless/marvell/libertas/mesh.h
index 44c4cd0230a8..e37db10e82a9 100644
--- a/drivers/net/wireless/marvell/libertas/mesh.h
+++ b/drivers/net/wireless/marvell/libertas/mesh.h
@@ -7,7 +7,6 @@
#include <net/iw_handler.h>
-#include <net/lib80211.h>
#include "host.h"
#include "dev.h"
diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
index 1cff001bdc51..b30ed321c625 100644
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
@@ -938,8 +938,10 @@ void mwifiex_process_assoc_resp(struct mwifiex_adapter *adapter)
assoc_resp.links[0].bss = priv->req_bss;
assoc_resp.buf = priv->assoc_rsp_buf;
assoc_resp.len = priv->assoc_rsp_size;
+ wiphy_lock(priv->wdev.wiphy);
cfg80211_rx_assoc_resp(priv->netdev,
&assoc_resp);
+ wiphy_unlock(priv->wdev.wiphy);
priv->assoc_rsp_size = 0;
}
}
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index d03129d5d24e..4a96281792cc 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -875,7 +875,7 @@ struct mwifiex_ietypes_chanstats {
struct mwifiex_ie_types_wildcard_ssid_params {
struct mwifiex_ie_types_header header;
u8 max_ssid_length;
- u8 ssid[1];
+ u8 ssid[];
} __packed;
#define TSF_DATA_SIZE 8
diff --git a/drivers/net/wireless/marvell/mwifiex/ioctl.h b/drivers/net/wireless/marvell/mwifiex/ioctl.h
index 516159b721d3..74747d3a379a 100644
--- a/drivers/net/wireless/marvell/mwifiex/ioctl.h
+++ b/drivers/net/wireless/marvell/mwifiex/ioctl.h
@@ -8,7 +8,7 @@
#ifndef _MWIFIEX_IOCTL_H_
#define _MWIFIEX_IOCTL_H_
-#include <net/lib80211.h>
+#define NUM_WEP_KEYS 4
enum {
MWIFIEX_SCAN_TYPE_UNCHANGED = 0,
diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
index 6d8f1d1d7ca4..5a1a0287c1d5 100644
--- a/drivers/net/wireless/marvell/mwifiex/join.c
+++ b/drivers/net/wireless/marvell/mwifiex/join.c
@@ -663,7 +663,6 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
bool enable_data = true;
u16 cap_info, status_code, aid;
const u8 *ie_ptr;
- struct ieee80211_ht_operation *assoc_resp_ht_oper;
if (!priv->attempted_bss_desc) {
mwifiex_dbg(priv->adapter, ERROR,
@@ -779,14 +778,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
ie_ptr = cfg80211_find_ie(WLAN_EID_HT_OPERATION, assoc_rsp->ie_buffer,
priv->assoc_rsp_size
- sizeof(struct ieee_types_assoc_rsp));
- if (ie_ptr) {
- assoc_resp_ht_oper = (struct ieee80211_ht_operation *)(ie_ptr
- + sizeof(struct ieee_types_header));
- priv->assoc_resp_ht_param = assoc_resp_ht_oper->ht_param;
- priv->ht_param_present = true;
- } else {
- priv->ht_param_present = false;
- }
+
+ priv->ht_param_present = ie_ptr ? true : false;
mwifiex_dbg(priv->adapter, INFO,
"info: ASSOC_RESP: curr_pkt_filter is %#x\n",
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index 96d1f6039fbc..855019fe5485 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1679,7 +1679,8 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
}
ret = devm_request_irq(dev, adapter->irq_wakeup,
- mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW,
+ mwifiex_irq_wakeup_handler,
+ IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN,
"wifi_wake", adapter);
if (ret) {
dev_err(dev, "Failed to request irq_wakeup %d (%d)\n",
@@ -1687,7 +1688,6 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
goto err_exit;
}
- disable_irq(adapter->irq_wakeup);
if (device_init_wakeup(dev, true)) {
dev_err(dev, "fail to init wakeup for mwifiex\n");
goto err_exit;
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index 566adce3413c..0674dcf7a537 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -19,7 +19,6 @@
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <net/sock.h>
-#include <net/lib80211.h>
#include <linux/vmalloc.h>
#include <linux/firmware.h>
#include <linux/ctype.h>
@@ -574,7 +573,6 @@ struct mwifiex_private {
u16 listen_interval;
u16 atim_window;
u8 adhoc_channel;
- u8 adhoc_is_link_sensed;
u8 adhoc_state;
struct mwifiex_802_11_security sec_info;
struct mwifiex_wep_key wep_key[NUM_WEP_KEYS];
@@ -683,7 +681,6 @@ struct mwifiex_private {
struct mwifiex_ds_mem_rw mem_rw;
struct sk_buff_head bypass_txq;
struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX];
- u8 assoc_resp_ht_param;
bool ht_param_present;
};
@@ -802,7 +799,6 @@ struct mwifiex_auto_tdls_peer {
unsigned long rssi_jiffies;
u8 failure_count;
u8 do_discover;
- u8 do_setup;
};
#define MWIFIEX_TYPE_AGGR_DATA_V2 11
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index b5f3821a6a8f..400348abeee5 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -177,17 +177,14 @@ void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code,
priv->is_data_rate_auto = true;
priv->data_rate = 0;
- priv->assoc_resp_ht_param = 0;
priv->ht_param_present = false;
if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) && priv->hist_data)
mwifiex_hist_data_reset(priv);
- if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+ if (priv->bss_mode == NL80211_IFTYPE_ADHOC)
priv->adhoc_state = ADHOC_IDLE;
- priv->adhoc_is_link_sensed = false;
- }
/*
* Memorize the previous SSID and BSSID so
@@ -843,7 +840,6 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
case EVENT_ADHOC_BCN_LOST:
mwifiex_dbg(adapter, EVENT, "event: ADHOC_BCN_LOST\n");
- priv->adhoc_is_link_sensed = false;
mwifiex_clean_txrx(priv);
mwifiex_stop_net_dev_queue(priv->netdev, adapter);
if (netif_carrier_ok(priv->netdev))
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
index d3cba6895f8c..e06a0622973e 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
@@ -351,8 +351,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
goto done;
}
- priv->adhoc_is_link_sensed = false;
-
ret = mwifiex_check_network_compatibility(priv, bss_desc);
mwifiex_stop_net_dev_queue(priv->netdev, adapter);
diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c
index 7823e67694e8..0a5f340876c3 100644
--- a/drivers/net/wireless/marvell/mwifiex/tdls.c
+++ b/drivers/net/wireless/marvell/mwifiex/tdls.c
@@ -1306,7 +1306,6 @@ int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb)
peer->mac_addr,
NL80211_TDLS_SETUP,
0, GFP_ATOMIC);
- peer->do_setup = false;
priv->check_tdls_tx = false;
} else if (peer->failure_count <
MWIFIEX_TDLS_MAX_FAIL_COUNT &&
@@ -1465,7 +1464,6 @@ void mwifiex_check_auto_tdls(struct timer_list *t)
tdls_peer->failure_count <
MWIFIEX_TDLS_MAX_FAIL_COUNT) {
priv->check_tdls_tx = true;
- tdls_peer->do_setup = true;
mwifiex_dbg(priv->adapter, INFO,
"check TDLS with peer=%pM\t"
"rssi=%d\n", tdls_peer->mac_addr,
diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
index 42c04bf858da..1f1f6280a0f2 100644
--- a/drivers/net/wireless/marvell/mwifiex/util.c
+++ b/drivers/net/wireless/marvell/mwifiex/util.c
@@ -494,7 +494,9 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
}
}
+ wiphy_lock(priv->wdev.wiphy);
cfg80211_rx_mlme_mgmt(priv->netdev, skb->data, pkt_len);
+ wiphy_unlock(priv->wdev.wiphy);
}
if (priv->adapter->host_mlme_enabled &&
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index d75e8dea1fbd..c6f498fc81ff 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -1163,9 +1163,10 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
+ struct ieee80211_link_sta *link_sta,
u32 changed)
{
+ struct ieee80211_sta *sta = link_sta->sta;
struct mt7915_phy *phy = mt7915_hw_phy(hw);
struct mt7915_dev *dev = phy->dev;
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
@@ -1709,7 +1710,7 @@ const struct ieee80211_ops mt7915_ops = {
.stop_ap = mt7915_stop_ap,
.sta_state = mt76_sta_state,
.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
- .sta_rc_update = mt7915_sta_rc_update,
+ .link_sta_rc_update = mt7915_sta_rc_update,
.set_key = mt7915_set_key,
.ampdu_action = mt7915_ampdu_action,
.set_rts_threshold = mt7915_set_rts_threshold,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 39f071ece35e..2b34ae5e0cb5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -1060,9 +1060,10 @@ static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta)
static void mt7996_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
+ struct ieee80211_link_sta *link_sta,
u32 changed)
{
+ struct ieee80211_sta *sta = link_sta->sta;
struct mt7996_phy *phy = mt7996_hw_phy(hw);
struct mt7996_dev *dev = phy->dev;
@@ -1472,7 +1473,7 @@ const struct ieee80211_ops mt7996_ops = {
.sta_add = mt7996_sta_add,
.sta_remove = mt7996_sta_remove,
.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
- .sta_rc_update = mt7996_sta_rc_update,
+ .link_sta_rc_update = mt7996_sta_rc_update,
.set_key = mt7996_set_key,
.ampdu_action = mt7996_ampdu_action,
.set_rts_threshold = mt7996_set_rts_threshold,
diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
index eb37b228d54e..e96736cc7259 100644
--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
@@ -231,6 +231,7 @@ struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
}
static int set_channel(struct wiphy *wiphy,
+ struct net_device *dev,
struct cfg80211_chan_def *chandef)
{
struct wilc *wl = wiphy_priv(wiphy);
@@ -1424,7 +1425,7 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
struct wilc_vif *vif = netdev_priv(dev);
int ret;
- ret = set_channel(wiphy, &settings->chandef);
+ ret = set_channel(wiphy, dev, &settings->chandef);
if (ret != 0)
netdev_err(dev, "Error in setting channel\n");
@@ -1757,57 +1758,10 @@ void wlan_deinit_locks(struct wilc *wilc)
cleanup_srcu_struct(&wilc->srcu);
}
-int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
- const struct wilc_hif_func *ops)
-{
- struct wilc *wl;
- int ret, i;
-
- wl = wilc_create_wiphy(dev);
- if (!wl)
- return -EINVAL;
-
- wlan_init_locks(wl);
-
- ret = wilc_wlan_cfg_init(wl);
- if (ret)
- goto free_wl;
-
- *wilc = wl;
- wl->io_type = io_type;
- wl->hif_func = ops;
-
- for (i = 0; i < NQUEUES; i++)
- INIT_LIST_HEAD(&wl->txq[i].txq_head.list);
-
- INIT_LIST_HEAD(&wl->rxq_head.list);
- INIT_LIST_HEAD(&wl->vif_list);
-
- wl->hif_workqueue = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM,
- wiphy_name(wl->wiphy));
- if (!wl->hif_workqueue) {
- ret = -ENOMEM;
- goto free_cfg;
- }
-
- return 0;
-
-free_cfg:
- wilc_wlan_cfg_deinit(wl);
-
-free_wl:
- wlan_deinit_locks(wl);
- wiphy_unregister(wl->wiphy);
- wiphy_free(wl->wiphy);
- return ret;
-}
-EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
-
-struct wilc *wilc_create_wiphy(struct device *dev)
+static struct wilc *wilc_create_wiphy(struct device *dev)
{
struct wiphy *wiphy;
struct wilc *wl;
- int ret;
wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
if (!wiphy)
@@ -1850,17 +1804,66 @@ struct wilc *wilc_create_wiphy(struct device *dev)
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_CLIENT);
wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
- wiphy->features |= NL80211_FEATURE_SAE;
set_wiphy_dev(wiphy, dev);
wl->wiphy = wiphy;
- ret = wiphy_register(wiphy);
- if (ret) {
- wiphy_free(wiphy);
- return NULL;
- }
return wl;
}
+int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
+ const struct wilc_hif_func *ops)
+{
+ struct wilc *wl;
+ int ret, i;
+
+ wl = wilc_create_wiphy(dev);
+ if (!wl)
+ return -EINVAL;
+
+ wlan_init_locks(wl);
+
+ ret = wilc_wlan_cfg_init(wl);
+ if (ret)
+ goto free_wl;
+
+ *wilc = wl;
+ wl->io_type = io_type;
+ wl->hif_func = ops;
+
+ for (i = 0; i < NQUEUES; i++)
+ INIT_LIST_HEAD(&wl->txq[i].txq_head.list);
+
+ INIT_LIST_HEAD(&wl->rxq_head.list);
+ INIT_LIST_HEAD(&wl->vif_list);
+
+ wl->hif_workqueue = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM,
+ wiphy_name(wl->wiphy));
+ if (!wl->hif_workqueue) {
+ ret = -ENOMEM;
+ goto free_cfg;
+ }
+
+ return 0;
+
+free_cfg:
+ wilc_wlan_cfg_deinit(wl);
+
+free_wl:
+ wlan_deinit_locks(wl);
+ wiphy_free(wl->wiphy);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
+
+int wilc_cfg80211_register(struct wilc *wilc)
+{
+ /* WPA3/SAE supported only on WILC1000 */
+ if (is_wilc1000(wilc->chipid))
+ wilc->wiphy->features |= NL80211_FEATURE_SAE;
+
+ return wiphy_register(wilc->wiphy);
+}
+EXPORT_SYMBOL_GPL(wilc_cfg80211_register);
+
int wilc_init_host_int(struct net_device *net)
{
int ret;
diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.h b/drivers/net/wireless/microchip/wilc1000/cfg80211.h
index 8c65951cfaf9..2dc9c1c42d60 100644
--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.h
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.h
@@ -10,7 +10,7 @@
int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
const struct wilc_hif_func *ops);
-struct wilc *wilc_create_wiphy(struct device *dev);
+int wilc_cfg80211_register(struct wilc *wilc);
void wilc_deinit_host_int(struct net_device *net);
int wilc_init_host_int(struct net_device *net);
void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size);
diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c
index 9ecf3fb29b55..7e84fc0fd911 100644
--- a/drivers/net/wireless/microchip/wilc1000/netdev.c
+++ b/drivers/net/wireless/microchip/wilc1000/netdev.c
@@ -23,6 +23,12 @@
#define __WILC1000_FW(api) WILC1000_FW_PREFIX #api ".bin"
#define WILC1000_FW(api) __WILC1000_FW(api)
+#define WILC3000_API_VER 1
+
+#define WILC3000_FW_PREFIX "atmel/wilc3000_wifi_firmware-"
+#define __WILC3000_FW(api) WILC3000_FW_PREFIX #api ".bin"
+#define WILC3000_FW(api) __WILC3000_FW(api)
+
static irqreturn_t isr_uh_routine(int irq, void *user_data)
{
struct wilc *wilc = user_data;
@@ -195,20 +201,24 @@ static int wilc_wlan_get_firmware(struct net_device *dev)
{
struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wilc = vif->wilc;
- int chip_id;
const struct firmware *wilc_fw;
+ char *firmware;
int ret;
- chip_id = wilc_get_chipid(wilc, false);
+ if (is_wilc1000(wilc->chipid))
+ firmware = WILC1000_FW(WILC1000_API_VER);
+ else if (is_wilc3000(wilc->chipid))
+ firmware = WILC3000_FW(WILC3000_API_VER);
+ else
+ return -EINVAL;
- netdev_info(dev, "ChipID [%x] loading firmware [%s]\n", chip_id,
- WILC1000_FW(WILC1000_API_VER));
+ netdev_info(dev, "WILC%d loading firmware [%s]\n",
+ is_wilc1000(wilc->chipid) ? 1000 : 3000,
+ firmware);
- ret = request_firmware(&wilc_fw, WILC1000_FW(WILC1000_API_VER),
- wilc->dev);
+ ret = request_firmware(&wilc_fw, firmware, wilc->dev);
if (ret != 0) {
- netdev_err(dev, "%s - firmware not available\n",
- WILC1000_FW(WILC1000_API_VER));
+ netdev_err(dev, "%s - firmware not available\n", firmware);
return -EINVAL;
}
wilc->firmware = wilc_fw;
@@ -233,7 +243,7 @@ static int wilc_start_firmware(struct net_device *dev)
return 0;
}
-static int wilc1000_firmware_download(struct net_device *dev)
+static int wilc_firmware_download(struct net_device *dev)
{
struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wilc = vif->wilc;
@@ -528,7 +538,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
if (ret)
goto fail_irq_enable;
- ret = wilc1000_firmware_download(dev);
+ ret = wilc_firmware_download(dev);
if (ret)
goto fail_irq_enable;
@@ -608,6 +618,9 @@ static int wilc_mac_open(struct net_device *ndev)
return ret;
}
+ wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), vif->iftype,
+ vif->idx);
+
netdev_dbg(ndev, "Mac address: %pM\n", ndev->dev_addr);
ret = wilc_set_mac_address(vif, ndev->dev_addr);
if (ret) {
@@ -618,9 +631,6 @@ static int wilc_mac_open(struct net_device *ndev)
return ret;
}
- wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), vif->iftype,
- vif->idx);
-
mgmt_regs.interface_stypes = vif->mgmt_reg_stypes;
/* so we detect a change */
vif->mgmt_reg_stypes = 0;
@@ -1014,3 +1024,4 @@ EXPORT_SYMBOL_GPL(wilc_netdev_ifc_init);
MODULE_DESCRIPTION("Atmel WILC1000 core wireless driver");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE(WILC1000_FW(WILC1000_API_VER));
+MODULE_FIRMWARE(WILC3000_FW(WILC3000_API_VER));
diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c
index b4da05d5a498..5262c8846c13 100644
--- a/drivers/net/wireless/microchip/wilc1000/sdio.c
+++ b/drivers/net/wireless/microchip/wilc1000/sdio.c
@@ -182,6 +182,14 @@ static int wilc_sdio_probe(struct sdio_func *func,
wilc_sdio_init(wilc, false);
+ ret = wilc_get_chipid(wilc);
+ if (ret)
+ goto dispose_irq;
+
+ ret = wilc_cfg80211_register(wilc);
+ if (ret)
+ goto dispose_irq;
+
ret = wilc_load_mac_from_nv(wilc);
if (ret) {
pr_err("Can not retrieve MAC address from chip\n");
@@ -667,7 +675,6 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume)
struct wilc_sdio *sdio_priv = wilc->bus_data;
struct sdio_cmd52 cmd;
int loop, ret;
- u32 chipid;
/**
* function 0 csa enable
@@ -756,18 +763,6 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume)
return ret;
}
- /**
- * make sure can read back chip id correctly
- **/
- if (!resume) {
- ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid);
- if (ret) {
- dev_err(&func->dev, "Fail cmd read chip id...\n");
- return ret;
- }
- dev_err(&func->dev, "chipid (%08x)\n", chipid);
- }
-
sdio_priv->isinit = true;
return 0;
}
@@ -815,13 +810,19 @@ static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status)
cmd.address = WILC_SDIO_EXT_IRQ_FLAG_REG;
} else {
cmd.function = 0;
- cmd.address = WILC_SDIO_IRQ_FLAG_REG;
+ cmd.address = is_wilc1000(wilc->chipid) ?
+ WILC1000_SDIO_IRQ_FLAG_REG :
+ WILC3000_SDIO_IRQ_FLAG_REG;
}
cmd.raw = 0;
cmd.read_write = 0;
cmd.data = 0;
wilc_sdio_cmd52(wilc, &cmd);
irq_flags = cmd.data;
+
+ if (sdio_priv->irq_gpio)
+ irq_flags &= is_wilc1000(wilc->chipid) ? 0x1f : 0x0f;
+
tmp |= FIELD_PREP(IRG_FLAGS_MASK, cmd.data);
if (FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags))
@@ -843,22 +844,56 @@ static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
if (sdio_priv->irq_gpio)
reg = val & (BIT(MAX_NUM_INT) - 1);
- /* select VMM table 0 */
- if (val & SEL_VMM_TBL0)
- reg |= BIT(5);
- /* select VMM table 1 */
- if (val & SEL_VMM_TBL1)
- reg |= BIT(6);
- /* enable VMM */
- if (val & EN_VMM)
- reg |= BIT(7);
+ if (is_wilc1000(wilc->chipid)) {
+ /* select VMM table 0 */
+ if (val & SEL_VMM_TBL0)
+ reg |= BIT(5);
+ /* select VMM table 1 */
+ if (val & SEL_VMM_TBL1)
+ reg |= BIT(6);
+ /* enable VMM */
+ if (val & EN_VMM)
+ reg |= BIT(7);
+ } else {
+ if (sdio_priv->irq_gpio && reg) {
+ struct sdio_cmd52 cmd;
+
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = WILC3000_SDIO_IRQ_FLAG_REG;
+ cmd.data = reg;
+
+ ret = wilc_sdio_cmd52(wilc, &cmd);
+ if (ret) {
+ dev_err(&func->dev,
+ "Failed cmd52, set 0xfe data (%d) ...\n",
+ __LINE__);
+ return ret;
+ }
+ }
+
+ reg = 0;
+ /* select VMM table 0 */
+ if (val & SEL_VMM_TBL0)
+ reg |= BIT(0);
+ /* select VMM table 1 */
+ if (val & SEL_VMM_TBL1)
+ reg |= BIT(1);
+ /* enable VMM */
+ if (val & EN_VMM)
+ reg |= BIT(2);
+ }
+
if (reg) {
struct sdio_cmd52 cmd;
cmd.read_write = 1;
cmd.function = 0;
cmd.raw = 0;
- cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG;
+ cmd.address = is_wilc1000(wilc->chipid) ?
+ WILC1000_SDIO_IRQ_CLEAR_FLAG_REG :
+ WILC3000_SDIO_VMM_TBL_CTRL_REG;
cmd.data = reg;
ret = wilc_sdio_cmd52(wilc, &cmd);
@@ -979,17 +1014,15 @@ static int wilc_sdio_suspend(struct device *dev)
if (!IS_ERR(wilc->rtc_clk))
clk_disable_unprepare(wilc->rtc_clk);
- host_sleep_notify(wilc);
-
- wilc_sdio_disable_interrupt(wilc);
-
- ret = wilc_sdio_reset(wilc);
+ ret = host_sleep_notify(wilc);
if (ret) {
- dev_err(&func->dev, "Fail reset sdio\n");
+ clk_prepare_enable(wilc->rtc_clk);
return ret;
}
- return 0;
+ wilc_sdio_disable_interrupt(wilc);
+
+ return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
}
static int wilc_sdio_resume(struct device *dev)
@@ -1008,9 +1041,7 @@ static int wilc_sdio_resume(struct device *dev)
wilc_sdio_init(wilc, true);
wilc_sdio_enable_interrupt(wilc);
- host_wakeup_notify(wilc);
-
- return 0;
+ return host_wakeup_notify(wilc);
}
static const struct of_device_id wilc_of_match[] = {
diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c
index 05b577b1068e..ce2a9cdd6aa7 100644
--- a/drivers/net/wireless/microchip/wilc1000/spi.c
+++ b/drivers/net/wireless/microchip/wilc1000/spi.c
@@ -245,7 +245,11 @@ static int wilc_bus_probe(struct spi_device *spi)
if (ret)
goto power_down;
- ret = wilc_validate_chipid(wilc);
+ ret = wilc_get_chipid(wilc);
+ if (ret)
+ goto power_down;
+
+ ret = wilc_cfg80211_register(wilc);
if (ret)
goto power_down;
@@ -1229,7 +1233,7 @@ static int wilc_validate_chipid(struct wilc *wilc)
dev_err(&spi->dev, "Fail cmd read chip id...\n");
return ret;
}
- if (!is_wilc1000(chipid)) {
+ if (!is_wilc1000(chipid) && !is_wilc3000(chipid)) {
dev_err(&spi->dev, "Unknown chip id 0x%x\n", chipid);
return -ENODEV;
}
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c
index 533939e71534..9d80adc45d6b 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.c
@@ -12,20 +12,6 @@
#define WAKE_UP_TRIAL_RETRY 10000
-static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
-{
- mutex_lock(&wilc->hif_cs);
- if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP && wilc->power_save_mode)
- chip_wakeup(wilc);
-}
-
-static inline void release_bus(struct wilc *wilc, enum bus_release release)
-{
- if (release == WILC_BUS_RELEASE_ALLOW_SLEEP && wilc->power_save_mode)
- chip_allow_sleep(wilc);
- mutex_unlock(&wilc->hif_cs);
-}
-
static void wilc_wlan_txq_remove(struct wilc *wilc, u8 q_num,
struct txq_entry_t *tqe)
{
@@ -555,7 +541,7 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
return rqe;
}
-void chip_allow_sleep(struct wilc *wilc)
+static int chip_allow_sleep_wilc1000(struct wilc *wilc)
{
u32 reg = 0;
const struct wilc_hif_func *hif_func = wilc->hif_func;
@@ -584,7 +570,7 @@ void chip_allow_sleep(struct wilc *wilc)
while (--trials) {
ret = hif_func->hif_read_reg(wilc, to_host_from_fw_reg, &reg);
if (ret)
- return;
+ return ret;
if ((reg & to_host_from_fw_bit) == 0)
break;
}
@@ -594,28 +580,62 @@ void chip_allow_sleep(struct wilc *wilc)
/* Clear bit 1 */
ret = hif_func->hif_read_reg(wilc, wakeup_reg, &reg);
if (ret)
- return;
+ return ret;
if (reg & wakeup_bit) {
reg &= ~wakeup_bit;
ret = hif_func->hif_write_reg(wilc, wakeup_reg, reg);
if (ret)
- return;
+ return ret;
}
ret = hif_func->hif_read_reg(wilc, from_host_to_fw_reg, &reg);
if (ret)
- return;
+ return ret;
if (reg & from_host_to_fw_bit) {
reg &= ~from_host_to_fw_bit;
ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg, reg);
if (ret)
- return;
+ return ret;
+ }
+ return 0;
+}
+
+static int chip_allow_sleep_wilc3000(struct wilc *wilc)
+{
+ u32 reg = 0;
+ int ret;
+ const struct wilc_hif_func *hif_func = wilc->hif_func;
+
+ if (wilc->io_type == WILC_HIF_SDIO) {
+ ret = hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
+ if (ret)
+ return ret;
+ ret = hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
+ reg & ~WILC_SDIO_WAKEUP_BIT);
+ if (ret)
+ return ret;
+ } else {
+ ret = hif_func->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, &reg);
+ if (ret)
+ return ret;
+ ret = hif_func->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
+ reg & ~WILC_SPI_WAKEUP_BIT);
+ if (ret)
+ return ret;
}
+ return 0;
+}
+
+static int chip_allow_sleep(struct wilc *wilc)
+{
+ if (is_wilc1000(wilc->chipid))
+ return chip_allow_sleep_wilc1000(wilc);
+ else
+ return chip_allow_sleep_wilc3000(wilc);
}
-EXPORT_SYMBOL_GPL(chip_allow_sleep);
-void chip_wakeup(struct wilc *wilc)
+static int chip_wakeup_wilc1000(struct wilc *wilc)
{
u32 ret = 0;
u32 clk_status_val = 0, trials = 0;
@@ -627,15 +647,15 @@ void chip_wakeup(struct wilc *wilc)
if (wilc->io_type == WILC_HIF_SDIO) {
wakeup_reg = WILC_SDIO_WAKEUP_REG;
wakeup_bit = WILC_SDIO_WAKEUP_BIT;
- clk_status_reg = WILC_SDIO_CLK_STATUS_REG;
- clk_status_bit = WILC_SDIO_CLK_STATUS_BIT;
+ clk_status_reg = WILC1000_SDIO_CLK_STATUS_REG;
+ clk_status_bit = WILC1000_SDIO_CLK_STATUS_BIT;
from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG;
from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT;
} else {
wakeup_reg = WILC_SPI_WAKEUP_REG;
wakeup_bit = WILC_SPI_WAKEUP_BIT;
- clk_status_reg = WILC_SPI_CLK_STATUS_REG;
- clk_status_bit = WILC_SPI_CLK_STATUS_BIT;
+ clk_status_reg = WILC1000_SPI_CLK_STATUS_REG;
+ clk_status_bit = WILC1000_SPI_CLK_STATUS_BIT;
from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG;
from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT;
}
@@ -644,20 +664,20 @@ void chip_wakeup(struct wilc *wilc)
ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg,
from_host_to_fw_bit);
if (ret)
- return;
+ return ret;
/* Set wake-up bit */
ret = hif_func->hif_write_reg(wilc, wakeup_reg,
wakeup_bit);
if (ret)
- return;
+ return ret;
while (trials < WAKE_UP_TRIAL_RETRY) {
ret = hif_func->hif_read_reg(wilc, clk_status_reg,
&clk_status_val);
if (ret) {
pr_err("Bus error %d %x\n", ret, clk_status_val);
- return;
+ return ret;
}
if (clk_status_val & clk_status_bit)
break;
@@ -666,29 +686,135 @@ void chip_wakeup(struct wilc *wilc)
}
if (trials >= WAKE_UP_TRIAL_RETRY) {
pr_err("Failed to wake-up the chip\n");
- return;
+ return -ETIMEDOUT;
}
/* Sometimes spi fail to read clock regs after reading
* writing clockless registers
*/
if (wilc->io_type == WILC_HIF_SPI)
wilc->hif_func->hif_reset(wilc);
+
+ return 0;
}
-EXPORT_SYMBOL_GPL(chip_wakeup);
-void host_wakeup_notify(struct wilc *wilc)
+static int chip_wakeup_wilc3000(struct wilc *wilc)
{
- acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
- wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1);
- release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ u32 wakeup_reg_val, clk_status_reg_val, trials = 0;
+ u32 wakeup_reg, wakeup_bit;
+ u32 clk_status_reg, clk_status_bit;
+ int wake_seq_trials = 5;
+ const struct wilc_hif_func *hif_func = wilc->hif_func;
+
+ if (wilc->io_type == WILC_HIF_SDIO) {
+ wakeup_reg = WILC_SDIO_WAKEUP_REG;
+ wakeup_bit = WILC_SDIO_WAKEUP_BIT;
+ clk_status_reg = WILC3000_SDIO_CLK_STATUS_REG;
+ clk_status_bit = WILC3000_SDIO_CLK_STATUS_BIT;
+ } else {
+ wakeup_reg = WILC_SPI_WAKEUP_REG;
+ wakeup_bit = WILC_SPI_WAKEUP_BIT;
+ clk_status_reg = WILC3000_SPI_CLK_STATUS_REG;
+ clk_status_bit = WILC3000_SPI_CLK_STATUS_BIT;
+ }
+
+ hif_func->hif_read_reg(wilc, wakeup_reg, &wakeup_reg_val);
+ do {
+ hif_func->hif_write_reg(wilc, wakeup_reg, wakeup_reg_val |
+ wakeup_bit);
+ /* Check the clock status */
+ hif_func->hif_read_reg(wilc, clk_status_reg,
+ &clk_status_reg_val);
+
+ /* In case of clocks off, wait 1ms, and check it again.
+ * if still off, wait for another 1ms, for a total wait of 3ms.
+ * If still off, redo the wake up sequence
+ */
+ while ((clk_status_reg_val & clk_status_bit) == 0 &&
+ (++trials % 4) != 0) {
+ /* Wait for the chip to stabilize*/
+ usleep_range(1000, 1100);
+
+ /* Make sure chip is awake. This is an extra step that
+ * can be removed later to avoid the bus access
+ * overhead
+ */
+ hif_func->hif_read_reg(wilc, clk_status_reg,
+ &clk_status_reg_val);
+ }
+ /* in case of failure, Reset the wakeup bit to introduce a new
+ * edge on the next loop
+ */
+ if ((clk_status_reg_val & clk_status_bit) == 0) {
+ hif_func->hif_write_reg(wilc, wakeup_reg,
+ wakeup_reg_val & (~wakeup_bit));
+ /* added wait before wakeup sequence retry */
+ usleep_range(200, 300);
+ }
+ } while ((clk_status_reg_val & clk_status_bit) == 0 && wake_seq_trials-- > 0);
+ if (!wake_seq_trials)
+ dev_err(wilc->dev, "clocks still OFF. Wake up failed\n");
+
+ return 0;
+}
+
+static int chip_wakeup(struct wilc *wilc)
+{
+ if (is_wilc1000(wilc->chipid))
+ return chip_wakeup_wilc1000(wilc);
+ else
+ return chip_wakeup_wilc3000(wilc);
+}
+
+static inline int acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
+{
+ int ret = 0;
+
+ mutex_lock(&wilc->hif_cs);
+ if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP && wilc->power_save_mode) {
+ ret = chip_wakeup(wilc);
+ if (ret)
+ mutex_unlock(&wilc->hif_cs);
+ }
+
+ return ret;
+}
+
+static inline int release_bus(struct wilc *wilc, enum bus_release release)
+{
+ int ret = 0;
+
+ if (release == WILC_BUS_RELEASE_ALLOW_SLEEP && wilc->power_save_mode)
+ ret = chip_allow_sleep(wilc);
+ mutex_unlock(&wilc->hif_cs);
+
+ return ret;
+}
+
+int host_wakeup_notify(struct wilc *wilc)
+{
+ int ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+
+ if (ret)
+ return ret;
+
+ wilc->hif_func->hif_write_reg(wilc, is_wilc1000(wilc->chipid) ?
+ WILC1000_CORTUS_INTERRUPT_2 :
+ WILC3000_CORTUS_INTERRUPT_2, 1);
+ return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
}
EXPORT_SYMBOL_GPL(host_wakeup_notify);
-void host_sleep_notify(struct wilc *wilc)
+int host_sleep_notify(struct wilc *wilc)
{
- acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
- wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1);
- release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ int ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+
+ if (ret)
+ return ret;
+
+ wilc->hif_func->hif_write_reg(wilc, is_wilc1000(wilc->chipid) ?
+ WILC1000_CORTUS_INTERRUPT_1 :
+ WILC3000_CORTUS_INTERRUPT_1, 1);
+ return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
}
EXPORT_SYMBOL_GPL(host_sleep_notify);
@@ -715,6 +841,7 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
int srcu_idx;
u8 *txb = wilc->tx_buffer;
struct wilc_vif *vif;
+ int rv;
if (wilc->quit)
goto out_update_cnt;
@@ -785,7 +912,10 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
goto out_unlock;
vmm_table[i] = 0x0;
- acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ if (ret)
+ goto out_unlock;
+
counter = 0;
func = wilc->hif_func;
do {
@@ -818,19 +948,45 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
if (ret)
break;
- ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
- if (ret)
- break;
+ if (is_wilc1000(wilc->chipid)) {
+ ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
+ if (ret)
+ break;
- do {
- ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
+ do {
+ ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
+ if (ret)
+ break;
+ if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
+ entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
+ break;
+ }
+ } while (--timeout);
+ } else {
+ ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0);
if (ret)
break;
- if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
- entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
+
+ /* interrupt firmware */
+ ret = func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_BASE, 1);
+ if (ret)
break;
- }
- } while (--timeout);
+
+ do {
+ ret = func->hif_read_reg(wilc, WILC_CORTUS_INTERRUPT_BASE, &reg);
+ if (ret)
+ break;
+ if (reg == 0) {
+ /* Get the entries */
+ ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
+ if (ret)
+ break;
+
+ entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
+ break;
+ }
+ } while (--timeout);
+ }
if (timeout <= 0) {
ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
break;
@@ -860,7 +1016,9 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
goto out_release_bus;
}
- release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ ret = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ if (ret)
+ goto out_unlock;
offset = 0;
i = 0;
@@ -922,7 +1080,9 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
for (i = 0; i < NQUEUES; i++)
wilc->txq[i].fw.count += ac_pkt_num_to_chip[i];
- acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ if (ret)
+ goto out_unlock;
ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
if (ret)
@@ -931,7 +1091,9 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
out_release_bus:
- release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ if (!ret && rv)
+ ret = rv;
out_unlock:
mutex_unlock(&wilc->txq_add_to_head_cs);
@@ -1060,8 +1222,14 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
void wilc_handle_isr(struct wilc *wilc)
{
u32 int_status;
+ int ret;
+
+ ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ if (ret) {
+ dev_err_ratelimited(wilc->dev, "Cannot acquire bus\n");
+ return;
+ }
- acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
wilc->hif_func->hif_read_int(wilc, &int_status);
if (int_status & DATA_INT_EXT)
@@ -1070,7 +1238,9 @@ void wilc_handle_isr(struct wilc *wilc)
if (!(int_status & (ALL_INT_EXT)))
wilc_unknown_isr_ext(wilc);
- release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ ret = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ if (ret)
+ dev_err_ratelimited(wilc->dev, "Cannot release bus\n");
}
EXPORT_SYMBOL_GPL(wilc_handle_isr);
@@ -1082,6 +1252,7 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
u8 *dma_buffer;
int ret = 0;
u32 reg = 0;
+ int rv;
blksz = BIT(12);
@@ -1092,7 +1263,9 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
offset = 0;
pr_debug("%s: Downloading firmware size = %d\n", __func__, buffer_size);
- acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ if (ret)
+ return ret;
wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
reg &= ~BIT(10);
@@ -1101,11 +1274,17 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
if (reg & BIT(10))
pr_err("%s: Failed to reset\n", __func__);
- release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+ ret = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+ if (ret)
+ goto fail;
+
do {
addr = get_unaligned_le32(&buffer[offset]);
size = get_unaligned_le32(&buffer[offset + 4]);
- acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ if (ret)
+ goto fail;
+
offset += 8;
while (((int)size) && (offset < buffer_size)) {
if (size <= blksz)
@@ -1123,7 +1302,9 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
offset += size2;
size -= size2;
}
- release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ if (!ret && rv)
+ ret = rv;
if (ret) {
pr_err("%s Bus error\n", __func__);
@@ -1142,7 +1323,7 @@ fail:
int wilc_wlan_start(struct wilc *wilc)
{
u32 reg = 0;
- int ret;
+ int ret, rv;
u32 chipid;
if (wilc->io_type == WILC_HIF_SDIO) {
@@ -1151,7 +1332,10 @@ int wilc_wlan_start(struct wilc *wilc)
} else if (wilc->io_type == WILC_HIF_SPI) {
reg = 1;
}
- acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+ ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+ if (ret)
+ return ret;
+
ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
if (ret)
goto release;
@@ -1160,6 +1344,9 @@ int wilc_wlan_start(struct wilc *wilc)
if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
reg |= WILC_HAVE_SDIO_IRQ_GPIO;
+ if (is_wilc3000(wilc->chipid))
+ reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC;
+
ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
if (ret)
goto release;
@@ -1182,16 +1369,18 @@ int wilc_wlan_start(struct wilc *wilc)
wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
release:
- release_bus(wilc, WILC_BUS_RELEASE_ONLY);
- return ret;
+ rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+ return ret ? ret : rv;
}
int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
{
u32 reg = 0;
- int ret;
+ int ret, rv;
- acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ if (ret)
+ return ret;
ret = wilc->hif_func->hif_read_reg(wilc, GLOBAL_MODE_CONTROL, &reg);
if (ret)
@@ -1227,9 +1416,9 @@ int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
ret = 0;
release:
/* host comm is disabled - we can't issue sleep command anymore: */
- release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+ rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
- return ret;
+ return ret ? ret : rv;
}
void wilc_wlan_cleanup(struct net_device *dev)
@@ -1402,19 +1591,56 @@ int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
return ret;
}
+int wilc_get_chipid(struct wilc *wilc)
+{
+ u32 chipid = 0;
+ u32 rfrevid = 0;
+
+ if (wilc->chipid == 0) {
+ wilc->hif_func->hif_read_reg(wilc, WILC3000_CHIP_ID, &chipid);
+ if (!is_wilc3000(chipid)) {
+ wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
+ wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
+ &rfrevid);
+
+ if (!is_wilc1000(chipid)) {
+ wilc->chipid = 0;
+ return -EINVAL;
+ }
+ if (chipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
+ if (rfrevid != 0x1)
+ chipid = WILC_1000_BASE_ID_2A_REV1;
+ } else if (chipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
+ if (rfrevid == 0x4)
+ chipid = WILC_1000_BASE_ID_2B_REV1;
+ else if (rfrevid != 0x3)
+ chipid = WILC_1000_BASE_ID_2B_REV2;
+ }
+ }
+
+ wilc->chipid = chipid;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wilc_get_chipid);
+
static int init_chip(struct net_device *dev)
{
- u32 chipid;
u32 reg;
- int ret = 0;
+ int ret, rv;
struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wilc = vif->wilc;
- acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ if (ret)
+ return ret;
- chipid = wilc_get_chipid(wilc, true);
+ ret = wilc_get_chipid(wilc);
+ if (ret)
+ goto release;
- if ((chipid & 0xfff) != 0xa0) {
+ if ((wilc->chipid & 0xfff) != 0xa0) {
ret = wilc->hif_func->hif_read_reg(wilc,
WILC_CORTUS_RESET_MUX_SEL,
&reg);
@@ -1439,46 +1665,35 @@ static int init_chip(struct net_device *dev)
}
}
-release:
- release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-
- return ret;
-}
-
-u32 wilc_get_chipid(struct wilc *wilc, bool update)
-{
- u32 chipid = 0;
- u32 rfrevid = 0;
-
- if (wilc->chipid == 0 || update) {
- wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
- wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
- &rfrevid);
- if (!is_wilc1000(chipid)) {
- wilc->chipid = 0;
- return wilc->chipid;
- }
- if (chipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
- if (rfrevid != 0x1)
- chipid = WILC_1000_BASE_ID_2A_REV1;
- } else if (chipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
- if (rfrevid == 0x4)
- chipid = WILC_1000_BASE_ID_2B_REV1;
- else if (rfrevid != 0x3)
- chipid = WILC_1000_BASE_ID_2B_REV2;
+ if (is_wilc3000(wilc->chipid)) {
+ ret = wilc->hif_func->hif_read_reg(wilc, WILC3000_BOOTROM_STATUS, &reg);
+ if (ret) {
+ netdev_err(dev, "failed to read WILC3000 BootROM status register\n");
+ goto release;
}
- wilc->chipid = chipid;
+ ret = wilc->hif_func->hif_write_reg(wilc, WILC3000_CORTUS_BOOT_REGISTER_2,
+ WILC_CORTUS_BOOT_FROM_IRAM);
+ if (ret) {
+ netdev_err(dev, "failed to write WILC3000 Boot register\n");
+ goto release;
+ }
}
- return wilc->chipid;
+
+release:
+ rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+
+ return ret ? ret : rv;
}
int wilc_load_mac_from_nv(struct wilc *wl)
{
- int ret = -EINVAL;
+ int ret, rv;
unsigned int i;
- acquire_bus(wl, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ ret = acquire_bus(wl, WILC_BUS_ACQUIRE_AND_WAKEUP);
+ if (ret)
+ return ret;
for (i = 0; i < WILC_NVMEM_MAX_NUM_BANK; i++) {
int bank_offset = get_bank_offset_from_bank_index(i);
@@ -1517,14 +1732,14 @@ int wilc_load_mac_from_nv(struct wilc *wl)
break;
}
- release_bus(wl, WILC_BUS_RELEASE_ALLOW_SLEEP);
- return ret;
+ rv = release_bus(wl, WILC_BUS_RELEASE_ALLOW_SLEEP);
+ return ret ? ret : rv;
}
EXPORT_SYMBOL_GPL(wilc_load_mac_from_nv);
int wilc_wlan_init(struct net_device *dev)
{
- int ret = 0;
+ int ret = 0, rv;
struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wilc;
@@ -1533,11 +1748,26 @@ int wilc_wlan_init(struct net_device *dev)
wilc->quit = 0;
if (!wilc->hif_func->hif_is_init(wilc)) {
- acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+ ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+ if (ret)
+ return ret;
+
ret = wilc->hif_func->hif_init(wilc, false);
- release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+ if (!ret)
+ ret = wilc_get_chipid(wilc);
+ rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+ if (!ret && rv)
+ ret = rv;
if (ret)
goto fail;
+
+ if (!is_wilc1000(wilc->chipid) && !is_wilc3000(wilc->chipid)) {
+ netdev_err(dev, "Unsupported chipid: %x\n", wilc->chipid);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ netdev_dbg(dev, "chipid (%08x)\n", wilc->chipid);
}
if (!wilc->vmm_table)
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h
index dd2fb3c2f06a..b9e7f9222ead 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan.h
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.h
@@ -96,8 +96,14 @@
#define WILC_SPI_WAKEUP_REG 0x1
#define WILC_SPI_WAKEUP_BIT BIT(1)
-#define WILC_SPI_CLK_STATUS_REG 0x0f
-#define WILC_SPI_CLK_STATUS_BIT BIT(2)
+/* WILC1000 specific */
+#define WILC1000_SPI_CLK_STATUS_REG 0x0f
+#define WILC1000_SPI_CLK_STATUS_BIT BIT(2)
+
+/* WILC3000 specific */
+#define WILC3000_SPI_CLK_STATUS_REG 0x13
+#define WILC3000_SPI_CLK_STATUS_BIT BIT(2)
+
#define WILC_SPI_HOST_TO_FW_REG 0x0b
#define WILC_SPI_HOST_TO_FW_BIT BIT(0)
@@ -123,14 +129,24 @@
#define WILC_SDIO_WAKEUP_REG 0xf0
#define WILC_SDIO_WAKEUP_BIT BIT(0)
-#define WILC_SDIO_CLK_STATUS_REG 0xf1
-#define WILC_SDIO_CLK_STATUS_BIT BIT(0)
+/* WILC1000 */
+#define WILC1000_SDIO_CLK_STATUS_REG 0xf1
+#define WILC1000_SDIO_CLK_STATUS_BIT BIT(0)
+
+#define WILC1000_SDIO_IRQ_FLAG_REG 0xf7
+#define WILC1000_SDIO_IRQ_CLEAR_FLAG_REG 0xf8
+
+/* WILC3000 specific */
+#define WILC3000_SDIO_CLK_STATUS_REG 0xf0 /* clk & wakeup are on same reg */
+#define WILC3000_SDIO_CLK_STATUS_BIT BIT(4)
+
+#define WILC3000_SDIO_VMM_TBL_CTRL_REG 0xf1
+#define WILC3000_SDIO_IRQ_FLAG_REG 0xfe
+/* Common vendor specific CCCR register */
#define WILC_SDIO_INTERRUPT_DATA_SZ_REG 0xf2 /* Read size (2 bytes) */
#define WILC_SDIO_VMM_TBL_CTRL_REG 0xf6
-#define WILC_SDIO_IRQ_FLAG_REG 0xf7
-#define WILC_SDIO_IRQ_CLEAR_FLAG_REG 0xf8
#define WILC_SDIO_HOST_TO_FW_REG 0xfa
#define WILC_SDIO_HOST_TO_FW_BIT BIT(0)
@@ -172,8 +188,11 @@
#define WILC_HAVE_USE_IRQ_AS_HOST_WAKE BIT(8)
#define WILC_CORTUS_INTERRUPT_BASE 0x10A8
-#define WILC_CORTUS_INTERRUPT_1 (WILC_CORTUS_INTERRUPT_BASE + 0x4)
-#define WILC_CORTUS_INTERRUPT_2 (WILC_CORTUS_INTERRUPT_BASE + 0x8)
+#define WILC1000_CORTUS_INTERRUPT_1 (WILC_CORTUS_INTERRUPT_BASE + 0x4)
+#define WILC3000_CORTUS_INTERRUPT_1 (WILC_CORTUS_INTERRUPT_BASE + 0x14)
+
+#define WILC1000_CORTUS_INTERRUPT_2 (WILC_CORTUS_INTERRUPT_BASE + 0x8)
+#define WILC3000_CORTUS_INTERRUPT_2 (WILC_CORTUS_INTERRUPT_BASE + 0x18)
/* tx control register 1 to 4 for RX */
#define WILC_REG_4_TO_1_RX 0x1e1c
@@ -183,6 +202,9 @@
#define WILC_CORTUS_RESET_MUX_SEL 0x1118
#define WILC_CORTUS_BOOT_REGISTER 0xc0000
+#define WILC3000_BOOTROM_STATUS 0x207ac
+#define WILC3000_CORTUS_BOOT_REGISTER_2 0x4f0000
+#define WILC3000_CHIP_ID 0x3b0000
#define WILC_CORTUS_BOOT_FROM_IRAM 0x71
@@ -195,6 +217,8 @@
#define WILC_1000_BASE_ID_2B_REV1 (WILC_1000_BASE_ID_2B + 1)
#define WILC_1000_BASE_ID_2B_REV2 (WILC_1000_BASE_ID_2B + 2)
+#define WILC_3000_BASE_ID 0x300000
+
#define WILC_CHIP_REV_FIELD GENMASK(11, 0)
/********************************************
@@ -413,6 +437,11 @@ static inline bool is_wilc1000(u32 id)
return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
}
+static inline bool is_wilc3000(u32 id)
+{
+ return (id & (~WILC_CHIP_REV_FIELD)) == WILC_3000_BASE_ID;
+}
+
int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
u32 buffer_size);
int wilc_wlan_start(struct wilc *wilc);
@@ -436,13 +465,11 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev);
void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size);
bool wilc_wfi_mgmt_frame_rx(struct wilc_vif *vif, u8 *buff, u32 size);
-void host_wakeup_notify(struct wilc *wilc);
-void host_sleep_notify(struct wilc *wilc);
-void chip_allow_sleep(struct wilc *wilc);
-void chip_wakeup(struct wilc *wilc);
+int host_wakeup_notify(struct wilc *wilc);
+int host_sleep_notify(struct wilc *wilc);
int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
u32 count);
int wilc_wlan_init(struct net_device *dev);
-u32 wilc_get_chipid(struct wilc *wilc, bool update);
+int wilc_get_chipid(struct wilc *wilc);
int wilc_load_mac_from_nv(struct wilc *wilc);
#endif
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 9540ad6196d7..956c5763662f 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -257,7 +257,7 @@ int qtnf_cmd_send_start_ap(struct qtnf_vif *vif,
cmd->beacon_interval = cpu_to_le16(s->beacon_interval);
cmd->hidden_ssid = qlink_hidden_ssid_nl2q(s->hidden_ssid);
cmd->inactivity_timeout = cpu_to_le16(s->inactivity_timeout);
- cmd->smps_mode = s->smps_mode;
+ cmd->smps_mode = NL80211_SMPS_OFF;
cmd->p2p_ctwindow = s->p2p_ctwindow;
cmd->p2p_opp_ps = s->p2p_opp_ps;
cmd->pbss = s->pbss;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.h b/drivers/net/wireless/quantenna/qtnfmac/core.h
index b204a24074ab..b375a4751580 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.h
@@ -13,7 +13,6 @@
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <net/sock.h>
-#include <net/lib80211.h>
#include <net/cfg80211.h>
#include <linux/vmalloc.h>
#include <linux/firmware.h>
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 3bb81bcff0ac..60c2a12e9d5e 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -3607,7 +3607,7 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 52, 0x0C);
rt2800_rfcsr_write(rt2x00dev, 54, 0xF8);
if (rf->channel <= 50) {
- rt2800_rfcsr_write(rt2x00dev, 55, 0x06),
+ rt2800_rfcsr_write(rt2x00dev, 55, 0x06);
rt2800_rfcsr_write(rt2x00dev, 56, 0xD3);
} else if (rf->channel >= 52) {
rt2800_rfcsr_write(rt2x00dev, 55, 0x04);
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c
index 7891c988dd5f..f95898f68d68 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c
@@ -5058,10 +5058,12 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
if (changed & BSS_CHANGED_BEACON_ENABLED) {
- if (bss_conf->enable_beacon)
+ if (bss_conf->enable_beacon) {
rtl8xxxu_start_tx_beacon(priv);
- else
+ schedule_delayed_work(&priv->update_beacon_work, 0);
+ } else {
rtl8xxxu_stop_tx_beacon(priv);
+ }
}
if (changed & BSS_CHANGED_BEACON)
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
index 0e77de1baaf8..bcfc53af4c1a 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
@@ -2040,31 +2040,33 @@ static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
- int params[] = {RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
- EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
- EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
- COUNTRY_CODE_WORLD_WIDE_13};
+ static const int params[] = {
+ RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
+ EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
+ EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
+ COUNTRY_CODE_WORLD_WIDE_13
+ };
u8 *hwinfo;
int i;
bool is_toshiba_smid1 = false;
bool is_toshiba_smid2 = false;
bool is_samsung_smid = false;
bool is_lenovo_smid = false;
- u16 toshiba_smid1[] = {
+ static const u16 toshiba_smid1[] = {
0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
};
- u16 toshiba_smid2[] = {
+ static const u16 toshiba_smid2[] = {
0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
};
- u16 samsung_smid[] = {
+ static const u16 samsung_smid[] = {
0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
0x8193, 0x9191, 0x9192, 0x9193
};
- u16 lenovo_smid[] = {
+ static const u16 lenovo_smid[] = {
0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
};
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index b9b0114e253b..813c12148819 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -267,7 +267,7 @@ static void rtw_fw_scan_result(struct rtw_dev *rtwdev, u8 *payload,
static void rtw_fw_adaptivity_result(struct rtw_dev *rtwdev, u8 *payload,
u8 length)
{
- struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
+ const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
struct rtw_c2h_adaptivity *result = (struct rtw_c2h_adaptivity *)payload;
rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY,
diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index 564f5988ee82..e5abcc20b63c 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -228,7 +228,7 @@ static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask,
}
static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
- const struct rtw_pwr_seq_cmd **cmd_seq)
+ const struct rtw_pwr_seq_cmd * const *cmd_seq)
{
u8 cut_mask;
u8 intf_mask;
@@ -271,7 +271,7 @@ static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
{
const struct rtw_chip_info *chip = rtwdev->chip;
- const struct rtw_pwr_seq_cmd **pwr_seq;
+ const struct rtw_pwr_seq_cmd * const *pwr_seq;
u32 imr = 0;
u8 rpwm;
bool cur_pwr;
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index b39e90fb66b4..026fbf4ad9cc 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -928,8 +928,10 @@ static int rtw_ops_set_sar_specs(struct ieee80211_hw *hw,
static void rtw_ops_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, u32 changed)
+ struct ieee80211_link_sta *link_sta,
+ u32 changed)
{
+ struct ieee80211_sta *sta = link_sta->sta;
struct rtw_dev *rtwdev = hw->priv;
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
@@ -973,7 +975,7 @@ const struct ieee80211_ops rtw_ops = {
.reconfig_complete = rtw_reconfig_complete,
.hw_scan = rtw_ops_hw_scan,
.cancel_hw_scan = rtw_ops_cancel_hw_scan,
- .sta_rc_update = rtw_ops_sta_rc_update,
+ .link_sta_rc_update = rtw_ops_sta_rc_update,
.set_sar_specs = rtw_ops_set_sar_specs,
#ifdef CONFIG_PM
.suspend = rtw_ops_suspend,
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 945117afe143..05cfb235f272 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -848,9 +848,8 @@ struct rtw_chip_ops {
void (*phy_set_param)(struct rtw_dev *rtwdev);
void (*set_channel)(struct rtw_dev *rtwdev, u8 channel,
u8 bandwidth, u8 primary_chan_idx);
- void (*query_rx_desc)(struct rtw_dev *rtwdev, u8 *rx_desc,
- struct rtw_rx_pkt_stat *pkt_stat,
- struct ieee80211_rx_status *rx_status);
+ void (*query_phy_status)(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat);
u32 (*read_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
u32 addr, u32 mask);
bool (*write_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
@@ -1167,7 +1166,7 @@ enum rtw_fwcd_item {
/* hardware configuration for each IC */
struct rtw_chip_info {
- struct rtw_chip_ops *ops;
+ const struct rtw_chip_ops *ops;
u8 id;
const char *fw_name;
@@ -1209,8 +1208,8 @@ struct rtw_chip_info {
/* init values */
u8 sys_func_en;
- const struct rtw_pwr_seq_cmd **pwr_on_seq;
- const struct rtw_pwr_seq_cmd **pwr_off_seq;
+ const struct rtw_pwr_seq_cmd * const *pwr_on_seq;
+ const struct rtw_pwr_seq_cmd * const *pwr_off_seq;
const struct rtw_rqpn *rqpn_table;
const struct rtw_prioq_addrs *prioq_addrs;
const struct rtw_page_table *page_table;
@@ -1242,7 +1241,7 @@ struct rtw_chip_info {
u8 bfer_su_max_num;
u8 bfer_mu_max_num;
- struct rtw_hw_reg_offset *edcca_th;
+ const struct rtw_hw_reg_offset *edcca_th;
s8 l2h_th_ini_cs;
s8 l2h_th_ini_ad;
diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c
index 0b9b8807af2c..f71e41d6f97c 100644
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
@@ -1065,7 +1065,7 @@ static u32 rtw_pci_rx_napi(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci,
dma_sync_single_for_cpu(rtwdev->dev, dma, RTK_PCI_RX_BUF_SIZE,
DMA_FROM_DEVICE);
rx_desc = skb->data;
- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
+ rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
/* offset from rx_desc to payload */
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index 37ef80c9091d..d57a2aabd89b 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -123,7 +123,7 @@ static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev)
void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l)
{
- struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
+ const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
rtw_write32_mask(rtwdev,
edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
index 222608de33cd..77399b8dd8cd 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
@@ -29,9 +29,6 @@
#define TBTT_PROHIBIT_HOLD_TIME 0x80
#define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x64
-/* raw pkt_stat->drv_info_sz is in unit of 8-bytes */
-#define RX_DRV_INFO_SZ_UNIT_8703B 8
-
#define TRANS_SEQ_END \
0xFFFF, \
RTW_PWR_CUT_ALL_MSK, \
@@ -481,14 +478,14 @@ static const struct rtw_pwr_seq_cmd trans_act_to_lps_8703b[] = {
{TRANS_SEQ_END},
};
-static const struct rtw_pwr_seq_cmd *card_enable_flow_8703b[] = {
+static const struct rtw_pwr_seq_cmd * const card_enable_flow_8703b[] = {
trans_pre_enable_8703b,
trans_carddis_to_cardemu_8703b,
trans_cardemu_to_act_8703b,
NULL
};
-static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = {
+static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = {
trans_act_to_lps_8703b,
trans_act_to_reset_mcu_8703b,
trans_act_to_cardemu_8703b,
@@ -1032,57 +1029,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
query_phy_status_ofdm(rtwdev, phy_status, pkt_stat);
}
-static void rtw8703b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
- struct rtw_rx_pkt_stat *pkt_stat,
- struct ieee80211_rx_status *rx_status)
-{
- struct ieee80211_hdr *hdr;
- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
- u8 *phy_status = NULL;
-
- memset(pkt_stat, 0, sizeof(*pkt_stat));
-
- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
- pkt_stat->ppdu_cnt = 0;
- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
-
- pkt_stat->drv_info_sz *= RX_DRV_INFO_SZ_UNIT_8703B;
-
- if (pkt_stat->is_c2h)
- return;
-
- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
- pkt_stat->drv_info_sz);
-
- pkt_stat->bw = GET_RX_DESC_BW(rx_desc);
-
- if (pkt_stat->phy_status) {
- phy_status = rx_desc + desc_sz + pkt_stat->shift;
- query_phy_status(rtwdev, phy_status, pkt_stat);
- }
-
- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
-
- /* Rtl8723cs driver checks for size < 14 or size > 8192 and
- * simply drops the packet. Maybe this should go into
- * rtw_rx_fill_rx_status()?
- */
- if (pkt_stat->pkt_len == 0) {
- rx_status->flag |= RX_FLAG_NO_PSDU;
- rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");
- }
-}
-
#define ADDA_ON_VAL_8703B 0x03c00014
static
@@ -1941,14 +1887,14 @@ static const struct coex_tdma_para tdma_sant_8703b[] = {
{ {0x61, 0x08, 0x03, 0x11, 0x11} },
};
-static struct rtw_chip_ops rtw8703b_ops = {
+static const struct rtw_chip_ops rtw8703b_ops = {
.mac_init = rtw8723x_mac_init,
.dump_fw_crash = NULL,
.shutdown = NULL,
.read_efuse = rtw8703b_read_efuse,
.phy_set_param = rtw8703b_phy_set_param,
.set_channel = rtw8703b_set_channel,
- .query_rx_desc = rtw8703b_query_rx_desc,
+ .query_phy_status = query_phy_status,
.read_rf = rtw_phy_read_rf_sipi,
.write_rf = rtw_phy_write_rf_reg_sipi,
.set_tx_power_index = rtw8723x_set_tx_power_index,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 3fba4054d45f..86a5e2497641 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -227,47 +227,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
}
}
-static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
- struct rtw_rx_pkt_stat *pkt_stat,
- struct ieee80211_rx_status *rx_status)
-{
- struct ieee80211_hdr *hdr;
- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
- u8 *phy_status = NULL;
-
- memset(pkt_stat, 0, sizeof(*pkt_stat));
-
- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
- pkt_stat->ppdu_cnt = 0;
- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
-
- /* drv_info_sz is in unit of 8-bytes */
- pkt_stat->drv_info_sz *= 8;
-
- /* c2h cmd pkt's rx/phy status is not interested */
- if (pkt_stat->is_c2h)
- return;
-
- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
- pkt_stat->drv_info_sz);
- if (pkt_stat->phy_status) {
- phy_status = rx_desc + desc_sz + pkt_stat->shift;
- query_phy_status(rtwdev, phy_status, pkt_stat);
- }
-
- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
-}
-
static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev,
u8 channel, u32 thres)
{
@@ -1430,10 +1389,10 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev)
dm_info->pwr_trk_triggered = false;
}
-static struct rtw_chip_ops rtw8723d_ops = {
+static const struct rtw_chip_ops rtw8723d_ops = {
.phy_set_param = rtw8723d_phy_set_param,
.read_efuse = rtw8723x_read_efuse,
- .query_rx_desc = rtw8723d_query_rx_desc,
+ .query_phy_status = query_phy_status,
.set_channel = rtw8723d_set_channel,
.mac_init = rtw8723x_mac_init,
.shutdown = rtw8723d_shutdown,
@@ -1788,7 +1747,7 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8723d[] = {
RTW_PWR_CMD_END, 0, 0},
};
-static const struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = {
+static const struct rtw_pwr_seq_cmd * const card_enable_flow_8723d[] = {
trans_carddis_to_cardemu_8723d,
trans_cardemu_to_act_8723d,
NULL
@@ -2004,7 +1963,7 @@ static const struct rtw_pwr_seq_cmd trans_act_to_post_carddis_8723d[] = {
RTW_PWR_CMD_END, 0, 0},
};
-static const struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = {
+static const struct rtw_pwr_seq_cmd * const card_disable_flow_8723d[] = {
trans_act_to_lps_8723d,
trans_act_to_pre_carddis_8723d,
trans_act_to_cardemu_8723d,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index 526e8de77b3e..66c79956e8e5 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -679,47 +679,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
}
}
-static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
- struct rtw_rx_pkt_stat *pkt_stat,
- struct ieee80211_rx_status *rx_status)
-{
- struct ieee80211_hdr *hdr;
- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
- u8 *phy_status = NULL;
-
- memset(pkt_stat, 0, sizeof(*pkt_stat));
-
- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
- pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
-
- /* drv_info_sz is in unit of 8-bytes */
- pkt_stat->drv_info_sz *= 8;
-
- /* c2h cmd pkt's rx/phy status is not interested */
- if (pkt_stat->is_c2h)
- return;
-
- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
- pkt_stat->drv_info_sz);
- if (pkt_stat->phy_status) {
- phy_status = rx_desc + desc_sz + pkt_stat->shift;
- query_phy_status(rtwdev, phy_status, pkt_stat);
- }
-
- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
-}
-
static void
rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
{
@@ -1254,7 +1213,7 @@ static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
fill_txdesc_checksum_common(txdesc, 16);
}
-static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
+static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
{0x0086,
RTW_PWR_CUT_ALL_MSK,
RTW_PWR_INTF_SDIO_MSK,
@@ -1292,7 +1251,7 @@ static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
RTW_PWR_CMD_END, 0, 0},
};
-static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
+static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
{0x0020,
RTW_PWR_CUT_ALL_MSK,
RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
@@ -1396,7 +1355,7 @@ static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
RTW_PWR_CMD_END, 0, 0},
};
-static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
+static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
{0x0093,
RTW_PWR_CUT_ALL_MSK,
RTW_PWR_INTF_ALL_MSK,
@@ -1454,7 +1413,7 @@ static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
RTW_PWR_CMD_END, 0, 0},
};
-static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
+static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
{0x0007,
RTW_PWR_CUT_ALL_MSK,
RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
@@ -1567,13 +1526,13 @@ static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
RTW_PWR_CMD_END, 0, 0},
};
-static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = {
+static const struct rtw_pwr_seq_cmd * const card_enable_flow_8821c[] = {
trans_carddis_to_cardemu_8821c,
trans_cardemu_to_act_8821c,
NULL
};
-static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = {
+static const struct rtw_pwr_seq_cmd * const card_disable_flow_8821c[] = {
trans_act_to_cardemu_8821c,
trans_cardemu_to_carddis_8821c,
NULL
@@ -1629,7 +1588,7 @@ static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
[6] = RTW_DEF_RFE(8821c, 0, 0),
};
-static struct rtw_hw_reg rtw8821c_dig[] = {
+static const struct rtw_hw_reg rtw8821c_dig[] = {
[0] = { .addr = 0xc50, .mask = 0x7f },
};
@@ -1639,7 +1598,7 @@ static const struct rtw_ltecoex_addr rtw8821c_ltecoex_addr = {
.rdata = LTECOEX_READ_DATA,
};
-static struct rtw_page_table page_table_8821c[] = {
+static const struct rtw_page_table page_table_8821c[] = {
/* not sure what [0] stands for */
{16, 16, 16, 14, 1},
{16, 16, 16, 14, 1},
@@ -1648,7 +1607,7 @@ static struct rtw_page_table page_table_8821c[] = {
{16, 16, 16, 14, 1},
};
-static struct rtw_rqpn rqpn_table_8821c[] = {
+static const struct rtw_rqpn rqpn_table_8821c[] = {
/* not sure what [0] stands for */
{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
@@ -1667,7 +1626,7 @@ static struct rtw_rqpn rqpn_table_8821c[] = {
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
};
-static struct rtw_prioq_addrs prioq_addrs_8821c = {
+static const struct rtw_prioq_addrs prioq_addrs_8821c = {
.prio[RTW_DMA_MAPPING_EXTRA] = {
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
},
@@ -1683,10 +1642,10 @@ static struct rtw_prioq_addrs prioq_addrs_8821c = {
.wsize = true,
};
-static struct rtw_chip_ops rtw8821c_ops = {
+static const struct rtw_chip_ops rtw8821c_ops = {
.phy_set_param = rtw8821c_phy_set_param,
.read_efuse = rtw8821c_read_efuse,
- .query_rx_desc = rtw8821c_query_rx_desc,
+ .query_phy_status = query_phy_status,
.set_channel = rtw8821c_set_channel,
.mac_init = rtw8821c_mac_init,
.read_rf = rtw_phy_read_rf,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index 6edb17aea90e..24f76a36f23e 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -934,47 +934,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
}
}
-static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
- struct rtw_rx_pkt_stat *pkt_stat,
- struct ieee80211_rx_status *rx_status)
-{
- struct ieee80211_hdr *hdr;
- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
- u8 *phy_status = NULL;
-
- memset(pkt_stat, 0, sizeof(*pkt_stat));
-
- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
- pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
-
- /* drv_info_sz is in unit of 8-bytes */
- pkt_stat->drv_info_sz *= 8;
-
- /* c2h cmd pkt's rx/phy status is not interested */
- if (pkt_stat->is_c2h)
- return;
-
- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
- pkt_stat->drv_info_sz);
- if (pkt_stat->phy_status) {
- phy_status = rx_desc + desc_sz + pkt_stat->shift;
- query_phy_status(rtwdev, phy_status, pkt_stat);
- }
-
- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
-}
-
static void
rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
{
@@ -1978,13 +1937,13 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822b[] = {
RTW_PWR_CMD_END, 0, 0},
};
-static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = {
+static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822b[] = {
trans_carddis_to_cardemu_8822b,
trans_cardemu_to_act_8822b,
NULL
};
-static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = {
+static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822b[] = {
trans_act_to_cardemu_8822b,
trans_cardemu_to_carddis_8822b,
NULL
@@ -2156,7 +2115,7 @@ static const struct rtw_rqpn rqpn_table_8822b[] = {
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
};
-static struct rtw_prioq_addrs prioq_addrs_8822b = {
+static const struct rtw_prioq_addrs prioq_addrs_8822b = {
.prio[RTW_DMA_MAPPING_EXTRA] = {
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
},
@@ -2172,10 +2131,10 @@ static struct rtw_prioq_addrs prioq_addrs_8822b = {
.wsize = true,
};
-static struct rtw_chip_ops rtw8822b_ops = {
+static const struct rtw_chip_ops rtw8822b_ops = {
.phy_set_param = rtw8822b_phy_set_param,
.read_efuse = rtw8822b_read_efuse,
- .query_rx_desc = rtw8822b_query_rx_desc,
+ .query_phy_status = query_phy_status,
.set_channel = rtw8822b_set_channel,
.mac_init = rtw8822b_mac_init,
.read_rf = rtw_phy_read_rf,
@@ -2521,7 +2480,7 @@ static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
{0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
};
-static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
+static const struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
[EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0},
[EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
};
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 1dbe1cdbc3fd..da74e66bda84 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -2690,48 +2690,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
}
}
-static void rtw8822c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
- struct rtw_rx_pkt_stat *pkt_stat,
- struct ieee80211_rx_status *rx_status)
-{
- struct ieee80211_hdr *hdr;
- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
- u8 *phy_status = NULL;
-
- memset(pkt_stat, 0, sizeof(*pkt_stat));
-
- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
- pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
-
- /* drv_info_sz is in unit of 8-bytes */
- pkt_stat->drv_info_sz *= 8;
-
- /* c2h cmd pkt's rx/phy status is not interested */
- if (pkt_stat->is_c2h)
- return;
-
- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
- pkt_stat->drv_info_sz);
- pkt_stat->hdr = hdr;
- if (pkt_stat->phy_status) {
- phy_status = rx_desc + desc_sz + pkt_stat->shift;
- query_phy_status(rtwdev, phy_status, pkt_stat);
- }
-
- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
-}
-
static void
rtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck,
u8 *tx_pwr_ref_ofdm)
@@ -4874,13 +4832,13 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822c[] = {
RTW_PWR_CMD_END, 0, 0},
};
-static const struct rtw_pwr_seq_cmd *card_enable_flow_8822c[] = {
+static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822c[] = {
trans_carddis_to_cardemu_8822c,
trans_cardemu_to_act_8822c,
NULL
};
-static const struct rtw_pwr_seq_cmd *card_disable_flow_8822c[] = {
+static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822c[] = {
trans_act_to_cardemu_8822c,
trans_cardemu_to_carddis_8822c,
NULL
@@ -4972,7 +4930,7 @@ static const struct rtw_rqpn rqpn_table_8822c[] = {
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
};
-static struct rtw_prioq_addrs prioq_addrs_8822c = {
+static const struct rtw_prioq_addrs prioq_addrs_8822c = {
.prio[RTW_DMA_MAPPING_EXTRA] = {
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
},
@@ -4988,10 +4946,10 @@ static struct rtw_prioq_addrs prioq_addrs_8822c = {
.wsize = true,
};
-static struct rtw_chip_ops rtw8822c_ops = {
+static const struct rtw_chip_ops rtw8822c_ops = {
.phy_set_param = rtw8822c_phy_set_param,
.read_efuse = rtw8822c_read_efuse,
- .query_rx_desc = rtw8822c_query_rx_desc,
+ .query_phy_status = query_phy_status,
.set_channel = rtw8822c_set_channel,
.mac_init = rtw8822c_mac_init,
.dump_fw_crash = rtw8822c_dump_fw_crash,
@@ -5301,7 +5259,7 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
.pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,
};
-static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
+static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
[EDCCA_TH_L2H_IDX] = {
{.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
},
diff --git a/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c
index 66f9419588cf..1de93fc9efe9 100644
--- a/drivers/net/wireless/realtek/rtw88/rx.c
+++ b/drivers/net/wireless/realtek/rtw88/rx.c
@@ -187,11 +187,10 @@ fill_rx_status:
}
EXPORT_SYMBOL(rtw_update_rx_freq_from_ie);
-void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
- struct rtw_rx_pkt_stat *pkt_stat,
- struct ieee80211_hdr *hdr,
- struct ieee80211_rx_status *rx_status,
- u8 *phy_status)
+static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
+ struct rtw_rx_pkt_stat *pkt_stat,
+ struct ieee80211_hdr *hdr,
+ struct ieee80211_rx_status *rx_status)
{
struct ieee80211_hw *hw = rtwdev->hw;
u8 path;
@@ -242,5 +241,64 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
}
rtw_rx_addr_match(rtwdev, pkt_stat, hdr);
+
+ /* Rtl8723cs driver checks for size < 14 or size > 8192 and
+ * simply drops the packet.
+ */
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && pkt_stat->pkt_len == 0) {
+ rx_status->flag |= RX_FLAG_NO_PSDU;
+ rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");
+ }
+}
+
+void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8,
+ struct rtw_rx_pkt_stat *pkt_stat,
+ struct ieee80211_rx_status *rx_status)
+{
+ u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
+ struct rtw_rx_desc *rx_desc = rx_desc8;
+ struct ieee80211_hdr *hdr;
+ u32 enc_type, swdec;
+ void *phy_status;
+
+ memset(pkt_stat, 0, sizeof(*pkt_stat));
+
+ pkt_stat->pkt_len = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PKT_LEN);
+ pkt_stat->crc_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_CRC32);
+ pkt_stat->icv_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ICV_ERR);
+ pkt_stat->drv_info_sz = le32_get_bits(rx_desc->w0,
+ RTW_RX_DESC_W0_DRV_INFO_SIZE);
+ enc_type = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ENC_TYPE);
+ pkt_stat->shift = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SHIFT);
+ pkt_stat->phy_status = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PHYST);
+ swdec = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SWDEC);
+ pkt_stat->decrypted = !swdec && enc_type != RX_DESC_ENC_NONE;
+
+ pkt_stat->cam_id = le32_get_bits(rx_desc->w1, RTW_RX_DESC_W1_MACID);
+
+ pkt_stat->is_c2h = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_C2H);
+ pkt_stat->ppdu_cnt = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_PPDU_CNT);
+
+ pkt_stat->rate = le32_get_bits(rx_desc->w3, RTW_RX_DESC_W3_RX_RATE);
+
+ pkt_stat->bw = le32_get_bits(rx_desc->w4, RTW_RX_DESC_W4_BW);
+
+ pkt_stat->tsf_low = le32_get_bits(rx_desc->w5, RTW_RX_DESC_W5_TSFL);
+
+ /* drv_info_sz is in unit of 8-bytes */
+ pkt_stat->drv_info_sz *= 8;
+
+ /* c2h cmd pkt's rx/phy status is not interested */
+ if (pkt_stat->is_c2h)
+ return;
+
+ phy_status = rx_desc8 + desc_sz + pkt_stat->shift;
+ hdr = phy_status + pkt_stat->drv_info_sz;
+ pkt_stat->hdr = hdr;
+
+ if (pkt_stat->phy_status)
+ rtwdev->chip->ops->query_phy_status(rtwdev, phy_status, pkt_stat);
+
+ rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status);
}
-EXPORT_SYMBOL(rtw_rx_fill_rx_status);
+EXPORT_SYMBOL(rtw_rx_query_rx_desc);
diff --git a/drivers/net/wireless/realtek/rtw88/rx.h b/drivers/net/wireless/realtek/rtw88/rx.h
index 9f0019112987..6b7dee245c0a 100644
--- a/drivers/net/wireless/realtek/rtw88/rx.h
+++ b/drivers/net/wireless/realtek/rtw88/rx.h
@@ -14,42 +14,40 @@ enum rtw_rx_desc_enc {
RX_DESC_ENC_WEP104 = 5,
};
-#define GET_RX_DESC_PHYST(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(26))
-#define GET_RX_DESC_ICV_ERR(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(15))
-#define GET_RX_DESC_CRC32(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(14))
-#define GET_RX_DESC_SWDEC(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(27))
-#define GET_RX_DESC_C2H(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x02), BIT(28))
-#define GET_RX_DESC_PKT_LEN(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(13, 0))
-#define GET_RX_DESC_DRV_INFO_SIZE(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(19, 16))
-#define GET_RX_DESC_SHIFT(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(25, 24))
-#define GET_RX_DESC_ENC_TYPE(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(22, 20))
-#define GET_RX_DESC_RX_RATE(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x03), GENMASK(6, 0))
-#define GET_RX_DESC_MACID(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x01), GENMASK(6, 0))
-#define GET_RX_DESC_PPDU_CNT(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x02), GENMASK(30, 29))
-#define GET_RX_DESC_TSFL(rxdesc) \
- le32_get_bits(*((__le32 *)(rxdesc) + 0x05), GENMASK(31, 0))
-#define GET_RX_DESC_BW(rxdesc) \
- (le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(5, 4)))
+struct rtw_rx_desc {
+ __le32 w0;
+ __le32 w1;
+ __le32 w2;
+ __le32 w3;
+ __le32 w4;
+ __le32 w5;
+} __packed;
+
+#define RTW_RX_DESC_W0_PKT_LEN GENMASK(13, 0)
+#define RTW_RX_DESC_W0_CRC32 BIT(14)
+#define RTW_RX_DESC_W0_ICV_ERR BIT(15)
+#define RTW_RX_DESC_W0_DRV_INFO_SIZE GENMASK(19, 16)
+#define RTW_RX_DESC_W0_ENC_TYPE GENMASK(22, 20)
+#define RTW_RX_DESC_W0_SHIFT GENMASK(25, 24)
+#define RTW_RX_DESC_W0_PHYST BIT(26)
+#define RTW_RX_DESC_W0_SWDEC BIT(27)
+
+#define RTW_RX_DESC_W1_MACID GENMASK(6, 0)
+
+#define RTW_RX_DESC_W2_C2H BIT(28)
+#define RTW_RX_DESC_W2_PPDU_CNT GENMASK(30, 29)
+
+#define RTW_RX_DESC_W3_RX_RATE GENMASK(6, 0)
+
+#define RTW_RX_DESC_W4_BW GENMASK(5, 4)
+
+#define RTW_RX_DESC_W5_TSFL GENMASK(31, 0)
void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
struct sk_buff *skb);
-void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
- struct rtw_rx_pkt_stat *pkt_stat,
- struct ieee80211_hdr *hdr,
- struct ieee80211_rx_status *rx_status,
- u8 *phy_status);
+void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8,
+ struct rtw_rx_pkt_stat *pkt_stat,
+ struct ieee80211_rx_status *rx_status);
void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
struct ieee80211_rx_status *rx_status,
struct rtw_rx_pkt_stat *pkt_stat);
diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
index 21d0754dd7f6..f0b06ed8f76d 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
@@ -981,8 +981,7 @@ static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len)
while (true) {
rx_desc = skb->data;
- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
- &rx_status);
+ rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
pkt_stat.shift;
@@ -1297,12 +1296,12 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev)
struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
int i;
- for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
- skb_queue_purge(&rtwsdio->tx_queue[i]);
-
flush_workqueue(rtwsdio->txwq);
destroy_workqueue(rtwsdio->txwq);
kfree(rtwsdio->tx_handler_data);
+
+ for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
+ ieee80211_purge_tx_queue(rtwdev->hw, &rtwsdio->tx_queue[i]);
}
int rtw_sdio_probe(struct sdio_func *sdio_func,
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
index e83ab6fb83f5..ba314d90ab3f 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -423,10 +423,11 @@ static void rtw_usb_tx_handler(struct work_struct *work)
static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb)
{
+ struct rtw_dev *rtwdev = rtwusb->rtwdev;
int i;
for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
- skb_queue_purge(&rtwusb->tx_queue[i]);
+ ieee80211_purge_tx_queue(rtwdev->hw, &rtwusb->tx_queue[i]);
}
static void rtw_usb_write_port_complete(struct urb *urb)
@@ -570,8 +571,8 @@ static void rtw_usb_rx_handler(struct work_struct *work)
do {
rx_desc = skb->data;
- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
- &rx_status);
+ rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat,
+ &rx_status);
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
pkt_stat.shift;
@@ -889,9 +890,9 @@ static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev)
{
struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- rtw_usb_tx_queue_purge(rtwusb);
flush_workqueue(rtwusb->txwq);
destroy_workqueue(rtwusb->txwq);
+ rtw_usb_tx_queue_purge(rtwusb);
}
static int rtw_usb_intf_init(struct rtw_dev *rtwdev,
diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c
index 4476fc7e53db..8d140b94cb44 100644
--- a/drivers/net/wireless/realtek/rtw89/cam.c
+++ b/drivers/net/wireless/realtek/rtw89/cam.c
@@ -211,25 +211,17 @@ static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
return 0;
}
-static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- const struct rtw89_sec_cam_entry *sec_cam,
- bool inform_fw)
+static int __rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ const struct rtw89_sec_cam_entry *sec_cam,
+ bool inform_fw)
{
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
- struct rtw89_vif *rtwvif;
struct rtw89_addr_cam_entry *addr_cam;
unsigned int i;
int ret = 0;
- if (!vif) {
- rtw89_err(rtwdev, "No iface for deleting sec cam\n");
- return -EINVAL;
- }
-
- rtwvif = (struct rtw89_vif *)vif->drv_priv;
- addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
+ addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
for_each_set_bit(i, addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM) {
if (addr_cam->sec_ent[i] != sec_cam->sec_cam_idx)
@@ -239,11 +231,11 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
}
if (inform_fw) {
- ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
+ ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
rtw89_err(rtwdev,
"failed to update dctl cam del key: %d\n", ret);
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret)
rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret);
}
@@ -251,25 +243,17 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
return ret;
}
-static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key,
- struct rtw89_sec_cam_entry *sec_cam)
+static int __rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ struct ieee80211_key_conf *key,
+ struct rtw89_sec_cam_entry *sec_cam)
{
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
- struct rtw89_vif *rtwvif;
struct rtw89_addr_cam_entry *addr_cam;
u8 key_idx = 0;
int ret;
- if (!vif) {
- rtw89_err(rtwdev, "No iface for adding sec cam\n");
- return -EINVAL;
- }
-
- rtwvif = (struct rtw89_vif *)vif->drv_priv;
- addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
+ addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
key->cipher == WLAN_CIPHER_SUITE_WEP104)
@@ -285,13 +269,13 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
addr_cam->sec_ent_keyid[key_idx] = key->keyidx;
addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx;
set_bit(key_idx, addr_cam->sec_cam_map);
- ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
+ ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
ret);
return ret;
}
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n",
ret);
@@ -302,6 +286,92 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
return 0;
}
+static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ const struct rtw89_sec_cam_entry *sec_cam,
+ bool inform_fw)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
+ struct rtw89_sta_link *rtwsta_link;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_vif *rtwvif;
+ unsigned int link_id;
+ int ret;
+
+ if (!vif) {
+ rtw89_err(rtwdev, "No iface for deleting sec cam\n");
+ return -EINVAL;
+ }
+
+ rtwvif = vif_to_rtwvif(vif);
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ rtwsta_link = rtwsta ? rtwsta->links[link_id] : NULL;
+ if (rtwsta && !rtwsta_link)
+ continue;
+
+ ret = __rtw89_cam_detach_sec_cam(rtwdev, rtwvif_link, rtwsta_link,
+ sec_cam, inform_fw);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key,
+ struct rtw89_sec_cam_entry *sec_cam)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
+ struct rtw89_sta_link *rtwsta_link;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_vif *rtwvif;
+ unsigned int link_id;
+ int key_link_id;
+ int ret;
+
+ if (!vif) {
+ rtw89_err(rtwdev, "No iface for adding sec cam\n");
+ return -EINVAL;
+ }
+
+ rtwvif = vif_to_rtwvif(vif);
+
+ key_link_id = ieee80211_vif_is_mld(vif) ? key->link_id : 0;
+ if (key_link_id >= 0) {
+ rtwvif_link = rtwvif->links[key_link_id];
+ rtwsta_link = rtwsta ? rtwsta->links[key_link_id] : NULL;
+
+ if (!rtwvif_link || (rtwsta && !rtwsta_link)) {
+ rtw89_err(rtwdev, "No drv link for adding sec cam\n");
+ return -ENOLINK;
+ }
+
+ return __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link,
+ rtwsta_link, key, sec_cam);
+ }
+
+ /* key_link_id < 0: MLD pairwise key */
+ if (!rtwsta) {
+ rtw89_err(rtwdev, "No sta for adding MLD pairwise sec cam\n");
+ return -EINVAL;
+ }
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link,
+ rtwsta_link, key, sec_cam);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -485,10 +555,10 @@ void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map);
}
-void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
- struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
+ struct rtw89_addr_cam_entry *addr_cam = &rtwvif_link->addr_cam;
+ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
rtw89_cam_deinit_addr_cam(rtwdev, addr_cam);
rtw89_cam_deinit_bssid_cam(rtwdev, bssid_cam);
@@ -593,7 +663,7 @@ static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev,
}
int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct rtw89_bssid_cam_entry *bssid_cam,
const u8 *bssid)
{
@@ -613,7 +683,7 @@ int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
}
bssid_cam->bssid_cam_idx = bssid_cam_idx;
- bssid_cam->phy_idx = rtwvif->phy_idx;
+ bssid_cam->phy_idx = rtwvif_link->phy_idx;
bssid_cam->len = BSSID_CAM_ENT_SIZE;
bssid_cam->offset = 0;
bssid_cam->valid = true;
@@ -622,20 +692,21 @@ int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
return 0;
}
-void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
+ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
- ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
+ ether_addr_copy(bssid_cam->bssid, rtwvif_link->bssid);
}
-int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
- struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
+ struct rtw89_addr_cam_entry *addr_cam = &rtwvif_link->addr_cam;
+ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
int ret;
- ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, rtwvif->bssid);
+ ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif_link, bssid_cam,
+ rtwvif_link->bssid);
if (ret) {
rtw89_err(rtwdev, "failed to init bssid cam\n");
return ret;
@@ -651,19 +722,27 @@ int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
}
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, u8 *cmd)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link, u8 *cmd)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta);
- u8 bss_color = vif->bss_conf.he_bss_color.color;
+ struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link,
+ rtwsta_link);
+ struct ieee80211_bss_conf *bss_conf;
+ u8 bss_color;
u8 bss_mask;
- if (vif->bss_conf.nontransmitted)
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+ bss_color = bss_conf->he_bss_color.color;
+
+ if (bss_conf->nontransmitted)
bss_mask = RTW89_BSSID_MATCH_5_BYTES;
else
bss_mask = RTW89_BSSID_MATCH_ALL;
+ rcu_read_unlock();
+
FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
@@ -694,19 +773,30 @@ static u8 rtw89_cam_addr_hash(u8 start, const u8 *addr)
}
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
const u8 *scan_mac_addr,
u8 *cmd)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
- struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
- const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_addr_cam_entry *addr_cam =
+ rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
+ struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link);
+ struct ieee80211_link_sta *link_sta;
+ const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif_link->mac_addr;
u8 sma_hash, tma_hash, addr_msk_start;
u8 sma_start = 0;
u8 tma_start = 0;
- u8 *tma = sta ? sta->addr : rtwvif->bssid;
+ const u8 *tma;
+
+ rcu_read_lock();
+
+ if (sta) {
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ tma = link_sta->addr;
+ } else {
+ tma = rtwvif_link->bssid;
+ }
if (addr_cam->addr_mask != 0) {
addr_msk_start = __ffs(addr_cam->addr_mask);
@@ -723,10 +813,10 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
FWCMD_SET_ADDR_LEN(cmd, addr_cam->len);
FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid);
- FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif->net_type);
- FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif->bcn_hit_cond);
- FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif->hit_rule);
- FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif->phy_idx);
+ FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif_link->net_type);
+ FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif_link->bcn_hit_cond);
+ FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif_link->hit_rule);
+ FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif_link->phy_idx);
FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask);
FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel);
FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash);
@@ -748,20 +838,21 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
FWCMD_SET_ADDR_TMA4(cmd, tma[4]);
FWCMD_SET_ADDR_TMA5(cmd, tma[5]);
- FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif->port);
- FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif->port);
- FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif->trigger);
- FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif->lsig_txop);
- FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif->tgt_ind);
- FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif->frm_tgt_ind);
- FWCMD_SET_ADDR_MACID(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
- if (rtwvif->net_type == RTW89_NET_TYPE_INFRA)
+ FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif_link->port);
+ FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif_link->port);
+ FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif_link->trigger);
+ FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif_link->lsig_txop);
+ FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif_link->tgt_ind);
+ FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif_link->frm_tgt_ind);
+ FWCMD_SET_ADDR_MACID(cmd, rtwsta_link ? rtwsta_link->mac_id :
+ rtwvif_link->mac_id);
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA)
FWCMD_SET_ADDR_AID12(cmd, vif->cfg.aid & 0xfff);
- else if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
FWCMD_SET_ADDR_AID12(cmd, sta ? sta->aid & 0xfff : 0);
- FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif->wowlan_pattern);
- FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif->wowlan_uc);
- FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif->wowlan_magic);
+ FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif_link->wowlan_pattern);
+ FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif_link->wowlan_uc);
+ FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif_link->wowlan_magic);
FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi);
FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode);
FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]);
@@ -780,18 +871,22 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]);
FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]);
FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]);
+
+ rcu_read_unlock();
}
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v1 *h2c)
{
- struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
+ struct rtw89_addr_cam_entry *addr_cam =
+ rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
- h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
+ h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id :
+ rtwvif_link->mac_id,
DCTLINFO_V1_C0_MACID) |
le32_encode_bits(1, DCTLINFO_V1_C0_OP);
@@ -862,15 +957,17 @@ void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
}
void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v2 *h2c)
{
- struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
+ struct rtw89_addr_cam_entry *addr_cam =
+ rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
- h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
+ h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id :
+ rtwvif_link->mac_id,
DCTLINFO_V2_C0_MACID) |
le32_encode_bits(1, DCTLINFO_V2_C0_OP);
diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h
index 5d7b624c2dd4..a6f72edd30fe 100644
--- a/drivers/net/wireless/realtek/rtw89/cam.h
+++ b/drivers/net/wireless/realtek/rtw89/cam.h
@@ -526,34 +526,34 @@ struct rtw89_h2c_dctlinfo_ud_v2 {
#define DCTLINFO_V2_W12_MLD_TA_BSSID_H_V1 GENMASK(15, 0)
#define DCTLINFO_V2_W12_ALL GENMASK(15, 0)
-int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
-void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
+int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
+void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
struct rtw89_addr_cam_entry *addr_cam,
const struct rtw89_bssid_cam_entry *bssid_cam);
void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev,
struct rtw89_addr_cam_entry *addr_cam);
int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct rtw89_bssid_cam_entry *bssid_cam,
const u8 *bssid);
void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
struct rtw89_bssid_cam_entry *bssid_cam);
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
- struct rtw89_vif *vif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *vif,
+ struct rtw89_sta_link *rtwsta_link,
const u8 *scan_mac_addr, u8 *cmd);
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v1 *h2c);
void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v2 *h2c);
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, u8 *cmd);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link, u8 *cmd);
int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -564,6 +564,6 @@ int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
struct ieee80211_key_conf *key,
bool inform_fw);
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
+ struct rtw89_vif_link *rtwvif_link);
void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 7070c85e2c28..ba6332da8019 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -234,6 +234,18 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
rtw89_config_default_chandef(rtwdev);
}
+static bool rtw89_vif_is_active_role(struct rtw89_vif *rtwvif)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ if (rtwvif_link->chanctx_assigned)
+ return true;
+
+ return false;
+}
+
static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
struct rtw89_entity_weight *w)
{
@@ -255,7 +267,7 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
}
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- if (rtwvif->chanctx_assigned)
+ if (rtw89_vif_is_active_role(rtwvif))
w->active_roles++;
}
}
@@ -387,9 +399,9 @@ int rtw89_iterate_mcc_roles(struct rtw89_dev *rtwdev,
static u32 rtw89_mcc_get_tbtt_ofst(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *role, u64 tsf)
{
- struct rtw89_vif *rtwvif = role->rtwvif;
+ struct rtw89_vif_link *rtwvif_link = role->rtwvif_link;
u32 bcn_intvl_us = ieee80211_tu_to_usec(role->beacon_interval);
- u64 sync_tsf = READ_ONCE(rtwvif->sync_bcn_tsf);
+ u64 sync_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf);
u32 remainder;
if (tsf < sync_tsf) {
@@ -413,8 +425,8 @@ static int __mcc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux
int ret;
req.group = mcc->group;
- req.macid_x = ref->rtwvif->mac_id;
- req.macid_y = aux->rtwvif->mac_id;
+ req.macid_x = ref->rtwvif_link->mac_id;
+ req.macid_y = aux->rtwvif_link->mac_id;
ret = rtw89_fw_h2c_mcc_req_tsf(rtwdev, &req, &rpt);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
@@ -440,10 +452,10 @@ static int __mrc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux
BUILD_BUG_ON(RTW89_MAC_MRC_MAX_REQ_TSF_NUM < NUM_OF_RTW89_MCC_ROLES);
arg.num = 2;
- arg.infos[0].band = ref->rtwvif->mac_idx;
- arg.infos[0].port = ref->rtwvif->port;
- arg.infos[1].band = aux->rtwvif->mac_idx;
- arg.infos[1].port = aux->rtwvif->port;
+ arg.infos[0].band = ref->rtwvif_link->mac_idx;
+ arg.infos[0].port = ref->rtwvif_link->port;
+ arg.infos[1].band = aux->rtwvif_link->mac_idx;
+ arg.infos[1].port = aux->rtwvif_link->port;
ret = rtw89_fw_h2c_mrc_req_tsf(rtwdev, &arg, &rpt);
if (ret) {
@@ -522,23 +534,31 @@ out:
static void rtw89_mcc_role_macid_sta_iter(void *data, struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_mcc_role *mcc_role = data;
- struct rtw89_vif *target = mcc_role->rtwvif;
+ struct rtw89_vif *target = mcc_role->rtwvif_link->rtwvif;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_sta_link *rtwsta_link;
if (rtwvif != target)
return;
- rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta->mac_id);
+ rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
+ if (unlikely(!rtwsta_link)) {
+ rtw89_err(rtwdev, "mcc sta macid: find no link on HW-0\n");
+ return;
+ }
+
+ rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta_link->mac_id);
}
static void rtw89_mcc_fill_role_macid_bitmap(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role)
{
- struct rtw89_vif *rtwvif = mcc_role->rtwvif;
+ struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link;
- rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif->mac_id);
+ rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif_link->mac_id);
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_mcc_role_macid_sta_iter,
mcc_role);
@@ -564,8 +584,9 @@ static void rtw89_mcc_fill_role_policy(struct rtw89_dev *rtwdev,
static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(mcc_role->rtwvif);
+ struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link;
struct ieee80211_p2p_noa_desc *noa_desc;
+ struct ieee80211_bss_conf *bss_conf;
u32 bcn_intvl_us = ieee80211_tu_to_usec(mcc_role->beacon_interval);
u32 max_toa_us, max_tob_us, max_dur_us;
u32 start_time, interval, duration;
@@ -576,13 +597,18 @@ static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev,
if (!mcc_role->is_go && !mcc_role->is_gc)
return;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
/* find the first periodic NoA */
for (i = 0; i < RTW89_P2P_MAX_NOA_NUM; i++) {
- noa_desc = &vif->bss_conf.p2p_noa_attr.desc[i];
+ noa_desc = &bss_conf->p2p_noa_attr.desc[i];
if (noa_desc->count == 255)
goto fill;
}
+ rcu_read_unlock();
return;
fill:
@@ -590,6 +616,8 @@ fill:
interval = le32_to_cpu(noa_desc->interval);
duration = le32_to_cpu(noa_desc->duration);
+ rcu_read_unlock();
+
if (interval != bcn_intvl_us) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC role limit: mismatch interval: %d vs. %d\n",
@@ -597,7 +625,7 @@ fill:
return;
}
- ret = rtw89_mac_port_get_tsf(rtwdev, mcc_role->rtwvif, &tsf);
+ ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
if (ret) {
rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
return;
@@ -632,15 +660,21 @@ fill:
}
static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct rtw89_mcc_role *role)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_bss_conf *bss_conf;
const struct rtw89_chan *chan;
memset(role, 0, sizeof(*role));
- role->rtwvif = rtwvif;
- role->beacon_interval = vif->bss_conf.beacon_int;
+ role->rtwvif_link = rtwvif_link;
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ role->beacon_interval = bss_conf->beacon_int;
+
+ rcu_read_unlock();
if (!role->beacon_interval) {
rtw89_warn(rtwdev,
@@ -650,10 +684,10 @@ static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev,
role->duration = role->beacon_interval / 2;
- chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
role->is_2ghz = chan->band_type == RTW89_BAND_2G;
- role->is_go = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_GO;
- role->is_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
+ role->is_go = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_GO;
+ role->is_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
rtw89_mcc_fill_role_macid_bitmap(rtwdev, role);
rtw89_mcc_fill_role_policy(rtwdev, role);
@@ -678,7 +712,7 @@ static void rtw89_mcc_fill_bt_role(struct rtw89_dev *rtwdev)
}
struct rtw89_mcc_fill_role_selector {
- struct rtw89_vif *bind_vif[NUM_OF_RTW89_CHANCTX];
+ struct rtw89_vif_link *bind_vif[NUM_OF_RTW89_CHANCTX];
};
static_assert((u8)NUM_OF_RTW89_CHANCTX >= NUM_OF_RTW89_MCC_ROLES);
@@ -689,7 +723,7 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
void *data)
{
struct rtw89_mcc_fill_role_selector *sel = data;
- struct rtw89_vif *role_vif = sel->bind_vif[ordered_idx];
+ struct rtw89_vif_link *role_vif = sel->bind_vif[ordered_idx];
int ret;
if (!role_vif) {
@@ -712,21 +746,28 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_fill_role_selector sel = {};
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
int ret;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- if (!rtwvif->chanctx_assigned)
+ if (!rtw89_vif_is_active_role(rtwvif))
+ continue;
+
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "mcc fill roles: find no link on HW-0\n");
continue;
+ }
- if (sel.bind_vif[rtwvif->chanctx_idx]) {
+ if (sel.bind_vif[rtwvif_link->chanctx_idx]) {
rtw89_warn(rtwdev,
"MCC skip extra vif <macid %d> on chanctx[%d]\n",
- rtwvif->mac_id, rtwvif->chanctx_idx);
+ rtwvif_link->mac_id, rtwvif_link->chanctx_idx);
continue;
}
- sel.bind_vif[rtwvif->chanctx_idx] = rtwvif;
+ sel.bind_vif[rtwvif_link->chanctx_idx] = rtwvif_link;
}
ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel);
@@ -754,13 +795,13 @@ static void rtw89_mcc_assign_pattern(struct rtw89_dev *rtwdev,
memset(&pattern->courtesy, 0, sizeof(pattern->courtesy));
if (pattern->tob_aux <= 0 || pattern->toa_aux <= 0) {
- pattern->courtesy.macid_tgt = aux->rtwvif->mac_id;
- pattern->courtesy.macid_src = ref->rtwvif->mac_id;
+ pattern->courtesy.macid_tgt = aux->rtwvif_link->mac_id;
+ pattern->courtesy.macid_src = ref->rtwvif_link->mac_id;
pattern->courtesy.slot_num = RTW89_MCC_DFLT_COURTESY_SLOT;
pattern->courtesy.enable = true;
} else if (pattern->tob_ref <= 0 || pattern->toa_ref <= 0) {
- pattern->courtesy.macid_tgt = ref->rtwvif->mac_id;
- pattern->courtesy.macid_src = aux->rtwvif->mac_id;
+ pattern->courtesy.macid_tgt = ref->rtwvif_link->mac_id;
+ pattern->courtesy.macid_src = aux->rtwvif_link->mac_id;
pattern->courtesy.slot_num = RTW89_MCC_DFLT_COURTESY_SLOT;
pattern->courtesy.enable = true;
}
@@ -1263,7 +1304,7 @@ static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev,
u64 tsf_src;
int ret;
- ret = rtw89_mac_port_get_tsf(rtwdev, src->rtwvif, &tsf_src);
+ ret = rtw89_mac_port_get_tsf(rtwdev, src->rtwvif_link, &tsf_src);
if (ret) {
rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
return;
@@ -1280,12 +1321,12 @@ static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev,
div_u64_rem(tbtt_tgt, bcn_intvl_src_us, &remainder);
tsf_ofst_tgt = bcn_intvl_src_us - remainder;
- config->sync.macid_tgt = tgt->rtwvif->mac_id;
- config->sync.band_tgt = tgt->rtwvif->mac_idx;
- config->sync.port_tgt = tgt->rtwvif->port;
- config->sync.macid_src = src->rtwvif->mac_id;
- config->sync.band_src = src->rtwvif->mac_idx;
- config->sync.port_src = src->rtwvif->port;
+ config->sync.macid_tgt = tgt->rtwvif_link->mac_id;
+ config->sync.band_tgt = tgt->rtwvif_link->mac_idx;
+ config->sync.port_tgt = tgt->rtwvif_link->port;
+ config->sync.macid_src = src->rtwvif_link->mac_id;
+ config->sync.band_src = src->rtwvif_link->mac_idx;
+ config->sync.port_src = src->rtwvif_link->port;
config->sync.offset = tsf_ofst_tgt / 1024;
config->sync.enable = true;
@@ -1294,7 +1335,7 @@ static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev,
config->sync.macid_tgt, config->sync.macid_src,
config->sync.offset);
- rtw89_mac_port_tsf_sync(rtwdev, tgt->rtwvif, src->rtwvif,
+ rtw89_mac_port_tsf_sync(rtwdev, tgt->rtwvif_link, src->rtwvif_link,
config->sync.offset);
}
@@ -1305,13 +1346,13 @@ static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev)
struct rtw89_mcc_config *config = &mcc->config;
u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval);
u32 tob_ref_us = ieee80211_tu_to_usec(config->pattern.tob_ref);
- struct rtw89_vif *rtwvif = ref->rtwvif;
+ struct rtw89_vif_link *rtwvif_link = ref->rtwvif_link;
u64 tsf, start_tsf;
u32 cur_tbtt_ofst;
u64 min_time;
int ret;
- ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif, &tsf);
+ ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
if (ret) {
rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
return ret;
@@ -1390,13 +1431,13 @@ static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *ro
const struct rtw89_chan *chan;
int ret;
- chan = rtw89_chan_get(rtwdev, role->rtwvif->chanctx_idx);
+ chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx);
req.central_ch_seg0 = chan->channel;
req.primary_ch = chan->primary_channel;
req.bandwidth = chan->band_width;
req.ch_band_type = chan->band_type;
- req.macid = role->rtwvif->mac_id;
+ req.macid = role->rtwvif_link->mac_id;
req.group = mcc->group;
req.c2h_rpt = policy->c2h_rpt;
req.tx_null_early = policy->tx_null_early;
@@ -1421,7 +1462,7 @@ static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *ro
}
ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group,
- role->rtwvif->mac_id,
+ role->rtwvif_link->mac_id,
role->macid_bitmap);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
@@ -1448,7 +1489,7 @@ void __mrc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role,
slot_arg->duration = role->duration;
slot_arg->role_num = 1;
- chan = rtw89_chan_get(rtwdev, role->rtwvif->chanctx_idx);
+ chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx);
slot_arg->roles[0].role_type = RTW89_H2C_MRC_ROLE_WIFI;
slot_arg->roles[0].is_master = role == ref;
@@ -1458,7 +1499,7 @@ void __mrc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role,
slot_arg->roles[0].primary_ch = chan->primary_channel;
slot_arg->roles[0].en_tx_null = !policy->dis_tx_null;
slot_arg->roles[0].null_early = policy->tx_null_early;
- slot_arg->roles[0].macid = role->rtwvif->mac_id;
+ slot_arg->roles[0].macid = role->rtwvif_link->mac_id;
slot_arg->roles[0].macid_main_bitmap =
rtw89_mcc_role_fw_macid_bitmap_to_u32(role);
}
@@ -1569,7 +1610,7 @@ static int __mcc_fw_start(struct rtw89_dev *rtwdev, bool replace)
}
}
- req.macid = ref->rtwvif->mac_id;
+ req.macid = ref->rtwvif_link->mac_id;
req.tsf_high = config->start_tsf >> 32;
req.tsf_low = config->start_tsf;
@@ -1598,7 +1639,7 @@ static void __mrc_fw_add_courtesy(struct rtw89_dev *rtwdev,
if (!courtesy->enable)
return;
- if (courtesy->macid_src == ref->rtwvif->mac_id) {
+ if (courtesy->macid_src == ref->rtwvif_link->mac_id) {
slot_arg_src = &arg->slots[ref->slot_idx];
slot_idx_tgt = aux->slot_idx;
} else {
@@ -1717,9 +1758,9 @@ static int __mcc_fw_set_duration_no_bt(struct rtw89_dev *rtwdev, bool sync_chang
struct rtw89_fw_mcc_duration req = {
.group = mcc->group,
.btc_in_group = false,
- .start_macid = ref->rtwvif->mac_id,
- .macid_x = ref->rtwvif->mac_id,
- .macid_y = aux->rtwvif->mac_id,
+ .start_macid = ref->rtwvif_link->mac_id,
+ .macid_x = ref->rtwvif_link->mac_id,
+ .macid_y = aux->rtwvif_link->mac_id,
.duration_x = ref->duration,
.duration_y = aux->duration,
.start_tsf_high = config->start_tsf >> 32,
@@ -1813,18 +1854,18 @@ static void rtw89_mcc_handle_beacon_noa(struct rtw89_dev *rtwdev, bool enable)
struct ieee80211_p2p_noa_desc noa_desc = {};
u64 start_time = config->start_tsf;
u32 interval = config->mcc_interval;
- struct rtw89_vif *rtwvif_go;
+ struct rtw89_vif_link *rtwvif_go;
u32 duration;
if (mcc->mode != RTW89_MCC_MODE_GO_STA)
return;
if (ref->is_go) {
- rtwvif_go = ref->rtwvif;
+ rtwvif_go = ref->rtwvif_link;
start_time += ieee80211_tu_to_usec(ref->duration);
duration = config->mcc_interval - ref->duration;
} else if (aux->is_go) {
- rtwvif_go = aux->rtwvif;
+ rtwvif_go = aux->rtwvif_link;
start_time += ieee80211_tu_to_usec(pattern->tob_ref) +
ieee80211_tu_to_usec(config->beacon_offset) +
ieee80211_tu_to_usec(pattern->toa_aux);
@@ -1865,9 +1906,9 @@ static void rtw89_mcc_start_beacon_noa(struct rtw89_dev *rtwdev)
return;
if (ref->is_go)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif, true);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, true);
else if (aux->is_go)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif, true);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, true);
rtw89_mcc_handle_beacon_noa(rtwdev, true);
}
@@ -1882,9 +1923,9 @@ static void rtw89_mcc_stop_beacon_noa(struct rtw89_dev *rtwdev)
return;
if (ref->is_go)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif, false);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, false);
else if (aux->is_go)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif, false);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, false);
rtw89_mcc_handle_beacon_noa(rtwdev, false);
}
@@ -1942,7 +1983,7 @@ struct rtw89_mcc_stop_sel {
static void rtw89_mcc_stop_sel_fill(struct rtw89_mcc_stop_sel *sel,
const struct rtw89_mcc_role *mcc_role)
{
- sel->mac_id = mcc_role->rtwvif->mac_id;
+ sel->mac_id = mcc_role->rtwvif_link->mac_id;
sel->slot_idx = mcc_role->slot_idx;
}
@@ -1953,7 +1994,7 @@ static int rtw89_mcc_stop_sel_iterator(struct rtw89_dev *rtwdev,
{
struct rtw89_mcc_stop_sel *sel = data;
- if (!mcc_role->rtwvif->chanctx_assigned)
+ if (!mcc_role->rtwvif_link->chanctx_assigned)
return 0;
rtw89_mcc_stop_sel_fill(sel, mcc_role);
@@ -2081,7 +2122,7 @@ static int __mcc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev,
int ret;
ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group,
- upd->rtwvif->mac_id,
+ upd->rtwvif_link->mac_id,
upd->macid_bitmap);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
@@ -2106,7 +2147,7 @@ static int __mrc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev,
int i;
arg.sch_idx = mcc->group;
- arg.macid = upd->rtwvif->mac_id;
+ arg.macid = upd->rtwvif_link->mac_id;
for (i = 0; i < 32; i++) {
if (add & BIT(i)) {
@@ -2144,7 +2185,7 @@ static int rtw89_mcc_upd_map_iterator(struct rtw89_dev *rtwdev,
void *data)
{
struct rtw89_mcc_role upd = {
- .rtwvif = mcc_role->rtwvif,
+ .rtwvif_link = mcc_role->rtwvif_link,
};
int ret;
@@ -2370,6 +2411,24 @@ void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev)
rtw89_queue_chanctx_work(rtwdev);
}
+static void __rtw89_swap_chanctx(struct rtw89_vif *rtwvif,
+ enum rtw89_chanctx_idx idx1,
+ enum rtw89_chanctx_idx idx2)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ if (!rtwvif_link->chanctx_assigned)
+ continue;
+
+ if (rtwvif_link->chanctx_idx == idx1)
+ rtwvif_link->chanctx_idx = idx2;
+ else if (rtwvif_link->chanctx_idx == idx2)
+ rtwvif_link->chanctx_idx = idx1;
+ }
+}
+
static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx idx1,
enum rtw89_chanctx_idx idx2)
@@ -2386,14 +2445,8 @@ static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
swap(hal->chanctx[idx1], hal->chanctx[idx2]);
- rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- if (!rtwvif->chanctx_assigned)
- continue;
- if (rtwvif->chanctx_idx == idx1)
- rtwvif->chanctx_idx = idx2;
- else if (rtwvif->chanctx_idx == idx2)
- rtwvif->chanctx_idx = idx1;
- }
+ rtw89_for_each_rtwvif(rtwdev, rtwvif)
+ __rtw89_swap_chanctx(rtwvif, idx1, idx2);
cur = atomic_read(&hal->roc_chanctx_idx);
if (cur == idx1)
@@ -2444,14 +2497,14 @@ void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
}
int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
struct rtw89_entity_weight w = {};
- rtwvif->chanctx_idx = cfg->idx;
- rtwvif->chanctx_assigned = true;
+ rtwvif_link->chanctx_idx = cfg->idx;
+ rtwvif_link->chanctx_assigned = true;
cfg->ref_count++;
if (cfg->idx == RTW89_CHANCTX_0)
@@ -2469,7 +2522,7 @@ out:
}
void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
@@ -2479,8 +2532,8 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
enum rtw89_entity_mode new;
int ret;
- rtwvif->chanctx_idx = RTW89_CHANCTX_0;
- rtwvif->chanctx_assigned = false;
+ rtwvif_link->chanctx_idx = RTW89_CHANCTX_0;
+ rtwvif_link->chanctx_assigned = false;
cfg->ref_count--;
if (cfg->ref_count != 0)
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index c6d31984e575..74de13a2e7da 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -43,18 +43,21 @@ struct rtw89_entity_weight {
unsigned int active_roles;
};
-static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev)
+static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
struct rtw89_hal *hal = &rtwdev->hal;
- return READ_ONCE(hal->entity_active);
+ return READ_ONCE(hal->entity_active[phy_idx]);
}
-static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev, bool active)
+static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx,
+ bool active)
{
struct rtw89_hal *hal = &rtwdev->hal;
- WRITE_ONCE(hal->entity_active, active);
+ WRITE_ONCE(hal->entity_active[phy_idx], active);
}
static inline
@@ -106,10 +109,10 @@ void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx,
u32 changed);
int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index df51b29142aa..989e6e882c6e 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -125,6 +125,9 @@ static const u32 cxtbl[] = {
0xfafaaafa, /* 23 */
0xfafffaff, /* 24 */
0xea6a5a5a, /* 25 */
+ 0xfaff5aff, /* 26 */
+ 0xffffdfff, /* 27 */
+ 0xe6555555, /* 28 */
};
static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
@@ -134,77 +137,88 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
- .fwevntrptl = 1, .drvinfo_type = 1, .info_buf = 1800, .max_role_num = 6,
+ .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
+ .max_role_num = 6,
},
{RTL8922A, RTW89_FW_VER_CODE(0, 35, 8, 0),
.fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 8, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
- .fwevntrptl = 1, .drvinfo_type = 1, .info_buf = 1800, .max_role_num = 6,
+ .fwevntrptl = 1, .fwc2hfunc = 1, .drvinfo_type = 1, .info_buf = 1800,
+ .max_role_num = 6,
},
{RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0),
.fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
+ .max_role_num = 6,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .max_role_num = 5,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .max_role_num = 5,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .max_role_num = 5,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0),
.fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
+ .max_role_num = 6,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0),
.fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
+ .max_role_num = 6,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 1, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .max_role_num = 5,
},
{RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1280,
+ .max_role_num = 5,
},
{RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0),
.fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2,
.fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0,
- .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1024, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1024,
+ .max_role_num = 5,
},
/* keep it to be the last as default entry */
@@ -213,7 +227,8 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0,
- .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1024, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1024,
+ .max_role_num = 5,
},
};
@@ -224,7 +239,7 @@ static const union rtw89_btc_wl_state_map btc_scanning_map = {
.scan = 1,
.connecting = 1,
.roaming = 1,
- .transacting = 1,
+ .dbccing = 1,
._4way = 1,
},
};
@@ -3017,7 +3032,7 @@ static void _update_btc_state_map(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
if (wl->status.map.connecting || wl->status.map._4way ||
- wl->status.map.roaming) {
+ wl->status.map.roaming || wl->status.map.dbccing) {
cx->state_map = BTC_WLINKING;
} else if (wl->status.map.scan) { /* wl scan */
if (bt_linfo->status.map.inq_pag)
@@ -3721,8 +3736,6 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
tbl_w1 = cxtbl[16];
}
- btc->bt_req_en = false;
-
switch (type) {
case BTC_CXP_USERDEF0:
btc->update_policy_force = true;
@@ -3744,6 +3757,10 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
case BTC_CXP_OFF_WL:
_slot_set_tbl(btc, CXST_OFF, cxtbl[1]);
break;
+ case BTC_CXP_OFF_WL2:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[1]);
+ _slot_set_type(btc, CXST_OFF, SLOT_ISO);
+ break;
case BTC_CXP_OFF_EQ0:
_slot_set_tbl(btc, CXST_OFF, cxtbl[0]);
_slot_set_type(btc, CXST_OFF, SLOT_ISO);
@@ -3757,6 +3774,12 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
case BTC_CXP_OFF_EQ3:
_slot_set_tbl(btc, CXST_OFF, cxtbl[24]);
break;
+ case BTC_CXP_OFF_EQ4:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[26]);
+ break;
+ case BTC_CXP_OFF_EQ5:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[27]);
+ break;
case BTC_CXP_OFF_BWB0:
_slot_set_tbl(btc, CXST_OFF, cxtbl[5]);
break;
@@ -3788,7 +3811,6 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
}
break;
case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */
- btc->bt_req_en = true;
_write_scbd(rtwdev, BTC_WSCB_TDMA, true);
*t = t_def[CXTD_OFF_EXT];
@@ -3831,9 +3853,9 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype);
break;
case BTC_CXP_OFFE_2GBWMIXB:
- _slot_set(btc, CXST_E2G, 0, 0x55555555, SLOT_MIX);
+ _slot_set(btc, CXST_E2G, 0, 0xea5a5555, SLOT_MIX);
_slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur,
- cpu_to_le32(0x55555555), s_def[CXST_EBT].cxtype);
+ s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype);
break;
case BTC_CXP_OFFE_WL: /* for 4-way */
_slot_set(btc, CXST_E2G, 0, cxtbl[1], SLOT_MIX);
@@ -3842,6 +3864,8 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
default:
break;
}
+ _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur,
+ s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype);
_slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur,
s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype);
break;
@@ -4246,6 +4270,7 @@ static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec,
_set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
break;
case BTC_ANT_WRFK:
+ case BTC_ANT_WRFK2:
rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
_set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO);
_set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE);
@@ -4623,12 +4648,21 @@ static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev)
static void _action_bt_pan(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
+ struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
+ struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc;
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
switch (btc->cx.state_map) {
case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN */
- _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN);
+ if (a2dp.active || !pan.exist) {
+ btc->dm.slot_dur[CXST_W1] = 80;
+ btc->dm.slot_dur[CXST_B1] = 20;
+ _set_policy(rtwdev, BTC_CXP_PFIX_TDW1B1, BTC_ACT_BT_PAN);
+ } else {
+ _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN);
+ }
break;
case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN */
_set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN);
@@ -4814,8 +4848,16 @@ static void _action_wl_rfk(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): band = %d\n",
__func__, rfk.band);
- _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK);
- _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK);
+ btc->dm.tdma_instant_excute = 1;
+
+ if (rfk.state == BTC_WRFK_ONESHOT_START ||
+ btc->ant_type == BTC_ANT_SHARED) {
+ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK2);
+ _set_policy(rtwdev, BTC_CXP_OFF_WL2, BTC_ACT_WL_RFK);
+ } else {
+ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK);
+ _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK);
+ }
}
static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
@@ -4855,6 +4897,8 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
if (rtwdev->dbcc_en) {
if (ver->fwlrole == 0) {
+ wl_rinfo.dbcc_2g_phy = RTW89_PHY_MAX;
+
for (i = 0; i < RTW89_PHY_MAX; i++) {
if (wl_dinfo->real_band[i] == RTW89_BAND_2G)
wl_rinfo.dbcc_2g_phy = i;
@@ -4989,18 +5033,16 @@ struct rtw89_txtime_data {
bool reenable;
};
-static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
+static void __rtw89_tx_time_iter(struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ struct rtw89_txtime_data *iter_data)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_txtime_data *iter_data =
- (struct rtw89_txtime_data *)data;
struct rtw89_dev *rtwdev = iter_data->rtwdev;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &cx->wl;
struct rtw89_btc_wl_link_info *plink = NULL;
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
u32 tx_time = iter_data->tx_time;
u8 tx_retry = iter_data->tx_retry;
u16 enable = iter_data->enable;
@@ -5023,8 +5065,8 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
/* backup the original tx time before tx-limit on */
if (reenable) {
- rtw89_mac_get_tx_time(rtwdev, rtwsta, &plink->tx_time);
- rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta, &plink->tx_retry);
+ rtw89_mac_get_tx_time(rtwdev, rtwsta_link, &plink->tx_time);
+ rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta_link, &plink->tx_retry);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): reenable, tx_time=%d tx_retry= %d\n",
__func__, plink->tx_time, plink->tx_retry);
@@ -5032,22 +5074,37 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
/* restore the original tx time if no tx-limit */
if (!enable) {
- rtw89_mac_set_tx_time(rtwdev, rtwsta, true, plink->tx_time);
- rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, true,
+ rtw89_mac_set_tx_time(rtwdev, rtwsta_link, true, plink->tx_time);
+ rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, true,
plink->tx_retry);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): restore, tx_time=%d tx_retry= %d\n",
__func__, plink->tx_time, plink->tx_retry);
} else {
- rtw89_mac_set_tx_time(rtwdev, rtwsta, false, tx_time);
- rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, false, tx_retry);
+ rtw89_mac_set_tx_time(rtwdev, rtwsta_link, false, tx_time);
+ rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, tx_retry);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): set, tx_time=%d tx_retry= %d\n",
__func__, tx_time, tx_retry);
}
}
+static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_txtime_data *iter_data =
+ (struct rtw89_txtime_data *)data;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ __rtw89_tx_time_iter(rtwvif_link, rtwsta_link, iter_data);
+ }
+}
+
static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
@@ -5231,8 +5288,14 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc;
struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc;
+ struct rtw89_btc_dm *dm = &btc->dm;
u8 profile_map = 0;
+ if (dm->freerun_chk) {
+ _action_freerun(rtwdev);
+ return;
+ }
+
if (bt_linfo->hfp_desc.exist)
profile_map |= BTC_BT_HFP;
@@ -5247,30 +5310,20 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
switch (profile_map) {
case BTC_BT_NOPROFILE:
- if (_check_freerun(rtwdev))
- _action_freerun(rtwdev);
- else if (pan.active)
+ if (pan.active)
_action_bt_pan(rtwdev);
else
_action_bt_idle(rtwdev);
break;
case BTC_BT_HFP:
- if (_check_freerun(rtwdev))
- _action_freerun(rtwdev);
- else
- _action_bt_hfp(rtwdev);
+ _action_bt_hfp(rtwdev);
break;
case BTC_BT_HFP | BTC_BT_HID:
case BTC_BT_HID:
- if (_check_freerun(rtwdev))
- _action_freerun(rtwdev);
- else
- _action_bt_hid(rtwdev);
+ _action_bt_hid(rtwdev);
break;
case BTC_BT_A2DP:
- if (_check_freerun(rtwdev))
- _action_freerun(rtwdev);
- else if (a2dp.sink)
+ if (a2dp.sink)
_action_bt_a2dpsink(rtwdev);
else if (bt_linfo->multi_link.now && !hid.pair_cnt)
_action_bt_a2dp_pan(rtwdev);
@@ -5283,13 +5336,18 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
case BTC_BT_A2DP | BTC_BT_HFP:
case BTC_BT_A2DP | BTC_BT_HID:
case BTC_BT_A2DP | BTC_BT_HFP | BTC_BT_HID:
- if (_check_freerun(rtwdev))
- _action_freerun(rtwdev);
+ if (a2dp.sink)
+ _action_bt_a2dpsink(rtwdev);
+ else if (pan.active)
+ _action_bt_a2dp_pan_hid(rtwdev);
else
_action_bt_a2dp_hid(rtwdev);
break;
case BTC_BT_A2DP | BTC_BT_PAN:
- _action_bt_a2dp_pan(rtwdev);
+ if (a2dp.sink)
+ _action_bt_a2dpsink(rtwdev);
+ else
+ _action_bt_a2dp_pan(rtwdev);
break;
case BTC_BT_PAN | BTC_BT_HFP:
case BTC_BT_PAN | BTC_BT_HID:
@@ -5299,7 +5357,10 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HID:
case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HFP:
default:
- _action_bt_a2dp_pan_hid(rtwdev);
+ if (a2dp.sink)
+ _action_bt_a2dpsink(rtwdev);
+ else
+ _action_bt_a2dp_pan_hid(rtwdev);
break;
}
}
@@ -5319,7 +5380,7 @@ static void _action_wl_25g_mcc(struct rtw89_dev *rtwdev)
policy_type = BTC_CXP_OFFE_WL;
else if (btc->cx.wl.status.val & btc_scanning_map.val)
policy_type = BTC_CXP_OFFE_2GBWMIXB;
- else if (btc->cx.bt.link_info.profile_cnt.now == 0)
+ else if (btc->cx.bt.link_info.status.map.connect == 0)
policy_type = BTC_CXP_OFFE_2GISOB;
else
policy_type = BTC_CXP_OFFE_2GBWISOB;
@@ -6891,6 +6952,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
bt->scan_rx_low_pri = false;
igno_bt = false;
+ dm->freerun_chk = _check_freerun(rtwdev); /* check if meet freerun */
+
if (always_freerun) {
_action_freerun(rtwdev);
igno_bt = true;
@@ -6929,18 +6992,9 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
goto exit;
}
- if (cx->state_map == BTC_WLINKING) {
- if (mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_2G_STA ||
- mode == BTC_WLINK_5G) {
- _action_wl_scan(rtwdev);
- bt->scan_rx_low_pri = false;
- goto exit;
- }
- }
-
- if (wl->status.map.scan) {
+ if (wl->status.val & btc_scanning_map.val) {
_action_wl_scan(rtwdev);
- bt->scan_rx_low_pri = false;
+ bt->scan_rx_low_pri = true;
goto exit;
}
@@ -7176,10 +7230,6 @@ void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band)
btc->dm.cnt_notify[BTC_NCNT_SWITCH_BAND]++;
- wl->scan_info.band[phy_idx] = band;
- wl->scan_info.phy_map |= BIT(phy_idx);
- _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN);
-
if (rtwdev->dbcc_en) {
wl->dbcc_info.scan_band[phy_idx] = band;
_update_dbcc_band(rtwdev, phy_idx);
@@ -7374,13 +7424,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
"[BTC], %s(): bt_info[2]=0x%02x\n",
__func__, bt->raw_info[2]);
- /* reset to mo-connect before update */
- b->status.val = BTC_BLINK_NOCONNECT;
b->profile_cnt.last = b->profile_cnt.now;
- b->relink.last = b->relink.now;
- a2dp->exist_last = a2dp->exist;
- b->multi_link.last = b->multi_link.now;
- bt->inq_pag.last = bt->inq_pag.now;
b->profile_cnt.now = 0;
hid->type = 0;
@@ -7399,7 +7443,8 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
b->profile_cnt.now += (u8)hid->exist;
a2dp->exist = btinfo.lb2.a2dp;
b->profile_cnt.now += (u8)a2dp->exist;
- pan->active = btinfo.lb2.pan;
+ pan->exist = btinfo.lb2.pan;
+ b->profile_cnt.now += (u8)pan->exist;
btc->dm.trx_info.bt_profile = u32_get_bits(btinfo.val, BT_PROFILE_PROTOCOL_MASK);
/* parse raw info low-Byte3 */
@@ -7423,8 +7468,14 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
/* parse raw info high-Byte1 */
btinfo.val = bt->raw_info[BTC_BTINFO_H1];
b->status.map.ble_connect = btinfo.hb1.ble_connect;
- if (btinfo.hb1.ble_connect)
- hid->type |= (hid->exist ? BTC_HID_BLE : BTC_HID_RCU);
+ if (btinfo.hb1.ble_connect) {
+ if (hid->exist)
+ hid->type |= BTC_HID_BLE;
+ else if (btinfo.hb1.voice)
+ hid->type |= BTC_HID_RCU_VOICE;
+ else
+ hid->type |= BTC_HID_RCU;
+ }
cx->cnt_bt[BTC_BCNT_REINIT] += !!(btinfo.hb1.reinit && !bt->reinit);
bt->reinit = btinfo.hb1.reinit;
@@ -7436,7 +7487,6 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
if (bt->igno_wl && !cx->wl.status.map.rf_off)
_set_bt_ignore_wlan_act(rtwdev, false);
- hid->type |= (btinfo.hb1.voice ? BTC_HID_RCU_VOICE : 0);
bt->ble_scan_en = btinfo.hb1.ble_scan;
cx->cnt_bt[BTC_BCNT_ROLESW] += !!(btinfo.hb1.role_sw && !b->role_sw);
@@ -7446,8 +7496,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
/* parse raw info high-Byte2 */
btinfo.val = bt->raw_info[BTC_BTINFO_H2];
- pan->exist = btinfo.hb2.pan_active;
- b->profile_cnt.now += (u8)pan->exist;
+ pan->active = !!btinfo.hb2.pan_active;
cx->cnt_bt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update);
b->afh_update = btinfo.hb2.afh_update;
@@ -7455,8 +7504,9 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
b->slave_role = btinfo.hb2.slave;
hid->slot_info = btinfo.hb2.hid_slot;
hid->pair_cnt = btinfo.hb2.hid_cnt;
- hid->type |= (hid->slot_info == BTC_HID_218 ?
- BTC_HID_218 : BTC_HID_418);
+ if (!b->status.map.ble_connect || hid->pair_cnt > 1)
+ hid->type |= (hid->slot_info == BTC_HID_218 ?
+ BTC_HID_218 : BTC_HID_418);
/* parse raw info high-Byte3 */
btinfo.val = bt->raw_info[BTC_BTINFO_H3];
a2dp->bitpool = btinfo.hb3.a2dp_bitpool;
@@ -7479,13 +7529,16 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
_run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO);
}
-void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, enum btc_role_state state)
+void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ enum btc_role_state state)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
+ rtwvif_link->chanctx_idx);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct ieee80211_bss_conf *bss_conf;
+ struct ieee80211_link_sta *link_sta;
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
@@ -7493,51 +7546,59 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
struct rtw89_btc_wl_link_info *wlinfo = NULL;
u8 mode = 0, rlink_id, link_mode_ori, pta_req_mac_ori, wa_type;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], state=%d\n", state);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], role is STA=%d\n",
vif->type == NL80211_IFTYPE_STATION);
- rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif->port);
+ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif_link->port);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n",
chan->band_type, chan->channel, chan->band_width);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n",
state == BTC_ROLE_MSTS_STA_CONN_END);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], bcn_period=%d dtim_period=%d\n",
- vif->bss_conf.beacon_int, vif->bss_conf.dtim_period);
+ bss_conf->beacon_int, bss_conf->dtim_period);
+
+ if (rtwsta_link) {
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
- if (rtwsta) {
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n",
- rtwsta->mac_id);
+ rtwsta_link->mac_id);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], STA support HE=%d VHT=%d HT=%d\n",
- sta->deflink.he_cap.has_he,
- sta->deflink.vht_cap.vht_supported,
- sta->deflink.ht_cap.ht_supported);
- if (sta->deflink.he_cap.has_he)
+ link_sta->he_cap.has_he,
+ link_sta->vht_cap.vht_supported,
+ link_sta->ht_cap.ht_supported);
+ if (link_sta->he_cap.has_he)
mode |= BIT(BTC_WL_MODE_HE);
- if (sta->deflink.vht_cap.vht_supported)
+ if (link_sta->vht_cap.vht_supported)
mode |= BIT(BTC_WL_MODE_VHT);
- if (sta->deflink.ht_cap.ht_supported)
+ if (link_sta->ht_cap.ht_supported)
mode |= BIT(BTC_WL_MODE_HT);
r.mode = mode;
}
- if (rtwvif->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX)
+ if (rtwvif_link->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) {
+ rcu_read_unlock();
return;
+ }
rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], wifi_role=%d\n", rtwvif->wifi_role);
+ "[BTC], wifi_role=%d\n", rtwvif_link->wifi_role);
- r.role = rtwvif->wifi_role;
- r.phy = rtwvif->phy_idx;
- r.pid = rtwvif->port;
+ r.role = rtwvif_link->wifi_role;
+ r.phy = rtwvif_link->phy_idx;
+ r.pid = rtwvif_link->port;
r.active = true;
r.connected = MLME_LINKED;
- r.bcn_period = vif->bss_conf.beacon_int;
- r.dtim_period = vif->bss_conf.dtim_period;
+ r.bcn_period = bss_conf->beacon_int;
+ r.dtim_period = bss_conf->dtim_period;
r.band = chan->band_type;
r.ch = chan->channel;
r.bw = chan->band_width;
@@ -7545,10 +7606,12 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
r.chdef.center_ch = chan->channel;
r.chdef.bw = chan->band_width;
r.chdef.chan = chan->primary_channel;
- ether_addr_copy(r.mac_addr, rtwvif->mac_addr);
+ ether_addr_copy(r.mac_addr, rtwvif_link->mac_addr);
+
+ rcu_read_unlock();
- if (rtwsta && vif->type == NL80211_IFTYPE_STATION)
- r.mac_id = rtwsta->mac_id;
+ if (rtwsta_link && vif->type == NL80211_IFTYPE_STATION)
+ r.mac_id = rtwsta_link->mac_id;
btc->dm.cnt_notify[BTC_NCNT_ROLE_INFO]++;
@@ -7779,26 +7842,26 @@ struct rtw89_btc_wl_sta_iter_data {
bool is_traffic_change;
};
-static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
+static
+void __rtw89_btc_ntfy_wl_sta_iter(struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ struct rtw89_btc_wl_sta_iter_data *iter_data)
{
- struct rtw89_btc_wl_sta_iter_data *iter_data =
- (struct rtw89_btc_wl_sta_iter_data *)data;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_dev *rtwdev = iter_data->rtwdev;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_link_info *link_info = NULL;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_traffic_stats *link_info_t = NULL;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_traffic_stats *stats = &rtwvif->stats;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc_wl_role_info *r;
struct rtw89_btc_wl_role_info_v1 *r1;
u32 last_tx_rate, last_rx_rate;
u16 last_tx_lvl, last_rx_lvl;
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
u8 rssi;
u8 busy = 0;
u8 dir = 0;
@@ -7806,11 +7869,11 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
u8 i = 0;
bool is_sta_change = false, is_traffic_change = false;
- rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR;
+ rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR;
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi);
link_info = &wl->link_info[port];
- link_info->stat.traffic = rtwvif->stats;
+ link_info->stat.traffic = *stats;
link_info_t = &link_info->stat.traffic;
if (link_info->connected == MLME_NO_LINK) {
@@ -7858,19 +7921,19 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
iter_data->busy_all |= busy;
iter_data->dir_all |= BIT(dir);
- if (rtwsta->rx_hw_rate <= RTW89_HW_RATE_CCK2 &&
+ if (rtwsta_link->rx_hw_rate <= RTW89_HW_RATE_CCK2 &&
last_rx_rate > RTW89_HW_RATE_CCK2 &&
link_info_t->rx_tfc_lv > RTW89_TFC_IDLE)
link_info->rx_rate_drop_cnt++;
- if (last_tx_rate != rtwsta->ra_report.hw_rate ||
- last_rx_rate != rtwsta->rx_hw_rate ||
+ if (last_tx_rate != rtwsta_link->ra_report.hw_rate ||
+ last_rx_rate != rtwsta_link->rx_hw_rate ||
last_tx_lvl != link_info_t->tx_tfc_lv ||
last_rx_lvl != link_info_t->rx_tfc_lv)
is_traffic_change = true;
- link_info_t->tx_rate = rtwsta->ra_report.hw_rate;
- link_info_t->rx_rate = rtwsta->rx_hw_rate;
+ link_info_t->tx_rate = rtwsta_link->ra_report.hw_rate;
+ link_info_t->rx_rate = rtwsta_link->rx_hw_rate;
if (link_info->role == RTW89_WIFI_ROLE_STATION ||
link_info->role == RTW89_WIFI_ROLE_P2P_CLIENT) {
@@ -7882,19 +7945,19 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
r = &wl->role_info;
r->active_role[port].tx_lvl = stats->tx_tfc_lv;
r->active_role[port].rx_lvl = stats->rx_tfc_lv;
- r->active_role[port].tx_rate = rtwsta->ra_report.hw_rate;
- r->active_role[port].rx_rate = rtwsta->rx_hw_rate;
+ r->active_role[port].tx_rate = rtwsta_link->ra_report.hw_rate;
+ r->active_role[port].rx_rate = rtwsta_link->rx_hw_rate;
} else if (ver->fwlrole == 1) {
r1 = &wl->role_info_v1;
r1->active_role_v1[port].tx_lvl = stats->tx_tfc_lv;
r1->active_role_v1[port].rx_lvl = stats->rx_tfc_lv;
- r1->active_role_v1[port].tx_rate = rtwsta->ra_report.hw_rate;
- r1->active_role_v1[port].rx_rate = rtwsta->rx_hw_rate;
+ r1->active_role_v1[port].tx_rate = rtwsta_link->ra_report.hw_rate;
+ r1->active_role_v1[port].rx_rate = rtwsta_link->rx_hw_rate;
} else if (ver->fwlrole == 2) {
dm->trx_info.tx_lvl = stats->tx_tfc_lv;
dm->trx_info.rx_lvl = stats->rx_tfc_lv;
- dm->trx_info.tx_rate = rtwsta->ra_report.hw_rate;
- dm->trx_info.rx_rate = rtwsta->rx_hw_rate;
+ dm->trx_info.tx_rate = rtwsta_link->ra_report.hw_rate;
+ dm->trx_info.rx_rate = rtwsta_link->rx_hw_rate;
}
dm->trx_info.tx_tp = link_info_t->tx_throughput;
@@ -7914,6 +7977,21 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
iter_data->is_traffic_change = true;
}
+static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_btc_wl_sta_iter_data *iter_data =
+ (struct rtw89_btc_wl_sta_iter_data *)data;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ __rtw89_btc_ntfy_wl_sta_iter(rtwvif_link, rtwsta_link, iter_data);
+ }
+}
+
#define BTC_NHM_CHK_INTVL 20
void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev)
@@ -7963,6 +8041,53 @@ void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev)
}
}
+static u8 rtw89_btc_c2h_get_index_by_ver(struct rtw89_dev *rtwdev, u8 func)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ const struct rtw89_btc_ver *ver = btc->ver;
+
+ switch (func) {
+ case BTF_EVNT_RPT:
+ case BTF_EVNT_BT_INFO:
+ case BTF_EVNT_BT_SCBD:
+ case BTF_EVNT_BT_REG:
+ case BTF_EVNT_CX_RUNINFO:
+ case BTF_EVNT_BT_PSD:
+ return func;
+ case BTF_EVNT_BT_DEV_INFO:
+ if (ver->fwc2hfunc == 0)
+ return BTF_EVNT_BUF_OVERFLOW;
+ else
+ return BTF_EVNT_BT_DEV_INFO;
+ case BTF_EVNT_BT_LEAUDIO_INFO:
+ if (ver->fwc2hfunc == 0)
+ return BTF_EVNT_C2H_LOOPBACK;
+ else if (ver->fwc2hfunc == 1)
+ return BTF_EVNT_BUF_OVERFLOW;
+ else if (ver->fwc2hfunc == 2)
+ return func;
+ else
+ return BTF_EVNT_MAX;
+ case BTF_EVNT_BUF_OVERFLOW:
+ if (ver->fwc2hfunc == 0)
+ return BTF_EVNT_MAX;
+ else if (ver->fwc2hfunc == 1)
+ return BTF_EVNT_C2H_LOOPBACK;
+ else if (ver->fwc2hfunc == 2)
+ return func;
+ else
+ return BTF_EVNT_MAX;
+ case BTF_EVNT_C2H_LOOPBACK:
+ if (ver->fwc2hfunc == 2)
+ return func;
+ else
+ return BTF_EVNT_MAX;
+ case BTF_EVNT_MAX:
+ default:
+ return BTF_EVNT_MAX;
+ }
+}
+
void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func)
{
@@ -7979,10 +8104,14 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (class != BTFC_FW_EVENT)
return;
+ func = rtw89_btc_c2h_get_index_by_ver(rtwdev, func);
+
switch (func) {
- case BTF_EVNT_RPT:
case BTF_EVNT_BUF_OVERFLOW:
pfwinfo->event[func]++;
+ break;
+ case BTF_EVNT_RPT:
+ pfwinfo->event[func]++;
/* Don't need rtw89_leave_ps_mode() */
btc_fw_event(rtwdev, func, buf, len);
break;
diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index de53b56632f7..dbdb56e063ef 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -271,8 +271,10 @@ void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work);
void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work);
void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work);
void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work);
-void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, enum btc_role_state state);
+void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ enum btc_role_state state);
void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state);
void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map,
enum btc_wl_rfk_type type,
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 4553810634c6..bba5bde95bb4 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -352,10 +352,6 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
enum rtw89_entity_mode mode;
bool entity_active;
- entity_active = rtw89_get_entity_state(rtwdev);
- if (!entity_active)
- return;
-
mode = rtw89_get_entity_mode(rtwdev);
switch (mode) {
case RTW89_ENTITY_MODE_SCC:
@@ -375,6 +371,11 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
chanctx_idx = roc_idx;
phy_idx = RTW89_PHY_0;
+
+ entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
+ if (!entity_active)
+ return;
+
chan = rtw89_chan_get(rtwdev, chanctx_idx);
chip->ops->set_txpwr(rtwdev, chan, phy_idx);
}
@@ -393,8 +394,6 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev)
enum rtw89_entity_mode mode;
bool entity_active;
- entity_active = rtw89_get_entity_state(rtwdev);
-
mode = rtw89_entity_recalc(rtwdev);
switch (mode) {
case RTW89_ENTITY_MODE_SCC:
@@ -416,6 +415,8 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev)
mac_idx = RTW89_MAC_0;
phy_idx = RTW89_PHY_0;
+ entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
+
chan = rtw89_chan_get(rtwdev, chanctx_idx);
chan_rcd = rtw89_chan_rcd_get(rtwdev, chanctx_idx);
@@ -432,19 +433,10 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev)
rtw89_chip_rfk_band_changed(rtwdev, phy_idx, chan);
}
- rtw89_set_entity_state(rtwdev, true);
+ rtw89_set_entity_state(rtwdev, phy_idx, true);
return 0;
}
-void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_chan *chan)
-{
- const struct cfg80211_chan_def *chandef;
-
- chandef = rtw89_chandef_get(rtwdev, rtwvif->chanctx_idx);
- rtw89_get_channel_params(chandef, chan);
-}
-
static enum rtw89_core_tx_type
rtw89_core_get_tx_type(struct rtw89_dev *rtwdev,
struct sk_buff *skb)
@@ -463,8 +455,9 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req,
enum btc_pkt_type pkt_type)
{
- struct ieee80211_sta *sta = tx_req->sta;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
+ struct ieee80211_link_sta *link_sta;
struct sk_buff *skb = tx_req->skb;
struct rtw89_sta *rtwsta;
u8 ampdu_num;
@@ -478,21 +471,26 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev,
if (!(IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU))
return;
- if (!sta) {
+ if (!rtwsta_link) {
rtw89_warn(rtwdev, "cannot set ampdu info without sta\n");
return;
}
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
- rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ rtwsta = rtwsta_link->rtwsta;
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
ampdu_num = (u8)((rtwsta->ampdu_params[tid].agg_num ?
rtwsta->ampdu_params[tid].agg_num :
- 4 << sta->deflink.ht_cap.ampdu_factor) - 1);
+ 4 << link_sta->ht_cap.ampdu_factor) - 1);
desc_info->agg_en = true;
- desc_info->ampdu_density = sta->deflink.ht_cap.ampdu_density;
+ desc_info->ampdu_density = link_sta->ht_cap.ampdu_density;
desc_info->ampdu_num = ampdu_num;
+
+ rcu_read_unlock();
}
static void
@@ -569,9 +567,13 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan)
{
struct sk_buff *skb = tx_req->skb;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = tx_info->control.vif;
+ struct ieee80211_bss_conf *bss_conf;
u16 lowest_rate;
+ u16 rate;
if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE ||
(vif && vif->p2p))
@@ -581,25 +583,35 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
else
lowest_rate = RTW89_HW_RATE_OFDM6;
- if (!vif || !vif->bss_conf.basic_rates || !tx_req->sta)
+ if (!rtwvif_link)
return lowest_rate;
- return __ffs(vif->bss_conf.basic_rates) + lowest_rate;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+ if (!bss_conf->basic_rates || !rtwsta_link) {
+ rate = lowest_rate;
+ goto out;
+ }
+
+ rate = __ffs(bss_conf->basic_rates) + lowest_rate;
+
+out:
+ rcu_read_unlock();
+
+ return rate;
}
static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
- struct ieee80211_vif *vif = tx_req->vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct ieee80211_sta *sta = tx_req->sta;
- struct rtw89_sta *rtwsta;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
- if (!sta)
- return rtwvif->mac_id;
+ if (!rtwsta_link)
+ return rtwvif_link->mac_id;
- rtwsta = (struct rtw89_sta *)sta->drv_priv;
- return rtwsta->mac_id;
+ return rtwsta_link->mac_id;
}
static void rtw89_core_tx_update_llc_hdr(struct rtw89_dev *rtwdev,
@@ -618,11 +630,10 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct ieee80211_vif *vif = tx_req->vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
+ rtwvif_link->chanctx_idx);
struct sk_buff *skb = tx_req->skb;
u8 qsel, ch_dma;
@@ -631,7 +642,7 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
desc_info->qsel = qsel;
desc_info->ch_dma = ch_dma;
- desc_info->port = desc_info->hiq ? rtwvif->port : 0;
+ desc_info->port = desc_info->hiq ? rtwvif_link->port : 0;
desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req);
desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL;
desc_info->hw_seq_mode = RTW89_MGMT_HW_SEQ_MODE;
@@ -701,26 +712,36 @@ __rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req,
enum btc_pkt_type pkt_type)
{
- struct ieee80211_sta *sta = tx_req->sta;
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
struct sk_buff *skb = tx_req->skb;
struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ieee80211_link_sta *link_sta;
__le16 fc = hdr->frame_control;
/* AP IOT issue with EAPoL, ARP and DHCP */
if (pkt_type < PACKET_MAX)
return false;
- if (!sta || !sta->deflink.he_cap.has_he)
+ if (!rtwsta_link)
return false;
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
+ if (!link_sta->he_cap.has_he) {
+ rcu_read_unlock();
+ return false;
+ }
+
+ rcu_read_unlock();
+
if (!ieee80211_is_data_qos(fc))
return false;
if (skb_headroom(skb) < IEEE80211_HT_CTL_LEN)
return false;
- if (rtwsta && rtwsta->ra_report.might_fallback_legacy)
+ if (rtwsta_link && rtwsta_link->ra_report.might_fallback_legacy)
return false;
return true;
@@ -730,8 +751,7 @@ static void
__rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
- struct ieee80211_sta *sta = tx_req->sta;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
struct sk_buff *skb = tx_req->skb;
struct ieee80211_hdr *hdr = (void *)skb->data;
__le16 fc = hdr->frame_control;
@@ -747,7 +767,7 @@ __rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev,
hdr = data;
htc = data + hdr_len;
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_ORDER);
- *htc = rtwsta->htc_template ? rtwsta->htc_template :
+ *htc = rtwsta_link->htc_template ? rtwsta_link->htc_template :
le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) |
le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_CAS, RTW89_HTC_MASK_CTL_ID);
@@ -761,8 +781,7 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev,
enum btc_pkt_type pkt_type)
{
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
- struct ieee80211_vif *vif = tx_req->vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
if (!__rtw89_core_tx_check_he_qos_htc(rtwdev, tx_req, pkt_type))
goto desc_bk;
@@ -773,23 +792,25 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev,
desc_info->a_ctrl_bsr = true;
desc_bk:
- if (!rtwvif || rtwvif->last_a_ctrl == desc_info->a_ctrl_bsr)
+ if (!rtwvif_link || rtwvif_link->last_a_ctrl == desc_info->a_ctrl_bsr)
return;
- rtwvif->last_a_ctrl = desc_info->a_ctrl_bsr;
+ rtwvif_link->last_a_ctrl = desc_info->a_ctrl_bsr;
desc_info->bk = true;
}
static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
- struct ieee80211_vif *vif = tx_req->vif;
- struct ieee80211_sta *sta = tx_req->sta;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern;
- enum rtw89_chanctx_idx idx = rtwvif->chanctx_idx;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern;
+ enum rtw89_chanctx_idx idx = rtwvif_link->chanctx_idx;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx);
+ struct ieee80211_link_sta *link_sta;
u16 lowest_rate;
+ u16 rate;
if (rate_pattern->enable)
return rate_pattern->rate;
@@ -801,20 +822,31 @@ static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev,
else
lowest_rate = RTW89_HW_RATE_OFDM6;
- if (!sta || !sta->deflink.supp_rates[chan->band_type])
+ if (!rtwsta_link)
return lowest_rate;
- return __ffs(sta->deflink.supp_rates[chan->band_type]) + lowest_rate;
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
+ if (!link_sta->supp_rates[chan->band_type]) {
+ rate = lowest_rate;
+ goto out;
+ }
+
+ rate = __ffs(link_sta->supp_rates[chan->band_type]) + lowest_rate;
+
+out:
+ rcu_read_unlock();
+
+ return rate;
}
static void
rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
- struct ieee80211_vif *vif = tx_req->vif;
- struct ieee80211_sta *sta = tx_req->sta;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
struct sk_buff *skb = tx_req->skb;
u8 tid, tid_indicate;
@@ -829,10 +861,10 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,
desc_info->tid_indicate = tid_indicate;
desc_info->qsel = qsel;
desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req);
- desc_info->port = desc_info->hiq ? rtwvif->port : 0;
- desc_info->er_cap = rtwsta ? rtwsta->er_cap : false;
- desc_info->stbc = rtwsta ? rtwsta->ra.stbc_cap : false;
- desc_info->ldpc = rtwsta ? rtwsta->ra.ldpc_cap : false;
+ desc_info->port = desc_info->hiq ? rtwvif_link->port : 0;
+ desc_info->er_cap = rtwsta_link ? rtwsta_link->er_cap : false;
+ desc_info->stbc = rtwsta_link ? rtwsta_link->ra.stbc_cap : false;
+ desc_info->ldpc = rtwsta_link ? rtwsta_link->ra.ldpc_cap : false;
/* enable wd_info for AMPDU */
desc_info->en_wd_info = true;
@@ -1027,13 +1059,34 @@ int rtw89_h2c_tx(struct rtw89_dev *rtwdev,
int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel)
{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_core_tx_request tx_req = {0};
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_sta_link *rtwsta_link = NULL;
+ struct rtw89_vif_link *rtwvif_link;
int ret;
+ /* By default, driver writes tx via the link on HW-0. And then,
+ * according to links' status, HW can change tx to another link.
+ */
+
+ if (rtwsta) {
+ rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
+ if (unlikely(!rtwsta_link)) {
+ rtw89_err(rtwdev, "tx: find no sta link on HW-0\n");
+ return -ENOLINK;
+ }
+ }
+
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "tx: find no vif link on HW-0\n");
+ return -ENOLINK;
+ }
+
tx_req.skb = skb;
- tx_req.sta = sta;
- tx_req.vif = vif;
+ tx_req.rtwvif_link = rtwvif_link;
+ tx_req.rtwsta_link = rtwsta_link;
rtw89_traffic_stats_accu(rtwdev, &rtwdev->stats, skb, true);
rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, true);
@@ -1514,16 +1567,24 @@ static u8 rtw89_get_data_rate_nss(struct rtw89_dev *rtwdev, u16 data_rate)
static void rtw89_core_rx_process_phy_ppdu_iter(void *data,
struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_rx_phy_ppdu *phy_ppdu = (struct rtw89_rx_phy_ppdu *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_dev *rtwdev = rtwsta->rtwdev;
struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_sta_link *rtwsta_link;
u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num;
u8 ant_pos = U8_MAX;
u8 evm_pos = 0;
int i;
- if (rtwsta->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self)
+ /* FIXME: For single link, taking link on HW-0 here is okay. But, when
+ * enabling multiple active links, we should determine the right link.
+ */
+ rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
+ if (unlikely(!rtwsta_link))
+ return;
+
+ if (rtwsta_link->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self)
return;
if (hal->ant_diversity && hal->antenna_rx) {
@@ -1531,22 +1592,24 @@ static void rtw89_core_rx_process_phy_ppdu_iter(void *data,
evm_pos = ant_pos;
}
- ewma_rssi_add(&rtwsta->avg_rssi, phy_ppdu->rssi_avg);
+ ewma_rssi_add(&rtwsta_link->avg_rssi, phy_ppdu->rssi_avg);
if (ant_pos < ant_num) {
- ewma_rssi_add(&rtwsta->rssi[ant_pos], phy_ppdu->rssi[0]);
+ ewma_rssi_add(&rtwsta_link->rssi[ant_pos], phy_ppdu->rssi[0]);
} else {
for (i = 0; i < rtwdev->chip->rf_path_num; i++)
- ewma_rssi_add(&rtwsta->rssi[i], phy_ppdu->rssi[i]);
+ ewma_rssi_add(&rtwsta_link->rssi[i], phy_ppdu->rssi[i]);
}
if (phy_ppdu->ofdm.has && (phy_ppdu->has_data || phy_ppdu->has_bcn)) {
- ewma_snr_add(&rtwsta->avg_snr, phy_ppdu->ofdm.avg_snr);
+ ewma_snr_add(&rtwsta_link->avg_snr, phy_ppdu->ofdm.avg_snr);
if (rtw89_get_data_rate_nss(rtwdev, phy_ppdu->rate) == 1) {
- ewma_evm_add(&rtwsta->evm_1ss, phy_ppdu->ofdm.evm_min);
+ ewma_evm_add(&rtwsta_link->evm_1ss, phy_ppdu->ofdm.evm_min);
} else {
- ewma_evm_add(&rtwsta->evm_min[evm_pos], phy_ppdu->ofdm.evm_min);
- ewma_evm_add(&rtwsta->evm_max[evm_pos], phy_ppdu->ofdm.evm_max);
+ ewma_evm_add(&rtwsta_link->evm_min[evm_pos],
+ phy_ppdu->ofdm.evm_min);
+ ewma_evm_add(&rtwsta_link->evm_max[evm_pos],
+ phy_ppdu->ofdm.evm_max);
}
}
}
@@ -1876,17 +1939,19 @@ struct rtw89_vif_rx_stats_iter_data {
};
static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf,
struct sk_buff *skb)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct ieee80211_trigger *tf = (struct ieee80211_trigger *)skb->data;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
u8 *pos, *end, type, tf_bw;
u16 aid, tf_rua;
- if (!ether_addr_equal(vif->bss_conf.bssid, tf->ta) ||
- rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION ||
- rtwvif->net_type == RTW89_NET_TYPE_NO_LINK)
+ if (!ether_addr_equal(bss_conf->bssid, tf->ta) ||
+ rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION ||
+ rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK)
return;
type = le64_get_bits(tf->common_info, IEEE80211_TRIGGER_TYPE_MASK);
@@ -1915,7 +1980,7 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev,
rtwdev->stats.rx_tf_acc++;
if (tf_bw == IEEE80211_TRIGGER_ULBW_160_80P80MHZ &&
rua <= NL80211_RATE_INFO_HE_RU_ALLOC_106)
- rtwvif->pwr_diff_en = true;
+ rtwvif_link->pwr_diff_en = true;
break;
}
@@ -1986,7 +2051,7 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev,
ieee80211_queue_work(rtwdev->hw, &rtwdev->cancel_6ghz_probe_work);
}
-static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif *rtwvif,
+static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif_link *rtwvif_link,
struct ieee80211_hdr *hdr, size_t len)
{
struct ieee80211_mgmt *mgmt = (typeof(mgmt))hdr;
@@ -1994,20 +2059,22 @@ static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif *rtwvif,
if (len < offsetof(typeof(*mgmt), u.beacon.variable))
return;
- WRITE_ONCE(rtwvif->sync_bcn_tsf, le64_to_cpu(mgmt->u.beacon.timestamp));
+ WRITE_ONCE(rtwvif_link->sync_bcn_tsf, le64_to_cpu(mgmt->u.beacon.timestamp));
}
static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif_rx_stats_iter_data *iter_data = data;
struct rtw89_dev *rtwdev = iter_data->rtwdev;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat;
struct rtw89_rx_desc_info *desc_info = iter_data->desc_info;
struct sk_buff *skb = iter_data->skb;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct rtw89_rx_phy_ppdu *phy_ppdu = iter_data->phy_ppdu;
+ struct ieee80211_bss_conf *bss_conf;
+ struct rtw89_vif_link *rtwvif_link;
const u8 *bssid = iter_data->bssid;
if (rtwdev->scanning &&
@@ -2015,33 +2082,49 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
ieee80211_is_probe_resp(hdr->frame_control)))
rtw89_core_cancel_6ghz_probe_tx(rtwdev, skb);
- if (!vif->bss_conf.bssid)
- return;
+ rcu_read_lock();
+
+ /* FIXME: For single link, taking link on HW-0 here is okay. But, when
+ * enabling multiple active links, we should determine the right link.
+ */
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (unlikely(!rtwvif_link))
+ goto out;
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+ if (!bss_conf->bssid)
+ goto out;
if (ieee80211_is_trigger(hdr->frame_control)) {
- rtw89_stats_trigger_frame(rtwdev, vif, skb);
- return;
+ rtw89_stats_trigger_frame(rtwdev, rtwvif_link, bss_conf, skb);
+ goto out;
}
- if (!ether_addr_equal(vif->bss_conf.bssid, bssid))
- return;
+ if (!ether_addr_equal(bss_conf->bssid, bssid))
+ goto out;
if (ieee80211_is_beacon(hdr->frame_control)) {
if (vif->type == NL80211_IFTYPE_STATION &&
!test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) {
- rtw89_vif_sync_bcn_tsf(rtwvif, hdr, skb->len);
+ rtw89_vif_sync_bcn_tsf(rtwvif_link, hdr, skb->len);
rtw89_fw_h2c_rssi_offload(rtwdev, phy_ppdu);
}
pkt_stat->beacon_nr++;
+
+ if (phy_ppdu)
+ ewma_rssi_add(&rtwdev->phystat.bcn_rssi, phy_ppdu->rssi_avg);
}
- if (!ether_addr_equal(vif->addr, hdr->addr1))
- return;
+ if (!ether_addr_equal(bss_conf->addr, hdr->addr1))
+ goto out;
if (desc_info->data_rate < RTW89_HW_RATE_NR)
pkt_stat->rx_rate_cnt[desc_info->data_rate]++;
rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, false);
+
+out:
+ rcu_read_unlock();
}
static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev,
@@ -2432,15 +2515,23 @@ void rtw89_core_stats_sta_rx_status_iter(void *data, struct ieee80211_sta *sta)
struct rtw89_core_iter_rx_status *iter_data =
(struct rtw89_core_iter_rx_status *)data;
struct ieee80211_rx_status *rx_status = iter_data->rx_status;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_rx_desc_info *desc_info = iter_data->desc_info;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_sta_link *rtwsta_link;
u8 mac_id = iter_data->mac_id;
- if (mac_id != rtwsta->mac_id)
+ /* FIXME: For single link, taking link on HW-0 here is okay. But, when
+ * enabling multiple active links, we should determine the right link.
+ */
+ rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
+ if (unlikely(!rtwsta_link))
+ return;
+
+ if (mac_id != rtwsta_link->mac_id)
return;
- rtwsta->rx_status = *rx_status;
- rtwsta->rx_hw_rate = desc_info->data_rate;
+ rtwsta_link->rx_status = *rx_status;
+ rtwsta_link->rx_hw_rate = desc_info->data_rate;
}
static void rtw89_core_stats_sta_rx_status(struct rtw89_dev *rtwdev,
@@ -2546,6 +2637,10 @@ static enum rtw89_ps_mode rtw89_update_ps_mode(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ /* FIXME: Fix __rtw89_enter_ps_mode() to consider MLO cases. */
+ if (rtwdev->support_mlo)
+ return RTW89_PS_MODE_NONE;
+
if (rtw89_disable_ps_mode || !chip->ps_mode_supported ||
RTW89_CHK_FW_FEATURE(NO_DEEP_PS, &rtwdev->fw))
return RTW89_PS_MODE_NONE;
@@ -2658,7 +2753,7 @@ static void rtw89_core_ba_work(struct work_struct *work)
list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) {
struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq);
struct ieee80211_sta *sta = txq->sta;
- struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
u8 tid = txq->tid;
if (!sta) {
@@ -2686,8 +2781,8 @@ skip_ba_work:
spin_unlock_bh(&rtwdev->ba_lock);
}
-static void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta)
+void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta)
{
struct rtw89_txq *rtwtxq, *tmp;
@@ -2701,8 +2796,8 @@ static void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev,
spin_unlock_bh(&rtwdev->ba_lock);
}
-static void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta)
+void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta)
{
struct rtw89_txq *rtwtxq, *tmp;
@@ -2718,10 +2813,10 @@ static void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev,
spin_unlock_bh(&rtwdev->ba_lock);
}
-static void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta)
+void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct sk_buff *skb, *tmp;
skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) {
@@ -2762,7 +2857,7 @@ static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev,
struct ieee80211_hw *hw = rtwdev->hw;
struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq);
struct ieee80211_sta *sta = txq->sta;
- struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
if (test_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags))
return;
@@ -2838,10 +2933,19 @@ static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev,
bool *sched_txq, bool *reinvoke)
{
struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv;
- struct ieee80211_sta *sta = txq->sta;
- struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(txq->sta);
+ struct rtw89_sta_link *rtwsta_link;
- if (!sta || rtwsta->max_agg_wait <= 0)
+ if (!rtwsta)
+ return false;
+
+ rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
+ if (unlikely(!rtwsta_link)) {
+ rtw89_err(rtwdev, "agg wait: find no link on HW-0\n");
+ return false;
+ }
+
+ if (rtwsta_link->max_agg_wait <= 0)
return false;
if (rtwdev->stats.tx_tfc_lv <= RTW89_TFC_MID)
@@ -2855,7 +2959,7 @@ static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev,
return false;
}
- if (*frame_cnt == 1 && rtwtxq->wait_cnt < rtwsta->max_agg_wait) {
+ if (*frame_cnt == 1 && rtwtxq->wait_cnt < rtwsta_link->max_agg_wait) {
*reinvoke = true;
rtwtxq->wait_cnt++;
return true;
@@ -2879,7 +2983,7 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv
ieee80211_txq_schedule_start(hw, ac);
while ((txq = ieee80211_next_txq(hw, ac))) {
rtwtxq = (struct rtw89_txq *)txq->drv_priv;
- rtwvif = (struct rtw89_vif *)txq->vif->drv_priv;
+ rtwvif = vif_to_rtwvif(txq->vif);
if (rtwvif->offchan) {
ieee80211_return_txq(hw, txq, true);
@@ -2955,16 +3059,23 @@ static void rtw89_forbid_ba_work(struct work_struct *w)
static void rtw89_core_sta_pending_tx_iter(void *data,
struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_vif *rtwvif_target = data, *rtwvif = rtwsta->rtwvif;
- struct rtw89_dev *rtwdev = rtwvif->rtwdev;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct rtw89_vif_link *target = data;
+ struct rtw89_vif_link *rtwvif_link;
struct sk_buff *skb, *tmp;
+ unsigned int link_id;
int qsel, ret;
- if (rtwvif->chanctx_idx != rtwvif_target->chanctx_idx)
- return;
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ if (rtwvif_link->chanctx_idx == target->chanctx_idx)
+ goto bottom;
+
+ return;
+bottom:
if (skb_queue_len(&rtwsta->roc_queue) == 0)
return;
@@ -2982,17 +3093,17 @@ static void rtw89_core_sta_pending_tx_iter(void *data,
}
static void rtw89_core_handle_sta_pending_tx(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_core_sta_pending_tx_iter,
- rtwvif);
+ rtwvif_link);
}
static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool qos, bool ps)
+ struct rtw89_vif_link *rtwvif_link, bool qos, bool ps)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct ieee80211_sta *sta;
struct ieee80211_hdr *hdr;
struct sk_buff *skb;
@@ -3002,7 +3113,7 @@ static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev,
return 0;
rcu_read_lock();
- sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
+ sta = ieee80211_find_sta(vif, vif->cfg.ap_addr);
if (!sta) {
ret = -EINVAL;
goto out;
@@ -3040,31 +3151,48 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct ieee80211_hw *hw = rtwdev->hw;
struct rtw89_roc *roc = &rtwvif->roc;
+ struct rtw89_vif_link *rtwvif_link;
struct cfg80211_chan_def roc_chan;
- struct rtw89_vif *tmp;
+ struct rtw89_vif *tmp_vif;
+ u32 reg;
int ret;
lockdep_assert_held(&rtwdev->mutex);
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
+
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "roc start: find no link on HW-0\n");
+ return;
+ }
+
rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_ROC);
- ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, true, true);
+ ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, true);
if (ret)
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"roc send null-1 failed: %d\n", ret);
- rtw89_for_each_rtwvif(rtwdev, tmp)
- if (tmp->chanctx_idx == rtwvif->chanctx_idx)
- tmp->offchan = true;
+ rtw89_for_each_rtwvif(rtwdev, tmp_vif) {
+ struct rtw89_vif_link *tmp_link;
+ unsigned int link_id;
+
+ rtw89_vif_for_each_link(tmp_vif, tmp_link, link_id) {
+ if (tmp_link->chanctx_idx == rtwvif_link->chanctx_idx) {
+ tmp_vif->offchan = true;
+ break;
+ }
+ }
+ }
cfg80211_chandef_create(&roc_chan, &roc->chan, NL80211_CHAN_NO_HT);
- rtw89_config_roc_chandef(rtwdev, rtwvif->chanctx_idx, &roc_chan);
+ rtw89_config_roc_chandef(rtwdev, rtwvif_link->chanctx_idx, &roc_chan);
rtw89_set_channel(rtwdev);
- rtw89_write32_clr(rtwdev,
- rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
- B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH);
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
+ rtw89_write32_clr(rtwdev, reg, B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH);
ieee80211_ready_on_channel(hw);
cancel_delayed_work(&rtwvif->roc.roc_work);
@@ -3077,7 +3205,9 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct ieee80211_hw *hw = rtwdev->hw;
struct rtw89_roc *roc = &rtwvif->roc;
- struct rtw89_vif *tmp;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_vif *tmp_vif;
+ u32 reg;
int ret;
lockdep_assert_held(&rtwdev->mutex);
@@ -3087,24 +3217,27 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
- rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
- B_AX_RX_FLTR_CFG_MASK,
- rtwdev->hal.rx_fltr);
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "roc end: find no link on HW-0\n");
+ return;
+ }
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr);
roc->state = RTW89_ROC_IDLE;
- rtw89_config_roc_chandef(rtwdev, rtwvif->chanctx_idx, NULL);
+ rtw89_config_roc_chandef(rtwdev, rtwvif_link->chanctx_idx, NULL);
rtw89_chanctx_proceed(rtwdev);
- ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, true, false);
+ ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, false);
if (ret)
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"roc send null-0 failed: %d\n", ret);
- rtw89_for_each_rtwvif(rtwdev, tmp)
- if (tmp->chanctx_idx == rtwvif->chanctx_idx)
- tmp->offchan = false;
+ rtw89_for_each_rtwvif(rtwdev, tmp_vif)
+ tmp_vif->offchan = false;
- rtw89_core_handle_sta_pending_tx(rtwdev, rtwvif);
+ rtw89_core_handle_sta_pending_tx(rtwdev, rtwvif_link);
queue_work(rtwdev->txq_wq, &rtwdev->txq_work);
if (hw->conf.flags & IEEE80211_CONF_IDLE)
@@ -3188,39 +3321,52 @@ static bool rtw89_traffic_stats_calc(struct rtw89_dev *rtwdev,
static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
bool tfc_changed;
tfc_changed = rtw89_traffic_stats_calc(rtwdev, &rtwdev->stats);
+
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats);
- rtw89_fw_h2c_tp_offload(rtwdev, rtwvif);
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_fw_h2c_tp_offload(rtwdev, rtwvif_link);
}
return tfc_changed;
}
-static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- if ((rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION &&
- rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) ||
- rtwvif->tdls_peer)
+ if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION &&
+ rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
return;
- if (rtwvif->offchan)
- return;
-
- if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE &&
- rtwvif->stats.rx_tfc_lv == RTW89_TFC_IDLE)
- rtw89_enter_lps(rtwdev, rtwvif, true);
+ rtw89_enter_lps(rtwdev, rtwvif_link, true);
}
static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ if (rtwvif->tdls_peer)
+ continue;
+ if (rtwvif->offchan)
+ continue;
+
+ if (rtwvif->stats.tx_tfc_lv != RTW89_TFC_IDLE ||
+ rtwvif->stats.rx_tfc_lv != RTW89_TFC_IDLE)
+ continue;
- rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_vif_enter_lps(rtwdev, rtwvif);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_vif_enter_lps(rtwdev, rtwvif_link);
+ }
}
static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev)
@@ -3234,14 +3380,16 @@ static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev)
rtw89_chip_rfk_track(rtwdev);
}
-void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf)
{
enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev);
if (mode == RTW89_ENTITY_MODE_MCC)
rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_P2P_PS_CHANGE);
else
- rtw89_process_p2p_ps(rtwdev, vif);
+ rtw89_process_p2p_ps(rtwdev, rtwvif_link, bss_conf);
}
void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev,
@@ -3326,7 +3474,8 @@ void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits)
}
int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
+ struct rtw89_sta_link *rtwsta_link, u8 tid,
+ u8 *cam_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
@@ -3363,7 +3512,7 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
}
entry->tid = tid;
- list_add_tail(&entry->list, &rtwsta->ba_cam_list);
+ list_add_tail(&entry->list, &rtwsta_link->ba_cam_list);
*cam_idx = idx;
@@ -3371,7 +3520,8 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
}
int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
+ struct rtw89_sta_link *rtwsta_link, u8 tid,
+ u8 *cam_idx)
{
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
struct rtw89_ba_cam_entry *entry = NULL, *tmp;
@@ -3379,7 +3529,7 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
lockdep_assert_held(&rtwdev->mutex);
- list_for_each_entry_safe(entry, tmp, &rtwsta->ba_cam_list, list) {
+ list_for_each_entry_safe(entry, tmp, &rtwsta_link->ba_cam_list, list) {
if (entry->tid != tid)
continue;
@@ -3396,24 +3546,25 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
#define RTW89_TYPE_MAPPING(_type) \
case NL80211_IFTYPE_ ## _type: \
- rtwvif->wifi_role = RTW89_WIFI_ROLE_ ## _type; \
+ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_ ## _type; \
break
-void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc)
+void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct ieee80211_bss_conf *bss_conf;
switch (vif->type) {
case NL80211_IFTYPE_STATION:
if (vif->p2p)
- rtwvif->wifi_role = RTW89_WIFI_ROLE_P2P_CLIENT;
+ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_P2P_CLIENT;
else
- rtwvif->wifi_role = RTW89_WIFI_ROLE_STATION;
+ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_STATION;
break;
case NL80211_IFTYPE_AP:
if (vif->p2p)
- rtwvif->wifi_role = RTW89_WIFI_ROLE_P2P_GO;
+ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_P2P_GO;
else
- rtwvif->wifi_role = RTW89_WIFI_ROLE_AP;
+ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_AP;
break;
RTW89_TYPE_MAPPING(ADHOC);
RTW89_TYPE_MAPPING(MONITOR);
@@ -3426,23 +3577,27 @@ void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc)
switch (vif->type) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_MESH_POINT:
- rtwvif->net_type = RTW89_NET_TYPE_AP_MODE;
- rtwvif->self_role = RTW89_SELF_ROLE_AP;
+ rtwvif_link->net_type = RTW89_NET_TYPE_AP_MODE;
+ rtwvif_link->self_role = RTW89_SELF_ROLE_AP;
break;
case NL80211_IFTYPE_ADHOC:
- rtwvif->net_type = RTW89_NET_TYPE_AD_HOC;
- rtwvif->self_role = RTW89_SELF_ROLE_CLIENT;
+ rtwvif_link->net_type = RTW89_NET_TYPE_AD_HOC;
+ rtwvif_link->self_role = RTW89_SELF_ROLE_CLIENT;
break;
case NL80211_IFTYPE_STATION:
if (assoc) {
- rtwvif->net_type = RTW89_NET_TYPE_INFRA;
- rtwvif->trigger = vif->bss_conf.he_support;
+ rtwvif_link->net_type = RTW89_NET_TYPE_INFRA;
+
+ rcu_read_lock();
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+ rtwvif_link->trigger = bss_conf->he_support;
+ rcu_read_unlock();
} else {
- rtwvif->net_type = RTW89_NET_TYPE_NO_LINK;
- rtwvif->trigger = false;
+ rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK;
+ rtwvif_link->trigger = false;
}
- rtwvif->self_role = RTW89_SELF_ROLE_CLIENT;
- rtwvif->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL;
+ rtwvif_link->self_role = RTW89_SELF_ROLE_CLIENT;
+ rtwvif_link->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL;
break;
case NL80211_IFTYPE_MONITOR:
break;
@@ -3452,137 +3607,110 @@ void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc)
}
}
-int rtw89_core_sta_add(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
struct rtw89_hal *hal = &rtwdev->hal;
u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num;
int i;
int ret;
- rtwsta->rtwdev = rtwdev;
- rtwsta->rtwvif = rtwvif;
- rtwsta->prev_rssi = 0;
- INIT_LIST_HEAD(&rtwsta->ba_cam_list);
- skb_queue_head_init(&rtwsta->roc_queue);
-
- for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
- rtw89_core_txq_init(rtwdev, sta->txq[i]);
-
- ewma_rssi_init(&rtwsta->avg_rssi);
- ewma_snr_init(&rtwsta->avg_snr);
- ewma_evm_init(&rtwsta->evm_1ss);
+ rtwsta_link->prev_rssi = 0;
+ INIT_LIST_HEAD(&rtwsta_link->ba_cam_list);
+ ewma_rssi_init(&rtwsta_link->avg_rssi);
+ ewma_snr_init(&rtwsta_link->avg_snr);
+ ewma_evm_init(&rtwsta_link->evm_1ss);
for (i = 0; i < ant_num; i++) {
- ewma_rssi_init(&rtwsta->rssi[i]);
- ewma_evm_init(&rtwsta->evm_min[i]);
- ewma_evm_init(&rtwsta->evm_max[i]);
+ ewma_rssi_init(&rtwsta_link->rssi[i]);
+ ewma_evm_init(&rtwsta_link->evm_min[i]);
+ ewma_evm_init(&rtwsta_link->evm_max[i]);
}
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
- /* for station mode, assign the mac_id from itself */
- rtwsta->mac_id = rtwvif->mac_id;
-
/* must do rtw89_reg_6ghz_recalc() before rfk channel */
- ret = rtw89_reg_6ghz_recalc(rtwdev, rtwvif, true);
+ ret = rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true);
if (ret)
return ret;
- rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link,
BTC_ROLE_MSTS_STA_CONN_START);
- rtw89_chip_rfk_channel(rtwdev, rtwvif);
+ rtw89_chip_rfk_channel(rtwdev, rtwvif_link);
} else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
- rtwsta->mac_id = rtw89_acquire_mac_id(rtwdev);
- if (rtwsta->mac_id == RTW89_MAX_MAC_ID_NUM)
- return -ENOSPC;
-
- ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta->mac_id, false);
+ ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta_link->mac_id, false);
if (ret) {
- rtw89_release_mac_id(rtwdev, rtwsta->mac_id);
rtw89_warn(rtwdev, "failed to send h2c macid pause\n");
return ret;
}
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta,
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link,
RTW89_ROLE_CREATE);
if (ret) {
- rtw89_release_mac_id(rtwdev, rtwsta->mac_id);
rtw89_warn(rtwdev, "failed to send h2c role info\n");
return ret;
}
- ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif, rtwsta);
+ ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
return ret;
- ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif, rtwsta);
+ ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
return ret;
-
- rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
}
return 0;
}
-int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
if (vif->type == NL80211_IFTYPE_STATION)
- rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, false);
-
- rtwdev->total_sta_assoc--;
- if (sta->tdls)
- rtwvif->tdls_peer--;
- rtwsta->disassoc = true;
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, false);
return 0;
}
-int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
int ret;
- rtw89_mac_bf_monitor_calc(rtwdev, sta, true);
- rtw89_mac_bf_disassoc(rtwdev, vif, sta);
- rtw89_core_free_sta_pending_ba(rtwdev, sta);
- rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta);
- rtw89_core_free_sta_pending_roc_tx(rtwdev, sta);
+ rtw89_mac_bf_monitor_calc(rtwdev, rtwsta_link, true);
+ rtw89_mac_bf_disassoc(rtwdev, rtwvif_link, rtwsta_link);
if (vif->type == NL80211_IFTYPE_AP || sta->tdls)
- rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
+ rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam);
if (sta->tdls)
- rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam);
+ rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam);
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
- rtw89_vif_type_mapping(vif, false);
- rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, true);
+ rtw89_vif_type_mapping(rtwvif_link, false);
+ rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, true);
}
- ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
+ ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cmac table\n");
return ret;
}
- ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, true);
+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, true);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c join info\n");
return ret;
}
/* update cam aid mac_id net_type */
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
@@ -3591,106 +3719,114 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
return ret;
}
-int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta);
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
+ struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link,
+ rtwsta_link);
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
+ rtwvif_link->chanctx_idx);
int ret;
if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
if (sta->tdls) {
- ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, sta->addr);
+ struct ieee80211_link_sta *link_sta;
+
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif_link, bssid_cam,
+ link_sta->addr);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c init bssid cam for TDLS\n");
+ rcu_read_unlock();
return ret;
}
+
+ rcu_read_unlock();
}
- ret = rtw89_cam_init_addr_cam(rtwdev, &rtwsta->addr_cam, bssid_cam);
+ ret = rtw89_cam_init_addr_cam(rtwdev, &rtwsta_link->addr_cam, bssid_cam);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c init addr cam\n");
return ret;
}
}
- ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
+ ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cmac table\n");
return ret;
}
- ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, false);
+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, false);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c join info\n");
return ret;
}
/* update cam aid mac_id net_type */
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
}
- rtwdev->total_sta_assoc++;
- if (sta->tdls)
- rtwvif->tdls_peer++;
- rtw89_phy_ra_assoc(rtwdev, sta);
- rtw89_mac_bf_assoc(rtwdev, vif, sta);
- rtw89_mac_bf_monitor_calc(rtwdev, sta, false);
+ rtw89_phy_ra_assoc(rtwdev, rtwsta_link);
+ rtw89_mac_bf_assoc(rtwdev, rtwvif_link, rtwsta_link);
+ rtw89_mac_bf_monitor_calc(rtwdev, rtwsta_link, false);
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ struct ieee80211_bss_conf *bss_conf;
+
+ rcu_read_lock();
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
if (bss_conf->he_support &&
!(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE))
- rtwsta->er_cap = true;
+ rtwsta_link->er_cap = true;
- rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
+ rcu_read_unlock();
+
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link,
BTC_ROLE_MSTS_STA_CONN_END);
- rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template, chan);
- rtw89_phy_ul_tb_assoc(rtwdev, rtwvif);
+ rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta_link->htc_template, chan);
+ rtw89_phy_ul_tb_assoc(rtwdev, rtwvif_link);
- ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id);
+ ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c general packet\n");
return ret;
}
- rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
}
return ret;
}
-int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
int ret;
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
- rtw89_reg_6ghz_recalc(rtwdev, rtwvif, false);
- rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
+ rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, false);
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link,
BTC_ROLE_MSTS_STA_DIS_CONN);
} else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
- rtw89_release_mac_id(rtwdev, rtwsta->mac_id);
-
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta,
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link,
RTW89_ROLE_REMOVE);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c role info\n");
return ret;
}
-
- rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
}
return 0;
@@ -4152,15 +4288,16 @@ static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev)
void rtw89_core_update_beacon_work(struct work_struct *work)
{
struct rtw89_dev *rtwdev;
- struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif,
- update_beacon_work);
+ struct rtw89_vif_link *rtwvif_link = container_of(work, struct rtw89_vif_link,
+ update_beacon_work);
- if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE)
+ if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE)
return;
- rtwdev = rtwvif->rtwdev;
+ rtwdev = rtwvif_link->rtwvif->rtwdev;
+
mutex_lock(&rtwdev->mutex);
- rtw89_chip_h2c_update_beacon(rtwdev, rtwvif);
+ rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
mutex_unlock(&rtwdev->mutex);
}
@@ -4266,8 +4403,8 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
rtw89_phy_dm_init(rtwdev);
- rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
- rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
+ rtw89_mac_cfg_ppdu_status_bands(rtwdev, true);
+ rtw89_mac_update_rts_threshold(rtwdev);
rtw89_tas_reset(rtwdev);
@@ -4355,6 +4492,168 @@ void rtw89_release_mac_id(struct rtw89_dev *rtwdev, u8 mac_id)
clear_bit(mac_id, rtwdev->mac_id_map);
}
+void rtw89_init_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ u8 mac_id, u8 port)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u8 support_link_num = chip->support_link_num;
+ u8 support_mld_num = 0;
+ unsigned int link_id;
+ u8 index;
+
+ bitmap_zero(rtwvif->links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++)
+ rtwvif->links[link_id] = NULL;
+
+ rtwvif->rtwdev = rtwdev;
+
+ if (rtwdev->support_mlo) {
+ rtwvif->links_inst_valid_num = support_link_num;
+ support_mld_num = chip->support_macid_num / support_link_num;
+ } else {
+ rtwvif->links_inst_valid_num = 1;
+ }
+
+ for (index = 0; index < rtwvif->links_inst_valid_num; index++) {
+ struct rtw89_vif_link *inst = &rtwvif->links_inst[index];
+
+ inst->rtwvif = rtwvif;
+ inst->mac_id = mac_id + index * support_mld_num;
+ inst->mac_idx = RTW89_MAC_0 + index;
+ inst->phy_idx = RTW89_PHY_0 + index;
+
+ /* multi-link use the same port id on different HW bands */
+ inst->port = port;
+ }
+}
+
+void rtw89_init_sta(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ struct rtw89_sta *rtwsta, u8 mac_id)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u8 support_link_num = chip->support_link_num;
+ u8 support_mld_num = 0;
+ unsigned int link_id;
+ u8 index;
+
+ bitmap_zero(rtwsta->links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++)
+ rtwsta->links[link_id] = NULL;
+
+ rtwsta->rtwdev = rtwdev;
+ rtwsta->rtwvif = rtwvif;
+
+ if (rtwdev->support_mlo) {
+ rtwsta->links_inst_valid_num = support_link_num;
+ support_mld_num = chip->support_macid_num / support_link_num;
+ } else {
+ rtwsta->links_inst_valid_num = 1;
+ }
+
+ for (index = 0; index < rtwsta->links_inst_valid_num; index++) {
+ struct rtw89_sta_link *inst = &rtwsta->links_inst[index];
+
+ inst->rtwvif_link = &rtwvif->links_inst[index];
+
+ inst->rtwsta = rtwsta;
+ inst->mac_id = mac_id + index * support_mld_num;
+ }
+}
+
+struct rtw89_vif_link *rtw89_vif_set_link(struct rtw89_vif *rtwvif,
+ unsigned int link_id)
+{
+ struct rtw89_vif_link *rtwvif_link = rtwvif->links[link_id];
+ u8 index;
+ int ret;
+
+ if (rtwvif_link)
+ return rtwvif_link;
+
+ index = find_first_zero_bit(rtwvif->links_inst_map,
+ rtwvif->links_inst_valid_num);
+ if (index == rtwvif->links_inst_valid_num) {
+ ret = -EBUSY;
+ goto err;
+ }
+
+ rtwvif_link = &rtwvif->links_inst[index];
+ rtwvif_link->link_id = link_id;
+
+ set_bit(index, rtwvif->links_inst_map);
+ rtwvif->links[link_id] = rtwvif_link;
+ return rtwvif_link;
+
+err:
+ rtw89_err(rtwvif->rtwdev, "vif (link_id %u) failed to set link: %d\n",
+ link_id, ret);
+ return NULL;
+}
+
+void rtw89_vif_unset_link(struct rtw89_vif *rtwvif, unsigned int link_id)
+{
+ struct rtw89_vif_link **container = &rtwvif->links[link_id];
+ struct rtw89_vif_link *link = *container;
+ u8 index;
+
+ if (!link)
+ return;
+
+ index = rtw89_vif_link_inst_get_index(link);
+ clear_bit(index, rtwvif->links_inst_map);
+ *container = NULL;
+}
+
+struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta,
+ unsigned int link_id)
+{
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+ struct rtw89_vif_link *rtwvif_link = rtwvif->links[link_id];
+ struct rtw89_sta_link *rtwsta_link = rtwsta->links[link_id];
+ u8 index;
+ int ret;
+
+ if (rtwsta_link)
+ return rtwsta_link;
+
+ if (!rtwvif_link) {
+ ret = -ENOLINK;
+ goto err;
+ }
+
+ index = rtw89_vif_link_inst_get_index(rtwvif_link);
+ if (test_bit(index, rtwsta->links_inst_map)) {
+ ret = -EBUSY;
+ goto err;
+ }
+
+ rtwsta_link = &rtwsta->links_inst[index];
+ rtwsta_link->link_id = link_id;
+
+ set_bit(index, rtwsta->links_inst_map);
+ rtwsta->links[link_id] = rtwsta_link;
+ return rtwsta_link;
+
+err:
+ rtw89_err(rtwsta->rtwdev, "sta (link_id %u) failed to set link: %d\n",
+ link_id, ret);
+ return NULL;
+}
+
+void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id)
+{
+ struct rtw89_sta_link **container = &rtwsta->links[link_id];
+ struct rtw89_sta_link *link = *container;
+ u8 index;
+
+ if (!link)
+ return;
+
+ index = rtw89_sta_link_inst_get_index(link);
+ clear_bit(index, rtwsta->links_inst_map);
+ *container = NULL;
+}
+
int rtw89_core_init(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
@@ -4444,39 +4743,45 @@ void rtw89_core_deinit(struct rtw89_dev *rtwdev)
}
EXPORT_SYMBOL(rtw89_core_deinit);
-void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
const u8 *mac_addr, bool hw_scan)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
+ rtwvif_link->chanctx_idx);
rtwdev->scanning = true;
rtw89_leave_lps(rtwdev);
if (hw_scan)
rtw89_leave_ips_by_hwflags(rtwdev);
- ether_addr_copy(rtwvif->mac_addr, mac_addr);
- rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, chan->band_type);
- rtw89_chip_rfk_scan(rtwdev, rtwvif, true);
+ ether_addr_copy(rtwvif_link->mac_addr, mac_addr);
+ rtw89_btc_ntfy_scan_start(rtwdev, rtwvif_link->phy_idx, chan->band_type);
+ rtw89_chip_rfk_scan(rtwdev, rtwvif_link, true);
rtw89_hci_recalc_int_mit(rtwdev);
rtw89_phy_config_edcca(rtwdev, true);
- rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, mac_addr);
+ rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr);
}
void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif, bool hw_scan)
+ struct rtw89_vif_link *rtwvif_link, bool hw_scan)
{
- struct rtw89_vif *rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
+ struct ieee80211_bss_conf *bss_conf;
- if (!rtwvif)
+ if (!rtwvif_link)
return;
- ether_addr_copy(rtwvif->mac_addr, vif->addr);
- rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr);
+
+ rcu_read_unlock();
+
+ rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
- rtw89_chip_rfk_scan(rtwdev, rtwvif, false);
- rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0);
+ rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false);
+ rtw89_btc_ntfy_scan_finish(rtwdev, rtwvif_link->phy_idx);
rtw89_phy_config_edcca(rtwdev, false);
rtwdev->scanning = false;
@@ -4688,17 +4993,39 @@ int rtw89_chip_info_setup(struct rtw89_dev *rtwdev)
}
EXPORT_SYMBOL(rtw89_chip_info_setup);
+void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct ieee80211_bss_conf *bss_conf;
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+ if (!bss_conf->he_support || !vif->cfg.assoc) {
+ rcu_read_unlock();
+ return;
+ }
+
+ rcu_read_unlock();
+
+ if (chip->ops->set_txpwr_ul_tb_offset)
+ chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif_link->mac_idx);
+}
+
static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ u8 n = rtwdev->support_mlo ? chip->support_link_num : 1;
struct ieee80211_hw *hw = rtwdev->hw;
struct rtw89_efuse *efuse = &rtwdev->efuse;
struct rtw89_hal *hal = &rtwdev->hal;
int ret;
int tx_headroom = IEEE80211_HT_CTL_LEN;
- hw->vif_data_size = sizeof(struct rtw89_vif);
- hw->sta_data_size = sizeof(struct rtw89_sta);
+ hw->vif_data_size = struct_size_t(struct rtw89_vif, links_inst, n);
+ hw->sta_data_size = struct_size_t(struct rtw89_sta, links_inst, n);
hw->txq_data_size = sizeof(struct rtw89_txq);
hw->chanctx_data_size = sizeof(struct rtw89_chanctx_cfg);
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 4ed9034fdb46..38df161bfd35 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -829,6 +829,8 @@ enum rtw89_phy_idx {
RTW89_PHY_MAX
};
+#define __RTW89_MLD_MAX_LINK_NUM 2
+
enum rtw89_chanctx_idx {
RTW89_CHANCTX_0 = 0,
RTW89_CHANCTX_1 = 1,
@@ -1166,8 +1168,8 @@ struct rtw89_core_tx_request {
enum rtw89_core_tx_type tx_type;
struct sk_buff *skb;
- struct ieee80211_vif *vif;
- struct ieee80211_sta *sta;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
struct rtw89_tx_desc_info desc_info;
};
@@ -1350,7 +1352,6 @@ struct rtw89_btc_wl_smap {
u32 connecting: 1;
u32 roaming: 1;
u32 dbccing: 1;
- u32 transacting: 1;
u32 _4way: 1;
u32 rf_off: 1;
u32 lps: 2;
@@ -2937,6 +2938,7 @@ struct rtw89_btc_dm {
u8 wl_pre_agc: 2;
u8 wl_lna2: 1;
+ u8 freerun_chk: 1;
u8 wl_pre_agc_rb: 2;
u8 bt_select: 2; /* 0:s0, 1:s1, 2:s0 & s1, refer to enum btc_bt_index */
u8 slot_req_more: 1;
@@ -2975,6 +2977,8 @@ enum rtw89_btc_btf_fw_event {
BTF_EVNT_BT_REG = 3,
BTF_EVNT_CX_RUNINFO = 4,
BTF_EVNT_BT_PSD = 5,
+ BTF_EVNT_BT_DEV_INFO = 6, /* fwc2hfunc > 0 */
+ BTF_EVNT_BT_LEAUDIO_INFO = 7, /* fwc2hfunc > 1 */
BTF_EVNT_BUF_OVERFLOW,
BTF_EVNT_C2H_LOOPBACK,
BTF_EVNT_MAX,
@@ -3141,6 +3145,7 @@ struct rtw89_btc_ver {
u8 fcxinit;
u8 fwevntrptl;
+ u8 fwc2hfunc;
u8 drvinfo_type;
u16 info_buf;
u8 max_role_num;
@@ -3354,12 +3359,13 @@ struct rtw89_sec_cam_entry {
u8 key[32];
};
-struct rtw89_sta {
+struct rtw89_sta_link {
+ struct rtw89_sta *rtwsta;
+ unsigned int link_id;
+
u8 mac_id;
- bool disassoc;
bool er_cap;
- struct rtw89_dev *rtwdev;
- struct rtw89_vif *rtwvif;
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_ra_info ra;
struct rtw89_ra_report ra_report;
int max_agg_wait;
@@ -3370,15 +3376,12 @@ struct rtw89_sta {
struct ewma_evm evm_1ss;
struct ewma_evm evm_min[RF_PATH_MAX];
struct ewma_evm evm_max[RF_PATH_MAX];
- struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
- DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS);
struct ieee80211_rx_status rx_status;
u16 rx_hw_rate;
__le32 htc_template;
struct rtw89_addr_cam_entry addr_cam; /* AP mode or TDLS peer only */
struct rtw89_bssid_cam_entry bssid_cam; /* TDLS peer only */
struct list_head ba_cam_list;
- struct sk_buff_head roc_queue;
bool use_cfg_mask;
struct cfg80211_bitrate_mask mask;
@@ -3460,10 +3463,10 @@ struct rtw89_p2p_noa_setter {
u8 noa_index;
};
-struct rtw89_vif {
- struct list_head list;
- struct rtw89_dev *rtwdev;
- struct rtw89_roc roc;
+struct rtw89_vif_link {
+ struct rtw89_vif *rtwvif;
+ unsigned int link_id;
+
bool chanctx_assigned; /* only valid when running with chanctx_ops */
enum rtw89_chanctx_idx chanctx_idx;
enum rtw89_reg_6ghz_power reg_6ghz_power;
@@ -3473,7 +3476,6 @@ struct rtw89_vif {
u8 port;
u8 mac_addr[ETH_ALEN];
u8 bssid[ETH_ALEN];
- __be32 ip_addr;
u8 phy_idx;
u8 mac_idx;
u8 net_type;
@@ -3484,7 +3486,6 @@ struct rtw89_vif {
u8 hit_rule;
u8 last_noa_nr;
u64 sync_bcn_tsf;
- bool offchan;
bool trigger;
bool lsig_txop;
u8 tgt_ind;
@@ -3498,15 +3499,11 @@ struct rtw89_vif {
bool pre_pwr_diff_en;
bool pwr_diff_en;
u8 def_tri_idx;
- u32 tdls_peer;
struct work_struct update_beacon_work;
struct rtw89_addr_cam_entry addr_cam;
struct rtw89_bssid_cam_entry bssid_cam;
struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS];
- struct rtw89_traffic_stats stats;
struct rtw89_phy_rate_pattern rate_pattern;
- struct cfg80211_scan_request *scan_req;
- struct ieee80211_scan_ies *scan_ies;
struct list_head general_pkt_list;
struct rtw89_p2p_noa_setter p2p_noa;
};
@@ -3599,11 +3596,11 @@ struct rtw89_chip_ops {
void (*rfk_hw_init)(struct rtw89_dev *rtwdev);
void (*rfk_init)(struct rtw89_dev *rtwdev);
void (*rfk_init_late)(struct rtw89_dev *rtwdev);
- void (*rfk_channel)(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+ void (*rfk_channel)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void (*rfk_band_changed)(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan);
- void (*rfk_scan)(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ void (*rfk_scan)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool start);
void (*rfk_track)(struct rtw89_dev *rtwdev);
void (*power_trim)(struct rtw89_dev *rtwdev);
@@ -3646,23 +3643,25 @@ struct rtw89_chip_ops {
u32 *tx_en, enum rtw89_sch_tx_sel sel);
int (*resume_sch_tx)(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en);
int (*h2c_dctl_sec_cam)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*h2c_default_cmac_tbl)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*h2c_assoc_cmac_tbl)(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*h2c_ampdu_cmac_tbl)(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*h2c_default_dmac_tbl)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*h2c_update_beacon)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
- int (*h2c_ba_cam)(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link);
+ int (*h2c_ba_cam)(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params);
void (*btc_set_rfe)(struct rtw89_dev *rtwdev);
@@ -4445,6 +4444,8 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V0,
RTW89_FW_FEATURE_WOW_REASON_V1,
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0,
+ RTW89_FW_FEATURE_RFK_RXDCK_V0,
+ RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX,
};
struct rtw89_fw_suit {
@@ -4672,7 +4673,7 @@ struct rtw89_hal {
struct rtw89_chanctx chanctx[NUM_OF_RTW89_CHANCTX];
struct cfg80211_chan_def roc_chandef;
- bool entity_active;
+ bool entity_active[RTW89_PHY_MAX];
bool entity_pause;
enum rtw89_entity_mode entity_mode;
@@ -4750,6 +4751,7 @@ DECLARE_EWMA(thermal, 4, 4);
struct rtw89_phy_stat {
struct ewma_thermal avg_thermal[RF_PATH_MAX];
+ struct ewma_rssi bcn_rssi;
struct rtw89_pkt_stat cur_pkt_stat;
struct rtw89_pkt_stat last_pkt_stat;
};
@@ -5196,7 +5198,7 @@ struct rtw89_early_h2c {
};
struct rtw89_hw_scan_info {
- struct ieee80211_vif *scanning_vif;
+ struct rtw89_vif_link *scanning_vif;
struct list_head pkt_list[NUM_NL80211_BANDS];
struct rtw89_chan op_chan;
bool abort;
@@ -5371,7 +5373,7 @@ struct rtw89_wow_aoac_report {
};
struct rtw89_wow_param {
- struct ieee80211_vif *wow_vif;
+ struct rtw89_vif_link *rtwvif_link;
DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM);
struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM];
struct rtw89_wow_key_info key_info;
@@ -5408,7 +5410,7 @@ struct rtw89_mcc_policy {
};
struct rtw89_mcc_role {
- struct rtw89_vif *rtwvif;
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_mcc_policy policy;
struct rtw89_mcc_limit limit;
@@ -5608,6 +5610,121 @@ struct rtw89_dev {
u8 priv[] __aligned(sizeof(void *));
};
+struct rtw89_vif {
+ struct rtw89_dev *rtwdev;
+ struct list_head list;
+
+ u8 mac_addr[ETH_ALEN];
+ __be32 ip_addr;
+
+ struct rtw89_traffic_stats stats;
+ u32 tdls_peer;
+
+ struct ieee80211_scan_ies *scan_ies;
+ struct cfg80211_scan_request *scan_req;
+
+ struct rtw89_roc roc;
+ bool offchan;
+
+ u8 links_inst_valid_num;
+ DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
+ struct rtw89_vif_link *links[IEEE80211_MLD_MAX_NUM_LINKS];
+ struct rtw89_vif_link links_inst[] __counted_by(links_inst_valid_num);
+};
+
+static inline bool rtw89_vif_assign_link_is_valid(struct rtw89_vif_link **rtwvif_link,
+ const struct rtw89_vif *rtwvif,
+ unsigned int link_id)
+{
+ *rtwvif_link = rtwvif->links[link_id];
+ return !!*rtwvif_link;
+}
+
+#define rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) \
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) \
+ if (rtw89_vif_assign_link_is_valid(&(rtwvif_link), rtwvif, link_id))
+
+struct rtw89_sta {
+ struct rtw89_dev *rtwdev;
+ struct rtw89_vif *rtwvif;
+
+ bool disassoc;
+
+ struct sk_buff_head roc_queue;
+
+ struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
+ DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS);
+
+ u8 links_inst_valid_num;
+ DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
+ struct rtw89_sta_link *links[IEEE80211_MLD_MAX_NUM_LINKS];
+ struct rtw89_sta_link links_inst[] __counted_by(links_inst_valid_num);
+};
+
+static inline bool rtw89_sta_assign_link_is_valid(struct rtw89_sta_link **rtwsta_link,
+ const struct rtw89_sta *rtwsta,
+ unsigned int link_id)
+{
+ *rtwsta_link = rtwsta->links[link_id];
+ return !!*rtwsta_link;
+}
+
+#define rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) \
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) \
+ if (rtw89_sta_assign_link_is_valid(&(rtwsta_link), rtwsta, link_id))
+
+static inline u8 rtw89_vif_get_main_macid(struct rtw89_vif *rtwvif)
+{
+ /* const after init, so no need to check if active first */
+ return rtwvif->links_inst[0].mac_id;
+}
+
+static inline u8 rtw89_vif_get_main_port(struct rtw89_vif *rtwvif)
+{
+ /* const after init, so no need to check if active first */
+ return rtwvif->links_inst[0].port;
+}
+
+static inline struct rtw89_vif_link *
+rtw89_vif_get_link_inst(struct rtw89_vif *rtwvif, u8 index)
+{
+ if (index >= rtwvif->links_inst_valid_num ||
+ !test_bit(index, rtwvif->links_inst_map))
+ return NULL;
+ return &rtwvif->links_inst[index];
+}
+
+static inline
+u8 rtw89_vif_link_inst_get_index(struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+
+ return rtwvif_link - rtwvif->links_inst;
+}
+
+static inline u8 rtw89_sta_get_main_macid(struct rtw89_sta *rtwsta)
+{
+ /* const after init, so no need to check if active first */
+ return rtwsta->links_inst[0].mac_id;
+}
+
+static inline struct rtw89_sta_link *
+rtw89_sta_get_link_inst(struct rtw89_sta *rtwsta, u8 index)
+{
+ if (index >= rtwsta->links_inst_valid_num ||
+ !test_bit(index, rtwsta->links_inst_map))
+ return NULL;
+ return &rtwsta->links_inst[index];
+}
+
+static inline
+u8 rtw89_sta_link_inst_get_index(struct rtw89_sta_link *rtwsta_link)
+{
+ struct rtw89_sta *rtwsta = rtwsta_link->rtwsta;
+
+ return rtwsta_link - rtwsta->links_inst;
+}
+
static inline int rtw89_hci_tx_write(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
@@ -5972,9 +6089,26 @@ static inline struct ieee80211_vif *rtwvif_to_vif_safe(struct rtw89_vif *rtwvif)
return rtwvif ? rtwvif_to_vif(rtwvif) : NULL;
}
+static inline
+struct ieee80211_vif *rtwvif_link_to_vif(struct rtw89_vif_link *rtwvif_link)
+{
+ return rtwvif_to_vif(rtwvif_link->rtwvif);
+}
+
+static inline
+struct ieee80211_vif *rtwvif_link_to_vif_safe(struct rtw89_vif_link *rtwvif_link)
+{
+ return rtwvif_link ? rtwvif_link_to_vif(rtwvif_link) : NULL;
+}
+
+static inline struct rtw89_vif *vif_to_rtwvif(struct ieee80211_vif *vif)
+{
+ return (struct rtw89_vif *)vif->drv_priv;
+}
+
static inline struct rtw89_vif *vif_to_rtwvif_safe(struct ieee80211_vif *vif)
{
- return vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
+ return vif ? vif_to_rtwvif(vif) : NULL;
}
static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta *rtwsta)
@@ -5989,11 +6123,88 @@ static inline struct ieee80211_sta *rtwsta_to_sta_safe(struct rtw89_sta *rtwsta)
return rtwsta ? rtwsta_to_sta(rtwsta) : NULL;
}
+static inline
+struct ieee80211_sta *rtwsta_link_to_sta(struct rtw89_sta_link *rtwsta_link)
+{
+ return rtwsta_to_sta(rtwsta_link->rtwsta);
+}
+
+static inline
+struct ieee80211_sta *rtwsta_link_to_sta_safe(struct rtw89_sta_link *rtwsta_link)
+{
+ return rtwsta_link ? rtwsta_link_to_sta(rtwsta_link) : NULL;
+}
+
+static inline struct rtw89_sta *sta_to_rtwsta(struct ieee80211_sta *sta)
+{
+ return (struct rtw89_sta *)sta->drv_priv;
+}
+
static inline struct rtw89_sta *sta_to_rtwsta_safe(struct ieee80211_sta *sta)
{
- return sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
+ return sta ? sta_to_rtwsta(sta) : NULL;
+}
+
+static inline struct ieee80211_bss_conf *
+__rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolink)
+{
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct ieee80211_bss_conf *bss_conf;
+
+ bss_conf = rcu_dereference(vif->link_conf[rtwvif_link->link_id]);
+ if (unlikely(!bss_conf)) {
+ *nolink = true;
+ return &vif->bss_conf;
+ }
+
+ *nolink = false;
+ return bss_conf;
}
+#define rtw89_vif_rcu_dereference_link(rtwvif_link, assert) \
+({ \
+ typeof(rtwvif_link) p = rtwvif_link; \
+ struct ieee80211_bss_conf *bss_conf; \
+ bool nolink; \
+ \
+ bss_conf = __rtw89_vif_rcu_dereference_link(p, &nolink); \
+ if (unlikely(nolink) && (assert)) \
+ rtw89_err(p->rtwvif->rtwdev, \
+ "%s: cannot find exact bss_conf for link_id %u\n",\
+ __func__, p->link_id); \
+ bss_conf; \
+})
+
+static inline struct ieee80211_link_sta *
+__rtw89_sta_rcu_dereference_link(struct rtw89_sta_link *rtwsta_link, bool *nolink)
+{
+ struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
+ struct ieee80211_link_sta *link_sta;
+
+ link_sta = rcu_dereference(sta->link[rtwsta_link->link_id]);
+ if (unlikely(!link_sta)) {
+ *nolink = true;
+ return &sta->deflink;
+ }
+
+ *nolink = false;
+ return link_sta;
+}
+
+#define rtw89_sta_rcu_dereference_link(rtwsta_link, assert) \
+({ \
+ typeof(rtwsta_link) p = rtwsta_link; \
+ struct ieee80211_link_sta *link_sta; \
+ bool nolink; \
+ \
+ link_sta = __rtw89_sta_rcu_dereference_link(p, &nolink); \
+ if (unlikely(nolink) && (assert)) \
+ rtw89_err(p->rtwsta->rtwdev, \
+ "%s: cannot find exact link_sta for link_id %u\n",\
+ __func__, p->link_id); \
+ link_sta; \
+})
+
static inline u8 rtw89_hw_to_rate_info_bw(enum rtw89_bandwidth hw_bw)
{
if (hw_bw == RTW89_CHANNEL_WIDTH_160)
@@ -6078,29 +6289,29 @@ enum nl80211_he_ru_alloc rtw89_he_rua_to_ru_alloc(u16 rua)
}
static inline
-struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- if (rtwsta) {
- struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
+ if (rtwsta_link) {
+ struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
- return &rtwsta->addr_cam;
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
+ return &rtwsta_link->addr_cam;
}
- return &rtwvif->addr_cam;
+ return &rtwvif_link->addr_cam;
}
static inline
-struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- if (rtwsta) {
- struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
+ if (rtwsta_link) {
+ struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
if (sta->tdls)
- return &rtwsta->bssid_cam;
+ return &rtwsta_link->bssid_cam;
}
- return &rtwvif->bssid_cam;
+ return &rtwvif_link->bssid_cam;
}
static inline
@@ -6159,11 +6370,10 @@ const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev,
static inline
const struct rtw89_chan *rtw89_scan_chan_get(struct rtw89_dev *rtwdev)
{
- struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
+ struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
- if (rtwvif)
- return rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
+ if (rtwvif_link)
+ return rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
else
return rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
}
@@ -6240,12 +6450,12 @@ static inline void rtw89_chip_rfk_init_late(struct rtw89_dev *rtwdev)
}
static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->rfk_channel)
- chip->ops->rfk_channel(rtwdev, rtwvif);
+ chip->ops->rfk_channel(rtwdev, rtwvif_link);
}
static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev,
@@ -6259,12 +6469,12 @@ static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev,
}
static inline void rtw89_chip_rfk_scan(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool start)
+ struct rtw89_vif_link *rtwvif_link, bool start)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->rfk_scan)
- chip->ops->rfk_scan(rtwdev, rtwvif, start);
+ chip->ops->rfk_scan(rtwdev, rtwvif_link, start);
}
static inline void rtw89_chip_rfk_track(struct rtw89_dev *rtwdev)
@@ -6279,8 +6489,12 @@ static inline void rtw89_chip_set_txpwr_ctrl(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- if (chip->ops->set_txpwr_ctrl)
- chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_0);
+ if (!chip->ops->set_txpwr_ctrl)
+ return;
+
+ chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_0);
+ if (rtwdev->dbcc_en)
+ chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_1);
}
static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev)
@@ -6291,8 +6505,8 @@ static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev)
chip->ops->power_trim(rtwdev);
}
-static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+static inline void __rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -6300,6 +6514,13 @@ static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev,
chip->ops->init_txpwr_unit(rtwdev, phy_idx);
}
+static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev)
+{
+ __rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0);
+ if (rtwdev->dbcc_en)
+ __rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_1);
+}
+
static inline u8 rtw89_chip_get_thermal(struct rtw89_dev *rtwdev,
enum rtw89_rf_path rf_path)
{
@@ -6347,20 +6568,6 @@ static inline void rtw89_chip_cfg_txrx_path(struct rtw89_dev *rtwdev)
chip->ops->cfg_txrx_path(rtwdev);
}
-static inline
-void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif)
-{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- const struct rtw89_chip_info *chip = rtwdev->chip;
-
- if (!vif->bss_conf.he_support || !vif->cfg.assoc)
- return;
-
- if (chip->ops->set_txpwr_ul_tb_offset)
- chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif->mac_idx);
-}
-
static inline void rtw89_chip_digital_pwr_comp(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
@@ -6457,14 +6664,14 @@ int rtw89_chip_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en)
static inline
int rtw89_chip_h2c_dctl_sec_cam(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (!chip->ops->h2c_dctl_sec_cam)
return 0;
- return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
+ return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
}
static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
@@ -6479,13 +6686,14 @@ static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
return hdr->addr3;
}
-static inline bool rtw89_sta_has_beamformer_cap(struct ieee80211_sta *sta)
+static inline
+bool rtw89_sta_has_beamformer_cap(struct ieee80211_link_sta *link_sta)
{
- if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
- (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) ||
- (sta->deflink.he_cap.he_cap_elem.phy_cap_info[3] &
+ if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
+ (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) ||
+ (link_sta->he_cap.he_cap_elem.phy_cap_info[3] &
IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
- (sta->deflink.he_cap.he_cap_elem.phy_cap_info[4] &
+ (link_sta->he_cap.he_cap_elem.phy_cap_info[4] &
IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER))
return true;
return false;
@@ -6605,21 +6813,21 @@ void rtw89_core_napi_start(struct rtw89_dev *rtwdev);
void rtw89_core_napi_stop(struct rtw89_dev *rtwdev);
int rtw89_core_napi_init(struct rtw89_dev *rtwdev);
void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev);
-int rtw89_core_sta_add(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
+int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
+int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
+int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
+int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
void rtw89_core_set_tid_config(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta,
struct cfg80211_tid_config *tid_config);
@@ -6635,22 +6843,40 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev);
u8 rtw89_acquire_mac_id(struct rtw89_dev *rtwdev);
void rtw89_release_mac_id(struct rtw89_dev *rtwdev, u8 mac_id);
+void rtw89_init_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ u8 mac_id, u8 port);
+void rtw89_init_sta(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ struct rtw89_sta *rtwsta, u8 mac_id);
+struct rtw89_vif_link *rtw89_vif_set_link(struct rtw89_vif *rtwvif,
+ unsigned int link_id);
+void rtw89_vif_unset_link(struct rtw89_vif *rtwvif, unsigned int link_id);
+struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta,
+ unsigned int link_id);
+void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id);
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev);
void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef);
void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
struct rtw89_chan *chan);
int rtw89_set_channel(struct rtw89_dev *rtwdev);
-void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_chan *chan);
u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size);
void rtw89_core_release_bit_map(unsigned long *addr, u8 bit);
void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits);
int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx);
+ struct rtw89_sta_link *rtwsta_link, u8 tid,
+ u8 *cam_idx);
int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx);
-void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc);
+ struct rtw89_sta_link *rtwsta_link, u8 tid,
+ u8 *cam_idx);
+void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta);
+void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta);
+void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta);
+void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc);
int rtw89_chip_info_setup(struct rtw89_dev *rtwdev);
+void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate);
int rtw89_regd_setup(struct rtw89_dev *rtwdev);
int rtw89_regd_init(struct rtw89_dev *rtwdev,
@@ -6667,13 +6893,15 @@ void rtw89_core_update_beacon_work(struct work_struct *work);
void rtw89_roc_work(struct work_struct *work);
void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
-void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
const u8 *mac_addr, bool hw_scan);
void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif, bool hw_scan);
-int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link, bool hw_scan);
+int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool active);
-void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
+void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf);
void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index 29f85210f919..74b0c722a5b8 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -3506,7 +3506,9 @@ out:
return count;
}
-static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
+static void rtw89_sta_link_info_get_iter(struct seq_file *m,
+ struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link)
{
static const char * const he_gi_str[] = {
[NL80211_RATE_INFO_HE_GI_0_8] = "0.8",
@@ -3518,20 +3520,26 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
[NL80211_RATE_INFO_EHT_GI_1_6] = "1.6",
[NL80211_RATE_INFO_EHT_GI_3_2] = "3.2",
};
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rate_info *rate = &rtwsta->ra_report.txrate;
- struct ieee80211_rx_status *status = &rtwsta->rx_status;
- struct seq_file *m = (struct seq_file *)data;
- struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rate_info *rate = &rtwsta_link->ra_report.txrate;
+ struct ieee80211_rx_status *status = &rtwsta_link->rx_status;
struct rtw89_hal *hal = &rtwdev->hal;
u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num;
bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity;
+ struct ieee80211_link_sta *link_sta;
u8 evm_min, evm_max, evm_1ss;
+ u16 max_rc_amsdu_len;
u8 rssi;
u8 snr;
int i;
- seq_printf(m, "TX rate [%d]: ", rtwsta->mac_id);
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ max_rc_amsdu_len = link_sta->agg.max_rc_amsdu_len;
+
+ rcu_read_unlock();
+
+ seq_printf(m, "TX rate [%u, %u]: ", rtwsta_link->mac_id, rtwsta_link->link_id);
if (rate->flags & RATE_INFO_FLAGS_MCS)
seq_printf(m, "HT MCS-%d%s", rate->mcs,
@@ -3549,13 +3557,13 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
eht_gi_str[rate->eht_gi] : "N/A");
else
seq_printf(m, "Legacy %d", rate->legacy);
- seq_printf(m, "%s", rtwsta->ra_report.might_fallback_legacy ? " FB_G" : "");
+ seq_printf(m, "%s", rtwsta_link->ra_report.might_fallback_legacy ? " FB_G" : "");
seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw));
- seq_printf(m, "\t(hw_rate=0x%x)", rtwsta->ra_report.hw_rate);
- seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta->max_agg_wait,
- sta->deflink.agg.max_rc_amsdu_len);
+ seq_printf(m, " (hw_rate=0x%x)", rtwsta_link->ra_report.hw_rate);
+ seq_printf(m, " ==> agg_wait=%d (%d)\n", rtwsta_link->max_agg_wait,
+ max_rc_amsdu_len);
- seq_printf(m, "RX rate [%d]: ", rtwsta->mac_id);
+ seq_printf(m, "RX rate [%u, %u]: ", rtwsta_link->mac_id, rtwsta_link->link_id);
switch (status->encoding) {
case RX_ENC_LEGACY:
@@ -3582,24 +3590,24 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
break;
}
seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw));
- seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta->rx_hw_rate);
+ seq_printf(m, " (hw_rate=0x%x)\n", rtwsta_link->rx_hw_rate);
- rssi = ewma_rssi_read(&rtwsta->avg_rssi);
+ rssi = ewma_rssi_read(&rtwsta_link->avg_rssi);
seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d) [",
- RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta->prev_rssi);
+ RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta_link->prev_rssi);
for (i = 0; i < ant_num; i++) {
- rssi = ewma_rssi_read(&rtwsta->rssi[i]);
+ rssi = ewma_rssi_read(&rtwsta_link->rssi[i]);
seq_printf(m, "%d%s%s", RTW89_RSSI_RAW_TO_DBM(rssi),
ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "",
i + 1 == ant_num ? "" : ", ");
}
seq_puts(m, "]\n");
- evm_1ss = ewma_evm_read(&rtwsta->evm_1ss);
+ evm_1ss = ewma_evm_read(&rtwsta_link->evm_1ss);
seq_printf(m, "EVM: [%2u.%02u, ", evm_1ss >> 2, (evm_1ss & 0x3) * 25);
for (i = 0; i < (hal->ant_diversity ? 2 : 1); i++) {
- evm_min = ewma_evm_read(&rtwsta->evm_min[i]);
- evm_max = ewma_evm_read(&rtwsta->evm_max[i]);
+ evm_min = ewma_evm_read(&rtwsta_link->evm_min[i]);
+ evm_max = ewma_evm_read(&rtwsta_link->evm_max[i]);
seq_printf(m, "%s(%2u.%02u, %2u.%02u)", i == 0 ? "" : " ",
evm_min >> 2, (evm_min & 0x3) * 25,
@@ -3607,10 +3615,22 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
}
seq_puts(m, "]\t");
- snr = ewma_snr_read(&rtwsta->avg_snr);
+ snr = ewma_snr_read(&rtwsta_link->avg_snr);
seq_printf(m, "SNR: %u\n", snr);
}
+static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct seq_file *m = (struct seq_file *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
+ rtw89_sta_link_info_get_iter(m, rtwdev, rtwsta_link);
+}
+
static void
rtw89_debug_append_rx_rate(struct seq_file *m, struct rtw89_pkt_stat *pkt_stat,
enum rtw89_hw_rate first_rate, int len)
@@ -3653,13 +3673,16 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_rx_rate_cnt_info *info;
enum rtw89_hw_rate first_rate;
+ u8 rssi;
int i;
+ rssi = ewma_rssi_read(&rtwdev->phystat.bcn_rssi);
+
seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d), RX: %u [%u] Mbps (lv: %d)\n",
stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv,
stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv);
- seq_printf(m, "Beacon: %u, TF: %u\n", pkt_stat->beacon_nr,
- stats->rx_tf_periodic);
+ seq_printf(m, "Beacon: %u (%d dBm), TF: %u\n", pkt_stat->beacon_nr,
+ RTW89_RSSI_RAW_TO_DBM(rssi), stats->rx_tf_periodic);
seq_printf(m, "Avg packet length: TX=%u, RX=%u\n", stats->tx_avg_len,
stats->rx_avg_len);
@@ -3737,28 +3760,41 @@ static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_lis
seq_puts(m, "\n");
}
+static void rtw89_vif_link_ids_get(struct seq_file *m, u8 *mac,
+ struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
+
+ seq_printf(m, " [%u] %pM\n", rtwvif_link->mac_id, rtwvif_link->mac_addr);
+ seq_printf(m, "\tlink_id=%u\n", rtwvif_link->link_id);
+ seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx);
+ rtw89_dump_addr_cam(m, rtwdev, &rtwvif_link->addr_cam);
+ rtw89_dump_pkt_offload(m, &rtwvif_link->general_pkt_list,
+ "\tpkt_ofld[GENERAL]: ");
+}
+
static
void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct seq_file *m = (struct seq_file *)data;
- struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_dev *rtwdev = rtwvif->rtwdev;
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
- seq_printf(m, "VIF [%d] %pM\n", rtwvif->mac_id, rtwvif->mac_addr);
- seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx);
- rtw89_dump_addr_cam(m, rtwdev, &rtwvif->addr_cam);
- rtw89_dump_pkt_offload(m, &rtwvif->general_pkt_list, "\tpkt_ofld[GENERAL]: ");
+ seq_printf(m, "VIF %pM\n", rtwvif->mac_addr);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_vif_link_ids_get(m, mac, rtwdev, rtwvif_link);
}
-static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta)
+static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
- struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct rtw89_ba_cam_entry *entry;
bool first = true;
- list_for_each_entry(entry, &rtwsta->ba_cam_list, list) {
+ list_for_each_entry(entry, &rtwsta_link->ba_cam_list, list) {
if (first) {
seq_puts(m, "\tba_cam ");
first = false;
@@ -3771,16 +3807,36 @@ static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta)
seq_puts(m, "\n");
}
+static void rtw89_sta_link_ids_get(struct seq_file *m,
+ struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link)
+{
+ struct ieee80211_link_sta *link_sta;
+
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ seq_printf(m, " [%u] %pM\n", rtwsta_link->mac_id, link_sta->addr);
+
+ rcu_read_unlock();
+
+ seq_printf(m, "\tlink_id=%u\n", rtwsta_link->link_id);
+ rtw89_dump_addr_cam(m, rtwdev, &rtwsta_link->addr_cam);
+ rtw89_dump_ba_cam(m, rtwdev, rtwsta_link);
+}
+
static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_dev *rtwdev = rtwsta->rtwdev;
struct seq_file *m = (struct seq_file *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
- seq_printf(m, "STA [%d] %pM %s\n", rtwsta->mac_id, sta->addr,
- sta->tdls ? "(TDLS)" : "");
- rtw89_dump_addr_cam(m, rtwdev, &rtwsta->addr_cam);
- rtw89_dump_ba_cam(m, rtwsta);
+ seq_printf(m, "STA %pM %s\n", sta->addr, sta->tdls ? "(TDLS)" : "");
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
+ rtw89_sta_link_ids_get(m, rtwdev, rtwsta_link);
}
static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index d9b0e7ebe619..2c2fdf21f065 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -665,11 +665,13 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER),
+ __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 37, 0, NO_WOW_CPU_IO_RX),
__CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD),
+ __CFG_FW_FEAT(RTL8852B, lt, 0, 29, 30, 0, NO_WOW_CPU_IO_RX),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, NO_LPS_PG),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 90, 0, CRASH_TRIGGER),
@@ -687,6 +689,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, RFK_PRE_NOTIFY_V0),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0),
};
static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
@@ -1741,8 +1744,8 @@ plain_log:
}
#define H2C_CAM_LEN 60
-int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, const u8 *scan_mac_addr)
+int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr)
{
struct sk_buff *skb;
int ret;
@@ -1753,8 +1756,9 @@ int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
return -ENOMEM;
}
skb_put(skb, H2C_CAM_LEN);
- rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, rtwsta, scan_mac_addr, skb->data);
- rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, rtwsta, skb->data);
+ rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link, scan_mac_addr,
+ skb->data);
+ rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, skb->data);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
@@ -1776,8 +1780,8 @@ fail:
}
int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
struct rtw89_h2c_dctlinfo_ud_v1 *h2c;
u32 len = sizeof(*h2c);
@@ -1792,7 +1796,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_dctlinfo_ud_v1 *)skb->data;
- rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, h2c);
+ rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif_link, rtwsta_link, h2c);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
@@ -1815,8 +1819,8 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1);
int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
struct rtw89_h2c_dctlinfo_ud_v2 *h2c;
u32 len = sizeof(*h2c);
@@ -1831,7 +1835,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data;
- rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif, rtwsta, h2c);
+ rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif_link, rtwsta_link, h2c);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
@@ -1854,10 +1858,10 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v2);
int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
struct rtw89_h2c_dctlinfo_ud_v2 *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
@@ -1908,21 +1912,24 @@ fail:
}
EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v2);
-int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_h2c_ba_cam *h2c;
- u8 macid = rtwsta->mac_id;
+ u8 macid = rtwsta_link->mac_id;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
u8 entry_idx;
int ret;
ret = valid ?
- rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) :
- rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx);
+ rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
+ &entry_idx) :
+ rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
+ &entry_idx);
if (ret) {
/* it still works even if we don't have static BA CAM, because
* hardware can create dynamic BA CAM automatically.
@@ -1960,7 +1967,8 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
if (chip->bacam_ver == RTW89_BACAM_V0_EXT) {
h2c->w1 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W1_STD_EN) |
- le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BA_CAM_W1_BAND);
+ le32_encode_bits(rtwvif_link->mac_idx,
+ RTW89_H2C_BA_CAM_W1_BAND);
}
end:
@@ -2039,13 +2047,14 @@ void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev)
}
}
-int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_h2c_ba_cam_v1 *h2c;
- u8 macid = rtwsta->mac_id;
+ u8 macid = rtwsta_link->mac_id;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
u8 entry_idx;
@@ -2053,8 +2062,10 @@ int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
int ret;
ret = valid ?
- rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) :
- rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx);
+ rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
+ &entry_idx) :
+ rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
+ &entry_idx);
if (ret) {
/* it still works even if we don't have static BA CAM, because
* hardware can create dynamic BA CAM automatically.
@@ -2092,7 +2103,8 @@ int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
entry_idx += chip->bacam_dynamic_num; /* std entry right after dynamic ones */
h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK) |
le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN) |
- le32_encode_bits(!!rtwvif->mac_idx, RTW89_H2C_BA_CAM_V1_W1_BAND_SEL);
+ le32_encode_bits(!!rtwvif_link->mac_idx,
+ RTW89_H2C_BA_CAM_V1_W1_BAND_SEL);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
@@ -2197,15 +2209,14 @@ fail:
}
static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88,
0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03};
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_eapol_2_of_2 *eapol_pkt;
+ struct ieee80211_bss_conf *bss_conf;
struct ieee80211_hdr_3addr *hdr;
struct sk_buff *skb;
u8 key_des_ver;
@@ -2227,10 +2238,17 @@ static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev,
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
IEEE80211_FCTL_TODS |
IEEE80211_FCTL_PROTECTED);
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
ether_addr_copy(hdr->addr1, bss_conf->bssid);
- ether_addr_copy(hdr->addr2, vif->addr);
+ ether_addr_copy(hdr->addr2, bss_conf->addr);
ether_addr_copy(hdr->addr3, bss_conf->bssid);
+ rcu_read_unlock();
+
skb_put_zero(skb, sec_hdr_len);
eapol_pkt = skb_put_zero(skb, sizeof(*eapol_pkt));
@@ -2241,11 +2259,10 @@ static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev,
}
static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
+ struct ieee80211_bss_conf *bss_conf;
struct ieee80211_hdr_3addr *hdr;
struct rtw89_sa_query *sa_query;
struct sk_buff *skb;
@@ -2258,10 +2275,17 @@ static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev,
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION |
IEEE80211_FCTL_PROTECTED);
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
ether_addr_copy(hdr->addr1, bss_conf->bssid);
- ether_addr_copy(hdr->addr2, vif->addr);
+ ether_addr_copy(hdr->addr2, bss_conf->addr);
ether_addr_copy(hdr->addr3, bss_conf->bssid);
+ rcu_read_unlock();
+
skb_put_zero(skb, sec_hdr_len);
sa_query = skb_put_zero(skb, sizeof(*sa_query));
@@ -2272,8 +2296,9 @@ static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev,
}
static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_hdr_3addr *hdr;
@@ -2295,9 +2320,9 @@ static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev,
fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS);
hdr->frame_control = fc;
- ether_addr_copy(hdr->addr1, rtwvif->bssid);
- ether_addr_copy(hdr->addr2, rtwvif->mac_addr);
- ether_addr_copy(hdr->addr3, rtwvif->bssid);
+ ether_addr_copy(hdr->addr1, rtwvif_link->bssid);
+ ether_addr_copy(hdr->addr2, rtwvif_link->mac_addr);
+ ether_addr_copy(hdr->addr3, rtwvif_link->bssid);
skb_put_zero(skb, sec_hdr_len);
@@ -2312,18 +2337,18 @@ static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev,
arp_hdr->ar_pln = 4;
arp_hdr->ar_op = htons(ARPOP_REPLY);
- ether_addr_copy(arp_skb->sender_hw, rtwvif->mac_addr);
+ ether_addr_copy(arp_skb->sender_hw, rtwvif_link->mac_addr);
arp_skb->sender_ip = rtwvif->ip_addr;
return skb;
}
static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
enum rtw89_fw_pkt_ofld_type type,
u8 *id)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_pktofld_info *info;
struct sk_buff *skb;
int ret;
@@ -2346,13 +2371,13 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, true);
break;
case RTW89_PKT_OFLD_TYPE_EAPOL_KEY:
- skb = rtw89_eapol_get(rtwdev, rtwvif);
+ skb = rtw89_eapol_get(rtwdev, rtwvif_link);
break;
case RTW89_PKT_OFLD_TYPE_SA_QUERY:
- skb = rtw89_sa_query_get(rtwdev, rtwvif);
+ skb = rtw89_sa_query_get(rtwdev, rtwvif_link);
break;
case RTW89_PKT_OFLD_TYPE_ARP_RSP:
- skb = rtw89_arp_response_get(rtwdev, rtwvif);
+ skb = rtw89_arp_response_get(rtwdev, rtwvif_link);
break;
default:
goto err;
@@ -2367,7 +2392,7 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
if (ret)
goto err;
- list_add_tail(&info->list, &rtwvif->general_pkt_list);
+ list_add_tail(&info->list, &rtwvif_link->general_pkt_list);
*id = info->id;
return 0;
@@ -2377,9 +2402,10 @@ err:
}
void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool notify_fw)
+ struct rtw89_vif_link *rtwvif_link,
+ bool notify_fw)
{
- struct list_head *pkt_list = &rtwvif->general_pkt_list;
+ struct list_head *pkt_list = &rtwvif_link->general_pkt_list;
struct rtw89_pktofld_info *info, *tmp;
list_for_each_entry_safe(info, tmp, pkt_list, list) {
@@ -2394,16 +2420,20 @@ void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, notify_fw);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link,
+ notify_fw);
}
#define H2C_GENERAL_PKT_LEN 6
#define H2C_GENERAL_PKT_ID_UND 0xff
int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u8 macid)
+ struct rtw89_vif_link *rtwvif_link, u8 macid)
{
u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND;
u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND;
@@ -2411,11 +2441,11 @@ int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev,
struct sk_buff *skb;
int ret;
- rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll);
- rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null);
- rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null);
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN);
@@ -2494,10 +2524,10 @@ fail:
return ret;
}
-int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
+ rtwvif_link->chanctx_idx);
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_h2c_lps_ch_info *h2c;
u32 len = sizeof(*h2c);
@@ -2546,13 +2576,14 @@ fail:
}
#define H2C_P2P_ACT_LEN 20
-int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf,
struct ieee80211_p2p_noa_desc *desc,
u8 act, u8 noa_id)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- bool p2p_type_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
- u8 ctwindow_oppps = vif->bss_conf.p2p_noa_attr.oppps_ctwindow;
+ bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
+ u8 ctwindow_oppps = bss_conf->p2p_noa_attr.oppps_ctwindow;
struct sk_buff *skb;
u8 *cmd;
int ret;
@@ -2565,7 +2596,7 @@ int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
skb_put(skb, H2C_P2P_ACT_LEN);
cmd = skb->data;
- RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif->mac_id);
+ RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif_link->mac_id);
RTW89_SET_FWCMD_P2P_P2PID(cmd, 0);
RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id);
RTW89_SET_FWCMD_P2P_ACT(cmd, act);
@@ -2622,11 +2653,11 @@ static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev,
#define H2C_CMC_TBL_LEN 68
int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- u8 macid = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ u8 macid = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
struct sk_buff *skb;
int ret;
@@ -2648,7 +2679,7 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
}
SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0);
SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0);
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
SET_CMC_TBL_DATA_DCM(skb->data, 0);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -2671,10 +2702,10 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl);
int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
@@ -2755,24 +2786,25 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_g7);
static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta, u8 *pads)
+ struct ieee80211_link_sta *link_sta,
+ u8 *pads)
{
bool ppe_th;
u8 ppe16, ppe8;
- u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
- u8 ppe_thres_hdr = sta->deflink.he_cap.ppe_thres[0];
+ u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1;
+ u8 ppe_thres_hdr = link_sta->he_cap.ppe_thres[0];
u8 ru_bitmap;
u8 n, idx, sh;
u16 ppe;
int i;
ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
- sta->deflink.he_cap.he_cap_elem.phy_cap_info[6]);
+ link_sta->he_cap.he_cap_elem.phy_cap_info[6]);
if (!ppe_th) {
u8 pad;
pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK,
- sta->deflink.he_cap.he_cap_elem.phy_cap_info[9]);
+ link_sta->he_cap.he_cap_elem.phy_cap_info[9]);
for (i = 0; i < RTW89_PPE_BW_NUM; i++)
pads[i] = pad;
@@ -2794,7 +2826,7 @@ static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev,
sh = n & 7;
n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2;
- ppe = le16_to_cpu(*((__le16 *)&sta->deflink.he_cap.ppe_thres[idx]));
+ ppe = le16_to_cpu(*((__le16 *)&link_sta->he_cap.ppe_thres[idx]));
ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
@@ -2809,23 +2841,35 @@ static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev,
}
int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
+ rtwvif_link->chanctx_idx);
+ struct ieee80211_link_sta *link_sta;
struct sk_buff *skb;
u8 pads[RTW89_PPE_BW_NUM];
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
u16 lowest_rate;
int ret;
memset(pads, 0, sizeof(pads));
- if (sta && sta->deflink.he_cap.has_he)
- __get_sta_he_pkt_padding(rtwdev, sta, pads);
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
+ return -ENOMEM;
+ }
+
+ rcu_read_lock();
+
+ if (rtwsta_link)
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ if (rtwsta_link && link_sta->he_cap.has_he)
+ __get_sta_he_pkt_padding(rtwdev, link_sta, pads);
if (vif->p2p)
lowest_rate = RTW89_HW_RATE_OFDM6;
@@ -2834,11 +2878,6 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
else
lowest_rate = RTW89_HW_RATE_OFDM6;
- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
- if (!skb) {
- rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
- return -ENOMEM;
- }
skb_put(skb, H2C_CMC_TBL_LEN);
SET_CTRL_INFO_MACID(skb->data, mac_id);
SET_CTRL_INFO_OPERATION(skb->data, 1);
@@ -2851,7 +2890,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
SET_CMC_TBL_ULDL(skb->data, 1);
else
SET_CMC_TBL_ULDL(skb->data, 0);
- SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port);
+ SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif_link->port);
if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) {
SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
@@ -2863,12 +2902,14 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
}
- if (sta)
+ if (rtwsta_link)
SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data,
- sta->deflink.he_cap.has_he);
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ link_sta->he_cap.has_he);
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
SET_CMC_TBL_DATA_DCM(skb->data, 0);
+ rcu_read_unlock();
+
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
chip->h2c_cctl_func_id, 0, 1,
@@ -2889,9 +2930,10 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl);
static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta, u8 *pads)
+ struct ieee80211_link_sta *link_sta,
+ u8 *pads)
{
- u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
+ u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1;
u16 ppe_thres_hdr;
u8 ppe16, ppe8;
u8 n, idx, sh;
@@ -2900,12 +2942,12 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
u16 ppe;
int i;
- ppe_th = !!u8_get_bits(sta->deflink.eht_cap.eht_cap_elem.phy_cap_info[5],
+ ppe_th = !!u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5],
IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT);
if (!ppe_th) {
u8 pad;
- pad = u8_get_bits(sta->deflink.eht_cap.eht_cap_elem.phy_cap_info[5],
+ pad = u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5],
IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK);
for (i = 0; i < RTW89_PPE_BW_NUM; i++)
@@ -2914,7 +2956,7 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
return;
}
- ppe_thres_hdr = get_unaligned_le16(sta->deflink.eht_cap.eht_ppe_thres);
+ ppe_thres_hdr = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres);
ru_bitmap = u16_get_bits(ppe_thres_hdr,
IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
n = hweight8(ru_bitmap);
@@ -2931,7 +2973,7 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
sh = n & 7;
n += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2;
- ppe = get_unaligned_le16(sta->deflink.eht_cap.eht_ppe_thres + idx);
+ ppe = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres + idx);
ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
sh += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE;
ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
@@ -2946,14 +2988,15 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
}
int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
+ struct ieee80211_bss_conf *bss_conf;
+ struct ieee80211_link_sta *link_sta;
u8 pads[RTW89_PPE_BW_NUM];
u32 len = sizeof(*h2c);
struct sk_buff *skb;
@@ -2961,11 +3004,24 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
int ret;
memset(pads, 0, sizeof(pads));
- if (sta) {
- if (sta->deflink.eht_cap.has_eht)
- __get_sta_eht_pkt_padding(rtwdev, sta, pads);
- else if (sta->deflink.he_cap.has_he)
- __get_sta_he_pkt_padding(rtwdev, sta, pads);
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n");
+ return -ENOMEM;
+ }
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
+ if (rtwsta_link) {
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ if (link_sta->eht_cap.has_eht)
+ __get_sta_eht_pkt_padding(rtwdev, link_sta, pads);
+ else if (link_sta->he_cap.has_he)
+ __get_sta_he_pkt_padding(rtwdev, link_sta, pads);
}
if (vif->p2p)
@@ -2975,11 +3031,6 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
else
lowest_rate = RTW89_HW_RATE_OFDM6;
- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
- if (!skb) {
- rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n");
- return -ENOMEM;
- }
skb_put(skb, len);
h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
@@ -3000,16 +3051,16 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
h2c->w3 = le32_encode_bits(0, CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL);
h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL);
- h2c->w4 = le32_encode_bits(rtwvif->port, CCTLINFO_G7_W4_MULTI_PORT_ID);
+ h2c->w4 = le32_encode_bits(rtwvif_link->port, CCTLINFO_G7_W4_MULTI_PORT_ID);
h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_MULTI_PORT_ID);
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) {
h2c->w4 |= le32_encode_bits(0, CCTLINFO_G7_W4_DATA_DCM);
h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_DATA_DCM);
}
- if (vif->bss_conf.eht_support) {
- u16 punct = vif->bss_conf.chanreq.oper.punctured;
+ if (bss_conf->eht_support) {
+ u16 punct = bss_conf->chanreq.oper.punctured;
h2c->w4 |= le32_encode_bits(~punct,
CCTLINFO_G7_W4_ACT_SUBCH_CBW);
@@ -3036,12 +3087,14 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
CCTLINFO_G7_W6_ULDL);
h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_ULDL);
- if (sta) {
- h2c->w8 = le32_encode_bits(sta->deflink.he_cap.has_he,
+ if (rtwsta_link) {
+ h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he,
CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT);
h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT);
}
+ rcu_read_unlock();
+
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
@@ -3062,10 +3115,10 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_g7);
int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = rtwsta_link->rtwsta;
struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
@@ -3102,7 +3155,7 @@ int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
else if (agg_num > 0x200 && agg_num <= 0x400)
ba_bmap = 5;
- h2c->c0 = le32_encode_bits(rtwsta->mac_id, CCTLINFO_G7_C0_MACID) |
+ h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) |
le32_encode_bits(1, CCTLINFO_G7_C0_OP);
h2c->w3 = le32_encode_bits(ba_bmap, CCTLINFO_G7_W3_BA_BMAP);
@@ -3128,7 +3181,7 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_g7);
int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta)
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct sk_buff *skb;
@@ -3140,15 +3193,15 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
skb_put(skb, H2C_CMC_TBL_LEN);
- SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
+ SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id);
SET_CTRL_INFO_OPERATION(skb->data, 1);
- if (rtwsta->cctl_tx_time) {
+ if (rtwsta_link->cctl_tx_time) {
SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1);
- SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time);
+ SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta_link->ampdu_max_time);
}
- if (rtwsta->cctl_tx_retry_limit) {
+ if (rtwsta_link->cctl_tx_retry_limit) {
SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1);
- SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt);
+ SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta_link->data_tx_cnt_lmt);
}
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -3170,7 +3223,7 @@ fail:
}
int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta)
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct sk_buff *skb;
@@ -3185,7 +3238,7 @@ int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
skb_put(skb, H2C_CMC_TBL_LEN);
- SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
+ SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id);
SET_CTRL_INFO_OPERATION(skb->data, 1);
__rtw89_fw_h2c_set_tx_path(rtwdev, skb);
@@ -3209,11 +3262,11 @@ fail:
}
int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ rtwvif_link->chanctx_idx);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_h2c_bcn_upd *h2c;
struct sk_buff *skb_beacon;
struct ieee80211_hdr *hdr;
@@ -3240,7 +3293,7 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
- noa_len = rtw89_p2p_noa_fetch(rtwvif, &noa_data);
+ noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data);
if (noa_len &&
(noa_len <= skb_tailroom(skb_beacon) ||
pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) {
@@ -3260,11 +3313,11 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_bcn_upd *)skb->data;
- h2c->w0 = le32_encode_bits(rtwvif->port, RTW89_H2C_BCN_UPD_W0_PORT) |
+ h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_W0_PORT) |
le32_encode_bits(0, RTW89_H2C_BCN_UPD_W0_MBSSID) |
- le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) |
+ le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) |
le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_W0_GRP_IE_OFST);
- h2c->w1 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) |
+ h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) |
le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_W1_SSN_SEL) |
le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_W1_SSN_MODE) |
le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_W1_RATE);
@@ -3289,10 +3342,10 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon);
int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_h2c_bcn_upd_be *h2c;
struct sk_buff *skb_beacon;
struct ieee80211_hdr *hdr;
@@ -3319,7 +3372,7 @@ int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
- noa_len = rtw89_p2p_noa_fetch(rtwvif, &noa_data);
+ noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data);
if (noa_len &&
(noa_len <= skb_tailroom(skb_beacon) ||
pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) {
@@ -3339,11 +3392,11 @@ int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_bcn_upd_be *)skb->data;
- h2c->w0 = le32_encode_bits(rtwvif->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) |
+ h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) |
le32_encode_bits(0, RTW89_H2C_BCN_UPD_BE_W0_MBSSID) |
- le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) |
+ le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) |
le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_BE_W0_GRP_IE_OFST);
- h2c->w1 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) |
+ h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) |
le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_BE_W1_SSN_SEL) |
le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_BE_W1_SSN_MODE) |
le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_BE_W1_RATE);
@@ -3373,22 +3426,22 @@ EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon_be);
#define H2C_ROLE_MAINTAIN_LEN 4
int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
enum rtw89_upd_mode upd_mode)
{
struct sk_buff *skb;
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
u8 self_role;
int ret;
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
- if (rtwsta)
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) {
+ if (rtwsta_link)
self_role = RTW89_SELF_ROLE_AP_CLIENT;
else
- self_role = rtwvif->self_role;
+ self_role = rtwvif_link->self_role;
} else {
- self_role = rtwvif->self_role;
+ self_role = rtwvif_link->self_role;
}
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN);
@@ -3400,7 +3453,7 @@ int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id);
SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role);
SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode);
- SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role);
+ SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif_link->wifi_role);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
@@ -3421,39 +3474,53 @@ fail:
}
static enum rtw89_fw_sta_type
-rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_bss_conf *bss_conf;
+ struct ieee80211_link_sta *link_sta;
+ enum rtw89_fw_sta_type type;
+
+ rcu_read_lock();
- if (!sta)
+ if (!rtwsta_link)
goto by_vif;
- if (sta->deflink.eht_cap.has_eht)
- return RTW89_FW_BE_STA;
- else if (sta->deflink.he_cap.has_he)
- return RTW89_FW_AX_STA;
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ if (link_sta->eht_cap.has_eht)
+ type = RTW89_FW_BE_STA;
+ else if (link_sta->he_cap.has_he)
+ type = RTW89_FW_AX_STA;
else
- return RTW89_FW_N_AC_STA;
+ type = RTW89_FW_N_AC_STA;
+
+ goto out;
by_vif:
- if (vif->bss_conf.eht_support)
- return RTW89_FW_BE_STA;
- else if (vif->bss_conf.he_support)
- return RTW89_FW_AX_STA;
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
+ if (bss_conf->eht_support)
+ type = RTW89_FW_BE_STA;
+ else if (bss_conf->he_support)
+ type = RTW89_FW_AX_STA;
else
- return RTW89_FW_N_AC_STA;
+ type = RTW89_FW_N_AC_STA;
+
+out:
+ rcu_read_unlock();
+
+ return type;
}
-int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, bool dis_conn)
+int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link, bool dis_conn)
{
struct sk_buff *skb;
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
- u8 self_role = rtwvif->self_role;
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
+ u8 self_role = rtwvif_link->self_role;
enum rtw89_fw_sta_type sta_type;
- u8 net_type = rtwvif->net_type;
+ u8 net_type = rtwvif_link->net_type;
struct rtw89_h2c_join_v1 *h2c_v1;
struct rtw89_h2c_join *h2c;
u32 len = sizeof(*h2c);
@@ -3465,7 +3532,7 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
format_v1 = true;
}
- if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta) {
+ if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta_link) {
self_role = RTW89_SELF_ROLE_AP_CLIENT;
net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type;
}
@@ -3480,16 +3547,17 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_JOININFO_W0_MACID) |
le32_encode_bits(dis_conn, RTW89_H2C_JOININFO_W0_OP) |
- le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_JOININFO_W0_BAND) |
- le32_encode_bits(rtwvif->wmm, RTW89_H2C_JOININFO_W0_WMM) |
- le32_encode_bits(rtwvif->trigger, RTW89_H2C_JOININFO_W0_TGR) |
+ le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_JOININFO_W0_BAND) |
+ le32_encode_bits(rtwvif_link->wmm, RTW89_H2C_JOININFO_W0_WMM) |
+ le32_encode_bits(rtwvif_link->trigger, RTW89_H2C_JOININFO_W0_TGR) |
le32_encode_bits(0, RTW89_H2C_JOININFO_W0_ISHESTA) |
le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DLBW) |
le32_encode_bits(0, RTW89_H2C_JOININFO_W0_TF_MAC_PAD) |
le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DL_T_PE) |
- le32_encode_bits(rtwvif->port, RTW89_H2C_JOININFO_W0_PORT_ID) |
+ le32_encode_bits(rtwvif_link->port, RTW89_H2C_JOININFO_W0_PORT_ID) |
le32_encode_bits(net_type, RTW89_H2C_JOININFO_W0_NET_TYPE) |
- le32_encode_bits(rtwvif->wifi_role, RTW89_H2C_JOININFO_W0_WIFI_ROLE) |
+ le32_encode_bits(rtwvif_link->wifi_role,
+ RTW89_H2C_JOININFO_W0_WIFI_ROLE) |
le32_encode_bits(self_role, RTW89_H2C_JOININFO_W0_SELF_ROLE);
if (!format_v1)
@@ -3497,7 +3565,7 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
h2c_v1 = (struct rtw89_h2c_join_v1 *)skb->data;
- sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif, rtwsta);
+ sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif_link, rtwsta_link);
h2c_v1->w1 = le32_encode_bits(sta_type, RTW89_H2C_JOININFO_W1_STA_TYPE);
h2c_v1->w2 = 0;
@@ -3618,7 +3686,7 @@ fail:
}
#define H2C_EDCA_LEN 12
-int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 ac, u32 val)
{
struct sk_buff *skb;
@@ -3631,7 +3699,7 @@ int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
}
skb_put(skb, H2C_EDCA_LEN);
RTW89_SET_EDCA_SEL(skb->data, 0);
- RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx);
+ RTW89_SET_EDCA_BAND(skb->data, rtwvif_link->mac_idx);
RTW89_SET_EDCA_WMM(skb->data, 0);
RTW89_SET_EDCA_AC(skb->data, ac);
RTW89_SET_EDCA_PARAM(skb->data, val);
@@ -3655,7 +3723,8 @@ fail:
}
#define H2C_TSF32_TOGL_LEN 4
-int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool en)
{
struct sk_buff *skb;
@@ -3671,9 +3740,9 @@ int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
skb_put(skb, H2C_TSF32_TOGL_LEN);
cmd = skb->data;
- RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif->mac_idx);
+ RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif_link->mac_idx);
RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en);
- RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif->port);
+ RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif_link->port);
RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -3727,11 +3796,10 @@ fail:
}
int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
+ struct rtw89_vif_link *rtwvif_link,
bool connect)
{
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
- struct ieee80211_bss_conf *bss_conf = vif ? &vif->bss_conf : NULL;
+ struct ieee80211_bss_conf *bss_conf;
s32 thold = RTW89_DEFAULT_CQM_THOLD;
u32 hyst = RTW89_DEFAULT_CQM_HYST;
struct rtw89_h2c_bcnfltr *h2c;
@@ -3742,9 +3810,20 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
return -EINVAL;
- if (!rtwvif || !bss_conf || rtwvif->net_type != RTW89_NET_TYPE_INFRA)
+ if (!rtwvif_link || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA)
return -EINVAL;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+
+ if (bss_conf->cqm_rssi_hyst)
+ hyst = bss_conf->cqm_rssi_hyst;
+ if (bss_conf->cqm_rssi_thold)
+ thold = bss_conf->cqm_rssi_thold;
+
+ rcu_read_unlock();
+
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n");
@@ -3754,11 +3833,6 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_bcnfltr *)skb->data;
- if (bss_conf->cqm_rssi_hyst)
- hyst = bss_conf->cqm_rssi_hyst;
- if (bss_conf->cqm_rssi_thold)
- thold = bss_conf->cqm_rssi_thold;
-
h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) |
le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) |
le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) |
@@ -3768,7 +3842,7 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
le32_encode_bits(hyst, RTW89_H2C_BCNFLTR_W0_RSSI_HYST) |
le32_encode_bits(thold + MAX_RSSI,
RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD) |
- le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID);
+ le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
@@ -3833,15 +3907,16 @@ fail:
return ret;
}
-int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_traffic_stats *stats = &rtwvif->stats;
struct rtw89_h2c_ofld *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
int ret;
- if (rtwvif->net_type != RTW89_NET_TYPE_INFRA)
+ if (rtwvif_link->net_type != RTW89_NET_TYPE_INFRA)
return -EINVAL;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
@@ -3853,7 +3928,7 @@ int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
skb_put(skb, len);
h2c = (struct rtw89_h2c_ofld *)skb->data;
- h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) |
+ h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) |
le32_encode_bits(stats->tx_throughput, RTW89_H2C_OFLD_W0_TX_TP) |
le32_encode_bits(stats->rx_throughput, RTW89_H2C_OFLD_W0_RX_TP);
@@ -4688,6 +4763,7 @@ int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
return 0;
}
+static
int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num,
struct list_head *chan_list)
{
@@ -4759,8 +4835,10 @@ int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num,
return 0;
}
+static
int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
- struct list_head *chan_list)
+ struct list_head *chan_list,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
struct rtw89_h2c_chinfo_elem_be *elem;
@@ -4785,7 +4863,8 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
h2c->ch_num = ch_num;
h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */
- h2c->arg = u8_encode_bits(RTW89_PHY_0, RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK);
+ h2c->arg = u8_encode_bits(rtwvif_link->mac_idx,
+ RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK);
list_for_each_entry(ch_info, chan_list, list) {
elem = (struct rtw89_h2c_chinfo_elem_be *)skb_put(skb, sizeof(*elem));
@@ -4858,7 +4937,7 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
#define RTW89_SCAN_DELAY_TSF_UNIT 104800
int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *option,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
bool wowlan)
{
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
@@ -4880,7 +4959,7 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
h2c = (struct rtw89_h2c_scanofld *)skb->data;
if (option->delay) {
- ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif, &tsf);
+ ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
if (ret) {
rtw89_warn(rtwdev, "NLO failed to get port tsf: %d\n", ret);
scan_mode = RTW89_SCAN_IMMEDIATE;
@@ -4890,9 +4969,9 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
}
}
- h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) |
- le32_encode_bits(rtwvif->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) |
- le32_encode_bits(RTW89_PHY_0, RTW89_H2C_SCANOFLD_W0_BAND) |
+ h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) |
+ le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) |
+ le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_SCANOFLD_W0_BAND) |
le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION);
h2c->w1 = le32_encode_bits(true, RTW89_H2C_SCANOFLD_W1_NOTIFY_END) |
@@ -4963,9 +5042,10 @@ static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev,
int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *option,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
bool wowlan)
{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
struct cfg80211_scan_request *req = rtwvif->scan_req;
@@ -5016,8 +5096,8 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_BE_W0_REPEAT) |
le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_NOTIFY_END) |
le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_LEARN_CH) |
- le32_encode_bits(rtwvif->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) |
- le32_encode_bits(rtwvif->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) |
+ le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) |
+ le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) |
le32_encode_bits(option->band, RTW89_H2C_SCANOFLD_BE_W0_BAND);
h2c->w1 = le32_encode_bits(option->num_macc_role, RTW89_H2C_SCANOFLD_BE_W1_NUM_MACC_ROLE) |
@@ -5082,11 +5162,11 @@ flex_member:
for (i = 0; i < option->num_opch; i++) {
opch = ptr;
- opch->w0 = le32_encode_bits(rtwvif->mac_id,
+ opch->w0 = le32_encode_bits(rtwvif_link->mac_id,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID) |
le32_encode_bits(option->band,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_BAND) |
- le32_encode_bits(rtwvif->port,
+ le32_encode_bits(rtwvif_link->port,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT) |
le32_encode_bits(RTW89_SCAN_OPMODE_INTV,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY) |
@@ -5518,30 +5598,44 @@ fail:
}
int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
- const struct rtw89_chan *chan)
+ const struct rtw89_chan *chan, bool is_chl_k)
{
+ struct rtw89_h2c_rf_rxdck_v0 *v0;
struct rtw89_h2c_rf_rxdck *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
+ int ver = -1;
int ret;
+ if (RTW89_CHK_FW_FEATURE(RFK_RXDCK_V0, &rtwdev->fw)) {
+ len = sizeof(*v0);
+ ver = 0;
+ }
+
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c RF RXDCK\n");
return -ENOMEM;
}
skb_put(skb, len);
- h2c = (struct rtw89_h2c_rf_rxdck *)skb->data;
+ v0 = (struct rtw89_h2c_rf_rxdck_v0 *)skb->data;
+
+ v0->len = len;
+ v0->phy = phy_idx;
+ v0->is_afe = false;
+ v0->kpath = RF_AB;
+ v0->cur_band = chan->band_type;
+ v0->cur_bw = chan->band_width;
+ v0->cur_ch = chan->channel;
+ v0->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK);
+
+ if (ver == 0)
+ goto hdr;
- h2c->len = len;
- h2c->phy = phy_idx;
- h2c->is_afe = false;
- h2c->kpath = RF_AB;
- h2c->cur_band = chan->band_type;
- h2c->cur_bw = chan->band_width;
- h2c->cur_ch = chan->channel;
- h2c->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK);
+ h2c = (struct rtw89_h2c_rf_rxdck *)skb->data;
+ h2c->is_chl_k = is_chl_k;
+hdr:
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
H2C_FUNC_RFK_RXDCK_OFFLOAD, 0, 0, len);
@@ -5871,12 +5965,10 @@ static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev)
}
static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct cfg80211_scan_request *req,
struct rtw89_pktofld_info *info,
enum nl80211_band band, u8 ssid_idx)
{
- struct cfg80211_scan_request *req = rtwvif->scan_req;
-
if (band != NL80211_BAND_6GHZ)
return false;
@@ -5892,11 +5984,13 @@ static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev,
}
static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct sk_buff *skb, u8 ssid_idx)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
+ struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_pktofld_info *info;
struct sk_buff *new;
int ret = 0;
@@ -5921,8 +6015,7 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
goto out;
}
- rtw89_is_6ghz_wildcard_probe_req(rtwdev, rtwvif, info, band,
- ssid_idx);
+ rtw89_is_6ghz_wildcard_probe_req(rtwdev, req, info, band, ssid_idx);
ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new);
if (ret) {
@@ -5939,22 +6032,23 @@ out:
}
static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct sk_buff *skb;
u8 num = req->n_ssids, i;
int ret;
for (i = 0; i < num; i++) {
- skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
+ skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr,
req->ssids[i].ssid,
req->ssids[i].ssid_len,
req->ie_len);
if (!skb)
return -ENOMEM;
- ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb, i);
+ ret = rtw89_append_probe_req_ie(rtwdev, rtwvif_link, skb, i);
kfree_skb(skb);
if (ret)
@@ -5965,13 +6059,12 @@ static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
}
static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev,
+ struct ieee80211_scan_ies *ies,
struct cfg80211_scan_request *req,
struct rtw89_mac_chinfo *ch_info)
{
- struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
- struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
struct cfg80211_scan_6ghz_params *params;
struct rtw89_pktofld_info *info, *tmp;
struct ieee80211_hdr *hdr;
@@ -6000,8 +6093,11 @@ static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev,
if (found)
continue;
- skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
+ skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr,
NULL, 0, req->ie_len);
+ if (!skb)
+ return -ENOMEM;
+
skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]);
skb_put_data(skb, ies->common_ies, ies->common_ie_len);
hdr = (struct ieee80211_hdr *)skb->data;
@@ -6090,8 +6186,9 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
struct rtw89_mac_chinfo *ch_info)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
- struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
struct rtw89_pktofld_info *info;
@@ -6117,7 +6214,7 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
}
}
- ret = rtw89_update_6ghz_rnr_chan(rtwdev, req, ch_info);
+ ret = rtw89_update_6ghz_rnr_chan(rtwdev, ies, req, ch_info);
if (ret)
rtw89_warn(rtwdev, "RNR fails: %d\n", ret);
@@ -6207,8 +6304,8 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
struct rtw89_mac_chinfo_be *ch_info)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
- struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_pktofld_info *info;
u8 band, probe_count = 0, i;
@@ -6265,7 +6362,7 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
}
int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
@@ -6315,8 +6412,9 @@ out:
}
int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected)
+ struct rtw89_vif_link *rtwvif_link, bool connected)
{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_mac_chinfo *ch_info, *tmp;
struct ieee80211_channel *channel;
@@ -6392,7 +6490,7 @@ out:
}
int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
@@ -6432,7 +6530,8 @@ int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
list_add_tail(&ch_info->list, &chan_list);
}
- ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list);
+ ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list,
+ rtwvif_link);
out:
list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
@@ -6444,8 +6543,9 @@ out:
}
int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected)
+ struct rtw89_vif_link *rtwvif_link, bool connected)
{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_mac_chinfo_be *ch_info, *tmp;
struct ieee80211_channel *channel;
@@ -6491,7 +6591,8 @@ int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
}
rtwdev->scan_info.last_chan_idx = idx;
- ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list);
+ ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list,
+ rtwvif_link);
out:
list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
@@ -6503,79 +6604,86 @@ out:
}
static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected)
+ struct rtw89_vif_link *rtwvif_link, bool connected)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
int ret;
- ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif);
+ ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif_link);
if (ret) {
rtw89_err(rtwdev, "Update probe request failed\n");
goto out;
}
- ret = mac->add_chan_list(rtwdev, rtwvif, connected);
+ ret = mac->add_chan_list(rtwdev, rtwvif_link, connected);
out:
return ret;
}
-void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+void rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
struct ieee80211_scan_request *scan_req)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct cfg80211_scan_request *req = &scan_req->req;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif_link->chanctx_idx);
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
u32 rx_fltr = rtwdev->hal.rx_fltr;
u8 mac_addr[ETH_ALEN];
+ u32 reg;
+
+ /* clone op and keep it during scan */
+ rtwdev->scan_info.op_chan = *chan;
- rtw89_get_channel(rtwdev, rtwvif, &rtwdev->scan_info.op_chan);
- rtwdev->scan_info.scanning_vif = vif;
+ rtwdev->scan_info.scanning_vif = rtwvif_link;
rtwdev->scan_info.last_chan_idx = 0;
rtwdev->scan_info.abort = false;
rtwvif->scan_ies = &scan_req->ies;
rtwvif->scan_req = req;
ieee80211_stop_queues(rtwdev->hw);
- rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, false);
+ rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, false);
if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
get_random_mask_addr(mac_addr, req->mac_addr,
req->mac_addr_mask);
else
- ether_addr_copy(mac_addr, vif->addr);
- rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true);
+ ether_addr_copy(mac_addr, rtwvif_link->mac_addr);
+ rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, true);
rx_fltr &= ~B_AX_A_BCN_CHK_EN;
rx_fltr &= ~B_AX_A_BC;
rx_fltr &= ~B_AX_A_A1_MATCH;
- rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
- B_AX_RX_FLTR_CFG_MASK,
- rx_fltr);
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr);
rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_HW_SCAN);
}
-void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool aborted)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
struct cfg80211_scan_info info = {
.aborted = aborted,
};
+ struct rtw89_vif *rtwvif;
+ u32 reg;
- if (!vif)
+ if (!rtwvif_link)
return;
- rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
- B_AX_RX_FLTR_CFG_MASK,
- rtwdev->hal.rx_fltr);
+ rtwvif = rtwvif_link->rtwvif;
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr);
- rtw89_core_scan_complete(rtwdev, vif, true);
+ rtw89_core_scan_complete(rtwdev, rtwvif_link, true);
ieee80211_scan_completed(rtwdev->hw, &info);
ieee80211_wake_queues(rtwdev->hw);
- rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, true);
+ rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true);
rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
rtw89_release_pkt_list(rtwdev);
@@ -6588,14 +6696,15 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
rtw89_chanctx_proceed(rtwdev);
}
-void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
int ret;
scan_info->abort = true;
- ret = rtw89_hw_scan_offload(rtwdev, vif, false);
+ ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, false);
if (ret)
rtw89_warn(rtwdev, "rtw89_hw_scan_offload failed ret %d\n", ret);
@@ -6604,40 +6713,43 @@ void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
* RTW89_SCAN_END_SCAN_NOTIFY, so that ieee80211_stop() can flush scan
* work properly.
*/
- rtw89_hw_scan_complete(rtwdev, vif, true);
+ rtw89_hw_scan_complete(rtwdev, rtwvif_link, true);
}
static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- /* This variable implies connected or during attempt to connect */
- if (!is_zero_ether_addr(rtwvif->bssid))
- return true;
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ /* This variable implies connected or during attempt to connect */
+ if (!is_zero_ether_addr(rtwvif_link->bssid))
+ return true;
+ }
}
return false;
}
-int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool enable)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_scan_option opt = {0};
- struct rtw89_vif *rtwvif;
bool connected;
int ret = 0;
- rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
- if (!rtwvif)
+ if (!rtwvif_link)
return -EINVAL;
connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
opt.enable = enable;
opt.target_ch_mode = connected;
if (enable) {
- ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif, connected);
+ ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif_link, connected);
if (ret)
goto out;
}
@@ -6645,14 +6757,14 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP;
opt.scan_mode = RTW89_SCAN_MODE_SA;
- opt.band = RTW89_PHY_0;
+ opt.band = rtwvif_link->mac_idx;
opt.num_macc_role = 0;
opt.mlo_mode = rtwdev->mlo_dbcc_mode;
opt.num_opch = connected ? 1 : 0;
opt.opch_end = connected ? 0 : RTW89_CHAN_INVALID;
}
- ret = mac->scan_offload(rtwdev, &opt, rtwvif, false);
+ ret = mac->scan_offload(rtwdev, &opt, rtwvif_link, false);
out:
return ret;
}
@@ -6758,7 +6870,7 @@ fail:
}
#define H2C_KEEP_ALIVE_LEN 4
-int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable)
{
struct sk_buff *skb;
@@ -6766,7 +6878,7 @@ int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
int ret;
if (enable) {
- ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_NULL_DATA,
&pkt_id);
if (ret)
@@ -6784,7 +6896,7 @@ int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable);
RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id);
RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5);
- RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif->mac_id);
+ RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif_link->mac_id);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
@@ -6806,7 +6918,7 @@ fail:
return ret;
}
-int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable)
{
struct rtw89_h2c_arp_offload *h2c;
@@ -6816,7 +6928,7 @@ int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
int ret;
if (enable) {
- ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_ARP_RSP,
&pkt_id);
if (ret)
@@ -6834,7 +6946,7 @@ int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
h2c->w0 = le32_encode_bits(enable, RTW89_H2C_ARP_OFFLOAD_W0_ENABLE) |
le32_encode_bits(0, RTW89_H2C_ARP_OFFLOAD_W0_ACTION) |
- le32_encode_bits(rtwvif->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) |
+ le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) |
le32_encode_bits(pkt_id, RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -6859,11 +6971,11 @@ fail:
#define H2C_DISCONNECT_DETECT_LEN 8
int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable)
+ struct rtw89_vif_link *rtwvif_link, bool enable)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct sk_buff *skb;
- u8 macid = rtwvif->mac_id;
+ u8 macid = rtwvif_link->mac_id;
int ret;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN);
@@ -6902,7 +7014,7 @@ fail:
return ret;
}
-int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
@@ -6923,7 +7035,7 @@ int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
h2c->w0 = le32_encode_bits(enable, RTW89_H2C_NLO_W0_ENABLE) |
le32_encode_bits(enable, RTW89_H2C_NLO_W0_IGNORE_CIPHER) |
- le32_encode_bits(rtwvif->mac_id, RTW89_H2C_NLO_W0_MACID);
+ le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_NLO_W0_MACID);
if (enable) {
h2c->nlo_cnt = nd_config->n_match_sets;
@@ -6953,12 +7065,12 @@ fail:
return ret;
}
-int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_h2c_wow_global *h2c;
- u8 macid = rtwvif->mac_id;
+ u8 macid = rtwvif_link->mac_id;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
int ret;
@@ -7002,12 +7114,12 @@ fail:
#define H2C_WAKEUP_CTRL_LEN 4
int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
bool enable)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct sk_buff *skb;
- u8 macid = rtwvif->mac_id;
+ u8 macid = rtwvif_link->mac_id;
int ret;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN);
@@ -7100,13 +7212,13 @@ fail:
}
int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
bool enable)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
struct rtw89_h2c_wow_gtk_ofld *h2c;
- u8 macid = rtwvif->mac_id;
+ u8 macid = rtwvif_link->mac_id;
u32 len = sizeof(*h2c);
u8 pkt_id_sa_query = 0;
struct sk_buff *skb;
@@ -7128,14 +7240,14 @@ int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev,
if (!enable)
goto hdr;
- ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_EAPOL_KEY,
&pkt_id_eapol);
if (ret)
goto fail;
if (gtk_info->igtk_keyid) {
- ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_SA_QUERY,
&pkt_id_sa_query);
if (ret)
@@ -7173,7 +7285,7 @@ fail:
return ret;
}
-int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable)
{
struct rtw89_wait_info *wait = &rtwdev->mac.ps_wait;
@@ -7189,7 +7301,7 @@ int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
skb_put(skb, len);
h2c = (struct rtw89_h2c_fwips *)skb->data;
- h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_FW_IPS_W0_MACID) |
+ h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_FW_IPS_W0_MACID) |
le32_encode_bits(enable, RTW89_H2C_FW_IPS_W0_ENABLE);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index ad47e77d740b..d338c3aec725 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -4286,7 +4286,7 @@ struct rtw89_h2c_rf_dack {
__le32 type;
} __packed;
-struct rtw89_h2c_rf_rxdck {
+struct rtw89_h2c_rf_rxdck_v0 {
u8 len;
u8 phy;
u8 is_afe;
@@ -4297,6 +4297,11 @@ struct rtw89_h2c_rf_rxdck {
u8 rxdck_dbg_en;
} __packed;
+struct rtw89_h2c_rf_rxdck {
+ struct rtw89_h2c_rf_rxdck_v0 v0;
+ u8 is_chl_k;
+} __packed;
+
enum rtw89_rf_log_type {
RTW89_RF_RUN_LOG = 0,
RTW89_RF_RPT_LOG = 1,
@@ -4313,6 +4318,42 @@ struct rtw89_c2h_rf_run_log {
__le32 arg[4];
} __packed;
+struct rtw89_c2h_rf_iqk_rpt_log {
+ bool iqk_tx_fail[2];
+ bool iqk_rx_fail[2];
+ bool is_iqk_init;
+ bool is_reload;
+ bool is_wb_txiqk[2];
+ bool is_wb_rxiqk[2];
+ bool is_nbiqk;
+ bool txiqk_en;
+ bool rxiqk_en;
+ bool lok_en;
+ bool iqk_xym_en;
+ bool iqk_sram_en;
+ bool iqk_fft_en;
+ bool is_fw_iqk;
+ bool is_iqk_enable;
+ bool iqk_cfir_en;
+ bool thermal_rek_en;
+ u8 iqk_band[2];
+ u8 iqk_ch[2];
+ u8 iqk_bw[2];
+ u8 iqk_times;
+ u8 version;
+ u8 phy;
+ u8 fwk_status;
+ u8 rsvd;
+ __le32 reload_cnt;
+ __le32 iqk_fail_cnt;
+ __le32 lok_idac[2];
+ __le32 lok_vbuf[2];
+ __le32 rftxgain[2][4];
+ __le32 rfrxgain[2][4];
+ __le32 tx_xym[2][4];
+ __le32 rx_xym[2][4];
+} __packed;
+
struct rtw89_c2h_rf_dpk_rpt_log {
u8 ver;
u8 idx[2];
@@ -4334,19 +4375,25 @@ struct rtw89_c2h_rf_dpk_rpt_log {
struct rtw89_c2h_rf_dack_rpt_log {
u8 fwdack_ver;
- u8 fwdack_rpt_ver;
+ u8 fwdack_info_ver;
u8 msbk_d[2][2][16];
u8 dadck_d[2][2];
u8 cdack_d[2][2][2];
- __le16 addck2_d[2][2][2];
+ u8 addck2_hd[2][2][2];
+ u8 addck2_ld[2][2][2];
u8 adgaink_d[2][2];
- __le16 biask_d[2][2];
+ u8 biask_hd[2][2];
+ u8 biask_ld[2][2];
u8 addck_timeout;
u8 cdack_timeout;
u8 dadck_timeout;
u8 msbk_timeout;
u8 adgaink_timeout;
+ u8 wbadcdck_timeout;
+ u8 drck_timeout;
u8 dack_fail;
+ u8 wbdck_d[2];
+ u8 rck_d;
} __packed;
struct rtw89_c2h_rf_rxdck_rpt_log {
@@ -4357,6 +4404,14 @@ struct rtw89_c2h_rf_rxdck_rpt_log {
u8 timeout[2];
} __packed;
+struct rtw89_c2h_rf_tssi_rpt_log {
+ s8 alignment_power[2][2][4];
+ u8 alignment_power_cw_h[2][2][4];
+ u8 alignment_power_cw_l[2][2][4];
+ u8 tssi_alimk_state[2][2];
+ u8 default_txagc_offset[2][2];
+} __packed;
+
struct rtw89_c2h_rf_txgapk_rpt_log {
__le32 r0x8010[2];
__le32 chk_cnt;
@@ -4404,59 +4459,59 @@ void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u8 type, u8 cat, u8 class, u8 func,
bool rack, bool dack, u32 len);
int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta);
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta);
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
+ struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
-int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *vif,
- struct rtw89_sta *rtwsta, const u8 *scan_mac_addr);
+ struct rtw89_vif_link *rtwvif_link);
+int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif,
+ struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr);
int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h);
void rtw89_fw_c2h_work(struct work_struct *work);
int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
enum rtw89_upd_mode upd_mode);
-int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, bool dis_conn);
+int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link, bool dis_conn);
int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en);
int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
bool pause);
-int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 ac, u32 val);
int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
+ struct rtw89_vif_link *rtwvif_link,
bool connect);
int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu);
-int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi);
int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev *rtwdev, u8 type);
@@ -4472,17 +4527,13 @@ int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id);
int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
struct sk_buff *skb_ofld);
-int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num,
- struct list_head *chan_list);
-int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
- struct list_head *chan_list);
int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *opt,
- struct rtw89_vif *vif,
+ struct rtw89_vif_link *vif,
bool wowlan);
int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *opt,
- struct rtw89_vif *vif,
+ struct rtw89_vif_link *vif,
bool wowlan);
int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
struct rtw89_fw_h2c_rf_reg_info *info,
@@ -4501,21 +4552,26 @@ int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan);
int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
- const struct rtw89_chan *chan);
+ const struct rtw89_chan *chan, bool is_chl_k);
int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
bool rack, bool dack);
int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len);
void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev);
void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev);
-int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 macid);
void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool notify_fw);
+ struct rtw89_vif_link *rtwvif_link,
+ bool notify_fw);
void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw);
-int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params);
-int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params);
void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users,
@@ -4524,8 +4580,8 @@ int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users,
int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
struct rtw89_lps_parm *lps_param);
int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
-int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link);
+int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len);
struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len);
@@ -4534,49 +4590,56 @@ int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
struct rtw89_mac_c2h_info *c2h_info);
int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable);
void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev);
-void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_scan_request *req);
-void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+void rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_scan_request *scan_req);
+void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool aborted);
-int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool enable);
-void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
+void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected);
+ struct rtw89_vif_link *rtwvif_link, bool connected);
int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
+ struct rtw89_vif_link *rtwvif_link);
int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected);
+ struct rtw89_vif_link *rtwvif_link, bool connected);
int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
+ struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev,
const struct rtw89_pkt_drop_params *params);
-int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf,
struct ieee80211_p2p_noa_desc *desc,
u8 act, u8 noa_id);
-int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool en);
-int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable);
-int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link, bool enable);
+int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
-int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable);
+ struct rtw89_vif_link *rtwvif_link, bool enable);
int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable);
-int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link, bool enable);
+int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable);
+ struct rtw89_vif_link *rtwvif_link, bool enable);
int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev,
struct rtw89_wow_cam_info *cam_info);
int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev,
@@ -4621,51 +4684,73 @@ static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev)
}
static inline int rtw89_chip_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif, rtwsta);
+ return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
}
static inline int rtw89_chip_h2c_default_dmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->h2c_default_dmac_tbl)
- return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif, rtwsta);
+ return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
return 0;
}
static inline int rtw89_chip_h2c_update_beacon(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- return chip->ops->h2c_update_beacon(rtwdev, rtwvif);
+ return chip->ops->h2c_update_beacon(rtwdev, rtwvif_link);
}
static inline int rtw89_chip_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- return chip->ops->h2c_assoc_cmac_tbl(rtwdev, vif, sta);
+ return chip->ops->h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
}
-static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+static inline
+int rtw89_chip_h2c_ampdu_link_cmac_tbl(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->h2c_ampdu_cmac_tbl)
- return chip->ops->h2c_ampdu_cmac_tbl(rtwdev, vif, sta);
+ return chip->ops->h2c_ampdu_cmac_tbl(rtwdev, rtwvif_link,
+ rtwsta_link);
+
+ return 0;
+}
+
+static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif,
+ struct rtw89_sta *rtwsta)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = rtw89_chip_h2c_ampdu_link_cmac_tbl(rtwdev, rtwvif_link,
+ rtwsta_link);
+ if (ret)
+ return ret;
+ }
return 0;
}
@@ -4675,8 +4760,20 @@ int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
bool valid, struct ieee80211_ampdu_params *params)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = chip->ops->h2c_ba_cam(rtwdev, rtwvif_link, rtwsta_link,
+ valid, params);
+ if (ret)
+ return ret;
+ }
- return chip->ops->h2c_ba_cam(rtwdev, rtwsta, valid, params);
+ return 0;
}
/* must consider compatibility; don't insert new in the mid */
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index c70a23a763b0..e09f926bb4a0 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -1483,7 +1483,8 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags);
clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_PWR_MAJOR);
- rtw89_set_entity_state(rtwdev, false);
+ rtw89_set_entity_state(rtwdev, RTW89_PHY_0, false);
+ rtw89_set_entity_state(rtwdev, RTW89_PHY_1, false);
}
return 0;
@@ -4076,17 +4077,17 @@ static const struct rtw89_port_reg rtw89_port_base_ax = {
};
static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u8 type)
+ struct rtw89_vif_link *rtwvif_link, u8 type)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif->port);
+ u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif_link->port);
u32 reg_info, reg_ctrl;
u32 val;
int ret;
- reg_info = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg_info, rtwvif->mac_idx);
- reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg, rtwvif->mac_idx);
+ reg_info = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg_info, rtwvif_link->mac_idx);
+ reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg_ctrl, B_AX_PTCL_DBG_SEL_MASK, type);
rtw89_write32_set(rtwdev, reg_ctrl, B_AX_PTCL_DBG_EN);
@@ -4098,26 +4099,32 @@ static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev,
rtw89_warn(rtwdev, "Polling beacon packet empty fail\n");
}
-static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_set(rtwdev, p->bcn_drop_all, BIT(rtwvif->port));
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK, 1);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area, B_AX_BCN_MSK_AREA_MASK, 0);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 0);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK, 2);
- rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK, 1);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK, 1);
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
-
- rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM0);
- if (rtwvif->port == RTW89_PORT_0)
- rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM1);
-
- rtw89_write32_clr(rtwdev, p->bcn_drop_all, BIT(rtwvif->port));
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TBTT_PROHIB_EN);
+ rtw89_write32_set(rtwdev, p->bcn_drop_all, BIT(rtwvif_link->port));
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK,
+ 1);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_area, B_AX_BCN_MSK_AREA_MASK,
+ 0);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK,
+ 0);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_early, B_AX_BCNERLY_MASK, 2);
+ rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_early,
+ B_AX_TBTTERLY_MASK, 1);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space,
+ B_AX_BCN_SPACE_MASK, 1);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN);
+
+ rtw89_mac_check_packet_ctrl(rtwdev, rtwvif_link, AX_PTCL_DBG_BCNQ_NUM0);
+ if (rtwvif_link->port == RTW89_PORT_0)
+ rtw89_mac_check_packet_ctrl(rtwdev, rtwvif_link, AX_PTCL_DBG_BCNQ_NUM1);
+
+ rtw89_write32_clr(rtwdev, p->bcn_drop_all, BIT(rtwvif_link->port));
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_TBTT_PROHIB_EN);
fsleep(2000);
}
@@ -4131,286 +4138,329 @@ static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvi
#define BCN_ERLY_SET_DLY (10 * 2)
static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct ieee80211_bss_conf *bss_conf;
bool need_backup = false;
u32 backup_val;
+ u16 beacon_int;
- if (!rtw89_read32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN))
+ if (!rtw89_read32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN))
return;
- if (chip->chip_id == RTL8852A && rtwvif->port != RTW89_PORT_0) {
+ if (chip->chip_id == RTL8852A && rtwvif_link->port != RTW89_PORT_0) {
need_backup = true;
- backup_val = rtw89_read32_port(rtwdev, rtwvif, p->tbtt_prohib);
+ backup_val = rtw89_read32_port(rtwdev, rtwvif_link, p->tbtt_prohib);
}
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
- rtw89_mac_bcn_drop(rtwdev, rtwvif);
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
+ rtw89_mac_bcn_drop(rtwdev, rtwvif_link);
if (chip->chip_id == RTL8852A) {
- rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1);
- rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK);
- rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->tbtt_prohib,
+ B_AX_TBTT_SETUP_MASK);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib,
+ B_AX_TBTT_HOLD_MASK, 1);
+ rtw89_write16_port_clr(rtwdev, rtwvif_link, p->tbtt_early,
+ B_AX_TBTTERLY_MASK);
+ rtw89_write16_port_clr(rtwdev, rtwvif_link, p->bcn_early,
+ B_AX_BCNERLY_MASK);
}
- msleep(vif->bss_conf.beacon_int + 1);
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN |
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ beacon_int = bss_conf->beacon_int;
+
+ rcu_read_unlock();
+
+ msleep(beacon_int + 1);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN |
B_AX_BRK_SETUP);
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSFTR_RST);
- rtw89_write32_port(rtwdev, rtwvif, p->bcn_cnt_tmr, 0);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSFTR_RST);
+ rtw89_write32_port(rtwdev, rtwvif_link, p->bcn_cnt_tmr, 0);
if (need_backup)
- rtw89_write32_port(rtwdev, rtwvif, p->tbtt_prohib, backup_val);
+ rtw89_write32_port(rtwdev, rtwvif_link, p->tbtt_prohib, backup_val);
}
static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en)
+ struct rtw89_vif_link *rtwvif_link, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg,
+ B_AX_TXBCN_RPT_EN);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg,
+ B_AX_TXBCN_RPT_EN);
}
static void rtw89_mac_port_cfg_rx_rpt(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en)
+ struct rtw89_vif_link *rtwvif_link, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg,
+ B_AX_RXBCN_RPT_EN);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg,
+ B_AX_RXBCN_RPT_EN);
}
static void rtw89_mac_port_cfg_net_type(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_NET_TYPE_MASK,
- rtwvif->net_type);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_NET_TYPE_MASK,
+ rtwvif_link->net_type);
}
static void rtw89_mac_port_cfg_bcn_prct(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- bool en = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK;
+ bool en = rtwvif_link->net_type != RTW89_NET_TYPE_NO_LINK;
u32 bits = B_AX_TBTT_PROHIB_EN | B_AX_BRK_SETUP;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bits);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, bits);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bits);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, bits);
}
static void rtw89_mac_port_cfg_rx_sw(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA ||
- rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
+ bool en = rtwvif_link->net_type == RTW89_NET_TYPE_INFRA ||
+ rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC;
u32 bit = B_AX_RX_BSSID_FIT_EN;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bit);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, bit);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bit);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, bit);
}
void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en)
+ struct rtw89_vif_link *rtwvif_link, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSF_UDT_EN);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSF_UDT_EN);
}
static void rtw89_mac_port_cfg_rx_sync_by_nettype(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
- bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA ||
- rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
+ bool en = rtwvif_link->net_type == RTW89_NET_TYPE_INFRA ||
+ rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC;
- rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, en);
+ rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, en);
}
static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en)
+ struct rtw89_vif_link *rtwvif_link, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN);
}
static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
- bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ||
- rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
+ bool en = rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE ||
+ rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC;
- rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en);
+ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en);
}
void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
- rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
+ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en);
}
static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- u16 bcn_int = vif->bss_conf.beacon_int ? vif->bss_conf.beacon_int : BCN_INTERVAL;
+ struct ieee80211_bss_conf *bss_conf;
+ u16 bcn_int;
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ if (bss_conf->beacon_int)
+ bcn_int = bss_conf->beacon_int;
+ else
+ bcn_int = BCN_INTERVAL;
+
+ rcu_read_unlock();
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK,
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space, B_AX_BCN_SPACE_MASK,
bcn_int);
}
static void rtw89_mac_port_cfg_hiq_win(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
- u8 win = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ? 16 : 0;
+ u8 win = rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE ? 16 : 0;
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
u32 reg;
- reg = rtw89_mac_reg_by_idx(rtwdev, p->hiq_win[port], rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, p->hiq_win[port], rtwvif_link->mac_idx);
rtw89_write8(rtwdev, reg, win);
}
static void rtw89_mac_port_cfg_hiq_dtim(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_bss_conf *bss_conf;
+ u8 dtim_period;
u32 addr;
- addr = rtw89_mac_reg_by_idx(rtwdev, p->md_tsft, rtwvif->mac_idx);
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ dtim_period = bss_conf->dtim_period;
+
+ rcu_read_unlock();
+
+ addr = rtw89_mac_reg_by_idx(rtwdev, p->md_tsft, rtwvif_link->mac_idx);
rtw89_write8_set(rtwdev, addr, B_AX_UPD_HGQMD | B_AX_UPD_TIMIE);
- rtw89_write16_port_mask(rtwdev, rtwvif, p->dtim_ctrl, B_AX_DTIM_NUM_MASK,
- vif->bss_conf.dtim_period);
+ rtw89_write16_port_mask(rtwdev, rtwvif_link, p->dtim_ctrl, B_AX_DTIM_NUM_MASK,
+ dtim_period);
}
static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib,
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib,
B_AX_TBTT_SETUP_MASK, BCN_SETUP_DEF);
}
static void rtw89_mac_port_cfg_bcn_hold_time(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib,
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib,
B_AX_TBTT_HOLD_MASK, BCN_HOLD_DEF);
}
static void rtw89_mac_port_cfg_bcn_mask_area(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area,
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_area,
B_AX_BCN_MSK_AREA_MASK, BCN_MASK_DEF);
}
static void rtw89_mac_port_cfg_tbtt_early(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early,
+ rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_early,
B_AX_TBTTERLY_MASK, TBTT_ERLY_DEF);
}
static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
static const u32 masks[RTW89_PORT_NUM] = {
B_AX_BSS_COLOB_AX_PORT_0_MASK, B_AX_BSS_COLOB_AX_PORT_1_MASK,
B_AX_BSS_COLOB_AX_PORT_2_MASK, B_AX_BSS_COLOB_AX_PORT_3_MASK,
B_AX_BSS_COLOB_AX_PORT_4_MASK,
};
- u8 port = rtwvif->port;
+ struct ieee80211_bss_conf *bss_conf;
+ u8 port = rtwvif_link->port;
u32 reg_base;
u32 reg;
u8 bss_color;
- bss_color = vif->bss_conf.he_bss_color.color;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ bss_color = bss_conf->he_bss_color.color;
+
+ rcu_read_unlock();
+
reg_base = port >= 4 ? p->bss_color + 4 : p->bss_color;
- reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, masks[port], bss_color);
}
static void rtw89_mac_port_cfg_mbssid(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
u32 reg;
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
return;
if (port == 0) {
- reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid, rtwvif_link->mac_idx);
rtw89_write32_clr(rtwdev, reg, B_AX_P0MB_ALL_MASK);
}
}
static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
u32 reg;
u32 val;
- reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid_drop, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid_drop, rtwvif_link->mac_idx);
val = rtw89_read32(rtwdev, reg);
val &= ~FIELD_PREP(B_AX_PORT_DROP_4_0_MASK, BIT(port));
if (port == 0)
@@ -4419,31 +4469,31 @@ static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev,
}
static void rtw89_mac_port_cfg_func_en(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable)
+ struct rtw89_vif_link *rtwvif_link, bool enable)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
if (enable)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg,
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg,
B_AX_PORT_FUNC_EN);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg,
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg,
B_AX_PORT_FUNC_EN);
}
static void rtw89_mac_port_cfg_bcn_early(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK,
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_early, B_AX_BCNERLY_MASK,
BCN_ERLY_DEF);
}
static void rtw89_mac_port_cfg_tbtt_shift(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
@@ -4452,20 +4502,20 @@ static void rtw89_mac_port_cfg_tbtt_shift(struct rtw89_dev *rtwdev,
if (rtwdev->chip->chip_id != RTL8852C)
return;
- if (rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT &&
- rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION)
+ if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT &&
+ rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION)
return;
val = FIELD_PREP(B_AX_TBTT_SHIFT_OFST_MAG, 1) |
B_AX_TBTT_SHIFT_OFST_SIGN;
- rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_shift,
+ rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_shift,
B_AX_TBTT_SHIFT_OFST_MASK, val);
}
void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_vif *rtwvif_src,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_vif_link *rtwvif_src,
u16 offset_tu)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
@@ -4473,8 +4523,8 @@ void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
u32 val, reg;
val = RTW89_PORT_OFFSET_TU_TO_32US(offset_tu);
- reg = rtw89_mac_reg_by_idx(rtwdev, p->tsf_sync + rtwvif->port * 4,
- rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, p->tsf_sync + rtwvif_link->port * 4,
+ rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port);
rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_OFFSET_VAL, val);
@@ -4482,16 +4532,16 @@ void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
}
static void rtw89_mac_port_tsf_sync_rand(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_vif *rtwvif_src,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_vif_link *rtwvif_src,
u8 offset, int *n_offset)
{
- if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif == rtwvif_src)
+ if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif_link == rtwvif_src)
return;
/* adjust offset randomly to avoid beacon conflict */
offset = offset - offset / 4 + get_random_u32() % (offset / 2);
- rtw89_mac_port_tsf_sync(rtwdev, rtwvif, rtwvif_src,
+ rtw89_mac_port_tsf_sync(rtwdev, rtwvif_link, rtwvif_src,
(*n_offset) * offset);
(*n_offset)++;
@@ -4499,15 +4549,19 @@ static void rtw89_mac_port_tsf_sync_rand(struct rtw89_dev *rtwdev,
static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev)
{
- struct rtw89_vif *src = NULL, *tmp;
+ struct rtw89_vif_link *src = NULL, *tmp;
u8 offset = 100, vif_aps = 0;
+ struct rtw89_vif *rtwvif;
+ unsigned int link_id;
int n_offset = 1;
- rtw89_for_each_rtwvif(rtwdev, tmp) {
- if (!src || tmp->net_type == RTW89_NET_TYPE_INFRA)
- src = tmp;
- if (tmp->net_type == RTW89_NET_TYPE_AP_MODE)
- vif_aps++;
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ rtw89_vif_for_each_link(rtwvif, tmp, link_id) {
+ if (!src || tmp->net_type == RTW89_NET_TYPE_INFRA)
+ src = tmp;
+ if (tmp->net_type == RTW89_NET_TYPE_AP_MODE)
+ vif_aps++;
+ }
}
if (vif_aps == 0)
@@ -4515,104 +4569,106 @@ static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev)
offset /= (vif_aps + 1);
- rtw89_for_each_rtwvif(rtwdev, tmp)
- rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset, &n_offset);
+ rtw89_for_each_rtwvif(rtwdev, rtwvif)
+ rtw89_vif_for_each_link(rtwvif, tmp, link_id)
+ rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset,
+ &n_offset);
}
-int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
int ret;
- ret = rtw89_mac_port_update(rtwdev, rtwvif);
+ ret = rtw89_mac_port_update(rtwdev, rtwvif_link);
if (ret)
return ret;
- rtw89_mac_dmac_tbl_init(rtwdev, rtwvif->mac_id);
- rtw89_mac_cmac_tbl_init(rtwdev, rtwvif->mac_id);
+ rtw89_mac_dmac_tbl_init(rtwdev, rtwvif_link->mac_id);
+ rtw89_mac_cmac_tbl_init(rtwdev, rtwvif_link->mac_id);
- ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif->mac_id, false);
+ ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif_link->mac_id, false);
if (ret)
return ret;
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_CREATE);
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_CREATE);
if (ret)
return ret;
- ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true);
if (ret)
return ret;
- ret = rtw89_cam_init(rtwdev, rtwvif);
+ ret = rtw89_cam_init(rtwdev, rtwvif_link);
if (ret)
return ret;
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
if (ret)
return ret;
- ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif, NULL);
+ ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, NULL);
if (ret)
return ret;
- ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif, NULL);
+ ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, NULL);
if (ret)
return ret;
return 0;
}
-int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
int ret;
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_REMOVE);
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_REMOVE);
if (ret)
return ret;
- rtw89_cam_deinit(rtwdev, rtwvif);
+ rtw89_cam_deinit(rtwdev, rtwvif_link);
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
if (ret)
return ret;
return 0;
}
-int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
if (port >= RTW89_PORT_NUM)
return -EINVAL;
- rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif);
- rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif, false);
- rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif, false);
- rtw89_mac_port_cfg_net_type(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif);
- rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif);
- rtw89_mac_port_cfg_rx_sync_by_nettype(rtwdev, rtwvif);
- rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif);
- rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif);
- rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif);
- rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif);
- rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif);
- rtw89_mac_port_cfg_tbtt_shift(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif);
- rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif);
- rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, true);
+ rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif_link, false);
+ rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif_link, false);
+ rtw89_mac_port_cfg_net_type(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_rx_sync_by_nettype(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_tbtt_shift(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_func_en(rtwdev, rtwvif_link, true);
rtw89_mac_port_tsf_resync_all(rtwdev);
fsleep(BCN_ERLY_SET_DLY);
- rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif);
+ rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif_link);
return 0;
}
-int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u64 *tsf)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
@@ -4620,12 +4676,12 @@ int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
u32 tsf_low, tsf_high;
int ret;
- ret = rtw89_mac_check_mac_en(rtwdev, rtwvif->mac_idx, RTW89_CMAC_SEL);
+ ret = rtw89_mac_check_mac_en(rtwdev, rtwvif_link->mac_idx, RTW89_CMAC_SEL);
if (ret)
return ret;
- tsf_low = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_l);
- tsf_high = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_h);
+ tsf_low = rtw89_read32_port(rtwdev, rtwvif_link, p->tsftr_l);
+ tsf_high = rtw89_read32_port(rtwdev, rtwvif_link, p->tsftr_h);
*tsf = (u64)tsf_high << 32 | tsf_low;
return 0;
@@ -4651,65 +4707,57 @@ static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
}
void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif)
+ struct rtw89_vif_link *rtwvif_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct ieee80211_hw *hw = rtwdev->hw;
+ struct ieee80211_bss_conf *bss_conf;
+ struct cfg80211_chan_def oper;
bool tolerated = true;
u32 reg;
- if (!vif->bss_conf.he_support || vif->type != NL80211_IFTYPE_STATION)
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ if (!bss_conf->he_support || vif->type != NL80211_IFTYPE_STATION) {
+ rcu_read_unlock();
return;
+ }
- if (!(vif->bss_conf.chanreq.oper.chan->flags & IEEE80211_CHAN_RADAR))
+ oper = bss_conf->chanreq.oper;
+ if (!(oper.chan->flags & IEEE80211_CHAN_RADAR)) {
+ rcu_read_unlock();
return;
+ }
- cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chanreq.oper,
+ rcu_read_unlock();
+
+ cfg80211_bss_iter(hw->wiphy, &oper,
rtw89_mac_check_he_obss_narrow_bw_ru_iter,
&tolerated);
reg = rtw89_mac_reg_by_idx(rtwdev, mac->narrow_bw_ru_dis.addr,
- rtwvif->mac_idx);
+ rtwvif_link->mac_idx);
if (tolerated)
rtw89_write32_clr(rtwdev, reg, mac->narrow_bw_ru_dis.mask);
else
rtw89_write32_set(rtwdev, reg, mac->narrow_bw_ru_dis.mask);
}
-void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif);
+ rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link);
}
-int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- int ret;
-
- rtwvif->mac_id = rtw89_acquire_mac_id(rtwdev);
- if (rtwvif->mac_id == RTW89_MAX_MAC_ID_NUM)
- return -ENOSPC;
-
- ret = rtw89_mac_vif_init(rtwdev, rtwvif);
- if (ret)
- goto release_mac_id;
-
- return 0;
-
-release_mac_id:
- rtw89_release_mac_id(rtwdev, rtwvif->mac_id);
-
- return ret;
+ return rtw89_mac_vif_init(rtwdev, rtwvif_link);
}
-int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- int ret;
-
- ret = rtw89_mac_vif_deinit(rtwdev, rtwvif);
- rtw89_release_mac_id(rtwdev, rtwvif->mac_id);
-
- return ret;
+ return rtw89_mac_vif_deinit(rtwdev, rtwvif_link);
}
static void
@@ -4730,8 +4778,8 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
{
const struct rtw89_c2h_scanofld *c2h =
(const struct rtw89_c2h_scanofld *)skb->data;
- struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
+ struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
+ struct rtw89_vif *rtwvif;
struct rtw89_chan new;
u8 reason, status, tx_fail, band, actual_period, expect_period;
u32 last_chan = rtwdev->scan_info.last_chan_idx, report_tsf;
@@ -4739,9 +4787,11 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u16 chan;
int ret;
- if (!rtwvif)
+ if (!rtwvif_link)
return;
+ rtwvif = rtwvif_link->rtwvif;
+
tx_fail = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_TX_FAIL);
status = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_STATUS);
chan = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_PRI_CH);
@@ -4781,28 +4831,28 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (rtwdev->scan_info.abort)
return;
- if (rtwvif && rtwvif->scan_req &&
+ if (rtwvif_link && rtwvif->scan_req &&
last_chan < rtwvif->scan_req->n_channels) {
- ret = rtw89_hw_scan_offload(rtwdev, vif, true);
+ ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true);
if (ret) {
- rtw89_hw_scan_abort(rtwdev, vif);
+ rtw89_hw_scan_abort(rtwdev, rtwvif_link);
rtw89_warn(rtwdev, "HW scan failed: %d\n", ret);
}
} else {
- rtw89_hw_scan_complete(rtwdev, vif, false);
+ rtw89_hw_scan_complete(rtwdev, rtwvif_link, false);
}
break;
case RTW89_SCAN_ENTER_OP_NOTIFY:
case RTW89_SCAN_ENTER_CH_NOTIFY:
if (rtw89_is_op_chan(rtwdev, band, chan)) {
- rtw89_assign_entity_chan(rtwdev, rtwvif->chanctx_idx,
+ rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx,
&rtwdev->scan_info.op_chan);
rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
ieee80211_wake_queues(rtwdev->hw);
} else {
rtw89_chan_create(&new, chan, chan, band,
RTW89_CHANNEL_WIDTH_20);
- rtw89_assign_entity_chan(rtwdev, rtwvif->chanctx_idx,
+ rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx,
&new);
}
break;
@@ -4812,10 +4862,11 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
}
static void
-rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
struct sk_buff *skb)
{
- struct ieee80211_vif *vif = rtwvif_to_vif_safe(rtwvif);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
enum nl80211_cqm_rssi_threshold_event nl_event;
const struct rtw89_c2h_mac_bcnfltr_rpt *c2h =
(const struct rtw89_c2h_mac_bcnfltr_rpt *)skb->data;
@@ -4827,7 +4878,7 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
event = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_EVENT);
mac_id = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MACID);
- if (mac_id != rtwvif->mac_id)
+ if (mac_id != rtwvif_link->mac_id)
return;
rtw89_debug(rtwdev, RTW89_DBG_FW,
@@ -4839,7 +4890,7 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
if (!rtwdev->scanning && !rtwvif->offchan)
ieee80211_connection_loss(vif);
else
- rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
return;
case RTW89_BCN_FLTR_NOTIFY:
nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
@@ -4863,10 +4914,13 @@ static void
rtw89_mac_c2h_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
u32 len)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif, c2h);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif_link, c2h);
}
static void
@@ -5490,7 +5544,8 @@ int rtw89_mac_cfg_ppdu_status_ax(struct rtw89_dev *rtwdev, u8 mac_idx, bool enab
return 0;
}
-void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx)
+static
+void __rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx)
{
#define MAC_AX_TIME_TH_SH 5
#define MAC_AX_LEN_TH_SH 4
@@ -5520,6 +5575,13 @@ void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx)
rtw89_write16_mask(rtwdev, reg, B_AX_RTS_LEN_TH_MASK, len_th);
}
+void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev)
+{
+ __rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
+ if (rtwdev->dbcc_en)
+ __rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_1);
+}
+
void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop)
{
bool empty;
@@ -5931,15 +5993,15 @@ static int rtw89_mac_init_bfee_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
}
static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- u8 mac_idx = rtwvif->mac_idx;
u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1;
- u8 port_sel = rtwvif->port;
+ struct ieee80211_link_sta *link_sta;
+ u8 mac_idx = rtwvif_link->mac_idx;
+ u8 port_sel = rtwvif_link->port;
u8 sound_dim = 3, t;
- u8 *phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info;
+ u8 *phy_cap;
u32 reg;
u16 val;
int ret;
@@ -5948,6 +6010,11 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev,
if (ret)
return ret;
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
+
if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
(phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) {
ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD);
@@ -5956,17 +6023,19 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev,
phy_cap[5]);
sound_dim = min(sound_dim, t);
}
- if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
- (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
- ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
- stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
+ if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
+ (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
+ ldpc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
+ stbc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
t = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
- sta->deflink.vht_cap.cap);
+ link_sta->vht_cap.cap);
sound_dim = min(sound_dim, t);
}
nc = min(nc, sound_dim);
nr = min(nr, sound_dim);
+ rcu_read_unlock();
+
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL);
@@ -5989,34 +6058,41 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev,
}
static int rtw89_mac_csi_rrsc_ax(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M);
+ struct ieee80211_link_sta *link_sta;
+ u8 mac_idx = rtwvif_link->mac_idx;
u32 reg;
- u8 mac_idx = rtwvif->mac_idx;
int ret;
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
if (ret)
return ret;
- if (sta->deflink.he_cap.has_he) {
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ if (link_sta->he_cap.has_he) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) |
BIT(RTW89_MAC_BF_RRSC_HE_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HE_MSC5));
}
- if (sta->deflink.vht_cap.vht_supported) {
+ if (link_sta->vht_cap.vht_supported) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) |
BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_VHT_MSC5));
}
- if (sta->deflink.ht_cap.ht_supported) {
+ if (link_sta->ht_cap.ht_supported) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC5));
}
+
+ rcu_read_unlock();
+
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL);
rtw89_write32_clr(rtwdev, reg, B_AX_BFMEE_CSI_FORCE_RETE_EN);
@@ -6028,35 +6104,53 @@ static int rtw89_mac_csi_rrsc_ax(struct rtw89_dev *rtwdev,
}
static void rtw89_mac_bf_assoc_ax(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct ieee80211_link_sta *link_sta;
+ bool has_beamformer_cap;
- if (rtw89_sta_has_beamformer_cap(sta)) {
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ has_beamformer_cap = rtw89_sta_has_beamformer_cap(link_sta);
+
+ rcu_read_unlock();
+
+ if (has_beamformer_cap) {
rtw89_debug(rtwdev, RTW89_DBG_BF,
"initialize bfee for new association\n");
- rtw89_mac_init_bfee_ax(rtwdev, rtwvif->mac_idx);
- rtw89_mac_set_csi_para_reg_ax(rtwdev, vif, sta);
- rtw89_mac_csi_rrsc_ax(rtwdev, vif, sta);
+ rtw89_mac_init_bfee_ax(rtwdev, rtwvif_link->mac_idx);
+ rtw89_mac_set_csi_para_reg_ax(rtwdev, rtwvif_link, rtwsta_link);
+ rtw89_mac_csi_rrsc_ax(rtwdev, rtwvif_link, rtwsta_link);
}
}
-void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
-
- rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, false);
+ rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, false);
}
void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *conf)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- u8 mac_idx = rtwvif->mac_idx;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ u8 mac_idx;
__le32 *p;
+ rtwvif_link = rtwvif->links[conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, conf->link_id);
+ return;
+ }
+
+ mac_idx = rtwvif_link->mac_idx;
+
rtw89_debug(rtwdev, RTW89_DBG_BF, "update bf GID table\n");
p = (__le32 *)conf->mu_group.membership;
@@ -6080,7 +6174,7 @@ void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *
struct rtw89_mac_bf_monitor_iter_data {
struct rtw89_dev *rtwdev;
- struct ieee80211_sta *down_sta;
+ struct rtw89_sta_link *down_rtwsta_link;
int count;
};
@@ -6089,23 +6183,41 @@ void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_mac_bf_monitor_iter_data *iter_data =
(struct rtw89_mac_bf_monitor_iter_data *)data;
- struct ieee80211_sta *down_sta = iter_data->down_sta;
+ struct rtw89_sta_link *down_rtwsta_link = iter_data->down_rtwsta_link;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct ieee80211_link_sta *link_sta;
+ struct rtw89_sta_link *rtwsta_link;
+ bool has_beamformer_cap = false;
int *count = &iter_data->count;
+ unsigned int link_id;
- if (down_sta == sta)
- return;
+ rcu_read_lock();
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ if (rtwsta_link == down_rtwsta_link)
+ continue;
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
+ if (rtw89_sta_has_beamformer_cap(link_sta)) {
+ has_beamformer_cap = true;
+ break;
+ }
+ }
- if (rtw89_sta_has_beamformer_cap(sta))
+ if (has_beamformer_cap)
(*count)++;
+
+ rcu_read_unlock();
}
void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta, bool disconnect)
+ struct rtw89_sta_link *rtwsta_link,
+ bool disconnect)
{
struct rtw89_mac_bf_monitor_iter_data data;
data.rtwdev = rtwdev;
- data.down_sta = disconnect ? sta : NULL;
+ data.down_rtwsta_link = disconnect ? rtwsta_link : NULL;
data.count = 0;
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_mac_bf_monitor_calc_iter,
@@ -6121,10 +6233,12 @@ void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev,
void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
{
struct rtw89_traffic_stats *stats = &rtwdev->stats;
- struct rtw89_vif *rtwvif;
+ struct rtw89_vif_link *rtwvif_link;
bool en = stats->tx_tfc_lv <= stats->rx_tfc_lv;
bool old = test_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags);
+ struct rtw89_vif *rtwvif;
bool keep_timer = true;
+ unsigned int link_id;
bool old_keep_timer;
old_keep_timer = test_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags);
@@ -6134,30 +6248,32 @@ void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
if (keep_timer != old_keep_timer) {
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_mac_bfee_standby_timer(rtwdev, rtwvif->mac_idx,
- keep_timer);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_mac_bfee_standby_timer(rtwdev, rtwvif_link->mac_idx,
+ keep_timer);
}
if (en == old)
return;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, en);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, en);
}
static int
-__rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+__rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
u32 tx_time)
{
#define MAC_AX_DFLT_TX_TIME 5280
- u8 mac_idx = rtwsta->rtwvif->mac_idx;
+ u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time;
u32 reg;
int ret = 0;
- if (rtwsta->cctl_tx_time) {
- rtwsta->ampdu_max_time = (max_tx_time - 512) >> 9;
- ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta);
+ if (rtwsta_link->cctl_tx_time) {
+ rtwsta_link->ampdu_max_time = (max_tx_time - 512) >> 9;
+ ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
} else {
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
if (ret) {
@@ -6173,31 +6289,31 @@ __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
return ret;
}
-int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
bool resume, u32 tx_time)
{
int ret = 0;
if (!resume) {
- rtwsta->cctl_tx_time = true;
- ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time);
+ rtwsta_link->cctl_tx_time = true;
+ ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta_link, tx_time);
} else {
- ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time);
- rtwsta->cctl_tx_time = false;
+ ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta_link, tx_time);
+ rtwsta_link->cctl_tx_time = false;
}
return ret;
}
-int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
u32 *tx_time)
{
- u8 mac_idx = rtwsta->rtwvif->mac_idx;
+ u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
u32 reg;
int ret = 0;
- if (rtwsta->cctl_tx_time) {
- *tx_time = (rtwsta->ampdu_max_time + 1) << 9;
+ if (rtwsta_link->cctl_tx_time) {
+ *tx_time = (rtwsta_link->ampdu_max_time + 1) << 9;
} else {
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
if (ret) {
@@ -6213,33 +6329,33 @@ int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
}
int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta,
+ struct rtw89_sta_link *rtwsta_link,
bool resume, u8 tx_retry)
{
int ret = 0;
- rtwsta->data_tx_cnt_lmt = tx_retry;
+ rtwsta_link->data_tx_cnt_lmt = tx_retry;
if (!resume) {
- rtwsta->cctl_tx_retry_limit = true;
- ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta);
+ rtwsta_link->cctl_tx_retry_limit = true;
+ ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
} else {
- ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta);
- rtwsta->cctl_tx_retry_limit = false;
+ ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
+ rtwsta_link->cctl_tx_retry_limit = false;
}
return ret;
}
int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 *tx_retry)
+ struct rtw89_sta_link *rtwsta_link, u8 *tx_retry)
{
- u8 mac_idx = rtwsta->rtwvif->mac_idx;
+ u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
u32 reg;
int ret = 0;
- if (rtwsta->cctl_tx_retry_limit) {
- *tx_retry = rtwsta->data_tx_cnt_lmt;
+ if (rtwsta_link->cctl_tx_retry_limit) {
+ *tx_retry = rtwsta_link->data_tx_cnt_lmt;
} else {
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
if (ret) {
@@ -6255,10 +6371,10 @@ int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
}
int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en)
+ struct rtw89_vif_link *rtwvif_link, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
- u8 mac_idx = rtwvif->mac_idx;
+ u8 mac_idx = rtwvif_link->mac_idx;
u16 set = mac->muedca_ctrl.mask;
u32 reg;
u32 ret;
@@ -6326,7 +6442,9 @@ int rtw89_mac_read_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
}
static
-void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
+void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
static const enum rtw89_pkt_drop_sel sels[] = {
RTW89_PKT_DROP_SEL_MACID_BE_ONCE,
@@ -6334,15 +6452,14 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
RTW89_PKT_DROP_SEL_MACID_VI_ONCE,
RTW89_PKT_DROP_SEL_MACID_VO_ONCE,
};
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_pkt_drop_params params = {0};
int i;
- params.mac_band = RTW89_MAC_0;
- params.macid = rtwsta->mac_id;
- params.port = rtwvif->port;
+ params.mac_band = rtwvif_link->mac_idx;
+ params.macid = rtwsta_link->mac_id;
+ params.port = rtwvif_link->port;
params.mbssid = 0;
- params.tf_trs = rtwvif->trigger;
+ params.tf_trs = rtwvif_link->trigger;
for (i = 0; i < ARRAY_SIZE(sels); i++) {
params.sel = sels[i];
@@ -6352,15 +6469,21 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
static void rtw89_mac_pkt_drop_vif_iter(void *data, struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
- struct rtw89_dev *rtwdev = rtwvif->rtwdev;
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
struct rtw89_vif *target = data;
+ unsigned int link_id;
if (rtwvif != target)
return;
- rtw89_mac_pkt_drop_sta(rtwdev, rtwsta);
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ rtw89_mac_pkt_drop_sta(rtwdev, rtwvif_link, rtwsta_link);
+ }
}
void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
@@ -6398,6 +6521,9 @@ int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable)
struct rtw89_mac_c2h_info c2h_info = {};
u32 ret;
+ if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw))
+ return 0;
+
h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL;
h2c_info.content_len = sizeof(h2c_info.u.hdr);
h2c_info.u.hdr.w0 = u32_encode_bits(wow_enable, RTW89_H2CREG_WOW_CPUIO_RX_CTRL_EN);
@@ -6434,6 +6560,9 @@ static int rtw89_wow_config_mac_ax(struct rtw89_dev *rtwdev, bool enable_wow)
rtw89_write32(rtwdev, R_AX_TF_FWD, 0);
rtw89_write32(rtwdev, R_AX_HW_RPT_FWD, 0);
+ if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw))
+ return 0;
+
if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
rtw89_write8(rtwdev, R_BE_DBG_WOW_READY, WOWLAN_NOT_READY);
else
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 67c2a4507124..e59c1fcfea46 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -951,8 +951,9 @@ struct rtw89_mac_gen_def {
void (*dmac_func_pre_en)(struct rtw89_dev *rtwdev);
void (*dle_func_en)(struct rtw89_dev *rtwdev, bool enable);
void (*dle_clk_en)(struct rtw89_dev *rtwdev, bool enable);
- void (*bf_assoc)(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ void (*bf_assoc)(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*typ_fltr_opt)(struct rtw89_dev *rtwdev,
enum rtw89_machdr_frame_type type,
@@ -1004,12 +1005,12 @@ struct rtw89_mac_gen_def {
bool (*is_txq_empty)(struct rtw89_dev *rtwdev);
int (*add_chan_list)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected);
+ struct rtw89_vif_link *rtwvif_link, bool connected);
int (*add_chan_list_pno)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
+ struct rtw89_vif_link *rtwvif_link);
int (*scan_offload)(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *option,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
bool wowlan);
int (*wow_config_mac)(struct rtw89_dev *rtwdev, bool enable_wow);
@@ -1033,81 +1034,89 @@ u32 rtw89_mac_reg_by_port(struct rtw89_dev *rtwdev, u32 base, u8 port, u8 mac_id
}
static inline u32
-rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base)
+rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
return rtw89_read32(rtwdev, reg);
}
static inline u32
-rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 mask)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
return rtw89_read32_mask(rtwdev, reg, mask);
}
static inline void
-rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base,
+rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base,
u32 data)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write32(rtwdev, reg, data);
}
static inline void
-rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 mask, u32 data)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, mask, data);
}
static inline void
-rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 mask, u16 data)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write16_mask(rtwdev, reg, mask, data);
}
static inline void
-rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 bit)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write32_clr(rtwdev, reg, bit);
}
static inline void
-rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u16 bit)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write16_clr(rtwdev, reg, bit);
}
static inline void
-rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 bit)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write32_set(rtwdev, reg, bit);
}
@@ -1139,21 +1148,21 @@ int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev,
struct rtw89_mac_dle_dfi_qempty *qempty);
void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev,
enum mac_ax_err_info err);
-int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
-int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
+int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_vif *rtwvif_src,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_vif_link *rtwvif_src,
u16 offset_tu);
-int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u64 *tsf);
void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en);
+ struct rtw89_vif_link *rtwvif_link, bool en);
void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif);
-void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+ struct rtw89_vif_link *rtwvif_link);
+void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en);
-int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
+int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev);
int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev);
@@ -1213,7 +1222,22 @@ int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
return mac->cfg_ppdu_status(rtwdev, mac_idx, enable);
}
-void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx);
+static inline
+int rtw89_mac_cfg_ppdu_status_bands(struct rtw89_dev *rtwdev, bool enable)
+{
+ int ret;
+
+ ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, enable);
+ if (ret)
+ return ret;
+
+ if (!rtwdev->dbcc_en)
+ return 0;
+
+ return rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_1, enable);
+}
+
+void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev);
void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop);
int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex);
int rtw89_mac_coex_init_v1(struct rtw89_dev *rtwdev,
@@ -1251,27 +1275,30 @@ void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter);
void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev);
static inline
-void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
if (mac->bf_assoc)
- mac->bf_assoc(rtwdev, vif, sta);
+ mac->bf_assoc(rtwdev, rtwvif_link, rtwsta_link);
}
-void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *conf);
void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta, bool disconnect);
+ struct rtw89_sta_link *rtwsta_link,
+ bool disconnect);
void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev);
void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en);
-int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
-int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
+int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en);
+ struct rtw89_vif_link *rtwvif_link, bool en);
int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause);
static inline void rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
@@ -1376,15 +1403,15 @@ static inline bool rtw89_mac_get_power_state(struct rtw89_dev *rtwdev)
return !!val;
}
-int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
bool resume, u32 tx_time);
-int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
u32 *tx_time);
int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta,
+ struct rtw89_sta_link *rtwsta_link,
bool resume, u8 tx_retry);
int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 *tx_retry);
+ struct rtw89_sta_link *rtwsta_link, u8 *tx_retry);
enum rtw89_mac_xtal_si_offset {
XTAL0 = 0x0,
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 48ad0d0f76bf..3f33c3a2ae7d 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -23,13 +23,13 @@ static void rtw89_ops_tx(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct ieee80211_sta *sta = control->sta;
u32 flags = IEEE80211_SKB_CB(skb)->flags;
int ret, qsel;
if (rtwvif->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) {
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
rtw89_debug(rtwdev, RTW89_DBG_TXRX, "ops_tx during offchan\n");
skb_queue_tail(&rtwsta->roc_queue, skb);
@@ -105,11 +105,61 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
return 0;
}
+static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct ieee80211_bss_conf *bss_conf;
+ int ret;
+
+ rtw89_leave_ps_mode(rtwdev);
+
+ rtw89_vif_type_mapping(rtwvif_link, false);
+
+ INIT_WORK(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work);
+ INIT_LIST_HEAD(&rtwvif_link->general_pkt_list);
+
+ rtwvif_link->hit_rule = 0;
+ rtwvif_link->bcn_hit_cond = 0;
+ rtwvif_link->chanctx_assigned = false;
+ rtwvif_link->chanctx_idx = RTW89_CHANCTX_0;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr);
+
+ rcu_read_unlock();
+
+ ret = rtw89_mac_add_vif(rtwdev, rtwvif_link);
+ if (ret)
+ return ret;
+
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_START);
+ return 0;
+}
+
+static void __rtw89_ops_remove_iface_link(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ mutex_unlock(&rtwdev->mutex);
+ cancel_work_sync(&rtwvif_link->update_beacon_work);
+ mutex_lock(&rtwdev->mutex);
+
+ rtw89_leave_ps_mode(rtwdev);
+
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_STOP);
+
+ rtw89_mac_remove_vif(rtwdev, rtwvif_link);
+}
+
static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ u8 mac_id, port;
int ret = 0;
rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n",
@@ -123,49 +173,56 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
IEEE80211_VIF_SUPPORTS_CQM_RSSI;
- rtwvif->rtwdev = rtwdev;
- rtwvif->roc.state = RTW89_ROC_IDLE;
- rtwvif->offchan = false;
+ mac_id = rtw89_acquire_mac_id(rtwdev);
+ if (mac_id == RTW89_MAX_MAC_ID_NUM) {
+ ret = -ENOSPC;
+ goto err;
+ }
+
+ port = rtw89_core_acquire_bit_map(rtwdev->hw_port, RTW89_PORT_NUM);
+ if (port == RTW89_PORT_NUM) {
+ ret = -ENOSPC;
+ goto release_macid;
+ }
+
+ rtw89_init_vif(rtwdev, rtwvif, mac_id, port);
+
+ rtw89_core_txq_init(rtwdev, vif->txq);
+
if (!rtw89_rtwvif_in_list(rtwdev, rtwvif))
list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
- INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work);
+ ether_addr_copy(rtwvif->mac_addr, vif->addr);
+
+ rtwvif->offchan = false;
+ rtwvif->roc.state = RTW89_ROC_IDLE;
INIT_DELAYED_WORK(&rtwvif->roc.roc_work, rtw89_roc_work);
- rtw89_leave_ps_mode(rtwdev);
rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
- rtw89_vif_type_mapping(vif, false);
- rtwvif->port = rtw89_core_acquire_bit_map(rtwdev->hw_port,
- RTW89_PORT_NUM);
- if (rtwvif->port == RTW89_PORT_NUM) {
- ret = -ENOSPC;
- list_del_init(&rtwvif->list);
- goto out;
- }
- rtwvif->bcn_hit_cond = 0;
- rtwvif->mac_idx = RTW89_MAC_0;
- rtwvif->phy_idx = RTW89_PHY_0;
- rtwvif->chanctx_idx = RTW89_CHANCTX_0;
- rtwvif->chanctx_assigned = false;
- rtwvif->hit_rule = 0;
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
- ether_addr_copy(rtwvif->mac_addr, vif->addr);
- INIT_LIST_HEAD(&rtwvif->general_pkt_list);
-
- ret = rtw89_mac_add_vif(rtwdev, rtwvif);
- if (ret) {
- rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
- list_del_init(&rtwvif->list);
- goto out;
+ rtwvif_link = rtw89_vif_set_link(rtwvif, 0);
+ if (!rtwvif_link) {
+ ret = -EINVAL;
+ goto release_port;
}
- rtw89_core_txq_init(rtwdev, vif->txq);
-
- rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START);
+ ret = __rtw89_ops_add_iface_link(rtwdev, rtwvif_link);
+ if (ret)
+ goto unset_link;
rtw89_recalc_lps(rtwdev);
-out:
+
+ mutex_unlock(&rtwdev->mutex);
+ return 0;
+
+unset_link:
+ rtw89_vif_unset_link(rtwvif, 0);
+release_port:
+ list_del_init(&rtwvif->list);
+ rtw89_core_release_bit_map(rtwdev->hw_port, port);
+release_macid:
+ rtw89_release_mac_id(rtwdev, mac_id);
+err:
mutex_unlock(&rtwdev->mutex);
return ret;
@@ -175,20 +232,35 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ u8 macid = rtw89_vif_get_main_macid(rtwvif);
+ u8 port = rtw89_vif_get_main_port(rtwvif);
+ struct rtw89_vif_link *rtwvif_link;
rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n",
vif->addr, vif->type, vif->p2p);
- cancel_work_sync(&rtwvif->update_beacon_work);
cancel_delayed_work_sync(&rtwvif->roc.roc_work);
mutex_lock(&rtwdev->mutex);
- rtw89_leave_ps_mode(rtwdev);
- rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP);
- rtw89_mac_remove_vif(rtwdev, rtwvif);
- rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
+
+ rtwvif_link = rtwvif->links[0];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, 0);
+ goto bottom;
+ }
+
+ __rtw89_ops_remove_iface_link(rtwdev, rtwvif_link);
+
+ rtw89_vif_unset_link(rtwvif, 0);
+
+bottom:
list_del_init(&rtwvif->list);
+ rtw89_core_release_bit_map(rtwdev->hw_port, port);
+ rtw89_release_mac_id(rtwdev, macid);
+
rtw89_recalc_lps(rtwdev);
rtw89_enter_ips_by_hwflags(rtwdev);
@@ -311,24 +383,30 @@ static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
};
static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u8 aifsn)
+ struct rtw89_vif_link *rtwvif_link, u8 aifsn)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
+ rtwvif_link->chanctx_idx);
+ struct ieee80211_bss_conf *bss_conf;
u8 slot_time;
u8 sifs;
- slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ slot_time = bss_conf->use_short_slot ? 9 : 20;
+
+ rcu_read_unlock();
+
sifs = chan->band_type == RTW89_BAND_2G ? 10 : 16;
return aifsn * slot_time + sifs;
}
static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u16 ac)
+ struct rtw89_vif_link *rtwvif_link, u16 ac)
{
- struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
+ struct ieee80211_tx_queue_params *params = &rtwvif_link->tx_params[ac];
u32 val;
u8 ecw_max, ecw_min;
u8 aifs;
@@ -336,12 +414,12 @@ static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev,
/* 2^ecw - 1 = cw; ecw = log2(cw + 1) */
ecw_max = ilog2(params->cw_max + 1);
ecw_min = ilog2(params->cw_min + 1);
- aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif, params->aifs);
+ aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif_link, params->aifs);
val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) |
FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) |
FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) |
FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs);
- rtw89_fw_h2c_set_edca(rtwdev, rtwvif, ac_to_fw_idx[ac], val);
+ rtw89_fw_h2c_set_edca(rtwdev, rtwvif_link, ac_to_fw_idx[ac], val);
}
#define R_MUEDCA_ACS_PARAM(acs) {R_AX_MUEDCA_ ## acs ## _PARAM_0, \
@@ -355,9 +433,9 @@ static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS][RTW89_CHIP_GEN_NUM] = {
};
static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u16 ac)
+ struct rtw89_vif_link *rtwvif_link, u16 ac)
{
- struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
+ struct ieee80211_tx_queue_params *params = &rtwvif_link->tx_params[ac];
struct ieee80211_he_mu_edca_param_ac_rec *mu_edca;
int gen = rtwdev->chip->chip_gen;
u8 aifs, aifsn;
@@ -370,32 +448,199 @@ static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
mu_edca = &params->mu_edca_param_rec;
aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn);
- aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif, aifsn) : 0;
+ aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif_link, aifsn) : 0;
timer_32us = mu_edca->mu_edca_timer << 8;
val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) |
FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) |
FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs);
- reg = rtw89_mac_reg_by_idx(rtwdev, ac_to_mu_edca_param[ac][gen], rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, ac_to_mu_edca_param[ac][gen],
+ rtwvif_link->mac_idx);
rtw89_write32(rtwdev, reg, val);
- rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true);
+ rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif_link, true);
}
static void __rtw89_conf_tx(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u16 ac)
+ struct rtw89_vif_link *rtwvif_link, u16 ac)
{
- ____rtw89_conf_tx_edca(rtwdev, rtwvif, ac);
- ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif, ac);
+ ____rtw89_conf_tx_edca(rtwdev, rtwvif_link, ac);
+ ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif_link, ac);
}
static void rtw89_conf_tx(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
u16 ac;
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
- __rtw89_conf_tx(rtwdev, rtwvif, ac);
+ __rtw89_conf_tx(rtwdev, rtwvif_link, ac);
+}
+
+static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ bool acquire_macid = false;
+ u8 macid;
+ int ret;
+ int i;
+
+ if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
+ /* for station mode, assign the mac_id from itself */
+ macid = rtw89_vif_get_main_macid(rtwvif);
+ } else {
+ macid = rtw89_acquire_mac_id(rtwdev);
+ if (macid == RTW89_MAX_MAC_ID_NUM)
+ return -ENOSPC;
+
+ acquire_macid = true;
+ }
+
+ rtw89_init_sta(rtwdev, rtwvif, rtwsta, macid);
+
+ for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
+ rtw89_core_txq_init(rtwdev, sta->txq[i]);
+
+ skb_queue_head_init(&rtwsta->roc_queue);
+
+ rtwsta_link = rtw89_sta_set_link(rtwsta, sta->deflink.link_id);
+ if (!rtwsta_link) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ rtwvif_link = rtwsta_link->rtwvif_link;
+
+ ret = rtw89_core_sta_link_add(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ goto unset_link;
+
+ if (vif->type == NL80211_IFTYPE_AP || sta->tdls)
+ rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
+
+ return 0;
+
+unset_link:
+ rtw89_sta_unset_link(rtwsta, sta->deflink.link_id);
+err:
+ if (acquire_macid)
+ rtw89_release_mac_id(rtwdev, macid);
+
+ return ret;
+}
+
+static int __rtw89_ops_sta_assoc(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ bool station_mode)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+
+ if (station_mode)
+ rtw89_vif_type_mapping(rtwvif_link, true);
+
+ ret = rtw89_core_sta_link_assoc(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ return ret;
+ }
+
+ rtwdev->total_sta_assoc++;
+ if (sta->tdls)
+ rtwvif->tdls_peer++;
+
+ return 0;
+}
+
+static int __rtw89_ops_sta_disassoc(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = rtw89_core_sta_link_disassoc(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ return ret;
+ }
+
+ rtwsta->disassoc = true;
+
+ rtwdev->total_sta_assoc--;
+ if (sta->tdls)
+ rtwvif->tdls_peer--;
+
+ return 0;
+}
+
+static int __rtw89_ops_sta_disconnect(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_core_free_sta_pending_ba(rtwdev, sta);
+ rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta);
+ rtw89_core_free_sta_pending_roc_tx(rtwdev, sta);
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = rtw89_core_sta_link_disconnect(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __rtw89_ops_sta_remove(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ u8 macid = rtw89_sta_get_main_macid(rtwsta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = rtw89_core_sta_link_remove(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ return ret;
+
+ rtw89_sta_unset_link(rtwsta, link_id);
+ }
+
+ if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
+ rtw89_release_mac_id(rtwdev, macid);
+ rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
+ }
+
+ return 0;
}
static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
@@ -412,16 +657,34 @@ static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
return;
}
- rtw89_vif_type_mapping(vif, true);
+ __rtw89_ops_sta_assoc(rtwdev, vif, sta, true);
+}
+
+static void __rtw89_ops_bss_link_assoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ rtw89_phy_set_bss_color(rtwdev, rtwvif_link);
+ rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link);
+ rtw89_mac_port_update(rtwdev, rtwvif_link);
+ rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, rtwvif_link);
+}
+
+static void __rtw89_ops_bss_assoc(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
- rtw89_core_sta_assoc(rtwdev, vif, sta);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ __rtw89_ops_bss_link_assoc(rtwdev, rtwvif_link);
}
static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u64 changed)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
@@ -429,10 +692,7 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_ASSOC) {
if (vif->cfg.assoc) {
rtw89_station_mode_sta_assoc(rtwdev, vif);
- rtw89_phy_set_bss_color(rtwdev, vif);
- rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
- rtw89_mac_port_update(rtwdev, rtwvif);
- rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, vif);
+ __rtw89_ops_bss_assoc(rtwdev, vif);
rtw89_queue_chanctx_work(rtwdev);
} else {
@@ -459,39 +719,49 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
u64 changed)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
+ rtwvif_link = rtwvif->links[conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, conf->link_id);
+ goto out;
+ }
+
if (changed & BSS_CHANGED_BSSID) {
- ether_addr_copy(rtwvif->bssid, conf->bssid);
- rtw89_cam_bssid_changed(rtwdev, rtwvif);
- rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
- WRITE_ONCE(rtwvif->sync_bcn_tsf, 0);
+ ether_addr_copy(rtwvif_link->bssid, conf->bssid);
+ rtw89_cam_bssid_changed(rtwdev, rtwvif_link);
+ rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
+ WRITE_ONCE(rtwvif_link->sync_bcn_tsf, 0);
}
if (changed & BSS_CHANGED_BEACON)
- rtw89_chip_h2c_update_beacon(rtwdev, rtwvif);
+ rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
if (changed & BSS_CHANGED_ERP_SLOT)
- rtw89_conf_tx(rtwdev, rtwvif);
+ rtw89_conf_tx(rtwdev, rtwvif_link);
if (changed & BSS_CHANGED_HE_BSS_COLOR)
- rtw89_phy_set_bss_color(rtwdev, vif);
+ rtw89_phy_set_bss_color(rtwdev, rtwvif_link);
if (changed & BSS_CHANGED_MU_GROUPS)
rtw89_mac_bf_set_gid_table(rtwdev, vif, conf);
if (changed & BSS_CHANGED_P2P_PS)
- rtw89_core_update_p2p_ps(rtwdev, vif);
+ rtw89_core_update_p2p_ps(rtwdev, rtwvif_link, conf);
if (changed & BSS_CHANGED_CQM)
- rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
if (changed & BSS_CHANGED_TPE)
- rtw89_reg_6ghz_recalc(rtwdev, rtwvif, true);
+ rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true);
+out:
mutex_unlock(&rtwdev->mutex);
}
@@ -500,12 +770,21 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *link_conf)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
const struct rtw89_chan *chan;
mutex_lock(&rtwdev->mutex);
- chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
+ rtwvif_link = rtwvif->links[link_conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, link_conf->link_id);
+ goto out;
+ }
+
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
if (chan->band_type == RTW89_BAND_6G) {
mutex_unlock(&rtwdev->mutex);
return -EOPNOTSUPP;
@@ -514,16 +793,18 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
if (rtwdev->scanning)
rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
- ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid);
- rtw89_cam_bssid_changed(rtwdev, rtwvif);
- rtw89_mac_port_update(rtwdev, rtwvif);
- rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
- rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_TYPE_CHANGE);
- rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
- rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
- rtw89_chip_rfk_channel(rtwdev, rtwvif);
+ ether_addr_copy(rtwvif_link->bssid, link_conf->bssid);
+ rtw89_cam_bssid_changed(rtwdev, rtwvif_link);
+ rtw89_mac_port_update(rtwdev, rtwvif_link);
+ rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL);
+ rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_TYPE_CHANGE);
+ rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true);
+ rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
+ rtw89_chip_rfk_channel(rtwdev, rtwvif_link);
rtw89_queue_chanctx_work(rtwdev);
+
+out:
mutex_unlock(&rtwdev->mutex);
return 0;
@@ -534,12 +815,24 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
- rtw89_mac_stop_ap(rtwdev, rtwvif);
- rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
- rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
+
+ rtwvif_link = rtwvif->links[link_conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, link_conf->link_id);
+ goto out;
+ }
+
+ rtw89_mac_stop_ap(rtwdev, rtwvif_link);
+ rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL);
+ rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true);
+
+out:
mutex_unlock(&rtwdev->mutex);
}
@@ -547,10 +840,13 @@ static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
bool set)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
- ieee80211_queue_work(rtwdev->hw, &rtwvif->update_beacon_work);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ ieee80211_queue_work(rtwdev->hw, &rtwvif_link->update_beacon_work);
return 0;
}
@@ -561,15 +857,29 @@ static int rtw89_ops_conf_tx(struct ieee80211_hw *hw,
const struct ieee80211_tx_queue_params *params)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ int ret = 0;
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
- rtwvif->tx_params[ac] = *params;
- __rtw89_conf_tx(rtwdev, rtwvif, ac);
+
+ rtwvif_link = rtwvif->links[link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, link_id);
+ ret = -ENOLINK;
+ goto out;
+ }
+
+ rtwvif_link->tx_params[ac] = *params;
+ __rtw89_conf_tx(rtwdev, rtwvif_link, ac);
+
+out:
mutex_unlock(&rtwdev->mutex);
- return 0;
+ return ret;
}
static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
@@ -582,26 +892,26 @@ static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
if (old_state == IEEE80211_STA_NOTEXIST &&
new_state == IEEE80211_STA_NONE)
- return rtw89_core_sta_add(rtwdev, vif, sta);
+ return __rtw89_ops_sta_add(rtwdev, vif, sta);
if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_ASSOC) {
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
return 0; /* defer to bss_info_changed to have vif info */
- return rtw89_core_sta_assoc(rtwdev, vif, sta);
+ return __rtw89_ops_sta_assoc(rtwdev, vif, sta, false);
}
if (old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTH)
- return rtw89_core_sta_disassoc(rtwdev, vif, sta);
+ return __rtw89_ops_sta_disassoc(rtwdev, vif, sta);
if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_NONE)
- return rtw89_core_sta_disconnect(rtwdev, vif, sta);
+ return __rtw89_ops_sta_disconnect(rtwdev, vif, sta);
if (old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_NOTEXIST)
- return rtw89_core_sta_remove(rtwdev, vif, sta);
+ return __rtw89_ops_sta_remove(rtwdev, vif, sta);
return 0;
}
@@ -667,7 +977,8 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
struct ieee80211_sta *sta = params->sta;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
u16 tid = params->tid;
struct ieee80211_txq *txq = sta->txq[tid];
struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv;
@@ -681,7 +992,7 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
mutex_lock(&rtwdev->mutex);
clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
clear_bit(tid, rtwsta->ampdu_map);
- rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, vif, sta);
+ rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta);
mutex_unlock(&rtwdev->mutex);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
break;
@@ -692,7 +1003,7 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
rtwsta->ampdu_params[tid].amsdu = params->amsdu;
set_bit(tid, rtwsta->ampdu_map);
rtw89_leave_ps_mode(rtwdev);
- rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, vif, sta);
+ rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta);
mutex_unlock(&rtwdev->mutex);
break;
case IEEE80211_AMPDU_RX_START:
@@ -720,7 +1031,7 @@ static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
- rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
+ rtw89_mac_update_rts_threshold(rtwdev);
mutex_unlock(&rtwdev->mutex);
return 0;
@@ -731,9 +1042,14 @@ static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
struct station_info *sinfo)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_sta_link *rtwsta_link;
+
+ rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
+ if (unlikely(!rtwsta_link))
+ return;
- sinfo->txrate = rtwsta->ra_report.txrate;
+ sinfo->txrate = rtwsta_link->ra_report.txrate;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
}
@@ -743,7 +1059,7 @@ void __rtw89_drop_packets(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
struct rtw89_vif *rtwvif;
if (vif) {
- rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ rtwvif = vif_to_rtwvif(vif);
rtw89_mac_pkt_drop_vif(rtwdev, rtwvif);
} else {
rtw89_for_each_rtwvif(rtwdev, rtwvif)
@@ -777,14 +1093,20 @@ struct rtw89_iter_bitrate_mask_data {
static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_iter_bitrate_mask_data *br_data = data;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
if (vif != br_data->vif || vif->p2p)
return;
- rtwsta->use_cfg_mask = true;
- rtwsta->mask = *br_data->mask;
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwsta_link->use_cfg_mask = true;
+ rtwsta_link->mask = *br_data->mask;
+ }
+
rtw89_phy_ra_update_sta(br_data->rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED);
}
@@ -854,10 +1176,20 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
const u8 *mac_addr)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
- rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, false);
+
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "sw scan start: find no link on HW-0\n");
+ goto out;
+ }
+
+ rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, false);
+
+out:
mutex_unlock(&rtwdev->mutex);
}
@@ -865,9 +1197,20 @@ static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
- rtw89_core_scan_complete(rtwdev, vif, false);
+
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "sw scan complete: find no link on HW-0\n");
+ goto out;
+ }
+
+ rtw89_core_scan_complete(rtwdev, rtwvif_link, false);
+
+out:
mutex_unlock(&rtwdev->mutex);
}
@@ -884,22 +1227,35 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_scan_request *req)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
- int ret = 0;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ int ret;
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
return 1;
- if (rtwdev->scanning || rtwvif->offchan)
- return -EBUSY;
-
mutex_lock(&rtwdev->mutex);
- rtw89_hw_scan_start(rtwdev, vif, req);
- ret = rtw89_hw_scan_offload(rtwdev, vif, true);
+
+ if (rtwdev->scanning || rtwvif->offchan) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "hw scan: find no link on HW-0\n");
+ ret = -ENOLINK;
+ goto out;
+ }
+
+ rtw89_hw_scan_start(rtwdev, rtwvif_link, req);
+ ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true);
if (ret) {
- rtw89_hw_scan_abort(rtwdev, vif);
+ rtw89_hw_scan_abort(rtwdev, rtwvif_link);
rtw89_err(rtwdev, "HW scan failed with status: %d\n", ret);
}
+
+out:
mutex_unlock(&rtwdev->mutex);
return ret;
@@ -909,6 +1265,8 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
return;
@@ -917,14 +1275,25 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
return;
mutex_lock(&rtwdev->mutex);
- rtw89_hw_scan_abort(rtwdev, vif);
+
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "cancel hw scan: find no link on HW-0\n");
+ goto out;
+ }
+
+ rtw89_hw_scan_abort(rtwdev, rtwvif_link);
+
+out:
mutex_unlock(&rtwdev->mutex);
}
static void rtw89_ops_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, u32 changed)
+ struct ieee80211_link_sta *link_sta,
+ u32 changed)
{
+ struct ieee80211_sta *sta = link_sta->sta;
struct rtw89_dev *rtwdev = hw->priv;
rtw89_phy_ra_update_sta(rtwdev, sta, changed);
@@ -970,11 +1339,24 @@ static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
int ret;
mutex_lock(&rtwdev->mutex);
- ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif, ctx);
+
+ rtwvif_link = rtwvif->links[link_conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, link_conf->link_id);
+ ret = -ENOLINK;
+ goto out;
+ }
+
+ ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, ctx);
+
+out:
mutex_unlock(&rtwdev->mutex);
return ret;
@@ -986,10 +1368,20 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
- rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif, ctx);
+
+ rtwvif_link = rtwvif->links[link_conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, link_conf->link_id);
+ return;
+ }
+
+ rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, ctx);
mutex_unlock(&rtwdev->mutex);
}
@@ -1003,7 +1395,7 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw,
struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
struct rtw89_roc *roc = &rtwvif->roc;
- if (!vif)
+ if (!rtwvif)
return -EINVAL;
mutex_lock(&rtwdev->mutex);
@@ -1053,8 +1445,8 @@ static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw,
static void rtw89_set_tid_config_iter(void *data, struct ieee80211_sta *sta)
{
struct cfg80211_tid_config *tid_config = data;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_dev *rtwdev = rtwsta->rtwvif->rtwdev;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
rtw89_core_set_tid_config(rtwdev, sta, tid_config);
}
@@ -1203,7 +1595,7 @@ const struct ieee80211_ops rtw89_ops = {
.remain_on_channel = rtw89_ops_remain_on_channel,
.cancel_remain_on_channel = rtw89_ops_cancel_remain_on_channel,
.set_sar_specs = rtw89_ops_set_sar_specs,
- .sta_rc_update = rtw89_ops_sta_rc_update,
+ .link_sta_rc_update = rtw89_ops_sta_rc_update,
.set_tid_config = rtw89_ops_set_tid_config,
#ifdef CONFIG_PM
.suspend = rtw89_ops_suspend,
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index 31f0a5225b11..30943462640f 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -773,7 +773,7 @@ static int dmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
return ret;
}
- ret = rtw89_mac_preload_init(rtwdev, RTW89_MAC_0, rtwdev->mac.qta_mode);
+ ret = rtw89_mac_preload_init(rtwdev, mac_idx, rtwdev->mac.qta_mode);
if (ret) {
rtw89_err(rtwdev, "[ERR]preload init %d\n", ret);
return ret;
@@ -2091,13 +2091,13 @@ static int rtw89_mac_init_bfee_be(struct rtw89_dev *rtwdev, u8 mac_idx)
}
static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1;
- u8 mac_idx = rtwvif->mac_idx;
- u8 port_sel = rtwvif->port;
+ struct ieee80211_link_sta *link_sta;
+ u8 mac_idx = rtwvif_link->mac_idx;
+ u8 port_sel = rtwvif_link->port;
u8 sound_dim = 3, t;
u8 *phy_cap;
u32 reg;
@@ -2108,7 +2108,10 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info;
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
(phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) {
@@ -2119,11 +2122,11 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
sound_dim = min(sound_dim, t);
}
- if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
- (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
- ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
- stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
- t = u32_get_bits(sta->deflink.vht_cap.cap,
+ if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
+ (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
+ ldpc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
+ stbc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
+ t = u32_get_bits(link_sta->vht_cap.cap,
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK);
sound_dim = min(sound_dim, t);
}
@@ -2131,6 +2134,8 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
nc = min(nc, sound_dim);
nr = min(nr, sound_dim);
+ rcu_read_unlock();
+
reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL);
@@ -2155,12 +2160,12 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
}
static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M);
- u8 mac_idx = rtwvif->mac_idx;
+ struct ieee80211_link_sta *link_sta;
+ u8 mac_idx = rtwvif_link->mac_idx;
int ret;
u32 reg;
@@ -2168,22 +2173,28 @@ static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- if (sta->deflink.he_cap.has_he) {
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ if (link_sta->he_cap.has_he) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) |
BIT(RTW89_MAC_BF_RRSC_HE_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HE_MSC5));
}
- if (sta->deflink.vht_cap.vht_supported) {
+ if (link_sta->vht_cap.vht_supported) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) |
BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_VHT_MSC5));
}
- if (sta->deflink.ht_cap.ht_supported) {
+ if (link_sta->ht_cap.ht_supported) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC5));
}
+ rcu_read_unlock();
+
reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL);
rtw89_write32_clr(rtwdev, reg, B_BE_BFMEE_CSI_FORCE_RETE_EN);
@@ -2195,17 +2206,25 @@ static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev,
}
static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct ieee80211_link_sta *link_sta;
+ bool has_beamformer_cap;
+
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ has_beamformer_cap = rtw89_sta_has_beamformer_cap(link_sta);
+
+ rcu_read_unlock();
- if (rtw89_sta_has_beamformer_cap(sta)) {
+ if (has_beamformer_cap) {
rtw89_debug(rtwdev, RTW89_DBG_BF,
"initialize bfee for new association\n");
- rtw89_mac_init_bfee_be(rtwdev, rtwvif->mac_idx);
- rtw89_mac_set_csi_para_reg_be(rtwdev, vif, sta);
- rtw89_mac_csi_rrsc_be(rtwdev, vif, sta);
+ rtw89_mac_init_bfee_be(rtwdev, rtwvif_link->mac_idx);
+ rtw89_mac_set_csi_para_reg_be(rtwdev, rtwvif_link, rtwsta_link);
+ rtw89_mac_csi_rrsc_be(rtwdev, rtwvif_link, rtwsta_link);
}
}
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 02afeb3acce4..5ed7eaa18c85 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -2358,13 +2358,15 @@ static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev)
return 0;
}
-static void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev)
+static void rtw89_pci_disable_eq_ax(struct rtw89_dev *rtwdev)
{
u16 g1_oobs, g2_oobs;
u32 backup_aspm;
u32 phy_offset;
+ u16 offset_cal;
u16 oobs_val;
int ret;
+ u8 gen;
if (rtwdev->chip->chip_id != RTL8852C)
return;
@@ -2400,6 +2402,28 @@ static void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev)
rtw89_write16_set(rtwdev, R_RAC_DIRECT_OFFSET_G2 + RAC_ANA09 * RAC_MULT,
BAC_OOBS_SEL);
+ /* offset K */
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_G1 :
+ R_RAC_DIRECT_OFFSET_G2;
+
+ rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT,
+ B_PCIE_BIT_RD_SEL);
+ }
+
+ offset_cal = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G1 +
+ RAC_ANA1F * RAC_MULT, OFFSET_CAL_MASK);
+
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_G1 :
+ R_RAC_DIRECT_OFFSET_G2;
+
+ rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA0B * RAC_MULT,
+ MANUAL_LVL_MASK, offset_cal);
+ rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT,
+ OFFSET_CAL_MODE);
+ }
+
out:
rtw89_write32(rtwdev, R_AX_PCIE_MIX_CFG_V1, backup_aspm);
}
@@ -3724,19 +3748,16 @@ static void rtw89_pci_free_irq(struct rtw89_dev *rtwdev,
pci_free_irq_vectors(pdev);
}
-static u16 gray_code_to_bin(u16 gray_code, u32 bit_num)
+static u16 gray_code_to_bin(u16 gray_code)
{
- u16 bin = 0, gray_bit;
- u32 bit_idx;
+ u16 binary = gray_code;
- for (bit_idx = 0; bit_idx < bit_num; bit_idx++) {
- gray_bit = (gray_code >> bit_idx) & 0x1;
- if (bit_num - bit_idx > 1)
- gray_bit ^= (gray_code >> (bit_idx + 1)) & 0x1;
- bin |= (gray_bit << bit_idx);
+ while (gray_code) {
+ gray_code >>= 1;
+ binary ^= gray_code;
}
- return bin;
+ return binary;
}
static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev)
@@ -3772,7 +3793,7 @@ static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev)
val16 = rtw89_read16_mask(rtwdev,
phy_offset + RAC_ANA1F * RAC_MULT,
FILTER_OUT_EQ_MASK);
- val16 = gray_code_to_bin(val16, hweight16(val16));
+ val16 = gray_code_to_bin(val16);
filter_out_val = rtw89_read16(rtwdev, phy_offset + RAC_ANA24 *
RAC_MULT);
filter_out_val &= ~REG_FILTER_OUT_MASK;
@@ -4188,6 +4209,17 @@ static void rtw89_pci_l2_hci_ldo(struct rtw89_dev *rtwdev)
RTW89_PCIE_BIT_CFG_RST_MSTATE);
}
+void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume)
+{
+ if (resume)
+ rtw89_pci_cfg_dac(rtwdev);
+
+ rtw89_pci_disable_eq(rtwdev);
+ rtw89_pci_filter_out(rtwdev);
+ rtw89_pci_link_cfg(rtwdev);
+ rtw89_pci_l1ss_cfg(rtwdev);
+}
+
static int __maybe_unused rtw89_pci_resume(struct device *dev)
{
struct ieee80211_hw *hw = dev_get_drvdata(dev);
@@ -4209,11 +4241,8 @@ static int __maybe_unused rtw89_pci_resume(struct device *dev)
B_AX_SEL_REQ_ENTR_L1);
}
rtw89_pci_l2_hci_ldo(rtwdev);
- rtw89_pci_disable_eq(rtwdev);
- rtw89_pci_cfg_dac(rtwdev);
- rtw89_pci_filter_out(rtwdev);
- rtw89_pci_link_cfg(rtwdev);
- rtw89_pci_l1ss_cfg(rtwdev);
+
+ rtw89_pci_basic_cfg(rtwdev, true);
return 0;
}
@@ -4246,6 +4275,8 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_ax = {
.aspm_set = rtw89_pci_aspm_set_ax,
.clkreq_set = rtw89_pci_clkreq_set_ax,
.l1ss_set = rtw89_pci_l1ss_set_ax,
+
+ .disable_eq = rtw89_pci_disable_eq_ax,
};
EXPORT_SYMBOL(rtw89_pci_gen_ax);
@@ -4345,10 +4376,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_clear_resource;
}
- rtw89_pci_disable_eq(rtwdev);
- rtw89_pci_filter_out(rtwdev);
- rtw89_pci_link_cfg(rtwdev);
- rtw89_pci_l1ss_cfg(rtwdev);
+ rtw89_pci_basic_cfg(rtwdev, false);
ret = rtw89_core_napi_init(rtwdev);
if (ret) {
diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h
index 48c3ab735db2..796f6cd3c965 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.h
+++ b/drivers/net/wireless/realtek/rtw89/pci.h
@@ -18,11 +18,16 @@
#define BAC_OOBS_SEL BIT(4)
#define RAC_ANA0A 0x0A
#define B_BAC_EQ_SEL BIT(5)
+#define RAC_ANA0B 0x0B
+#define MANUAL_LVL_MASK GENMASK(8, 5)
#define RAC_ANA0C 0x0C
#define B_PCIE_BIT_PSAVE BIT(15)
#define RAC_ANA0D 0x0D
+#define OFFSET_CAL_MODE BIT(13)
#define BAC_RX_TEST_EN BIT(6)
#define RAC_ANA10 0x10
+#define ADDR_SEL_MASK GENMASK(9, 4)
+#define ADDR_SEL_VAL 0x3C
#define ADDR_SEL_PINOUT_DIS_VAL 0x3C4
#define B_PCIE_BIT_PINOUT_DIS BIT(3)
#define RAC_REG_REV2 0x1B
@@ -38,6 +43,7 @@
#define RAC_ANA1E_G2_VAL 0x6EEA
#define RAC_ANA1F 0x1F
#define OOBS_LEVEL_MASK GENMASK(12, 8)
+#define OFFSET_CAL_MASK GENMASK(7, 4)
#define RAC_ANA24 0x24
#define B_AX_DEGLITCH GENMASK(11, 8)
#define RAC_ANA26 0x26
@@ -134,6 +140,11 @@
#define REG_FILTER_OUT_MASK GENMASK(6, 2)
#define RAC_MULT 2
+#define R_RAC_DIRECT_OFFSET_BE_LANE0_G1 0x3800
+#define R_RAC_DIRECT_OFFSET_BE_LANE1_G1 0x3880
+#define R_RAC_DIRECT_OFFSET_BE_LANE0_G2 0x3900
+#define R_RAC_DIRECT_OFFSET_BE_LANE1_G2 0x3980
+
#define RTW89_PCI_WR_RETRY_CNT 20
/* Interrupts */
@@ -299,6 +310,7 @@
#define B_BE_L1SS_TIMEOUT_CTRL BIT(18)
#define B_BE_ASPM_CTRL_L1 BIT(17)
#define B_BE_ASPM_CTRL_L0 BIT(16)
+#define B_BE_RTK_ASPM_CTRL_MASK GENMASK(17, 16)
#define B_BE_XFER_PENDING_FW BIT(11)
#define B_BE_XFER_PENDING BIT(10)
#define B_BE_REQ_EXIT_L1 BIT(9)
@@ -1276,6 +1288,8 @@ struct rtw89_pci_gen_def {
void (*aspm_set)(struct rtw89_dev *rtwdev, bool enable);
void (*clkreq_set)(struct rtw89_dev *rtwdev, bool enable);
void (*l1ss_set)(struct rtw89_dev *rtwdev, bool enable);
+
+ void (*disable_eq)(struct rtw89_dev *rtwdev);
};
struct rtw89_pci_info {
@@ -1600,6 +1614,7 @@ struct pci_device_id;
int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
void rtw89_pci_remove(struct pci_dev *pdev);
+void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume);
void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev);
int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en);
int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en);
@@ -1766,4 +1781,13 @@ static inline int rtw89_pci_poll_txdma_ch_idle(struct rtw89_dev *rtwdev)
return gen_def->poll_txdma_ch_idle(rtwdev);
}
+
+static inline void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_pci_info *info = rtwdev->pci_info;
+ const struct rtw89_pci_gen_def *gen_def = info->gen_def;
+
+ gen_def->disable_eq(rtwdev);
+}
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/pci_be.c b/drivers/net/wireless/realtek/rtw89/pci_be.c
index 7cc328222965..34154506f5d4 100644
--- a/drivers/net/wireless/realtek/rtw89/pci_be.c
+++ b/drivers/net/wireless/realtek/rtw89/pci_be.c
@@ -550,6 +550,79 @@ static int rtw89_pci_lv1rst_start_dma_be(struct rtw89_dev *rtwdev)
return 0;
}
+static void rtw89_pci_disable_eq_be(struct rtw89_dev *rtwdev)
+{
+ u32 backup_aspm, phy_offset;
+ u16 oobs_val, offset_cal;
+ u16 g1_oobs, g2_oobs;
+ u8 gen;
+
+ if (rtwdev->chip->chip_id != RTL8922A)
+ return;
+
+ g1_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 +
+ RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL);
+ g2_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G2 +
+ RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL);
+ if (g1_oobs && g2_oobs)
+ return;
+
+ backup_aspm = rtw89_read32(rtwdev, R_BE_PCIE_MIX_CFG);
+ rtw89_write32_clr(rtwdev, R_BE_PCIE_MIX_CFG, B_BE_RTK_ASPM_CTRL_MASK);
+
+ /* offset K */
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
+ R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
+
+ rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT,
+ B_PCIE_BIT_RD_SEL);
+ }
+
+ offset_cal = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 +
+ RAC_ANA1F * RAC_MULT, OFFSET_CAL_MASK);
+
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
+ R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
+
+ rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA0B * RAC_MULT,
+ MANUAL_LVL_MASK, offset_cal);
+ rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT,
+ OFFSET_CAL_MODE);
+ }
+
+ /* OOBS */
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
+ R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
+
+ rtw89_write16_set(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT,
+ BAC_RX_TEST_EN);
+ rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT,
+ ADDR_SEL_MASK, ADDR_SEL_VAL);
+ rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT,
+ B_PCIE_BIT_PINOUT_DIS);
+ rtw89_write16_set(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT,
+ B_PCIE_BIT_RD_SEL);
+ }
+
+ oobs_val = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 +
+ RAC_ANA1F * RAC_MULT, OOBS_LEVEL_MASK);
+
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
+ R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
+
+ rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA03 * RAC_MULT,
+ OOBS_SEN_MASK, oobs_val);
+ rtw89_write16_set(rtwdev, phy_offset + RAC_ANA09 * RAC_MULT,
+ BAC_OOBS_SEL);
+ }
+
+ rtw89_write32(rtwdev, R_BE_PCIE_MIX_CFG, backup_aspm);
+}
+
static int __maybe_unused rtw89_pci_suspend_be(struct device *dev)
{
struct ieee80211_hw *hw = dev_get_drvdata(dev);
@@ -584,6 +657,8 @@ static int __maybe_unused rtw89_pci_resume_be(struct device *dev)
rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
rtw89_write32_set(rtwdev, R_BE_REG_PL1_MASK, B_BE_SER_PM_MASTER_IMR);
+ rtw89_pci_basic_cfg(rtwdev, true);
+
return 0;
}
@@ -614,5 +689,7 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
.aspm_set = rtw89_pci_aspm_set_be,
.clkreq_set = rtw89_pci_clkreq_set_be,
.l1ss_set = rtw89_pci_l1ss_set_be,
+
+ .disable_eq = rtw89_pci_disable_eq_be,
};
EXPORT_SYMBOL(rtw89_pci_gen_be);
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index c7165e757842..5a08e3d46bac 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -75,12 +75,12 @@ static u64 get_mcs_ra_mask(u16 mcs_map, u8 highest_mcs, u8 gap)
return ra_mask;
}
-static u64 get_he_ra_mask(struct ieee80211_sta *sta)
+static u64 get_he_ra_mask(struct ieee80211_link_sta *link_sta)
{
- struct ieee80211_sta_he_cap cap = sta->deflink.he_cap;
+ struct ieee80211_sta_he_cap cap = link_sta->he_cap;
u16 mcs_map;
- switch (sta->deflink.bandwidth) {
+ switch (link_sta->bandwidth) {
case IEEE80211_STA_RX_BW_160:
if (cap.he_cap_elem.phy_cap_info[0] &
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
@@ -118,14 +118,14 @@ static u64 get_eht_mcs_ra_mask(u8 *max_nss, u8 start_mcs, u8 n_nss)
return mask;
}
-static u64 get_eht_ra_mask(struct ieee80211_sta *sta)
+static u64 get_eht_ra_mask(struct ieee80211_link_sta *link_sta)
{
- struct ieee80211_sta_eht_cap *eht_cap = &sta->deflink.eht_cap;
+ struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap;
struct ieee80211_eht_mcs_nss_supp_20mhz_only *mcs_nss_20mhz;
struct ieee80211_eht_mcs_nss_supp_bw *mcs_nss;
- u8 *he_phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info;
+ u8 *he_phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
- switch (sta->deflink.bandwidth) {
+ switch (link_sta->bandwidth) {
case IEEE80211_STA_RX_BW_320:
mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._320;
/* MCS 9, 11, 13 */
@@ -195,15 +195,16 @@ static u64 rtw89_phy_ra_mask_recover(u64 ra_mask, u64 ra_mask_bak)
return ra_mask;
}
-static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link,
+ struct ieee80211_link_sta *link_sta,
const struct rtw89_chan *chan)
{
- struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
- struct cfg80211_bitrate_mask *mask = &rtwsta->mask;
+ struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask;
enum nl80211_band band;
u64 cfg_mask;
- if (!rtwsta->use_cfg_mask)
+ if (!rtwsta_link->use_cfg_mask)
return -1;
switch (chan->band_type) {
@@ -227,17 +228,17 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtw
return -1;
}
- if (sta->deflink.he_cap.has_he) {
+ if (link_sta->he_cap.has_he) {
cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0],
RA_MASK_HE_1SS_RATES);
cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1],
RA_MASK_HE_2SS_RATES);
- } else if (sta->deflink.vht_cap.vht_supported) {
+ } else if (link_sta->vht_cap.vht_supported) {
cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0],
RA_MASK_VHT_1SS_RATES);
cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1],
RA_MASK_VHT_2SS_RATES);
- } else if (sta->deflink.ht_cap.ht_supported) {
+ } else if (link_sta->ht_cap.ht_supported) {
cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0],
RA_MASK_HT_1SS_RATES);
cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1],
@@ -261,17 +262,17 @@ rtw89_ra_mask_eht_rates[4] = {RA_MASK_EHT_1SS_RATES, RA_MASK_EHT_2SS_RATES,
RA_MASK_EHT_3SS_RATES, RA_MASK_EHT_4SS_RATES};
static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta,
+ struct rtw89_sta_link *rtwsta_link,
const struct rtw89_chan *chan,
bool *fix_giltf_en, u8 *fix_giltf)
{
- struct cfg80211_bitrate_mask *mask = &rtwsta->mask;
+ struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask;
u8 band = chan->band_type;
enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
u8 he_gi = mask->control[nl_band].he_gi;
u8 he_ltf = mask->control[nl_band].he_ltf;
- if (!rtwsta->use_cfg_mask)
+ if (!rtwsta_link->use_cfg_mask)
return;
if (he_ltf == 2 && he_gi == 2) {
@@ -295,17 +296,17 @@ static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev,
}
static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta, bool csi)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ struct ieee80211_link_sta *link_sta,
+ bool p2p, bool csi)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
- struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern;
- struct rtw89_ra_info *ra = &rtwsta->ra;
+ struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern;
+ struct rtw89_ra_info *ra = &rtwsta_link->ra;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
+ rtwvif_link->chanctx_idx);
const u64 *high_rate_masks = rtw89_ra_mask_ht_rates;
- u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi);
+ u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi);
u64 ra_mask = 0;
u64 ra_mask_bak;
u8 mode = 0;
@@ -320,65 +321,65 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
memset(ra, 0, sizeof(*ra));
/* Set the ra mask from sta's capability */
- if (sta->deflink.eht_cap.has_eht) {
+ if (link_sta->eht_cap.has_eht) {
mode |= RTW89_RA_MODE_EHT;
- ra_mask |= get_eht_ra_mask(sta);
+ ra_mask |= get_eht_ra_mask(link_sta);
high_rate_masks = rtw89_ra_mask_eht_rates;
- } else if (sta->deflink.he_cap.has_he) {
+ } else if (link_sta->he_cap.has_he) {
mode |= RTW89_RA_MODE_HE;
csi_mode = RTW89_RA_RPT_MODE_HE;
- ra_mask |= get_he_ra_mask(sta);
+ ra_mask |= get_he_ra_mask(link_sta);
high_rate_masks = rtw89_ra_mask_he_rates;
- if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[2] &
+ if (link_sta->he_cap.he_cap_elem.phy_cap_info[2] &
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
stbc_en = 1;
- if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[1] &
+ if (link_sta->he_cap.he_cap_elem.phy_cap_info[1] &
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
ldpc_en = 1;
- rtw89_phy_ra_gi_ltf(rtwdev, rtwsta, chan, &fix_giltf_en, &fix_giltf);
- } else if (sta->deflink.vht_cap.vht_supported) {
- u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map);
+ rtw89_phy_ra_gi_ltf(rtwdev, rtwsta_link, chan, &fix_giltf_en, &fix_giltf);
+ } else if (link_sta->vht_cap.vht_supported) {
+ u16 mcs_map = le16_to_cpu(link_sta->vht_cap.vht_mcs.rx_mcs_map);
mode |= RTW89_RA_MODE_VHT;
csi_mode = RTW89_RA_RPT_MODE_VHT;
/* MCS9 (non-20MHz), MCS8, MCS7 */
- if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)
+ if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
ra_mask |= get_mcs_ra_mask(mcs_map, 8, 1);
else
ra_mask |= get_mcs_ra_mask(mcs_map, 9, 1);
high_rate_masks = rtw89_ra_mask_vht_rates;
- if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
+ if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
stbc_en = 1;
- if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
+ if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
ldpc_en = 1;
- } else if (sta->deflink.ht_cap.ht_supported) {
+ } else if (link_sta->ht_cap.ht_supported) {
mode |= RTW89_RA_MODE_HT;
csi_mode = RTW89_RA_RPT_MODE_HT;
- ra_mask |= ((u64)sta->deflink.ht_cap.mcs.rx_mask[3] << 48) |
- ((u64)sta->deflink.ht_cap.mcs.rx_mask[2] << 36) |
- ((u64)sta->deflink.ht_cap.mcs.rx_mask[1] << 24) |
- ((u64)sta->deflink.ht_cap.mcs.rx_mask[0] << 12);
+ ra_mask |= ((u64)link_sta->ht_cap.mcs.rx_mask[3] << 48) |
+ ((u64)link_sta->ht_cap.mcs.rx_mask[2] << 36) |
+ ((u64)link_sta->ht_cap.mcs.rx_mask[1] << 24) |
+ ((u64)link_sta->ht_cap.mcs.rx_mask[0] << 12);
high_rate_masks = rtw89_ra_mask_ht_rates;
- if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
+ if (link_sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
stbc_en = 1;
- if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)
+ if (link_sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)
ldpc_en = 1;
}
switch (chan->band_type) {
case RTW89_BAND_2G:
- ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ];
- if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] & 0xf)
+ ra_mask |= link_sta->supp_rates[NL80211_BAND_2GHZ];
+ if (link_sta->supp_rates[NL80211_BAND_2GHZ] & 0xf)
mode |= RTW89_RA_MODE_CCK;
- if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] & 0xff0)
+ if (link_sta->supp_rates[NL80211_BAND_2GHZ] & 0xff0)
mode |= RTW89_RA_MODE_OFDM;
break;
case RTW89_BAND_5G:
- ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4;
+ ra_mask |= (u64)link_sta->supp_rates[NL80211_BAND_5GHZ] << 4;
mode |= RTW89_RA_MODE_OFDM;
break;
case RTW89_BAND_6G:
- ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_6GHZ] << 4;
+ ra_mask |= (u64)link_sta->supp_rates[NL80211_BAND_6GHZ] << 4;
mode |= RTW89_RA_MODE_OFDM;
break;
default:
@@ -405,48 +406,48 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra_mask &= rtw89_phy_ra_mask_rssi(rtwdev, rssi, 0);
ra_mask = rtw89_phy_ra_mask_recover(ra_mask, ra_mask_bak);
- ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta, chan);
+ ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, link_sta, chan);
- switch (sta->deflink.bandwidth) {
+ switch (link_sta->bandwidth) {
case IEEE80211_STA_RX_BW_160:
bw_mode = RTW89_CHANNEL_WIDTH_160;
- sgi = sta->deflink.vht_cap.vht_supported &&
- (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160);
+ sgi = link_sta->vht_cap.vht_supported &&
+ (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160);
break;
case IEEE80211_STA_RX_BW_80:
bw_mode = RTW89_CHANNEL_WIDTH_80;
- sgi = sta->deflink.vht_cap.vht_supported &&
- (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80);
+ sgi = link_sta->vht_cap.vht_supported &&
+ (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80);
break;
case IEEE80211_STA_RX_BW_40:
bw_mode = RTW89_CHANNEL_WIDTH_40;
- sgi = sta->deflink.ht_cap.ht_supported &&
- (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
+ sgi = link_sta->ht_cap.ht_supported &&
+ (link_sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
break;
default:
bw_mode = RTW89_CHANNEL_WIDTH_20;
- sgi = sta->deflink.ht_cap.ht_supported &&
- (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
+ sgi = link_sta->ht_cap.ht_supported &&
+ (link_sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
break;
}
- if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[3] &
+ if (link_sta->he_cap.he_cap_elem.phy_cap_info[3] &
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM)
ra->dcm_cap = 1;
- if (rate_pattern->enable && !vif->p2p) {
- ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta, chan);
+ if (rate_pattern->enable && !p2p) {
+ ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, link_sta, chan);
ra_mask &= rate_pattern->ra_mask;
mode = rate_pattern->ra_mode;
}
ra->bw_cap = bw_mode;
- ra->er_cap = rtwsta->er_cap;
+ ra->er_cap = rtwsta_link->er_cap;
ra->mode_ctrl = mode;
- ra->macid = rtwsta->mac_id;
+ ra->macid = rtwsta_link->mac_id;
ra->stbc_cap = stbc_en;
ra->ldpc_cap = ldpc_en;
- ra->ss_num = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
+ ra->ss_num = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1;
ra->en_sgi = sgi;
ra->ra_mask = ra_mask;
ra->fix_giltf_en = fix_giltf_en;
@@ -458,20 +459,29 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra->fixed_csi_rate_en = false;
ra->ra_csi_rate_en = true;
ra->cr_tbl_sel = false;
- ra->band_num = rtwvif->phy_idx;
+ ra->band_num = rtwvif_link->phy_idx;
ra->csi_bw = bw_mode;
ra->csi_gi_ltf = RTW89_GILTF_LGI_4XHE32;
ra->csi_mcs_ss_idx = 5;
ra->csi_mode = csi_mode;
}
-void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
- u32 changed)
+static void __rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ u32 changed)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_ra_info *ra = &rtwsta->ra;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_ra_info *ra = &rtwsta_link->ra;
+ struct ieee80211_link_sta *link_sta;
+
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
+ rtw89_phy_ra_sta_update(rtwdev, rtwvif_link, rtwsta_link,
+ link_sta, vif->p2p, false);
- rtw89_phy_ra_sta_update(rtwdev, sta, false);
+ rcu_read_unlock();
if (changed & IEEE80211_RC_SUPP_RATES_CHANGED)
ra->upd_mask = 1;
@@ -489,6 +499,20 @@ void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta
rtw89_fw_h2c_ra(rtwdev, ra, false);
}
+void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
+ u32 changed)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ __rtw89_phy_ra_update_sta(rtwdev, rtwvif_link, rtwsta_link, changed);
+ }
+}
+
static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next,
u16 rate_base, u64 ra_mask, u8 ra_mode,
u32 rate_ctrl, u32 ctrl_skip, bool force)
@@ -523,15 +547,15 @@ static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next,
[RTW89_CHIP_BE] = RTW89_HW_RATE_V1_ ## rate, \
}
-void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- const struct cfg80211_bitrate_mask *mask)
+static
+void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ const struct cfg80211_bitrate_mask *mask)
{
struct ieee80211_supported_band *sband;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_phy_rate_pattern next_pattern = {0};
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
+ rtwvif_link->chanctx_idx);
static const u16 hw_rate_he[][RTW89_CHIP_GEN_NUM] = {
RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS1_MCS0),
RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS2_MCS0),
@@ -600,7 +624,7 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
if (!next_pattern.enable)
goto out;
- rtwvif->rate_pattern = next_pattern;
+ rtwvif_link->rate_pattern = next_pattern;
rtw89_debug(rtwdev, RTW89_DBG_RA,
"configure pattern: rate 0x%x, mask 0x%llx, mode 0x%x\n",
next_pattern.rate,
@@ -609,10 +633,22 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
return;
out:
- rtwvif->rate_pattern.enable = false;
+ rtwvif_link->rate_pattern.enable = false;
rtw89_debug(rtwdev, RTW89_DBG_RA, "unset rate pattern\n");
}
+void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ __rtw89_phy_rate_pattern_vif(rtwdev, rtwvif_link, mask);
+}
+
static void rtw89_phy_ra_update_sta_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_dev *rtwdev = (struct rtw89_dev *)data;
@@ -627,14 +663,24 @@ void rtw89_phy_ra_update(struct rtw89_dev *rtwdev)
rtwdev);
}
-void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta)
+void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_ra_info *ra = &rtwsta->ra;
- u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR;
- bool csi = rtw89_sta_has_beamformer_cap(sta);
+ struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_ra_info *ra = &rtwsta_link->ra;
+ u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR;
+ struct ieee80211_link_sta *link_sta;
+ bool csi;
- rtw89_phy_ra_sta_update(rtwdev, sta, csi);
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ csi = rtw89_sta_has_beamformer_cap(link_sta);
+
+ rtw89_phy_ra_sta_update(rtwdev, rtwvif_link, rtwsta_link,
+ link_sta, vif->p2p, csi);
+
+ rcu_read_unlock();
if (rssi > 40)
ra->init_rate_lv = 1;
@@ -1068,14 +1114,21 @@ static bool rtw89_chip_rf_v1(struct rtw89_dev *rtwdev)
return rtwdev->chip->ops->write_rf == rtw89_phy_write_rf_v1;
}
-static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+static void __rtw89_phy_bb_reset(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
chip->ops->bb_reset(rtwdev, phy_idx);
}
+static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev)
+{
+ __rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0);
+ if (rtwdev->dbcc_en)
+ __rtw89_phy_bb_reset(rtwdev, RTW89_PHY_1);
+}
+
static void rtw89_phy_config_bb_reg(struct rtw89_dev *rtwdev,
const struct rtw89_reg2_def *reg,
enum rtw89_rf_path rf_path,
@@ -1621,13 +1674,15 @@ void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev)
if (rtwdev->dbcc_en)
rtw89_phy_init_reg(rtwdev, bb_table, rtw89_phy_config_bb_reg,
(void *)RTW89_PHY_1);
- rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0);
+
+ rtw89_chip_init_txpwr_unit(rtwdev);
bb_gain_table = elm_info->bb_gain ? elm_info->bb_gain : chip->bb_gain_table;
if (bb_gain_table)
rtw89_phy_init_reg(rtwdev, bb_gain_table,
chip->phy_def->config_bb_gain, NULL);
- rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0);
+
+ rtw89_phy_bb_reset(rtwdev);
}
static u32 rtw89_phy_nctl_poll(struct rtw89_dev *rtwdev)
@@ -1747,6 +1802,24 @@ void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
}
EXPORT_SYMBOL(rtw89_phy_write32_idx);
+void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
+ enum rtw89_phy_idx phy_idx)
+{
+ if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1)
+ addr += rtw89_phy0_phy1_offset(rtwdev, addr);
+ rtw89_phy_write32_set(rtwdev, addr, bits);
+}
+EXPORT_SYMBOL(rtw89_phy_write32_idx_set);
+
+void rtw89_phy_write32_idx_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
+ enum rtw89_phy_idx phy_idx)
+{
+ if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1)
+ addr += rtw89_phy0_phy1_offset(rtwdev, addr);
+ rtw89_phy_write32_clr(rtwdev, addr, bits);
+}
+EXPORT_SYMBOL(rtw89_phy_write32_idx_clr);
+
u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
enum rtw89_phy_idx phy_idx)
{
@@ -2553,14 +2626,14 @@ struct rtw89_phy_iter_ra_data {
struct sk_buff *c2h;
};
-static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
+static void __rtw89_phy_c2h_ra_rpt_iter(struct rtw89_sta_link *rtwsta_link,
+ struct ieee80211_link_sta *link_sta,
+ struct rtw89_phy_iter_ra_data *ra_data)
{
- struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data;
struct rtw89_dev *rtwdev = ra_data->rtwdev;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
const struct rtw89_c2h_ra_rpt *c2h =
(const struct rtw89_c2h_ra_rpt *)ra_data->c2h->data;
- struct rtw89_ra_report *ra_report = &rtwsta->ra_report;
+ struct rtw89_ra_report *ra_report = &rtwsta_link->ra_report;
const struct rtw89_chip_info *chip = rtwdev->chip;
bool format_v1 = chip->chip_gen == RTW89_CHIP_BE;
u8 mode, rate, bw, giltf, mac_id;
@@ -2570,7 +2643,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
u8 t;
mac_id = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_MACID);
- if (mac_id != rtwsta->mac_id)
+ if (mac_id != rtwsta_link->mac_id)
return;
rate = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MCSNSS);
@@ -2661,8 +2734,26 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
u16_encode_bits(mode, RTW89_HW_RATE_MASK_MOD) |
u16_encode_bits(rate, RTW89_HW_RATE_MASK_VAL);
ra_report->might_fallback_legacy = mcs <= 2;
- sta->deflink.agg.max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report);
- rtwsta->max_agg_wait = sta->deflink.agg.max_rc_amsdu_len / 1500 - 1;
+ link_sta->agg.max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report);
+ rtwsta_link->max_agg_wait = link_sta->agg.max_rc_amsdu_len / 1500 - 1;
+}
+
+static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_sta_link *rtwsta_link;
+ struct ieee80211_link_sta *link_sta;
+ unsigned int link_id;
+
+ rcu_read_lock();
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
+ __rtw89_phy_c2h_ra_rpt_iter(rtwsta_link, link_sta, ra_data);
+ }
+
+ rcu_read_unlock();
}
static void
@@ -2692,9 +2783,85 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
struct rtw89_c2h_rf_txgapk_rpt_log *txgapk;
struct rtw89_c2h_rf_rxdck_rpt_log *rxdck;
struct rtw89_c2h_rf_dack_rpt_log *dack;
+ struct rtw89_c2h_rf_tssi_rpt_log *tssi;
struct rtw89_c2h_rf_dpk_rpt_log *dpk;
+ struct rtw89_c2h_rf_iqk_rpt_log *iqk;
+ int i, j, k;
switch (func) {
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_IQK:
+ if (len != sizeof(*iqk))
+ goto out;
+
+ iqk = content;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->is_iqk_init = %x\n", iqk->is_iqk_init);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->is_reload = %x\n", iqk->is_reload);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->is_nbiqk = %x\n", iqk->is_nbiqk);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->txiqk_en = %x\n", iqk->txiqk_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->rxiqk_en = %x\n", iqk->rxiqk_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->lok_en = %x\n", iqk->lok_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->iqk_xym_en = %x\n", iqk->iqk_xym_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->iqk_sram_en = %x\n", iqk->iqk_sram_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->iqk_fft_en = %x\n", iqk->iqk_fft_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->is_fw_iqk = %x\n", iqk->is_fw_iqk);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->is_iqk_enable = %x\n", iqk->is_iqk_enable);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->iqk_cfir_en = %x\n", iqk->iqk_cfir_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->thermal_rek_en = %x\n", iqk->thermal_rek_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->version = %x\n", iqk->version);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->phy = %x\n", iqk->phy);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->fwk_status = %x\n", iqk->fwk_status);
+
+ for (i = 0; i < 2; i++) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] ======== Path %x ========\n", i);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_band[%d] = %x\n",
+ i, iqk->iqk_band[i]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_ch[%d] = %x\n",
+ i, iqk->iqk_ch[i]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_bw[%d] = %x\n",
+ i, iqk->iqk_bw[i]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_idac[%d] = %x\n",
+ i, le32_to_cpu(iqk->lok_idac[i]));
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_vbuf[%d] = %x\n",
+ i, le32_to_cpu(iqk->lok_vbuf[i]));
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_tx_fail[%d] = %x\n",
+ i, iqk->iqk_tx_fail[i]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_rx_fail[%d] = %x\n",
+ i, iqk->iqk_rx_fail[i]);
+ for (j = 0; j < 4; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->rftxgain[%d][%d] = %x\n",
+ i, j, le32_to_cpu(iqk->rftxgain[i][j]));
+ for (j = 0; j < 4; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->tx_xym[%d][%d] = %x\n",
+ i, j, le32_to_cpu(iqk->tx_xym[i][j]));
+ for (j = 0; j < 4; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->rfrxgain[%d][%d] = %x\n",
+ i, j, le32_to_cpu(iqk->rfrxgain[i][j]));
+ for (j = 0; j < 4; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->rx_xym[%d][%d] = %x\n",
+ i, j, le32_to_cpu(iqk->rx_xym[i][j]));
+ }
+ return;
case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK:
if (len != sizeof(*dpk))
goto out;
@@ -2716,8 +2883,23 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
dack = content;
- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ver=0x%x 0x%x\n",
- dack->fwdack_ver, dack->fwdack_rpt_ver);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]FWDACK SUMMARY!!!!!\n");
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]FWDACK ver = 0x%x, FWDACK rpt_ver = 0x%x, driver rpt_ver = 0x%x\n",
+ dack->fwdack_ver, dack->fwdack_info_ver, 0x2);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]timeout code = [0x%x 0x%x 0x%x 0x%x 0x%x]\n",
+ dack->addck_timeout, dack->cdack_timeout, dack->dadck_timeout,
+ dack->adgaink_timeout, dack->msbk_timeout);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]DACK fail = 0x%x\n", dack->dack_fail);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]S0 WBADCK = [0x%x]\n", dack->wbdck_d[0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]S1 WBADCK = [0x%x]\n", dack->wbdck_d[1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]DRCK = [0x%x]\n", dack->rck_d);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK ic = [0x%x, 0x%x]\n",
dack->cdack_d[0][0][0], dack->cdack_d[0][0][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK qc = [0x%x, 0x%x]\n",
@@ -2728,13 +2910,17 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
dack->cdack_d[1][1][0], dack->cdack_d[1][1][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK ic = [0x%x, 0x%x]\n",
- dack->addck2_d[0][0][0], dack->addck2_d[0][0][1]);
+ ((u32)dack->addck2_hd[0][0][0] << 8) | dack->addck2_ld[0][0][0],
+ ((u32)dack->addck2_hd[0][0][1] << 8) | dack->addck2_ld[0][0][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK qc = [0x%x, 0x%x]\n",
- dack->addck2_d[0][1][0], dack->addck2_d[0][1][1]);
+ ((u32)dack->addck2_hd[0][1][0] << 8) | dack->addck2_ld[0][1][0],
+ ((u32)dack->addck2_hd[0][1][1] << 8) | dack->addck2_ld[0][1][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK ic = [0x%x, 0x%x]\n",
- dack->addck2_d[1][0][0], dack->addck2_d[1][0][1]);
+ ((u32)dack->addck2_hd[1][0][0] << 8) | dack->addck2_ld[1][0][0],
+ ((u32)dack->addck2_hd[1][0][1] << 8) | dack->addck2_ld[1][0][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK qc = [0x%x, 0x%x]\n",
- dack->addck2_d[1][1][0], dack->addck2_d[1][1][1]);
+ ((u32)dack->addck2_hd[1][1][0] << 8) | dack->addck2_ld[1][1][0],
+ ((u32)dack->addck2_hd[1][1][1] << 8) | dack->addck2_ld[1][1][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_GAINK ic = 0x%x, qc = 0x%x\n",
dack->adgaink_d[0][0], dack->adgaink_d[0][1]);
@@ -2747,18 +2933,29 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
dack->dadck_d[1][0], dack->dadck_d[1][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 biask iqc = 0x%x\n",
- dack->biask_d[0][0]);
+ ((u32)dack->biask_hd[0][0] << 8) | dack->biask_ld[0][0]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 biask iqc = 0x%x\n",
- dack->biask_d[1][0]);
-
- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic: %*ph\n",
- (int)sizeof(dack->msbk_d[0][0]), dack->msbk_d[0][0]);
- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc: %*ph\n",
- (int)sizeof(dack->msbk_d[0][1]), dack->msbk_d[0][1]);
- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic: %*ph\n",
- (int)sizeof(dack->msbk_d[1][0]), dack->msbk_d[1][0]);
- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc: %*ph\n",
- (int)sizeof(dack->msbk_d[1][1]), dack->msbk_d[1][1]);
+ ((u32)dack->biask_hd[1][0] << 8) | dack->biask_ld[1][0]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n");
+ for (i = 0; i < 0x10; i++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
+ dack->msbk_d[0][0][i]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n");
+ for (i = 0; i < 0x10; i++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
+ dack->msbk_d[0][1][i]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n");
+ for (i = 0; i < 0x10; i++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
+ dack->msbk_d[1][0][i]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n");
+ for (i = 0; i < 0x10; i++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
+ dack->msbk_d[1][1][i]);
return;
case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK:
if (len != sizeof(*rxdck))
@@ -2770,6 +2967,39 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
rxdck->ver, rxdck->band, rxdck->bw, rxdck->ch,
rxdck->timeout);
return;
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI:
+ if (len != sizeof(*tssi))
+ goto out;
+
+ tssi = content;
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ for (k = 0; k < 4; k++) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] alignment_power_cw_h[%d][%d][%d]=%d\n",
+ i, j, k, tssi->alignment_power_cw_h[i][j][k]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] alignment_power_cw_l[%d][%d][%d]=%d\n",
+ i, j, k, tssi->alignment_power_cw_l[i][j][k]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] alignment_power[%d][%d][%d]=%d\n",
+ i, j, k, tssi->alignment_power[i][j][k]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] alignment_power_cw[%d][%d][%d]=%d\n",
+ i, j, k,
+ (tssi->alignment_power_cw_h[i][j][k] << 8) +
+ tssi->alignment_power_cw_l[i][j][k]);
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] tssi_alimk_state[%d][%d]=%d\n",
+ i, j, tssi->tssi_alimk_state[i][j]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] default_txagc_offset[%d]=%d\n",
+ j, tssi->default_txagc_offset[0][j]);
+ }
+ }
+ return;
case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK:
if (len != sizeof(*txgapk))
goto out;
@@ -3171,13 +3401,13 @@ EXPORT_SYMBOL(rtw89_phy_rfk_dack_and_wait);
int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan,
- unsigned int ms)
+ bool is_chl_k, unsigned int ms)
{
int ret;
rtw89_phy_rfk_report_prep(rtwdev);
- ret = rtw89_fw_h2c_rf_rxdck(rtwdev, phy_idx, chan);
+ ret = rtw89_fw_h2c_rf_rxdck(rtwdev, phy_idx, chan, is_chl_k);
if (ret)
return ret;
@@ -4290,33 +4520,33 @@ void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val,
cfo->packet_count++;
}
-void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->chanctx_idx);
+ rtwvif_link->chanctx_idx);
struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info;
if (!chip->ul_tb_waveform_ctrl)
return;
- rtwvif->def_tri_idx =
+ rtwvif_link->def_tri_idx =
rtw89_phy_read32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG);
if (chip->chip_id == RTL8852B && rtwdev->hal.cv > CHIP_CBV)
- rtwvif->dyn_tb_bedge_en = false;
+ rtwvif_link->dyn_tb_bedge_en = false;
else if (chan->band_type >= RTW89_BAND_5G &&
chan->band_width >= RTW89_CHANNEL_WIDTH_40)
- rtwvif->dyn_tb_bedge_en = true;
+ rtwvif_link->dyn_tb_bedge_en = true;
else
- rtwvif->dyn_tb_bedge_en = false;
+ rtwvif_link->dyn_tb_bedge_en = false;
rtw89_debug(rtwdev, RTW89_DBG_UL_TB,
"[ULTB] def_if_bandedge=%d, def_tri_idx=%d\n",
- ul_tb_info->def_if_bandedge, rtwvif->def_tri_idx);
+ ul_tb_info->def_if_bandedge, rtwvif_link->def_tri_idx);
rtw89_debug(rtwdev, RTW89_DBG_UL_TB,
"[ULTB] dyn_tb_begde_en=%d, dyn_tb_tri_en=%d\n",
- rtwvif->dyn_tb_bedge_en, ul_tb_info->dyn_tb_tri_en);
+ rtwvif_link->dyn_tb_bedge_en, ul_tb_info->dyn_tb_tri_en);
}
struct rtw89_phy_ul_tb_check_data {
@@ -4338,7 +4568,7 @@ struct rtw89_phy_power_diff {
};
static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
static const struct rtw89_phy_power_diff table[2] = {
{0x0, 0x0, 0x0, 0x0, 0xf4, 0x3, 0x3},
@@ -4350,13 +4580,13 @@ static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev,
if (!rtwdev->chip->ul_tb_pwr_diff)
return;
- if (rtwvif->pwr_diff_en == rtwvif->pre_pwr_diff_en) {
- rtwvif->pwr_diff_en = false;
+ if (rtwvif_link->pwr_diff_en == rtwvif_link->pre_pwr_diff_en) {
+ rtwvif_link->pwr_diff_en = false;
return;
}
- rtwvif->pre_pwr_diff_en = rtwvif->pwr_diff_en;
- param = &table[rtwvif->pwr_diff_en];
+ rtwvif_link->pre_pwr_diff_en = rtwvif_link->pwr_diff_en;
+ param = &table[rtwvif_link->pwr_diff_en];
rtw89_phy_write32_mask(rtwdev, R_Q_MATRIX_00, B_Q_MATRIX_00_REAL,
param->q_00);
@@ -4365,32 +4595,32 @@ static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev,
rtw89_phy_write32_mask(rtwdev, R_CUSTOMIZE_Q_MATRIX,
B_CUSTOMIZE_Q_MATRIX_EN, param->q_matrix_en);
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_NORM_BW160,
param->ultb_1t_norm_160);
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_NORM_BW160,
param->ultb_2t_norm_160);
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM1, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM1, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PATH_COM1_NORM_1STS,
param->com1_norm_1sts);
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM2, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM2, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PATH_COM2_RESP_1STS_PATH,
param->com2_resp_1sts_path);
}
static
void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct rtw89_phy_ul_tb_check_data *ul_tb_data)
{
struct rtw89_traffic_stats *stats = &rtwdev->stats;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
- if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION)
+ if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION)
return;
if (!vif->cfg.assoc)
@@ -4403,11 +4633,11 @@ void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev,
ul_tb_data->low_tf_client = true;
ul_tb_data->valid = true;
- ul_tb_data->def_tri_idx = rtwvif->def_tri_idx;
- ul_tb_data->dyn_tb_bedge_en = rtwvif->dyn_tb_bedge_en;
+ ul_tb_data->def_tri_idx = rtwvif_link->def_tri_idx;
+ ul_tb_data->dyn_tb_bedge_en = rtwvif_link->dyn_tb_bedge_en;
}
- rtw89_phy_ofdma_power_diff(rtwdev, rtwvif);
+ rtw89_phy_ofdma_power_diff(rtwdev, rtwvif_link);
}
static void rtw89_phy_ul_tb_waveform_ctrl(struct rtw89_dev *rtwdev,
@@ -4453,7 +4683,9 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_phy_ul_tb_check_data ul_tb_data = {};
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
if (!chip->ul_tb_waveform_ctrl && !chip->ul_tb_pwr_diff)
return;
@@ -4462,7 +4694,8 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev)
return;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif, &ul_tb_data);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif_link, &ul_tb_data);
if (!ul_tb_data.valid)
return;
@@ -4626,30 +4859,42 @@ struct rtw89_phy_iter_rssi_data {
bool rssi_changed;
};
-static void rtw89_phy_stat_rssi_update_iter(void *data,
- struct ieee80211_sta *sta)
+static
+void __rtw89_phy_stat_rssi_update_iter(struct rtw89_sta_link *rtwsta_link,
+ struct rtw89_phy_iter_rssi_data *rssi_data)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_phy_iter_rssi_data *rssi_data =
- (struct rtw89_phy_iter_rssi_data *)data;
struct rtw89_phy_ch_info *ch_info = rssi_data->ch_info;
unsigned long rssi_curr;
- rssi_curr = ewma_rssi_read(&rtwsta->avg_rssi);
+ rssi_curr = ewma_rssi_read(&rtwsta_link->avg_rssi);
if (rssi_curr < ch_info->rssi_min) {
ch_info->rssi_min = rssi_curr;
- ch_info->rssi_min_macid = rtwsta->mac_id;
+ ch_info->rssi_min_macid = rtwsta_link->mac_id;
}
- if (rtwsta->prev_rssi == 0) {
- rtwsta->prev_rssi = rssi_curr;
- } else if (abs((int)rtwsta->prev_rssi - (int)rssi_curr) > (3 << RSSI_FACTOR)) {
- rtwsta->prev_rssi = rssi_curr;
+ if (rtwsta_link->prev_rssi == 0) {
+ rtwsta_link->prev_rssi = rssi_curr;
+ } else if (abs((int)rtwsta_link->prev_rssi - (int)rssi_curr) >
+ (3 << RSSI_FACTOR)) {
+ rtwsta_link->prev_rssi = rssi_curr;
rssi_data->rssi_changed = true;
}
}
+static void rtw89_phy_stat_rssi_update_iter(void *data,
+ struct ieee80211_sta *sta)
+{
+ struct rtw89_phy_iter_rssi_data *rssi_data =
+ (struct rtw89_phy_iter_rssi_data *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
+ __rtw89_phy_stat_rssi_update_iter(rtwsta_link, rssi_data);
+}
+
static void rtw89_phy_stat_rssi_update(struct rtw89_dev *rtwdev)
{
struct rtw89_phy_iter_rssi_data rssi_data = {0};
@@ -4676,6 +4921,8 @@ static void rtw89_phy_stat_init(struct rtw89_dev *rtwdev)
memset(&phystat->cur_pkt_stat, 0, sizeof(phystat->cur_pkt_stat));
memset(&phystat->last_pkt_stat, 0, sizeof(phystat->last_pkt_stat));
+
+ ewma_rssi_init(&phystat->bcn_rssi);
}
void rtw89_phy_stat_track(struct rtw89_dev *rtwdev)
@@ -5188,7 +5435,8 @@ static u32 rtw89_phy_get_ie_bitmap_addr(enum rtw89_phy_status_bitmap ie_page)
}
static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev,
- enum rtw89_phy_status_bitmap ie_page)
+ enum rtw89_phy_status_bitmap ie_page,
+ enum rtw89_phy_idx phy_idx)
{
u32 addr;
@@ -5197,12 +5445,12 @@ static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev,
addr = rtw89_phy_get_ie_bitmap_addr(ie_page);
- return rtw89_phy_read32(rtwdev, addr);
+ return rtw89_phy_read32_idx(rtwdev, addr, MASKDWORD, phy_idx);
}
static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev,
enum rtw89_phy_status_bitmap ie_page,
- u32 val)
+ u32 val, enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 addr;
@@ -5214,22 +5462,22 @@ static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev,
val &= B_PHY_STS_BITMAP_MSK_52A;
addr = rtw89_phy_get_ie_bitmap_addr(ie_page);
- rtw89_phy_write32(rtwdev, addr, val);
+ rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx);
}
static void rtw89_physts_enable_ie_bitmap(struct rtw89_dev *rtwdev,
enum rtw89_phy_status_bitmap bitmap,
enum rtw89_phy_status_ie_type ie,
- bool enable)
+ bool enable, enum rtw89_phy_idx phy_idx)
{
- u32 val = rtw89_physts_get_ie_bitmap(rtwdev, bitmap);
+ u32 val = rtw89_physts_get_ie_bitmap(rtwdev, bitmap, phy_idx);
if (enable)
val |= BIT(ie);
else
val &= ~BIT(ie);
- rtw89_physts_set_ie_bitmap(rtwdev, bitmap, val);
+ rtw89_physts_set_ie_bitmap(rtwdev, bitmap, val, phy_idx);
}
static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev,
@@ -5240,44 +5488,52 @@ static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev,
const struct rtw89_physts_regs *physts = phy->physts;
if (enable) {
- rtw89_phy_write32_clr(rtwdev, physts->setting_addr,
- physts->dis_trigger_fail_mask);
- rtw89_phy_write32_clr(rtwdev, physts->setting_addr,
- physts->dis_trigger_brk_mask);
+ rtw89_phy_write32_idx_clr(rtwdev, physts->setting_addr,
+ physts->dis_trigger_fail_mask, phy_idx);
+ rtw89_phy_write32_idx_clr(rtwdev, physts->setting_addr,
+ physts->dis_trigger_brk_mask, phy_idx);
} else {
- rtw89_phy_write32_set(rtwdev, physts->setting_addr,
- physts->dis_trigger_fail_mask);
- rtw89_phy_write32_set(rtwdev, physts->setting_addr,
- physts->dis_trigger_brk_mask);
+ rtw89_phy_write32_idx_set(rtwdev, physts->setting_addr,
+ physts->dis_trigger_fail_mask, phy_idx);
+ rtw89_phy_write32_idx_set(rtwdev, physts->setting_addr,
+ physts->dis_trigger_brk_mask, phy_idx);
}
}
-static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev)
+static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
u8 i;
- rtw89_physts_enable_fail_report(rtwdev, false, RTW89_PHY_0);
+ rtw89_physts_enable_fail_report(rtwdev, false, phy_idx);
for (i = 0; i < RTW89_PHYSTS_BITMAP_NUM; i++) {
if (i >= RTW89_CCK_PKT)
rtw89_physts_enable_ie_bitmap(rtwdev, i,
RTW89_PHYSTS_IE09_FTR_0,
- true);
+ true, phy_idx);
if ((i >= RTW89_CCK_BRK && i <= RTW89_VHT_MU) ||
(i >= RTW89_RSVD_9 && i <= RTW89_CCK_PKT))
continue;
rtw89_physts_enable_ie_bitmap(rtwdev, i,
RTW89_PHYSTS_IE24_OFDM_TD_PATH_A,
- true);
+ true, phy_idx);
}
rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_VHT_PKT,
- RTW89_PHYSTS_IE13_DL_MU_DEF, true);
+ RTW89_PHYSTS_IE13_DL_MU_DEF, true, phy_idx);
rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_HE_PKT,
- RTW89_PHYSTS_IE13_DL_MU_DEF, true);
+ RTW89_PHYSTS_IE13_DL_MU_DEF, true, phy_idx);
/* force IE01 for channel index, only channel field is valid */
rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_CCK_PKT,
- RTW89_PHYSTS_IE01_CMN_OFDM, true);
+ RTW89_PHYSTS_IE01_CMN_OFDM, true, phy_idx);
+}
+
+static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev)
+{
+ __rtw89_physts_parsing_init(rtwdev, RTW89_PHY_0);
+ if (rtwdev->dbcc_en)
+ __rtw89_physts_parsing_init(rtwdev, RTW89_PHY_1);
}
static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type)
@@ -5753,26 +6009,15 @@ void rtw89_phy_dig(struct rtw89_dev *rtwdev)
rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, false);
}
-static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta)
+static void __rtw89_phy_tx_path_div_sta_iter(struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_dev *rtwdev = rtwsta->rtwdev;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_hal *hal = &rtwdev->hal;
- bool *done = data;
u8 rssi_a, rssi_b;
u32 candidate;
- if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION || sta->tdls)
- return;
-
- if (*done)
- return;
-
- *done = true;
-
- rssi_a = ewma_rssi_read(&rtwsta->rssi[RF_PATH_A]);
- rssi_b = ewma_rssi_read(&rtwsta->rssi[RF_PATH_B]);
+ rssi_a = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_A]);
+ rssi_b = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_B]);
if (rssi_a > rssi_b + RTW89_TX_DIV_RSSI_RAW_TH)
candidate = RF_A;
@@ -5785,7 +6030,7 @@ static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta
return;
hal->antenna_tx = candidate;
- rtw89_fw_h2c_txpath_cmac_tbl(rtwdev, rtwsta);
+ rtw89_fw_h2c_txpath_cmac_tbl(rtwdev, rtwsta_link);
if (hal->antenna_tx == RF_A) {
rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, B_P0_RFMODE_MUX, 0x12);
@@ -5796,6 +6041,37 @@ static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta
}
}
+static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ bool *done = data;
+
+ if (WARN(ieee80211_vif_is_mld(vif), "MLD mix path_div\n"))
+ return;
+
+ if (sta->tdls)
+ return;
+
+ if (*done)
+ return;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION)
+ continue;
+
+ *done = true;
+ __rtw89_phy_tx_path_div_sta_iter(rtwdev, rtwsta_link);
+ return;
+ }
+}
+
void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
@@ -6002,17 +6278,27 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
rtw89_chip_cfg_txrx_path(rtwdev);
}
-void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_reg_def *bss_clr_vld = &chip->bss_clr_vld;
- enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
+ struct ieee80211_bss_conf *bss_conf;
u8 bss_color;
- if (!vif->bss_conf.he_support || !vif->cfg.assoc)
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ if (!bss_conf->he_support || !vif->cfg.assoc) {
+ rcu_read_unlock();
return;
+ }
+
+ bss_color = bss_conf->he_bss_color.color;
- bss_color = vif->bss_conf.he_bss_color.color;
+ rcu_read_unlock();
rtw89_phy_write32_idx(rtwdev, bss_clr_vld->addr, bss_clr_vld->mask, 0x1,
phy_idx);
diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
index 6dd8ec46939a..c683f4d7d29b 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.h
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
@@ -815,6 +815,10 @@ void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev,
void rtw89_phy_dm_init(struct rtw89_dev *rtwdev);
void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 data, enum rtw89_phy_idx phy_idx);
+void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
+ enum rtw89_phy_idx phy_idx);
+void rtw89_phy_write32_idx_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
+ enum rtw89_phy_idx phy_idx);
u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
enum rtw89_phy_idx phy_idx);
s8 *rtw89_phy_raw_byr_seek(struct rtw89_dev *rtwdev,
@@ -892,7 +896,7 @@ void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
phy->set_txpwr_limit_ru(rtwdev, chan, phy_idx);
}
-void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta);
+void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link);
void rtw89_phy_ra_update(struct rtw89_dev *rtwdev);
void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
u32 changed);
@@ -929,7 +933,7 @@ int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev,
int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan,
- unsigned int ms);
+ bool is_chl_k, unsigned int ms);
void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
const struct rtw89_chan *chan,
@@ -953,11 +957,12 @@ void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu);
void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev);
void rtw89_phy_antdiv_work(struct work_struct *work);
-void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
+void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev,
enum rtw89_mac_idx mac_idx,
enum rtw89_tssi_bandedge_cfg bandedge_cfg);
-void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev);
u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band);
void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
diff --git a/drivers/net/wireless/realtek/rtw89/phy_be.c b/drivers/net/wireless/realtek/rtw89/phy_be.c
index 72eda9bbd3ae..37d8f254ae32 100644
--- a/drivers/net/wireless/realtek/rtw89/phy_be.c
+++ b/drivers/net/wireless/realtek/rtw89/phy_be.c
@@ -398,10 +398,9 @@ static void rtw89_phy_bb_wrap_ul_pwr(struct rtw89_dev *rtwdev)
}
}
-static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev)
+static void __rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_idx mac_idx)
{
- enum rtw89_mac_idx mac_idx = RTW89_MAC_0;
-
rtw89_phy_bb_wrap_pwr_by_macid_init(rtwdev);
rtw89_phy_bb_wrap_tx_path_by_macid_init(rtwdev);
rtw89_phy_bb_wrap_listen_path_en_init(rtwdev);
@@ -411,6 +410,13 @@ static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev)
rtw89_phy_bb_wrap_ul_pwr(rtwdev);
}
+static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev)
+{
+ __rtw89_phy_bb_wrap_init_be(rtwdev, RTW89_MAC_0);
+ if (rtwdev->dbcc_en)
+ __rtw89_phy_bb_wrap_init_be(rtwdev, RTW89_MAC_1);
+}
+
static void rtw89_phy_ch_info_init_be(struct rtw89_dev *rtwdev)
{
rtw89_phy_write32_mask(rtwdev, R_CHINFO_SEG, B_CHINFO_SEG_LEN, 0x0);
diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c
index aebd6404f802..c1c12abc2ea9 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.c
+++ b/drivers/net/wireless/realtek/rtw89/ps.c
@@ -62,9 +62,9 @@ static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
rtw89_mac_power_mode_change(rtwdev, enter);
}
-void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- if (rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
+ if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
return;
if (!rtwdev->ps_mode)
@@ -85,23 +85,25 @@ void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
rtw89_ps_power_mode_change(rtwdev, false);
}
-static void __rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void __rtw89_enter_lps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_lps_parm lps_param = {
- .macid = rtwvif->mac_id,
+ .macid = rtwvif_link->mac_id,
.psmode = RTW89_MAC_AX_PS_MODE_LEGACY,
.lastrpwm = RTW89_LAST_RPWM_PS,
};
rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_FW_CTRL);
rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
- rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif);
+ rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif_link);
}
-static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void __rtw89_leave_lps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_lps_parm lps_param = {
- .macid = rtwvif->mac_id,
+ .macid = rtwvif_link->mac_id,
.psmode = RTW89_MAC_AX_PS_MODE_ACTIVE,
.lastrpwm = RTW89_LAST_RPWM_ACTIVE,
};
@@ -109,7 +111,7 @@ static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
rtw89_fw_leave_lps_check(rtwdev, 0);
rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON);
- rtw89_chip_digital_pwr_comp(rtwdev, rtwvif->phy_idx);
+ rtw89_chip_digital_pwr_comp(rtwdev, rtwvif_link->phy_idx);
}
void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
@@ -119,7 +121,7 @@ void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
__rtw89_leave_ps_mode(rtwdev);
}
-void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool ps_mode)
{
lockdep_assert_held(&rtwdev->mutex);
@@ -127,23 +129,26 @@ void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags))
return;
- __rtw89_enter_lps(rtwdev, rtwvif);
+ __rtw89_enter_lps(rtwdev, rtwvif_link);
if (ps_mode)
- __rtw89_enter_ps_mode(rtwdev, rtwvif);
+ __rtw89_enter_ps_mode(rtwdev, rtwvif_link);
}
-static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION &&
- rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
+ if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION &&
+ rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
return;
- __rtw89_leave_lps(rtwdev, rtwvif);
+ __rtw89_leave_lps(rtwdev, rtwvif_link);
}
void rtw89_leave_lps(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
lockdep_assert_held(&rtwdev->mutex);
@@ -153,12 +158,15 @@ void rtw89_leave_lps(struct rtw89_dev *rtwdev)
__rtw89_leave_ps_mode(rtwdev);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_leave_lps_vif(rtwdev, rtwvif);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_leave_lps_vif(rtwdev, rtwvif_link);
}
void rtw89_enter_ips(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags);
@@ -166,14 +174,17 @@ void rtw89_enter_ips(struct rtw89_dev *rtwdev)
return;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_mac_vif_deinit(rtwdev, rtwvif);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_mac_vif_deinit(rtwdev, rtwvif_link);
rtw89_core_stop(rtwdev);
}
void rtw89_leave_ips(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
int ret;
if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
@@ -186,7 +197,8 @@ void rtw89_leave_ips(struct rtw89_dev *rtwdev)
rtw89_set_channel(rtwdev);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_mac_vif_init(rtwdev, rtwvif);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_mac_vif_init(rtwdev, rtwvif_link);
clear_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags);
}
@@ -197,48 +209,50 @@ void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl)
rtw89_leave_lps(rtwdev);
}
-static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
enum rtw89_p2pps_action act)
{
if (act == RTW89_P2P_ACT_UPDATE || act == RTW89_P2P_ACT_REMOVE)
return;
if (act == RTW89_P2P_ACT_INIT)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif, true);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, true);
else if (act == RTW89_P2P_ACT_TERMINATE)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif, false);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, false);
}
static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif)
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
enum rtw89_p2pps_action act;
u8 noa_id;
- if (rtwvif->last_noa_nr == 0)
+ if (rtwvif_link->last_noa_nr == 0)
return;
- for (noa_id = 0; noa_id < rtwvif->last_noa_nr; noa_id++) {
- if (noa_id == rtwvif->last_noa_nr - 1)
+ for (noa_id = 0; noa_id < rtwvif_link->last_noa_nr; noa_id++) {
+ if (noa_id == rtwvif_link->last_noa_nr - 1)
act = RTW89_P2P_ACT_TERMINATE;
else
act = RTW89_P2P_ACT_REMOVE;
- rtw89_tsf32_toggle(rtwdev, rtwvif, act);
- rtw89_fw_h2c_p2p_act(rtwdev, vif, NULL, act, noa_id);
+ rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
+ rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf,
+ NULL, act, noa_id);
}
}
static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif)
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct ieee80211_p2p_noa_desc *desc;
enum rtw89_p2pps_action act;
u8 noa_id;
for (noa_id = 0; noa_id < RTW89_P2P_MAX_NOA_NUM; noa_id++) {
- desc = &vif->bss_conf.p2p_noa_attr.desc[noa_id];
+ desc = &bss_conf->p2p_noa_attr.desc[noa_id];
if (!desc->count || !desc->duration)
break;
@@ -246,16 +260,19 @@ static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
act = RTW89_P2P_ACT_INIT;
else
act = RTW89_P2P_ACT_UPDATE;
- rtw89_tsf32_toggle(rtwdev, rtwvif, act);
- rtw89_fw_h2c_p2p_act(rtwdev, vif, desc, act, noa_id);
+ rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
+ rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf,
+ desc, act, noa_id);
}
- rtwvif->last_noa_nr = noa_id;
+ rtwvif_link->last_noa_nr = noa_id;
}
-void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf)
{
- rtw89_p2p_disable_all_noa(rtwdev, vif);
- rtw89_p2p_update_noa(rtwdev, vif);
+ rtw89_p2p_disable_all_noa(rtwdev, rtwvif_link, bss_conf);
+ rtw89_p2p_update_noa(rtwdev, rtwvif_link, bss_conf);
}
void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
@@ -265,6 +282,12 @@ void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
enum rtw89_entity_mode mode;
int count = 0;
+ /* FIXME: Fix rtw89_enter_lps() and __rtw89_enter_ps_mode()
+ * to take MLO cases into account before doing the following.
+ */
+ if (rtwdev->support_mlo)
+ goto disable_lps;
+
mode = rtw89_get_entity_mode(rtwdev);
if (mode == RTW89_ENTITY_MODE_MCC)
goto disable_lps;
@@ -291,9 +314,9 @@ disable_lps:
rtwdev->lps_enabled = false;
}
-void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif)
+void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link)
{
- struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
+ struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa;
struct rtw89_p2p_noa_ie *ie = &setter->ie;
struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head;
struct rtw89_noa_attr_head *noa_head = &ie->noa_head;
@@ -318,10 +341,10 @@ void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif)
noa_head->oppps_ctwindow = 0;
}
-void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
+void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link,
const struct ieee80211_p2p_noa_desc *desc)
{
- struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
+ struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa;
struct rtw89_p2p_noa_ie *ie = &setter->ie;
struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head;
struct rtw89_noa_attr_head *noa_head = &ie->noa_head;
@@ -338,9 +361,9 @@ void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
ie->noa_desc[setter->noa_count++] = *desc;
}
-u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data)
+u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data)
{
- struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
+ struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa;
struct rtw89_p2p_noa_ie *ie = &setter->ie;
void *tail;
diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h
index 54486e4550b6..cdd712966b09 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.h
+++ b/drivers/net/wireless/realtek/rtw89/ps.h
@@ -5,21 +5,23 @@
#ifndef __RTW89_PS_H_
#define __RTW89_PS_H_
-void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool ps_mode);
void rtw89_leave_lps(struct rtw89_dev *rtwdev);
void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
-void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
void rtw89_enter_ips(struct rtw89_dev *rtwdev);
void rtw89_leave_ips(struct rtw89_dev *rtwdev);
void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl);
-void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
+void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf);
void rtw89_recalc_lps(struct rtw89_dev *rtwdev);
-void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif);
-void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
+void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link);
+void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link,
const struct ieee80211_p2p_noa_desc *desc);
-u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data);
+u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data);
static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev)
{
diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c
index a7720a1f17a7..bb064a086970 100644
--- a/drivers/net/wireless/realtek/rtw89/regd.c
+++ b/drivers/net/wireless/realtek/rtw89/regd.c
@@ -793,22 +793,26 @@ static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
struct rtw89_reg_6ghz_tpe new = {};
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
bool changed = false;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
const struct rtw89_reg_6ghz_tpe *tmp;
const struct rtw89_chan *chan;
- chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
- if (chan->band_type != RTW89_BAND_6G)
- continue;
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ if (chan->band_type != RTW89_BAND_6G)
+ continue;
- tmp = &rtwvif->reg_6ghz_tpe;
- if (!tmp->valid)
- continue;
+ tmp = &rtwvif_link->reg_6ghz_tpe;
+ if (!tmp->valid)
+ continue;
- tpe_intersect_constraint(&new, tmp->constraint);
+ tpe_intersect_constraint(&new, tmp->constraint);
+ }
}
if (memcmp(&regulatory->reg_6ghz_tpe, &new,
@@ -831,19 +835,24 @@ static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev)
}
static int rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool active,
+ struct rtw89_vif_link *rtwvif_link, bool active,
unsigned int *changed)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- struct rtw89_reg_6ghz_tpe *tpe = &rtwvif->reg_6ghz_tpe;
+ struct rtw89_reg_6ghz_tpe *tpe = &rtwvif_link->reg_6ghz_tpe;
+ struct ieee80211_bss_conf *bss_conf;
memset(tpe, 0, sizeof(*tpe));
- if (!active || rtwvif->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD)
+ if (!active || rtwvif_link->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD)
goto bottom;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
rtw89_calculate_tpe(rtwdev, tpe, &bss_conf->tpe);
+
+ rcu_read_unlock();
+
if (!tpe->valid)
goto bottom;
@@ -867,20 +876,24 @@ static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
const struct rtw89_regd *regd = regulatory->regd;
enum rtw89_reg_6ghz_power sel;
const struct rtw89_chan *chan;
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
int count = 0;
u8 index;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
- if (chan->band_type != RTW89_BAND_6G)
- continue;
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ if (chan->band_type != RTW89_BAND_6G)
+ continue;
- if (count != 0 && rtwvif->reg_6ghz_power == sel)
- continue;
+ if (count != 0 && rtwvif_link->reg_6ghz_power == sel)
+ continue;
- sel = rtwvif->reg_6ghz_power;
- count++;
+ sel = rtwvif_link->reg_6ghz_power;
+ count++;
+ }
}
if (count != 1)
@@ -908,35 +921,41 @@ static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
}
static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool active,
+ struct rtw89_vif_link *rtwvif_link, bool active,
unsigned int *changed)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_bss_conf *bss_conf;
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
if (active) {
- switch (vif->bss_conf.power_type) {
+ switch (bss_conf->power_type) {
case IEEE80211_REG_VLP_AP:
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP;
break;
case IEEE80211_REG_LPI_AP:
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI;
break;
case IEEE80211_REG_SP_AP:
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD;
break;
default:
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
break;
}
} else {
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
}
+ rcu_read_unlock();
+
*changed += __rtw89_reg_6ghz_power_recalc(rtwdev);
return 0;
}
-int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool active)
{
unsigned int changed = 0;
@@ -948,11 +967,11 @@ int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
* so must do reg_6ghz_tpe_recalc() after reg_6ghz_power_recalc().
*/
- ret = rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif, active, &changed);
+ ret = rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif_link, active, &changed);
if (ret)
return ret;
- ret = rtw89_reg_6ghz_tpe_recalc(rtwdev, rtwvif, active, &changed);
+ ret = rtw89_reg_6ghz_tpe_recalc(rtwdev, rtwvif_link, active, &changed);
if (ret)
return ret;
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
index 1679bd408ef3..f9766bf30e71 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
@@ -1590,10 +1590,11 @@ static void rtw8851b_rfk_init(struct rtw89_dev *rtwdev)
rtw8851b_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
}
-static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
- enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8851b_rx_dck(rtwdev, phy_idx, chanctx_idx);
rtw8851b_iqk(rtwdev, phy_idx, chanctx_idx);
@@ -1608,10 +1609,12 @@ static void rtw8851b_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw8851b_tssi_scan(rtwdev, phy_idx, chan);
}
-static void rtw8851b_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+static void rtw8851b_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool start)
{
- rtw8851b_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx, rtwvif->chanctx_idx);
+ rtw8851b_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx,
+ rtwvif_link->chanctx_idx);
}
static void rtw8851b_rfk_track(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index dde96bd63021..42d369d2e916 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -1350,10 +1350,11 @@ static void rtw8852a_rfk_init(struct rtw89_dev *rtwdev)
rtw8852a_rx_dck(rtwdev, RTW89_PHY_0, true, RTW89_CHANCTX_0);
}
-static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
- enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852a_rx_dck(rtwdev, phy_idx, true, chanctx_idx);
rtw8852a_iqk(rtwdev, phy_idx, chanctx_idx);
@@ -1368,10 +1369,11 @@ static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw8852a_tssi_scan(rtwdev, phy_idx, chan);
}
-static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool start)
{
- rtw8852a_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx);
+ rtw8852a_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx);
}
static void rtw8852a_rfk_track(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
index 12be52f76427..364aa21cbd44 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
@@ -562,10 +562,11 @@ static void rtw8852b_rfk_init(struct rtw89_dev *rtwdev)
rtw8852b_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
}
-static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
- enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852b_rx_dck(rtwdev, phy_idx, chanctx_idx);
rtw8852b_iqk(rtwdev, phy_idx, chanctx_idx);
@@ -580,10 +581,12 @@ static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw8852b_tssi_scan(rtwdev, phy_idx, chan);
}
-static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool start)
{
- rtw8852b_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx, rtwvif->chanctx_idx);
+ rtw8852b_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx,
+ rtwvif_link->chanctx_idx);
}
static void rtw8852b_rfk_track(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
index 7dfdcb5964e1..dab7e71ec6a1 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
@@ -535,10 +535,11 @@ static void rtw8852bt_rfk_init(struct rtw89_dev *rtwdev)
rtw8852bt_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
}
-static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
- enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852bt_rx_dck(rtwdev, phy_idx, chanctx_idx);
rtw8852bt_iqk(rtwdev, phy_idx, chanctx_idx);
@@ -553,10 +554,12 @@ static void rtw8852bt_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw8852bt_tssi_scan(rtwdev, phy_idx, chan);
}
-static void rtw8852bt_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+static void rtw8852bt_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool start)
{
- rtw8852bt_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx, rtwvif->chanctx_idx);
+ rtw8852bt_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx,
+ rtwvif_link->chanctx_idx);
}
static void rtw8852bt_rfk_track(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 1c6e89ab0f4b..dbe77abb2c48 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -1846,10 +1846,11 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev)
rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false);
}
-static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
- enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852c_mcc_get_ch_info(rtwdev, phy_idx);
rtw8852c_rx_dck(rtwdev, phy_idx, false);
@@ -1866,10 +1867,11 @@ static void rtw8852c_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw8852c_tssi_scan(rtwdev, phy_idx, chan);
}
-static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool start)
{
- rtw8852c_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx);
+ rtw8852c_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx);
}
static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
index 211c051c2967..3281ee9d7523 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
@@ -2350,7 +2350,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
if (dgain > 0x5fc || dgain < 0x556) {
_dpk_one_shot(rtwdev, phy, path, D_SYNC);
- dgain = _dpk_dgain_read(rtwdev);
+ _dpk_dgain_read(rtwdev);
}
if (agc_cnt == 0) {
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index 63b1ff2f98ed..58c9721ac3ab 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -13,7 +13,7 @@
#include "rtw8922a_rfk.h"
#include "util.h"
-#define RTW8922A_FW_FORMAT_MAX 1
+#define RTW8922A_FW_FORMAT_MAX 2
#define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw"
#define RTW8922A_MODULE_FIRMWARE \
RTW8922A_FW_BASENAME "-" __stringify(RTW8922A_FW_FORMAT_MAX) ".bin"
@@ -1991,14 +1991,23 @@ static void rtw8922a_rfk_init(struct rtw89_dev *rtwdev)
memset(rfk_mcc, 0, sizeof(*rfk_mcc));
}
+static void __rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
+{
+ rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
+
+ rtw89_phy_rfk_dack_and_wait(rtwdev, phy_idx, chan, 58);
+ rtw89_phy_rfk_rxdck_and_wait(rtwdev, phy_idx, chan, false, 32);
+}
+
static void rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
- rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5);
-
- rtw89_phy_rfk_dack_and_wait(rtwdev, RTW89_PHY_0, chan, 58);
- rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, 32);
+ __rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_0, chan);
+ if (rtwdev->dbcc_en)
+ __rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_1, chan);
}
static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
@@ -2020,11 +2029,12 @@ static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
}
}
-static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
- enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx);
u32 tx_en;
@@ -2035,9 +2045,9 @@ static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtw
rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
rtw89_phy_rfk_txgapk_and_wait(rtwdev, phy_idx, chan, 54);
rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, chan, 84);
- rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 6);
+ rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 20);
rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, chan, 34);
- rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, 32);
+ rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, true, 32);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_STOP);
@@ -2050,7 +2060,8 @@ static void rtw8922a_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_SCAN, 6);
}
-static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool start)
{
}
diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c
index 5fc2faa9ba5a..7b203bb7f151 100644
--- a/drivers/net/wireless/realtek/rtw89/ser.c
+++ b/drivers/net/wireless/realtek/rtw89/ser.c
@@ -300,37 +300,54 @@ static void drv_resume_rx(struct rtw89_ser *ser)
static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
- rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
- rtwvif->net_type = RTW89_NET_TYPE_NO_LINK;
- rtwvif->trigger = false;
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
rtwvif->tdls_peer = 0;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port);
+ rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK;
+ rtwvif_link->trigger = false;
+ }
}
static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_vif *target_rtwvif = (struct rtw89_vif *)data;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
if (rtwvif != target_rtwvif)
return;
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
- rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
- if (sta->tdls)
- rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam);
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
- INIT_LIST_HEAD(&rtwsta->ba_cam_list);
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
+ rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam);
+ if (sta->tdls)
+ rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam);
+
+ INIT_LIST_HEAD(&rtwsta_link->ba_cam_list);
+ }
}
static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
ieee80211_iterate_stations_atomic(rtwdev->hw,
ser_sta_deinit_cam_iter,
rtwvif);
- rtw89_cam_deinit(rtwdev, rtwvif);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_cam_deinit(rtwdev, rtwvif_link);
bitmap_zero(rtwdev->cam_info.ba_cam_map, RTW89_MAX_BA_CAM_NUM);
}
diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c
index 86e24e07780d..3e81fd974ec1 100644
--- a/drivers/net/wireless/realtek/rtw89/wow.c
+++ b/drivers/net/wireless/realtek/rtw89/wow.c
@@ -421,7 +421,8 @@ static void rtw89_wow_construct_key_info(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_key_info *key_info = &rtw_wow->key_info;
- struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
bool err = false;
rcu_read_lock();
@@ -596,7 +597,8 @@ static int rtw89_wow_get_aoac_rpt(struct rtw89_dev *rtwdev, bool rx_ready)
static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev,
u32 cipher, u8 keyidx, u8 *gtk)
{
- struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
const struct rtw89_cipher_info *cipher_info;
struct ieee80211_key_conf *rekey_conf;
struct ieee80211_key_conf *key;
@@ -632,11 +634,13 @@ static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev,
static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready)
{
- struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
struct rtw89_set_key_info_iter_data data = {.error = false,
.rx_ready = rx_ready};
+ struct ieee80211_bss_conf *bss_conf;
struct ieee80211_key_conf *key;
rcu_read_lock();
@@ -669,9 +673,15 @@ static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready)
return;
rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn);
- ieee80211_gtk_rekey_notify(wow_vif, wow_vif->bss_conf.bssid,
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ ieee80211_gtk_rekey_notify(wow_vif, bss_conf->bssid,
aoac_rpt->eapol_key_replay_count,
- GFP_KERNEL);
+ GFP_ATOMIC);
+
+ rcu_read_unlock();
}
static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)
@@ -681,27 +691,24 @@ static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)
static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev)
{
- struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
- __rtw89_enter_ps_mode(rtwdev, rtwvif);
+ __rtw89_enter_ps_mode(rtwdev, rtwvif_link);
}
static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev)
{
- struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
if (rtw89_wow_mgd_linked(rtwdev))
- rtw89_enter_lps(rtwdev, rtwvif, false);
+ rtw89_enter_lps(rtwdev, rtwvif_link, false);
else if (rtw89_wow_no_link(rtwdev))
- rtw89_fw_h2c_fwips(rtwdev, rtwvif, true);
+ rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, true);
}
static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow)
{
- struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
if (rtw89_wow_mgd_linked(rtwdev)) {
rtw89_leave_lps(rtwdev);
@@ -709,7 +716,7 @@ static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow)
if (enable_wow)
rtw89_leave_ips(rtwdev);
else
- rtw89_fw_h2c_fwips(rtwdev, rtwvif, false);
+ rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, false);
}
}
@@ -734,6 +741,8 @@ static void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable)
static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
struct cfg80211_wowlan_nd_info nd_info;
@@ -780,35 +789,34 @@ static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
break;
default:
rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason);
- ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, NULL,
- GFP_KERNEL);
+ ieee80211_report_wowlan_wakeup(wow_vif, NULL, GFP_KERNEL);
return;
}
- ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, &wakeup,
- GFP_KERNEL);
+ ieee80211_report_wowlan_wakeup(wow_vif, &wakeup, GFP_KERNEL);
}
-static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
/* Current WoWLAN function support setting of only vif in
* infra mode or no link mode. When one suitable vif is found,
* stop the iteration.
*/
- if (rtw_wow->wow_vif || vif->type != NL80211_IFTYPE_STATION)
+ if (rtw_wow->rtwvif_link || vif->type != NL80211_IFTYPE_STATION)
return;
- switch (rtwvif->net_type) {
+ switch (rtwvif_link->net_type) {
case RTW89_NET_TYPE_INFRA:
if (rtw_wow_has_mgd_features(rtwdev))
- rtw_wow->wow_vif = vif;
+ rtw_wow->rtwvif_link = rtwvif_link;
break;
case RTW89_NET_TYPE_NO_LINK:
if (rtw_wow->pno_inited)
- rtw_wow->wow_vif = vif;
+ rtw_wow->rtwvif_link = rtwvif_link;
break;
default:
break;
@@ -865,7 +873,7 @@ static u16 rtw89_calc_crc(u8 *pdata, int length)
return ~crc;
}
-static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif,
+static int rtw89_wow_pattern_get_type(struct rtw89_vif_link *rtwvif_link,
struct rtw89_wow_cam_info *rtw_pattern,
const u8 *pattern, u8 da_mask)
{
@@ -885,7 +893,7 @@ static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif,
rtw_pattern->bc = true;
else if (is_multicast_ether_addr(da))
rtw_pattern->mc = true;
- else if (ether_addr_equal(da, rtwvif->mac_addr) &&
+ else if (ether_addr_equal(da, rtwvif_link->mac_addr) &&
da_mask == GENMASK(5, 0))
rtw_pattern->uc = true;
else if (!da_mask) /*da_mask == 0 mean wildcard*/
@@ -897,7 +905,7 @@ static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif,
}
static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
const struct cfg80211_pkt_pattern *pkt_pattern,
struct rtw89_wow_cam_info *rtw_pattern)
{
@@ -916,7 +924,7 @@ static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev,
mask_len = DIV_ROUND_UP(len, 8);
memset(rtw_pattern, 0, sizeof(*rtw_pattern));
- ret = rtw89_wow_pattern_get_type(rtwvif, rtw_pattern, pattern,
+ ret = rtw89_wow_pattern_get_type(rtwvif_link, rtw_pattern, pattern,
mask[0] & GENMASK(5, 0));
if (ret)
return ret;
@@ -970,7 +978,7 @@ static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev,
}
static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct cfg80211_wowlan *wowlan)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
@@ -983,7 +991,7 @@ static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev,
for (i = 0; i < wowlan->n_patterns; i++) {
rtw_pattern = &rtw_wow->patterns[i];
- ret = rtw89_wow_pattern_generate(rtwdev, rtwvif,
+ ret = rtw89_wow_pattern_generate(rtwdev, rtwvif_link,
&wowlan->patterns[i],
rtw_pattern);
if (ret) {
@@ -1040,7 +1048,7 @@ static void rtw89_wow_clear_wakeups(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- rtw_wow->wow_vif = NULL;
+ rtw_wow->rtwvif_link = NULL;
rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM);
rtw_wow->pattern_cnt = 0;
rtw_wow->pno_inited = false;
@@ -1066,6 +1074,7 @@ static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev,
struct cfg80211_wowlan *wowlan)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
if (wowlan->disconnect)
@@ -1078,36 +1087,40 @@ static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev,
if (wowlan->nd_config)
rtw89_wow_init_pno(rtwdev, wowlan->nd_config);
- rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_wow_vif_iter(rtwdev, rtwvif);
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ /* use the link on HW-0 to do wow flow */
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (!rtwvif_link)
+ continue;
+
+ rtw89_wow_vif_iter(rtwdev, rtwvif_link);
+ }
- if (!rtw_wow->wow_vif)
+ rtwvif_link = rtw_wow->rtwvif_link;
+ if (!rtwvif_link)
return -EPERM;
- rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
- return rtw89_wow_parse_patterns(rtwdev, rtwvif, wowlan);
+ return rtw89_wow_parse_patterns(rtwdev, rtwvif_link, wowlan);
}
static int rtw89_wow_cfg_wake_pno(struct rtw89_dev *rtwdev, bool wow)
{
- struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
int ret;
- ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif, true);
+ ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, true);
if (ret) {
rtw89_err(rtwdev, "failed to config pno\n");
return ret;
}
- ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif, wow);
+ ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n");
return ret;
}
- ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif, wow);
+ ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow global\n");
return ret;
@@ -1119,34 +1132,39 @@ static int rtw89_wow_cfg_wake_pno(struct rtw89_dev *rtwdev, bool wow)
static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
struct ieee80211_sta *wow_sta;
- struct rtw89_sta *rtwsta = NULL;
+ struct rtw89_sta_link *rtwsta_link = NULL;
+ struct rtw89_sta *rtwsta;
int ret;
- wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
- if (wow_sta)
- rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
+ wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr);
+ if (wow_sta) {
+ rtwsta = sta_to_rtwsta(wow_sta);
+ rtwsta_link = rtwsta->links[rtwvif_link->link_id];
+ if (!rtwsta_link)
+ return -ENOLINK;
+ }
if (wow) {
if (rtw_wow->pattern_cnt)
- rtwvif->wowlan_pattern = true;
+ rtwvif_link->wowlan_pattern = true;
if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags))
- rtwvif->wowlan_magic = true;
+ rtwvif_link->wowlan_magic = true;
} else {
- rtwvif->wowlan_pattern = false;
- rtwvif->wowlan_magic = false;
+ rtwvif_link->wowlan_pattern = false;
+ rtwvif_link->wowlan_magic = false;
}
- ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif, wow);
+ ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n");
return ret;
}
if (wow) {
- ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
+ ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
ret);
@@ -1154,13 +1172,13 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow)
}
}
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
}
- ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif, wow);
+ ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow global\n");
return ret;
@@ -1190,25 +1208,30 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL;
enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
const struct rtw89_chip_info *chip = rtwdev->chip;
bool include_bb = !!chip->bbmcu_nr;
bool disable_intr_for_dlfw = false;
struct ieee80211_sta *wow_sta;
- struct rtw89_sta *rtwsta = NULL;
+ struct rtw89_sta_link *rtwsta_link = NULL;
+ struct rtw89_sta *rtwsta;
bool is_conn = true;
int ret;
if (chip_id == RTL8852C || chip_id == RTL8922A)
disable_intr_for_dlfw = true;
- wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
- if (wow_sta)
- rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
- else
+ wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr);
+ if (wow_sta) {
+ rtwsta = sta_to_rtwsta(wow_sta);
+ rtwsta_link = rtwsta->links[rtwvif_link->link_id];
+ if (!rtwsta_link)
+ return -ENOLINK;
+ } else {
is_conn = false;
+ }
if (disable_intr_for_dlfw)
rtw89_hci_disable_intr(rtwdev);
@@ -1224,14 +1247,14 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
rtw89_phy_init_rf_reg(rtwdev, true);
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta,
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link,
RTW89_ROLE_FW_RESTORE);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c role maintain\n");
return ret;
}
- ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, wow_vif, wow_sta);
+ ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c assoc cmac tbl\n");
return ret;
@@ -1240,27 +1263,27 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
if (!is_conn)
rtw89_cam_reset_keys(rtwdev);
- ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, !is_conn);
+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, !is_conn);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c join info\n");
return ret;
}
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
}
if (is_conn) {
- ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id);
+ ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c general packet\n");
return ret;
}
- rtw89_phy_ra_assoc(rtwdev, wow_sta);
- rtw89_phy_set_bss_color(rtwdev, wow_vif);
- rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif);
+ rtw89_phy_ra_assoc(rtwdev, rtwsta_link);
+ rtw89_phy_set_bss_color(rtwdev, rtwvif_link);
+ rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link);
}
if (chip_gen == RTW89_CHIP_BE)
@@ -1363,21 +1386,20 @@ static int rtw89_wow_disable_trx_pre(struct rtw89_dev *rtwdev)
static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev)
{
- struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *vif = rtw_wow->wow_vif;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
int ret;
ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
if (ret)
rtw89_err(rtwdev, "cfg ppdu status\n");
- rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
return ret;
}
static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct list_head *pkt_list = &rtw_wow->pno_pkt_list;
@@ -1391,7 +1413,7 @@ static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev,
}
static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
@@ -1401,7 +1423,7 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
int ret;
for (i = 0; i < num; i++) {
- skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
+ skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr,
nd_config->match_sets[i].ssid.ssid,
nd_config->match_sets[i].ssid.ssid_len,
nd_config->ie_len);
@@ -1413,7 +1435,7 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
kfree_skb(skb);
- rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif);
+ rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link);
return -ENOMEM;
}
@@ -1421,7 +1443,7 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
if (ret) {
kfree_skb(skb);
kfree(info);
- rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif);
+ rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link);
return ret;
}
@@ -1436,20 +1458,19 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
int interval = rtw_wow->nd_config->scan_plans[0].interval;
struct rtw89_scan_option opt = {};
int ret;
if (enable) {
- ret = rtw89_pno_scan_update_probe_req(rtwdev, rtwvif);
+ ret = rtw89_pno_scan_update_probe_req(rtwdev, rtwvif_link);
if (ret) {
rtw89_err(rtwdev, "Update probe request failed\n");
return ret;
}
- ret = mac->add_chan_list_pno(rtwdev, rtwvif);
+ ret = mac->add_chan_list_pno(rtwdev, rtwvif_link);
if (ret) {
rtw89_err(rtwdev, "Update channel list failed\n");
return ret;
@@ -1471,7 +1492,7 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable)
opt.opch_end = RTW89_CHAN_INVALID;
}
- mac->scan_offload(rtwdev, &opt, rtwvif, true);
+ mac->scan_offload(rtwdev, &opt, rtwvif_link, true);
return 0;
}
@@ -1479,8 +1500,7 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable)
static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
int ret;
if (rtw89_wow_no_link(rtwdev)) {
@@ -1499,25 +1519,25 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
rtw89_wow_pattern_write(rtwdev);
rtw89_wow_construct_key_info(rtwdev);
- ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, true);
+ ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to enable keep alive\n");
return ret;
}
- ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, true);
+ ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to enable disconnect detect\n");
return ret;
}
- ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif, true);
+ ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to enable GTK offload\n");
return ret;
}
- ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif, true);
+ ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, true);
if (ret)
rtw89_warn(rtwdev, "wow: failed to enable arp offload\n");
}
@@ -1548,8 +1568,7 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
int ret;
if (rtw89_wow_no_link(rtwdev)) {
@@ -1559,35 +1578,35 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev)
return ret;
}
- ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif, false);
+ ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable pno\n");
return ret;
}
- rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif);
+ rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link);
} else {
rtw89_wow_pattern_clear(rtwdev);
- ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, false);
+ ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable keep alive\n");
return ret;
}
- ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false);
+ ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n");
return ret;
}
- ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif, false);
+ ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable GTK offload\n");
return ret;
}
- ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif, false);
+ ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, false);
if (ret)
rtw89_warn(rtwdev, "wow: failed to disable arp offload\n");
diff --git a/drivers/net/wireless/realtek/rtw89/wow.h b/drivers/net/wireless/realtek/rtw89/wow.h
index 3fbc2b87c058..f91991e8f2e3 100644
--- a/drivers/net/wireless/realtek/rtw89/wow.h
+++ b/drivers/net/wireless/realtek/rtw89/wow.h
@@ -97,18 +97,16 @@ static inline int rtw89_wow_get_sec_hdr_len(struct rtw89_dev *rtwdev)
#ifdef CONFIG_PM
static inline bool rtw89_wow_mgd_linked(struct rtw89_dev *rtwdev)
{
- struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
- return rtwvif->net_type == RTW89_NET_TYPE_INFRA;
+ return rtwvif_link->net_type == RTW89_NET_TYPE_INFRA;
}
static inline bool rtw89_wow_no_link(struct rtw89_dev *rtwdev)
{
- struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
- return rtwvif->net_type == RTW89_NET_TYPE_NO_LINK;
+ return rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK;
}
static inline bool rtw_wow_has_mgd_features(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/st/cw1200/queue.c b/drivers/net/wireless/st/cw1200/queue.c
index 805a3c1bf8fe..259739e53fc1 100644
--- a/drivers/net/wireless/st/cw1200/queue.c
+++ b/drivers/net/wireless/st/cw1200/queue.c
@@ -411,33 +411,6 @@ int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id)
return ret;
}
-int cw1200_queue_requeue_all(struct cw1200_queue *queue)
-{
- struct cw1200_queue_item *item, *tmp;
- struct cw1200_queue_stats *stats = queue->stats;
- spin_lock_bh(&queue->lock);
-
- list_for_each_entry_safe_reverse(item, tmp, &queue->pending, head) {
- --queue->num_pending;
- ++queue->link_map_cache[item->txpriv.link_id];
-
- spin_lock_bh(&stats->lock);
- ++stats->num_queued;
- ++stats->link_map_cache[item->txpriv.link_id];
- spin_unlock_bh(&stats->lock);
-
- ++item->generation;
- item->packet_id = cw1200_queue_mk_packet_id(queue->generation,
- queue->queue_id,
- item->generation,
- item - queue->pool);
- list_move(&item->head, &queue->queue);
- }
- spin_unlock_bh(&queue->lock);
-
- return 0;
-}
-
int cw1200_queue_remove(struct cw1200_queue *queue, u32 packet_id)
{
int ret = 0;
diff --git a/drivers/net/wireless/st/cw1200/queue.h b/drivers/net/wireless/st/cw1200/queue.h
index 96ac69ae97de..d46304b58747 100644
--- a/drivers/net/wireless/st/cw1200/queue.h
+++ b/drivers/net/wireless/st/cw1200/queue.h
@@ -85,7 +85,6 @@ int cw1200_queue_get(struct cw1200_queue *queue,
struct ieee80211_tx_info **tx_info,
const struct cw1200_txpriv **txpriv);
int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id);
-int cw1200_queue_requeue_all(struct cw1200_queue *queue);
int cw1200_queue_remove(struct cw1200_queue *queue,
u32 packet_id);
int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index c705081249d6..b45050243129 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -233,8 +233,8 @@ static int wl1251_sdio_probe(struct sdio_func *func,
}
if (wl->irq) {
- irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
- ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
+ ret = request_irq(wl->irq, wl1251_line_irq, IRQF_NO_AUTOEN,
+ "wl1251", wl);
if (ret < 0) {
wl1251_error("request_irq() failed: %d", ret);
goto disable;
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 0c77b8524160..986b07bfa0ee 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5789,9 +5789,10 @@ static int wlcore_op_cancel_remain_on_channel(struct ieee80211_hw *hw,
static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
+ struct ieee80211_link_sta *link_sta,
u32 changed)
{
+ struct ieee80211_sta *sta = link_sta->sta;
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update");
@@ -6052,7 +6053,7 @@ static const struct ieee80211_ops wl1271_ops = {
.assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
.unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx,
.switch_vif_chanctx = wlcore_op_switch_vif_chanctx,
- .sta_rc_update = wlcore_op_sta_rc_update,
+ .link_sta_rc_update = wlcore_op_sta_rc_update,
.sta_statistics = wlcore_op_sta_statistics,
.get_expected_throughput = wlcore_op_get_expected_throughput,
CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 92fb5b8dcdae..a73207bbe5d7 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -323,17 +323,12 @@ static int wl1271_probe(struct sdio_func *func,
memset(res, 0x00, sizeof(res));
- res[0].start = irq;
- res[0].flags = IORESOURCE_IRQ |
- irqd_get_trigger_type(irq_get_irq_data(irq));
- res[0].name = "irq";
-
+ res[0] = DEFINE_RES_IRQ_NAMED(irq, "irq");
+ res[0].flags |= irq_get_trigger_type(irq);
if (wakeirq > 0) {
- res[1].start = wakeirq;
- res[1].flags = IORESOURCE_IRQ |
- irqd_get_trigger_type(irq_get_irq_data(wakeirq));
- res[1].name = "wakeirq";
+ res[1] = DEFINE_RES_IRQ_NAMED(wakeirq, "wakeirq");
+ res[1].flags |= irq_get_trigger_type(wakeirq);
num_irqs = 2;
} else {
num_irqs = 1;
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index f0e528abb1b4..2a36b58f7a15 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -2442,7 +2442,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
if (!data->started || !link_data->beacon_int) {
hrtimer_cancel(&link_data->beacon_timer);
- } else if (!hrtimer_is_queued(&link_data->beacon_timer)) {
+ } else if (!hrtimer_active(&link_data->beacon_timer)) {
u64 tsf = mac80211_hwsim_get_tsf(hw, NULL);
u32 bcn_int = link_data->beacon_int;
u64 until_tbtt = bcn_int - do_div(tsf, bcn_int);
@@ -2537,7 +2537,7 @@ static void mac80211_hwsim_link_info_changed(struct ieee80211_hw *hw,
info->enable_beacon, info->beacon_int);
vp->bcn_en = info->enable_beacon;
if (data->started &&
- !hrtimer_is_queued(&link_data->beacon_timer) &&
+ !hrtimer_active(&link_data->beacon_timer) &&
info->enable_beacon) {
u64 tsf, until_tbtt;
u32 bcn_int;
@@ -2594,10 +2594,11 @@ static void mac80211_hwsim_link_info_changed(struct ieee80211_hw *hw,
static void
mac80211_hwsim_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
+ struct ieee80211_link_sta *link_sta,
u32 changed)
{
struct mac80211_hwsim_data *data = hw->priv;
+ struct ieee80211_sta *sta = link_sta->sta;
u32 bw = U32_MAX;
int link_id;
@@ -2607,7 +2608,6 @@ mac80211_hwsim_sta_rc_update(struct ieee80211_hw *hw,
link_id++) {
enum nl80211_chan_width confbw = NL80211_CHAN_WIDTH_20_NOHT;
struct ieee80211_bss_conf *vif_conf;
- struct ieee80211_link_sta *link_sta;
link_sta = rcu_dereference(sta->link[link_id]);
@@ -2659,7 +2659,7 @@ static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,
hwsim_check_magic(vif);
hwsim_set_sta_magic(sta);
- mac80211_hwsim_sta_rc_update(hw, vif, sta, 0);
+ mac80211_hwsim_sta_rc_update(hw, vif, &sta->deflink, 0);
if (sta->valid_links) {
WARN(hweight16(sta->valid_links) > 1,
@@ -3961,7 +3961,7 @@ out:
.link_info_changed = mac80211_hwsim_link_info_changed, \
.tx_last_beacon = mac80211_hwsim_tx_last_beacon, \
.sta_notify = mac80211_hwsim_sta_notify, \
- .sta_rc_update = mac80211_hwsim_sta_rc_update, \
+ .link_sta_rc_update = mac80211_hwsim_sta_rc_update, \
.conf_tx = mac80211_hwsim_conf_tx, \
.get_survey = mac80211_hwsim_get_survey, \
CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd) \
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 3fb68d60dfc1..fcdd559a8acf 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -26,8 +26,6 @@ if STAGING
source "drivers/staging/olpc_dcon/Kconfig"
-source "drivers/staging/rtl8192e/Kconfig"
-
source "drivers/staging/rtl8723bs/Kconfig"
source "drivers/staging/rtl8712/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index c977aa13fad4..4a84c4848664 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -3,7 +3,6 @@
obj-y += media/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
-obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_RTL8723BS) += rtl8723bs/
obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_RTS5208) += rts5208/
diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig
deleted file mode 100644
index e06c189b4ce4..000000000000
--- a/drivers/staging/rtl8192e/Kconfig
+++ /dev/null
@@ -1,61 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config RTLLIB
- tristate "Support for rtllib wireless devices"
- depends on WLAN && m
- select LIB80211
- select CRC32
- help
- If you have a wireless card that uses rtllib, say
- Y. Currently the only card is the rtl8192e.
-
- If unsure, say N.
-
- This driver adds support for rtllib wireless cards.
- Only the rtl8192e is supported as of now.
-
-if RTLLIB
-
-config RTLLIB_CRYPTO_CCMP
- tristate "Support for rtllib CCMP crypto"
- depends on RTLLIB
- select CRYPTO
- select CRYPTO_AES
- select CRYPTO_CCM
- default y
- help
- CCMP crypto driver for rtllib.
-
- If you enabled RTLLIB, you want this.
- Adds support for the CCM mode Protocol crypto driver for
- use in wireless cards (including rtllib cards).
-
-config RTLLIB_CRYPTO_TKIP
- tristate "Support for rtllib TKIP crypto"
- depends on RTLLIB
- select CRYPTO
- select CRYPTO_LIB_ARC4
- select CRYPTO_MICHAEL_MIC
- default y
- help
- TKIP crypto driver for rtllib.
-
- If you enabled RTLLIB, you want this.
- Adds support for the Temporal Key Integrity Protocol for
- the IEEE 802.11i standard for use on wireless cards.
-
-config RTLLIB_CRYPTO_WEP
- tristate "Support for rtllib WEP crypto"
- select CRYPTO_LIB_ARC4
- depends on RTLLIB
- default y
- help
- WEP crypto driver for rtllib.
-
- If you enabled RTLLIB, you want this.
- Adds support for the (now weak) Wired Equivalent Privacy
- (WEP) crypto protocol for wireless cards.
- NOTE: This protocol is now considered insecure.
-
-source "drivers/staging/rtl8192e/rtl8192e/Kconfig"
-
-endif
diff --git a/drivers/staging/rtl8192e/Makefile b/drivers/staging/rtl8192e/Makefile
deleted file mode 100644
index a1492215dab1..000000000000
--- a/drivers/staging/rtl8192e/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-rtllib-objs := \
- rtllib_module.o \
- rtllib_rx.o \
- rtllib_tx.o \
- rtllib_wx.o \
- rtllib_softmac.o \
- rtllib_softmac_wx.o \
- rtl819x_BAProc.o \
- rtl819x_HTProc.o \
- rtl819x_TSProc.o
-
-obj-$(CONFIG_RTLLIB) += rtllib.o
-
-obj-$(CONFIG_RTLLIB_CRYPTO_CCMP) += rtllib_crypt_ccmp.o
-obj-$(CONFIG_RTLLIB_CRYPTO_TKIP) += rtllib_crypt_tkip.o
-obj-$(CONFIG_RTLLIB_CRYPTO_WEP) += rtllib_crypt_wep.o
-
-obj-$(CONFIG_RTL8192E) += rtl8192e/
diff --git a/drivers/staging/rtl8192e/TODO b/drivers/staging/rtl8192e/TODO
deleted file mode 100644
index 7221ae65d63e..000000000000
--- a/drivers/staging/rtl8192e/TODO
+++ /dev/null
@@ -1,18 +0,0 @@
-To-do list:
-
-* merge into drivers/net/wireless/realtek/rtlwifi/rtl8192*
-* clean up function naming
-* Correct the coding style according to Linux guidelines; please read the document
- at https://www.kernel.org/doc/html/latest/process/coding-style.html.
-* Remove unnecessary debugging/printing macros; for those that are still needed
- use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()).
-* Remove dead code such as unusued functions, variables, fields, etc..
-* Use in-kernel API and remove unnecessary wrappers where possible.
-* Fix bugs due to code that sleeps in atomic context.
-* Remove the HAL layer and migrate its functionality into the relevant parts of
- the driver.
-* Switch to use LIB80211.
-* Switch to use MAC80211.
-* Switch to use CFG80211.
-* Improve the error handling of various functions, particularly those that use
- existing kernel APIs.
diff --git a/drivers/staging/rtl8192e/rtl8192e/Kconfig b/drivers/staging/rtl8192e/rtl8192e/Kconfig
deleted file mode 100644
index f8f774a16295..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config RTL8192E
- tristate "RealTek RTL8192E Wireless LAN NIC driver"
- depends on PCI && WLAN && RTLLIB
- depends on m
- select CFG80211
- select WIRELESS_EXT
- select WEXT_PRIV
- select CRYPTO
- select FW_LOADER
diff --git a/drivers/staging/rtl8192e/rtl8192e/Makefile b/drivers/staging/rtl8192e/rtl8192e/Makefile
deleted file mode 100644
index a442d79ea71e..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-r8192e_pci-objs := \
- r8192E_dev.o \
- r8192E_phy.o \
- r8192E_firmware.o \
- r8192E_cmdpkt.o \
- table.o \
- r8190P_rtl8256.o \
- rtl_cam.o \
- rtl_core.o \
- rtl_dm.o \
- rtl_eeprom.o \
- rtl_ethtool.o \
- rtl_pci.o \
- rtl_pm.o \
- rtl_ps.o \
- rtl_wx.o \
-
-obj-$(CONFIG_RTL8192E) += r8192e_pci.o
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h b/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h
deleted file mode 100644
index 552fd9b6e3e5..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef R8190P_DEF_H
-#define R8190P_DEF_H
-
-#include <linux/types.h>
-#include "r8192E_phy.h"
-
-#define MAX_SILENT_RESET_RX_SLOT_NUM 10
-
-enum rtl819x_loopback {
- RTL819X_NO_LOOPBACK = 0,
- RTL819X_MAC_LOOPBACK = 1,
- RTL819X_DMA_LOOPBACK = 2,
- RTL819X_CCK_LOOPBACK = 3,
-};
-
-#define DESC90_RATE1M 0x00
-#define DESC90_RATE2M 0x01
-#define DESC90_RATE5_5M 0x02
-#define DESC90_RATE11M 0x03
-#define DESC90_RATE6M 0x04
-#define DESC90_RATE9M 0x05
-#define DESC90_RATE12M 0x06
-#define DESC90_RATE18M 0x07
-#define DESC90_RATE24M 0x08
-#define DESC90_RATE36M 0x09
-#define DESC90_RATE48M 0x0a
-#define DESC90_RATE54M 0x0b
-#define DESC90_RATEMCS0 0x00
-#define DESC90_RATEMCS1 0x01
-#define DESC90_RATEMCS2 0x02
-#define DESC90_RATEMCS3 0x03
-#define DESC90_RATEMCS4 0x04
-#define DESC90_RATEMCS5 0x05
-#define DESC90_RATEMCS6 0x06
-#define DESC90_RATEMCS7 0x07
-#define DESC90_RATEMCS8 0x08
-#define DESC90_RATEMCS9 0x09
-#define DESC90_RATEMCS10 0x0a
-#define DESC90_RATEMCS11 0x0b
-#define DESC90_RATEMCS12 0x0c
-#define DESC90_RATEMCS13 0x0d
-#define DESC90_RATEMCS14 0x0e
-#define DESC90_RATEMCS15 0x0f
-#define DESC90_RATEMCS32 0x20
-
-#define SHORT_SLOT_TIME 9
-#define NON_SHORT_SLOT_TIME 20
-
-#define RX_SMOOTH 20
-
-#define QSLT_BK 0x1
-#define QSLT_BE 0x0
-#define QSLT_VI 0x4
-#define QSLT_VO 0x6
-#define QSLT_BEACON 0x10
-#define QSLT_HIGH 0x11
-#define QSLT_MGNT 0x12
-#define QSLT_CMD 0x13
-
-#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x007
-#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x0aa
-#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x024
-#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x007
-#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x10
-#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x4
-#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xd
-
-#define APPLIED_RESERVED_QUEUE_IN_FW 0x80000000
-#define RSVD_FW_QUEUE_PAGE_BK_SHIFT 0x00
-#define RSVD_FW_QUEUE_PAGE_BE_SHIFT 0x08
-#define RSVD_FW_QUEUE_PAGE_VI_SHIFT 0x10
-#define RSVD_FW_QUEUE_PAGE_VO_SHIFT 0x18
-#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT 0x10
-#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00
-#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08
-
-#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
-#define HAL_PRIME_CHNL_OFFSET_LOWER 1
-#define HAL_PRIME_CHNL_OFFSET_UPPER 2
-
-enum version_8190_loopback {
- VERSION_8190_BD = 0x3,
- VERSION_8190_BE
-};
-
-#define IC_VersionCut_D 0x3
-
-enum rf_optype {
- RF_OP_By_SW_3wire = 0,
- RF_OP_By_FW,
- RF_OP_MAX
-};
-
-struct bb_reg_definition {
- u32 rfintfs;
- u32 rfintfo;
- u32 rfintfe;
- u32 rf3wireOffset;
- u32 rfHSSIPara2;
- u32 rfLSSIReadBack;
- u32 rfLSSIReadBackPi;
-};
-
-struct tx_fwinfo_8190pci {
- u8 TxRate:7;
- u8 CtsEnable:1;
- u8 RtsRate:7;
- u8 RtsEnable:1;
- u8 TxHT:1;
- u8 Short:1;
- u8 TxBandwidth:1;
- u8 TxSubCarrier:2;
- u8 STBC:2;
- u8 AllowAggregation:1;
- u8 RtsHT:1;
- u8 RtsShort:1;
- u8 RtsBandwidth:1;
- u8 RtsSubcarrier:2;
- u8 RtsSTBC:2;
- u8 EnableCPUDur:1;
-
- u32 RxMF:2;
- u32 RxAMD:3;
- u32 TxPerPktInfoFeedback:1;
- u32 Reserved1:2;
- u32 TxAGCOffset:4;
- u32 TxAGCSign:1;
- u32 RAW_TXD:1;
- u32 Retry_Limit:4;
- u32 Reserved2:1;
- u32 PacketID:13;
-};
-
-struct phy_sts_ofdm_819xpci {
- u8 trsw_gain_X[RF90_PATH_MAX];
- u8 pwdb_all;
- u8 cfosho_X[4];
- u8 cfotail_X[4];
- u8 rxevm_X[2];
- u8 rxsnr_X[4];
- u8 pdsnr_X[2];
- u8 csi_current_X[2];
- u8 csi_target_X[2];
- u8 sigevm;
- u8 max_ex_pwr;
- u8 sgi_en;
- u8 rxsc_sgien_exflg;
-};
-
-struct phy_sts_cck_819xpci {
- u8 adc_pwdb_X[4];
- u8 sq_rpt;
- u8 cck_agc_rpt;
-};
-
-#define PHY_RSSI_SLID_WIN_MAX 100
-#define PHY_Beacon_RSSI_SLID_WIN_MAX 10
-
-struct tx_desc {
- u16 PktSize;
- u8 Offset;
- u8 Reserved1:3;
- u8 CmdInit:1;
- u8 LastSeg:1;
- u8 FirstSeg:1;
- u8 LINIP:1;
- u8 OWN:1;
-
- u8 TxFWInfoSize;
- u8 RATid:3;
- u8 DISFB:1;
- u8 USERATE:1;
- u8 MOREFRAG:1;
- u8 NoEnc:1;
- u8 PIFS:1;
- u8 QueueSelect:5;
- u8 NoACM:1;
- u8 Resv:2;
- u8 SecCAMID:5;
- u8 SecDescAssign:1;
- u8 SecType:2;
-
- u16 TxBufferSize;
- u8 PktId:7;
- u8 Resv1:1;
- u8 Reserved2;
-
- u32 TxBuffAddr;
-
- u32 NextDescAddress;
-
- u32 Reserved5;
- u32 Reserved6;
- u32 Reserved7;
-};
-
-struct tx_desc_cmd {
- u16 PktSize;
- u8 Reserved1;
- u8 CmdType:3;
- u8 CmdInit:1;
- u8 LastSeg:1;
- u8 FirstSeg:1;
- u8 LINIP:1;
- u8 OWN:1;
-
- u16 ElementReport;
- u16 Reserved2;
-
- u16 TxBufferSize;
- u16 Reserved3;
-
- u32 TxBuffAddr;
- u32 NextDescAddress;
- u32 Reserved4;
- u32 Reserved5;
- u32 Reserved6;
-};
-
-struct rx_desc {
- u16 Length:14;
- u16 CRC32:1;
- u16 ICV:1;
- u8 rx_drv_info_size;
- u8 Shift:2;
- u8 PHYStatus:1;
- u8 SWDec:1;
- u8 LastSeg:1;
- u8 FirstSeg:1;
- u8 EOR:1;
- u8 OWN:1;
-
- u32 Reserved2;
-
- u32 Reserved3;
-
- u32 BufferAddress;
-};
-
-struct rx_fwinfo {
- u16 Reserved1:12;
- u16 PartAggr:1;
- u16 FirstAGGR:1;
- u16 Reserved2:2;
-
- u8 RxRate:7;
- u8 RxHT:1;
-
- u8 BW:1;
- u8 SPLCP:1;
- u8 Reserved3:2;
- u8 PAM:1;
- u8 Mcast:1;
- u8 Bcast:1;
- u8 Reserved4:1;
-
- u32 TSFL;
-};
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c b/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c
deleted file mode 100644
index 7061f1cf4d3a..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c
+++ /dev/null
@@ -1,198 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtl_core.h"
-#include "r8192E_phyreg.h"
-#include "r8192E_phy.h"
-#include "r8190P_rtl8256.h"
-
-void rtl92e_set_bandwidth(struct net_device *dev,
- enum ht_channel_width bandwidth)
-{
- u8 eRFPath;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->card_8192_version != VERSION_8190_BD &&
- priv->card_8192_version != VERSION_8190_BE) {
- netdev_warn(dev, "%s(): Unknown HW version.\n", __func__);
- return;
- }
-
- for (eRFPath = 0; eRFPath < priv->num_total_rf_path; eRFPath++) {
- switch (bandwidth) {
- case HT_CHANNEL_WIDTH_20:
- rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
- 0x0b, bMask12Bits, 0x100);
- rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
- 0x2c, bMask12Bits, 0x3d7);
- rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
- 0x0e, bMask12Bits, 0x021);
- break;
- case HT_CHANNEL_WIDTH_20_40:
- rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
- 0x0b, bMask12Bits, 0x300);
- rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
- 0x2c, bMask12Bits, 0x3ff);
- rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
- 0x0e, bMask12Bits, 0x0e1);
- break;
- default:
- netdev_err(dev, "%s(): Unknown bandwidth: %#X\n",
- __func__, bandwidth);
- break;
- }
- }
-}
-
-bool rtl92e_config_rf(struct net_device *dev)
-{
- u32 u4RegValue = 0;
- u8 eRFPath;
- bool rtStatus = true;
- struct bb_reg_definition *pPhyReg;
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 RegOffSetToBeCheck = 0x3;
- u32 RegValueToBeCheck = 0x7f1;
- u32 RF3_Final_Value = 0;
- u8 ConstRetryTimes = 5, RetryTimes = 5;
- u8 ret = 0;
-
- priv->num_total_rf_path = RTL819X_TOTAL_RF_PATH;
-
- for (eRFPath = (enum rf90_radio_path)RF90_PATH_A;
- eRFPath < priv->num_total_rf_path; eRFPath++) {
- pPhyReg = &priv->phy_reg_def[eRFPath];
-
- switch (eRFPath) {
- case RF90_PATH_A:
- u4RegValue = rtl92e_get_bb_reg(dev, pPhyReg->rfintfs,
- bRFSI_RFENV);
- break;
- case RF90_PATH_B:
- u4RegValue = rtl92e_get_bb_reg(dev, pPhyReg->rfintfs,
- bRFSI_RFENV << 16);
- break;
- }
-
- rtl92e_set_bb_reg(dev, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1);
-
- rtl92e_set_bb_reg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
-
- rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2,
- b3WireAddressLength, 0x0);
- rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2,
- b3WireDataLength, 0x0);
-
- rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath, 0x0,
- bMask12Bits, 0xbf);
-
- rtStatus = rtl92e_check_bb_and_rf(dev, HW90_BLOCK_RF,
- (enum rf90_radio_path)eRFPath);
- if (!rtStatus) {
- netdev_err(dev, "%s(): Failed to check RF Path %d.\n",
- __func__, eRFPath);
- goto fail;
- }
-
- RetryTimes = ConstRetryTimes;
- RF3_Final_Value = 0;
- while (RF3_Final_Value != RegValueToBeCheck &&
- RetryTimes != 0) {
- ret = rtl92e_config_rf_path(dev,
- (enum rf90_radio_path)eRFPath);
- RF3_Final_Value = rtl92e_get_rf_reg(dev,
- (enum rf90_radio_path)eRFPath,
- RegOffSetToBeCheck,
- bMask12Bits);
- RetryTimes--;
- }
-
- switch (eRFPath) {
- case RF90_PATH_A:
- rtl92e_set_bb_reg(dev, pPhyReg->rfintfs, bRFSI_RFENV,
- u4RegValue);
- break;
- case RF90_PATH_B:
- rtl92e_set_bb_reg(dev, pPhyReg->rfintfs,
- bRFSI_RFENV << 16, u4RegValue);
- break;
- }
-
- if (ret) {
- netdev_err(dev,
- "%s(): Failed to initialize RF Path %d.\n",
- __func__, eRFPath);
- goto fail;
- }
- }
- return true;
-
-fail:
- return false;
-}
-
-void rtl92e_set_cck_tx_power(struct net_device *dev, u8 powerlevel)
-{
- u32 TxAGC = 0;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- TxAGC = powerlevel;
- if (priv->dynamic_tx_low_pwr) {
- if (priv->customer_id == RT_CID_819X_NETCORE)
- TxAGC = 0x22;
- else
- TxAGC += priv->cck_pwr_enl;
- }
- if (TxAGC > 0x24)
- TxAGC = 0x24;
- rtl92e_set_bb_reg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
-}
-
-void rtl92e_set_ofdm_tx_power(struct net_device *dev, u8 powerlevel)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
- u8 index = 0;
- u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
- u8 byte0, byte1, byte2, byte3;
-
- powerBase0 = powerlevel + priv->legacy_ht_tx_pwr_diff;
- powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
- (powerBase0 << 8) | powerBase0;
- powerBase1 = powerlevel;
- powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) |
- (powerBase1 << 8) | powerBase1;
-
- for (index = 0; index < 6; index++) {
- writeVal = (u32)(priv->mcs_tx_pwr_level_org_offset[index] +
- ((index < 2) ? powerBase0 : powerBase1));
- byte0 = writeVal & 0x7f;
- byte1 = (writeVal & 0x7f00) >> 8;
- byte2 = (writeVal & 0x7f0000) >> 16;
- byte3 = (writeVal & 0x7f000000) >> 24;
- if (byte0 > 0x24)
- byte0 = 0x24;
- if (byte1 > 0x24)
- byte1 = 0x24;
- if (byte2 > 0x24)
- byte2 = 0x24;
- if (byte3 > 0x24)
- byte3 = 0x24;
-
- if (index == 3) {
- writeVal_tmp = (byte3 << 24) | (byte2 << 16) |
- (byte1 << 8) | byte0;
- priv->pwr_track = writeVal_tmp;
- }
-
- if (priv->dynamic_tx_high_pwr)
- writeVal = 0x03030303;
- else
- writeVal = (byte3 << 24) | (byte2 << 16) |
- (byte1 << 8) | byte0;
- rtl92e_set_bb_reg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
- }
-}
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.h b/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.h
deleted file mode 100644
index 3c52e2b43095..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef RTL8225H
-#define RTL8225H
-
-#define RTL819X_TOTAL_RF_PATH 2
-void rtl92e_set_bandwidth(struct net_device *dev,
- enum ht_channel_width bandwidth);
-bool rtl92e_config_rf(struct net_device *dev);
-void rtl92e_set_cck_tx_power(struct net_device *dev, u8 powerlevel);
-void rtl92e_set_ofdm_tx_power(struct net_device *dev, u8 powerlevel);
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c
deleted file mode 100644
index 533cc4e723f6..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c
+++ /dev/null
@@ -1,79 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtl_core.h"
-#include "r8192E_hw.h"
-#include "r8192E_cmdpkt.h"
-
-bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data,
- u32 len)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u16 frag_length = 0, frag_offset = 0;
- struct sk_buff *skb;
- unsigned char *seg_ptr;
- struct cb_desc *tcb_desc;
- u8 last_ini_pkt;
-
- struct tx_fwinfo_8190pci *pTxFwInfo = NULL;
-
- do {
- if ((len - frag_offset) > CMDPACKET_FRAG_SIZE) {
- frag_length = CMDPACKET_FRAG_SIZE;
- last_ini_pkt = 0;
-
- } else {
- frag_length = (u16)(len - frag_offset);
- last_ini_pkt = 1;
- }
-
- if (type == DESC_PACKET_TYPE_NORMAL)
- skb = dev_alloc_skb(frag_length +
- priv->rtllib->tx_headroom + 4);
- else
- skb = dev_alloc_skb(frag_length + 4);
-
- if (!skb)
- return false;
-
- memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
- tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- tcb_desc->queue_index = TXCMD_QUEUE;
- tcb_desc->cmd_or_init = type;
- tcb_desc->last_ini_pkt = last_ini_pkt;
-
- if (type == DESC_PACKET_TYPE_NORMAL) {
- tcb_desc->pkt_size = frag_length;
-
- seg_ptr = skb_put(skb, priv->rtllib->tx_headroom);
- pTxFwInfo = (struct tx_fwinfo_8190pci *)seg_ptr;
- memset(pTxFwInfo, 0, sizeof(struct tx_fwinfo_8190pci));
- memset(pTxFwInfo, 0x12, 8);
- } else {
- tcb_desc->txbuf_size = frag_length;
- }
-
- skb_put_data(skb, data, frag_length);
-
- if (type == DESC_PACKET_TYPE_INIT &&
- (!priv->rtllib->check_nic_enough_desc(dev, TXCMD_QUEUE) ||
- (!skb_queue_empty(&priv->rtllib->skb_waitq[TXCMD_QUEUE])) ||
- (priv->rtllib->queue_stop))) {
- skb_queue_tail(&priv->rtllib->skb_waitq[TXCMD_QUEUE],
- skb);
- } else {
- priv->rtllib->softmac_hard_start_xmit(skb, dev);
- }
-
- data += frag_length;
- frag_offset += frag_length;
-
- } while (frag_offset < len);
-
- rtl92e_writeb(dev, TP_POLL, TP_POLL_CQ);
-
- return true;
-}
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h
deleted file mode 100644
index c63909199e93..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef R819XUSB_CMDPKT_H
-#define R819XUSB_CMDPKT_H
-
-bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data,
- u32 len);
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
deleted file mode 100644
index 2672b1ddf88e..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
+++ /dev/null
@@ -1,1915 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtl_core.h"
-#include "r8192E_phy.h"
-#include "r8192E_phyreg.h"
-#include "r8190P_rtl8256.h"
-#include "r8192E_cmdpkt.h"
-#include "rtl_dm.h"
-#include "rtl_wx.h"
-
-static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI,
- EDCAPARA_VO};
-
-static void _rtl92e_update_msr(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 msr;
-
- msr = rtl92e_readb(dev, MSR);
- msr &= ~MSR_LINK_MASK;
-
- switch (priv->rtllib->iw_mode) {
- case IW_MODE_INFRA:
- if (priv->rtllib->link_state == MAC80211_LINKED)
- msr |= MSR_LINK_MANAGED;
- break;
- default:
- break;
- }
-
- rtl92e_writeb(dev, MSR, msr);
-}
-
-void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- switch (variable) {
- case HW_VAR_BSSID:
- /* BSSIDR 2 byte alignment */
- rtl92e_writew(dev, BSSIDR, *(u16 *)val);
- rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(val + 2));
- break;
-
- case HW_VAR_MEDIA_STATUS:
- {
- enum rt_op_mode op_mode = *((enum rt_op_mode *)(val));
- u8 btMsr = rtl92e_readb(dev, MSR);
-
- btMsr &= 0xfc;
-
- switch (op_mode) {
- case RT_OP_MODE_INFRASTRUCTURE:
- btMsr |= MSR_INFRA;
- break;
-
- case RT_OP_MODE_IBSS:
- btMsr |= MSR_ADHOC;
- break;
-
- case RT_OP_MODE_AP:
- btMsr |= MSR_AP;
- break;
-
- default:
- btMsr |= MSR_NOLINK;
- break;
- }
-
- rtl92e_writeb(dev, MSR, btMsr);
- }
- break;
-
- case HW_VAR_CECHK_BSSID:
- {
- u32 RegRCR, Type;
-
- Type = val[0];
- RegRCR = rtl92e_readl(dev, RCR);
- priv->receive_config = RegRCR;
-
- if (Type)
- RegRCR |= (RCR_CBSSID);
- else
- RegRCR &= (~RCR_CBSSID);
-
- rtl92e_writel(dev, RCR, RegRCR);
- priv->receive_config = RegRCR;
- }
- break;
-
- case HW_VAR_SLOT_TIME:
-
- priv->slot_time = val[0];
- rtl92e_writeb(dev, SLOT_TIME, val[0]);
-
- break;
-
- case HW_VAR_ACK_PREAMBLE:
- {
- u32 regTmp;
-
- priv->short_preamble = (bool)*val;
- regTmp = priv->basic_rate;
- if (priv->short_preamble)
- regTmp |= BRSR_AckShortPmb;
- rtl92e_writel(dev, RRSR, regTmp);
- break;
- }
-
- case HW_VAR_CPU_RST:
- rtl92e_writel(dev, CPU_GEN, ((u32 *)(val))[0]);
- break;
-
- case HW_VAR_AC_PARAM:
- {
- u8 pAcParam = *val;
- u32 eACI = pAcParam;
- u8 u1bAIFS;
- u32 u4bAcParam;
- u8 mode = priv->rtllib->mode;
- struct rtllib_qos_parameters *qop =
- &priv->rtllib->current_network.qos_data.parameters;
-
- u1bAIFS = qop->aifs[pAcParam] *
- ((mode & (WIRELESS_MODE_G | WIRELESS_MODE_N_24G)) ? 9 : 20) + asifs_time;
-
- rtl92e_dm_init_edca_turbo(dev);
-
- u4bAcParam = (le16_to_cpu(qop->tx_op_limit[pAcParam]) <<
- AC_PARAM_TXOP_LIMIT_OFFSET) |
- ((le16_to_cpu(qop->cw_max[pAcParam])) <<
- AC_PARAM_ECW_MAX_OFFSET) |
- ((le16_to_cpu(qop->cw_min[pAcParam])) <<
- AC_PARAM_ECW_MIN_OFFSET) |
- (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET);
-
- switch (eACI) {
- case AC1_BK:
- rtl92e_writel(dev, EDCAPARA_BK, u4bAcParam);
- break;
-
- case AC0_BE:
- rtl92e_writel(dev, EDCAPARA_BE, u4bAcParam);
- break;
-
- case AC2_VI:
- rtl92e_writel(dev, EDCAPARA_VI, u4bAcParam);
- break;
-
- case AC3_VO:
- rtl92e_writel(dev, EDCAPARA_VO, u4bAcParam);
- break;
-
- default:
- netdev_info(dev, "SetHwReg8185(): invalid ACI: %d !\n",
- eACI);
- break;
- }
- priv->rtllib->set_hw_reg_handler(dev, HW_VAR_ACM_CTRL,
- &pAcParam);
- break;
- }
-
- case HW_VAR_ACM_CTRL:
- {
- struct rtllib_qos_parameters *qos_parameters =
- &priv->rtllib->current_network.qos_data.parameters;
- u8 pAcParam = *val;
- u32 eACI = pAcParam;
- union aci_aifsn *pAciAifsn = (union aci_aifsn *)&
- (qos_parameters->aifs[0]);
- u8 acm = pAciAifsn->f.acm;
- u8 AcmCtrl = rtl92e_readb(dev, ACM_HW_CTRL);
-
- if (acm) {
- switch (eACI) {
- case AC0_BE:
- AcmCtrl |= ACM_HW_BEQ_EN;
- break;
-
- case AC2_VI:
- AcmCtrl |= ACM_HW_VIQ_EN;
- break;
-
- case AC3_VO:
- AcmCtrl |= ACM_HW_VOQ_EN;
- break;
- }
- } else {
- switch (eACI) {
- case AC0_BE:
- AcmCtrl &= (~ACM_HW_BEQ_EN);
- break;
-
- case AC2_VI:
- AcmCtrl &= (~ACM_HW_VIQ_EN);
- break;
-
- case AC3_VO:
- AcmCtrl &= (~ACM_HW_BEQ_EN);
- break;
-
- default:
- break;
- }
- }
- rtl92e_writeb(dev, ACM_HW_CTRL, AcmCtrl);
- break;
- }
-
- case HW_VAR_SIFS:
- rtl92e_writeb(dev, SIFS, val[0]);
- rtl92e_writeb(dev, SIFS + 1, val[0]);
- break;
-
- case HW_VAR_RF_TIMING:
- {
- u8 Rf_Timing = *val;
-
- rtl92e_writeb(dev, rFPGA0_RFTiming1, Rf_Timing);
- break;
- }
-
- default:
- break;
- }
-}
-
-static void _rtl92e_read_eeprom_info(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- const u8 bMac_Tmp_Addr[ETH_ALEN] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
- u8 tempval;
- u8 ICVer8192, ICVer8256;
- u16 i, usValue, IC_Version;
- u16 EEPROMId;
-
- EEPROMId = rtl92e_eeprom_read(dev, 0);
- if (EEPROMId != RTL8190_EEPROM_ID) {
- netdev_err(dev, "%s(): Invalid EEPROM ID: %x\n", __func__,
- EEPROMId);
- priv->autoload_fail_flag = true;
- } else {
- priv->autoload_fail_flag = false;
- }
-
- if (!priv->autoload_fail_flag) {
- priv->eeprom_vid = rtl92e_eeprom_read(dev, EEPROM_VID >> 1);
- priv->eeprom_did = rtl92e_eeprom_read(dev, EEPROM_DID >> 1);
-
- usValue = rtl92e_eeprom_read(dev,
- (EEPROM_Customer_ID >> 1)) >> 8;
- priv->eeprom_customer_id = usValue & 0xff;
- usValue = rtl92e_eeprom_read(dev,
- EEPROM_ICVersion_ChannelPlan >> 1);
- IC_Version = (usValue & 0xff00) >> 8;
-
- ICVer8192 = IC_Version & 0xf;
- ICVer8256 = (IC_Version & 0xf0) >> 4;
- if (ICVer8192 == 0x2) {
- if (ICVer8256 == 0x5)
- priv->card_8192_version = VERSION_8190_BE;
- }
- switch (priv->card_8192_version) {
- case VERSION_8190_BD:
- case VERSION_8190_BE:
- break;
- default:
- priv->card_8192_version = VERSION_8190_BD;
- break;
- }
- } else {
- priv->card_8192_version = VERSION_8190_BD;
- priv->eeprom_vid = 0;
- priv->eeprom_did = 0;
- priv->eeprom_customer_id = 0;
- }
-
- if (!priv->autoload_fail_flag) {
- u8 addr[ETH_ALEN];
-
- for (i = 0; i < 6; i += 2) {
- usValue = rtl92e_eeprom_read(dev,
- (EEPROM_NODE_ADDRESS_BYTE_0 + i) >> 1);
- *(u16 *)(&addr[i]) = usValue;
- }
- eth_hw_addr_set(dev, addr);
- } else {
- eth_hw_addr_set(dev, bMac_Tmp_Addr);
- }
-
- if (priv->card_8192_version > VERSION_8190_BD)
- priv->tx_pwr_data_read_from_eeprom = true;
- else
- priv->tx_pwr_data_read_from_eeprom = false;
-
- if (priv->card_8192_version > VERSION_8190_BD) {
- if (!priv->autoload_fail_flag) {
- tempval = (rtl92e_eeprom_read(dev,
- (EEPROM_RFInd_PowerDiff >> 1))) & 0xff;
- priv->eeprom_legacy_ht_tx_pwr_diff = tempval & 0xf;
- } else {
- priv->eeprom_legacy_ht_tx_pwr_diff = 0x04;
- }
-
- if (!priv->autoload_fail_flag)
- priv->eeprom_thermal_meter = ((rtl92e_eeprom_read(dev,
- (EEPROM_ThermalMeter >> 1))) &
- 0xff00) >> 8;
- else
- priv->eeprom_thermal_meter = EEPROM_Default_ThermalMeter;
- priv->tssi_13dBm = priv->eeprom_thermal_meter * 100;
-
- if (priv->epromtype == EEPROM_93C46) {
- if (!priv->autoload_fail_flag) {
- usValue = rtl92e_eeprom_read(dev,
- EEPROM_TxPwDiff_CrystalCap >> 1);
- priv->eeprom_ant_pwr_diff = usValue & 0x0fff;
- priv->eeprom_crystal_cap = (usValue & 0xf000)
- >> 12;
- } else {
- priv->eeprom_ant_pwr_diff =
- EEPROM_Default_AntTxPowerDiff;
- priv->eeprom_crystal_cap =
- EEPROM_Default_TxPwDiff_CrystalCap;
- }
-
- for (i = 0; i < 14; i += 2) {
- if (!priv->autoload_fail_flag)
- usValue = rtl92e_eeprom_read(dev,
- (EEPROM_TxPwIndex_CCK + i) >> 1);
- else
- usValue = EEPROM_Default_TxPower;
- *((u16 *)(&priv->eeprom_tx_pwr_level_cck[i])) =
- usValue;
- }
- for (i = 0; i < 14; i += 2) {
- if (!priv->autoload_fail_flag)
- usValue = rtl92e_eeprom_read(dev,
- (EEPROM_TxPwIndex_OFDM_24G + i) >> 1);
- else
- usValue = EEPROM_Default_TxPower;
- *((u16 *)(&priv->eeprom_tx_pwr_level_ofdm24g[i]))
- = usValue;
- }
- }
- if (priv->epromtype == EEPROM_93C46) {
- for (i = 0; i < 14; i++) {
- priv->tx_pwr_level_cck[i] =
- priv->eeprom_tx_pwr_level_cck[i];
- priv->tx_pwr_level_ofdm_24g[i] =
- priv->eeprom_tx_pwr_level_ofdm24g[i];
- }
- priv->legacy_ht_tx_pwr_diff =
- priv->eeprom_legacy_ht_tx_pwr_diff;
- priv->antenna_tx_pwr_diff[0] = priv->eeprom_ant_pwr_diff & 0xf;
- priv->antenna_tx_pwr_diff[1] = (priv->eeprom_ant_pwr_diff &
- 0xf0) >> 4;
- priv->antenna_tx_pwr_diff[2] = (priv->eeprom_ant_pwr_diff &
- 0xf00) >> 8;
- priv->crystal_cap = priv->eeprom_crystal_cap;
- priv->thermal_meter[0] = priv->eeprom_thermal_meter & 0xf;
- priv->thermal_meter[1] = (priv->eeprom_thermal_meter &
- 0xf0) >> 4;
- } else if (priv->epromtype == EEPROM_93C56) {
- priv->legacy_ht_tx_pwr_diff =
- priv->eeprom_legacy_ht_tx_pwr_diff;
- priv->antenna_tx_pwr_diff[0] = 0;
- priv->antenna_tx_pwr_diff[1] = 0;
- priv->antenna_tx_pwr_diff[2] = 0;
- priv->crystal_cap = priv->eeprom_crystal_cap;
- priv->thermal_meter[0] = priv->eeprom_thermal_meter & 0xf;
- priv->thermal_meter[1] = (priv->eeprom_thermal_meter &
- 0xf0) >> 4;
- }
- }
-
- rtl92e_init_adaptive_rate(dev);
-
- switch (priv->eeprom_customer_id) {
- case EEPROM_CID_NetCore:
- priv->customer_id = RT_CID_819X_NETCORE;
- break;
- case EEPROM_CID_TOSHIBA:
- priv->customer_id = RT_CID_TOSHIBA;
- break;
- }
-
- if (priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
- priv->rtllib->bSupportRemoteWakeUp = true;
- else
- priv->rtllib->bSupportRemoteWakeUp = false;
-}
-
-void rtl92e_get_eeprom_size(struct net_device *dev)
-{
- u16 curCR;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- curCR = rtl92e_readw(dev, EPROM_CMD);
- priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EEPROM_93C56 :
- EEPROM_93C46;
- _rtl92e_read_eeprom_info(dev);
-}
-
-static void _rtl92e_hwconfig(struct net_device *dev)
-{
- u32 regRATR = 0, regRRSR = 0;
- u8 regBwOpMode = 0, regTmp = 0;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- switch (priv->rtllib->mode) {
- case WIRELESS_MODE_B:
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK;
- regRRSR = RATE_ALL_CCK;
- break;
- case WIRELESS_MODE_AUTO:
- case WIRELESS_MODE_N_24G:
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
- RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
- regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- break;
- case WIRELESS_MODE_G:
- default:
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- break;
- }
-
- rtl92e_writeb(dev, BW_OPMODE, regBwOpMode);
- {
- u32 ratr_value;
-
- ratr_value = regRATR;
- ratr_value &= ~(RATE_ALL_OFDM_2SS);
- rtl92e_writel(dev, RATR0, ratr_value);
- rtl92e_writeb(dev, UFWP, 1);
- }
- regTmp = rtl92e_readb(dev, 0x313);
- regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
- rtl92e_writel(dev, RRSR, regRRSR);
-
- rtl92e_writew(dev, RETRY_LIMIT,
- priv->short_retry_limit << RETRY_LIMIT_SHORT_SHIFT |
- priv->long_retry_limit << RETRY_LIMIT_LONG_SHIFT);
-}
-
-bool rtl92e_start_adapter(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 ulRegRead;
- bool rtStatus = true;
- u8 tmpvalue;
- u8 ICVersion, SwitchingRegulatorOutput;
- bool bfirmwareok = true;
- u32 tmpRegA, TempCCk;
- int i = 0;
- u32 retry_times = 0;
-
- priv->being_init_adapter = true;
-
-start:
- rtl92e_reset_desc_ring(dev);
- priv->rf_mode = RF_OP_By_SW_3wire;
-
- rtl92e_writeb(dev, ANAPAR, 0x37);
- mdelay(500);
-
- priv->fw_info->status = FW_STATUS_0_INIT;
-
- ulRegRead = rtl92e_readl(dev, CPU_GEN);
- if (priv->fw_info->status == FW_STATUS_0_INIT)
- ulRegRead |= CPU_GEN_SYSTEM_RESET;
- else if (priv->fw_info->status == FW_STATUS_5_READY)
- ulRegRead |= CPU_GEN_FIRMWARE_RESET;
- else
- netdev_err(dev, "%s(): undefined firmware state: %d.\n",
- __func__, priv->fw_info->status);
-
- rtl92e_writel(dev, CPU_GEN, ulRegRead);
-
- ICVersion = rtl92e_readb(dev, IC_VERRSION);
- if (ICVersion >= 0x4) {
- SwitchingRegulatorOutput = rtl92e_readb(dev, SWREGULATOR);
- if (SwitchingRegulatorOutput != 0xb8) {
- rtl92e_writeb(dev, SWREGULATOR, 0xa8);
- mdelay(1);
- rtl92e_writeb(dev, SWREGULATOR, 0xb8);
- }
- }
- rtStatus = rtl92e_config_bb(dev);
- if (!rtStatus) {
- netdev_warn(dev, "%s(): Failed to configure BB\n", __func__);
- return rtStatus;
- }
-
- priv->loopback_mode = RTL819X_NO_LOOPBACK;
- ulRegRead = rtl92e_readl(dev, CPU_GEN);
- if (priv->loopback_mode == RTL819X_NO_LOOPBACK)
- ulRegRead = (ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) |
- CPU_GEN_NO_LOOPBACK_SET;
- else if (priv->loopback_mode == RTL819X_MAC_LOOPBACK)
- ulRegRead |= CPU_CCK_LOOPBACK;
- else
- netdev_err(dev, "%s: Invalid loopback mode setting.\n",
- __func__);
-
- rtl92e_writel(dev, CPU_GEN, ulRegRead);
-
- udelay(500);
-
- _rtl92e_hwconfig(dev);
- rtl92e_writeb(dev, CMDR, CR_RE | CR_TE);
-
- rtl92e_writeb(dev, PCIF, ((MXDMA2_NO_LIMIT << MXDMA2_RX_SHIFT) |
- (MXDMA2_NO_LIMIT << MXDMA2_TX_SHIFT)));
- rtl92e_writel(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
- rtl92e_writew(dev, MAC4, ((u16 *)(dev->dev_addr + 4))[0]);
- rtl92e_writel(dev, RCR, priv->receive_config);
-
- rtl92e_writel(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK <<
- RSVD_FW_QUEUE_PAGE_BK_SHIFT |
- NUM_OF_PAGE_IN_FW_QUEUE_BE <<
- RSVD_FW_QUEUE_PAGE_BE_SHIFT |
- NUM_OF_PAGE_IN_FW_QUEUE_VI <<
- RSVD_FW_QUEUE_PAGE_VI_SHIFT |
- NUM_OF_PAGE_IN_FW_QUEUE_VO <<
- RSVD_FW_QUEUE_PAGE_VO_SHIFT);
- rtl92e_writel(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT <<
- RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
- rtl92e_writel(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW |
- NUM_OF_PAGE_IN_FW_QUEUE_BCN <<
- RSVD_FW_QUEUE_PAGE_BCN_SHIFT |
- NUM_OF_PAGE_IN_FW_QUEUE_PUB <<
- RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
-
- rtl92e_tx_enable(dev);
- rtl92e_rx_enable(dev);
- ulRegRead = (0xFFF00000 & rtl92e_readl(dev, RRSR)) |
- RATE_ALL_OFDM_AG | RATE_ALL_CCK;
- rtl92e_writel(dev, RRSR, ulRegRead);
- rtl92e_writel(dev, RATR0 + 4 * 7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
-
- rtl92e_writeb(dev, ACK_TIMEOUT, 0x30);
-
- rtl92e_set_wireless_mode(dev, priv->rtllib->mode);
- rtl92e_cam_reset(dev);
- {
- u8 SECR_value = 0x0;
-
- SECR_value |= SCR_TxEncEnable;
- SECR_value |= SCR_RxDecEnable;
- SECR_value |= SCR_NoSKMC;
- rtl92e_writeb(dev, SECR, SECR_value);
- }
- rtl92e_writew(dev, ATIMWND, 2);
- rtl92e_writew(dev, BCN_INTERVAL, 100);
-
- for (i = 0; i < QOS_QUEUE_NUM; i++)
- rtl92e_writel(dev, WDCAPARA_ADD[i], 0x005e4332);
-
- rtl92e_writeb(dev, 0xbe, 0xc0);
-
- rtl92e_config_mac(dev);
-
- if (priv->card_8192_version > VERSION_8190_BD) {
- rtl92e_get_tx_power(dev);
- rtl92e_set_tx_power(dev, priv->chan);
- }
-
- tmpvalue = rtl92e_readb(dev, IC_VERRSION);
- priv->ic_cut = tmpvalue;
-
- bfirmwareok = rtl92e_init_fw(dev);
- if (!bfirmwareok) {
- if (retry_times < 10) {
- retry_times++;
- goto start;
- } else {
- rtStatus = false;
- goto end;
- }
- }
-
- rtStatus = rtl92e_config_rf(dev);
- if (!rtStatus) {
- netdev_info(dev, "RF Config failed\n");
- return rtStatus;
- }
-
- rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
- rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
-
- rtl92e_writeb(dev, 0x87, 0x0);
-
- if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_PS) {
- rtl92e_set_rf_state(dev, rf_off, priv->rtllib->rf_off_reason);
- } else if (priv->rtllib->rf_off_reason >= RF_CHANGE_BY_IPS) {
- rtl92e_set_rf_state(dev, rf_off, priv->rtllib->rf_off_reason);
- } else {
- priv->rtllib->rf_power_state = rf_on;
- priv->rtllib->rf_off_reason = 0;
- }
-
- if (priv->rtllib->FwRWRF)
- priv->rf_mode = RF_OP_By_FW;
- else
- priv->rf_mode = RF_OP_By_SW_3wire;
-
- rtl92e_dm_init_txpower_tracking(dev);
-
- if (priv->ic_cut >= IC_VersionCut_D) {
- tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance,
- bMaskDWord);
- rtl92e_get_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord);
-
- for (i = 0; i < TX_BB_GAIN_TABLE_LEN; i++) {
- if (tmpRegA == dm_tx_bb_gain[i]) {
- priv->rfa_txpowertrackingindex = i;
- priv->rfa_txpowertrackingindex_real = i;
- priv->rfa_txpowertracking_default =
- priv->rfa_txpowertrackingindex;
- break;
- }
- }
-
- TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1,
- bMaskByte2);
-
- for (i = 0; i < CCK_TX_BB_GAIN_TABLE_LEN; i++) {
- if (TempCCk == dm_cck_tx_bb_gain[i][0]) {
- priv->cck_present_attn_20m_def = i;
- break;
- }
- }
- priv->cck_present_attn_40m_def = 0;
- priv->cck_present_attn_diff = 0;
- priv->cck_present_attn =
- priv->cck_present_attn_20m_def;
- priv->btxpower_tracking = false;
- }
- rtl92e_irq_enable(dev);
-end:
- priv->being_init_adapter = false;
- return rtStatus;
-}
-
-static void _rtl92e_net_update(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_network *net;
- u16 rate_config = 0;
-
- net = &priv->rtllib->current_network;
- rtl92e_config_rate(dev, &rate_config);
- priv->dot11_current_preamble_mode = PREAMBLE_AUTO;
- priv->basic_rate = rate_config &= 0x15f;
- rtl92e_writew(dev, BSSIDR, *(u16 *)net->bssid);
- rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(net->bssid + 2));
-}
-
-void rtl92e_link_change(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
-
- if (!priv->up)
- return;
-
- if (ieee->link_state == MAC80211_LINKED) {
- _rtl92e_net_update(dev);
- rtl92e_update_ratr_table(dev);
- if ((ieee->pairwise_key_type == KEY_TYPE_WEP40) ||
- (ieee->pairwise_key_type == KEY_TYPE_WEP104))
- rtl92e_enable_hw_security_config(dev);
- } else {
- rtl92e_writeb(dev, 0x173, 0);
- }
- _rtl92e_update_msr(dev);
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- u32 reg;
-
- reg = rtl92e_readl(dev, RCR);
- if (priv->rtllib->link_state == MAC80211_LINKED)
- priv->receive_config = reg |= RCR_CBSSID;
- else
- priv->receive_config = reg &= ~RCR_CBSSID;
-
- rtl92e_writel(dev, RCR, reg);
- }
-}
-
-void rtl92e_set_monitor_mode(struct net_device *dev, bool allow_all_da,
- bool write_into_reg)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (allow_all_da)
- priv->receive_config |= RCR_AAP;
- else
- priv->receive_config &= ~RCR_AAP;
-
- if (write_into_reg)
- rtl92e_writel(dev, RCR, priv->receive_config);
-}
-
-static u8 _rtl92e_rate_mgn_to_hw(u8 rate)
-{
- u8 ret = DESC90_RATE1M;
-
- switch (rate) {
- case MGN_1M:
- ret = DESC90_RATE1M;
- break;
- case MGN_2M:
- ret = DESC90_RATE2M;
- break;
- case MGN_5_5M:
- ret = DESC90_RATE5_5M;
- break;
- case MGN_11M:
- ret = DESC90_RATE11M;
- break;
- case MGN_6M:
- ret = DESC90_RATE6M;
- break;
- case MGN_9M:
- ret = DESC90_RATE9M;
- break;
- case MGN_12M:
- ret = DESC90_RATE12M;
- break;
- case MGN_18M:
- ret = DESC90_RATE18M;
- break;
- case MGN_24M:
- ret = DESC90_RATE24M;
- break;
- case MGN_36M:
- ret = DESC90_RATE36M;
- break;
- case MGN_48M:
- ret = DESC90_RATE48M;
- break;
- case MGN_54M:
- ret = DESC90_RATE54M;
- break;
- case MGN_MCS0:
- ret = DESC90_RATEMCS0;
- break;
- case MGN_MCS1:
- ret = DESC90_RATEMCS1;
- break;
- case MGN_MCS2:
- ret = DESC90_RATEMCS2;
- break;
- case MGN_MCS3:
- ret = DESC90_RATEMCS3;
- break;
- case MGN_MCS4:
- ret = DESC90_RATEMCS4;
- break;
- case MGN_MCS5:
- ret = DESC90_RATEMCS5;
- break;
- case MGN_MCS6:
- ret = DESC90_RATEMCS6;
- break;
- case MGN_MCS7:
- ret = DESC90_RATEMCS7;
- break;
- case MGN_MCS8:
- ret = DESC90_RATEMCS8;
- break;
- case MGN_MCS9:
- ret = DESC90_RATEMCS9;
- break;
- case MGN_MCS10:
- ret = DESC90_RATEMCS10;
- break;
- case MGN_MCS11:
- ret = DESC90_RATEMCS11;
- break;
- case MGN_MCS12:
- ret = DESC90_RATEMCS12;
- break;
- case MGN_MCS13:
- ret = DESC90_RATEMCS13;
- break;
- case MGN_MCS14:
- ret = DESC90_RATEMCS14;
- break;
- case MGN_MCS15:
- ret = DESC90_RATEMCS15;
- break;
- case (0x80 | 0x20):
- ret = DESC90_RATEMCS32;
- break;
- default:
- break;
- }
- return ret;
-}
-
-static u8 _rtl92e_hw_queue_to_fw_queue(struct net_device *dev, u8 QueueID,
- u8 priority)
-{
- u8 QueueSelect = 0x0;
-
- switch (QueueID) {
- case BE_QUEUE:
- QueueSelect = QSLT_BE;
- break;
-
- case BK_QUEUE:
- QueueSelect = QSLT_BK;
- break;
-
- case VO_QUEUE:
- QueueSelect = QSLT_VO;
- break;
-
- case VI_QUEUE:
- QueueSelect = QSLT_VI;
- break;
- case MGNT_QUEUE:
- QueueSelect = QSLT_MGNT;
- break;
- case BEACON_QUEUE:
- QueueSelect = QSLT_BEACON;
- break;
- case TXCMD_QUEUE:
- QueueSelect = QSLT_CMD;
- break;
- case HIGH_QUEUE:
- QueueSelect = QSLT_HIGH;
- break;
- default:
- netdev_warn(dev, "%s(): Impossible Queue Selection: %d\n",
- __func__, QueueID);
- break;
- }
- return QueueSelect;
-}
-
-static u8 _rtl92e_query_is_short(u8 TxHT, u8 TxRate, struct cb_desc *tcb_desc)
-{
- u8 tmp_Short;
-
- tmp_Short = (TxHT == 1) ? ((tcb_desc->use_short_gi) ? 1 : 0) :
- ((tcb_desc->use_short_preamble) ? 1 : 0);
- if (TxHT == 1 && TxRate != DESC90_RATEMCS15)
- tmp_Short = 0;
-
- return tmp_Short;
-}
-
-void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc,
- struct cb_desc *cb_desc, struct sk_buff *skb)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- dma_addr_t mapping;
- struct tx_fwinfo_8190pci *pTxFwInfo;
-
- pTxFwInfo = (struct tx_fwinfo_8190pci *)skb->data;
- memset(pTxFwInfo, 0, sizeof(struct tx_fwinfo_8190pci));
- pTxFwInfo->TxHT = (cb_desc->data_rate & 0x80) ? 1 : 0;
- pTxFwInfo->TxRate = _rtl92e_rate_mgn_to_hw(cb_desc->data_rate);
- pTxFwInfo->EnableCPUDur = cb_desc->tx_enable_fw_calc_dur;
- pTxFwInfo->Short = _rtl92e_query_is_short(pTxFwInfo->TxHT,
- pTxFwInfo->TxRate, cb_desc);
-
- if (cb_desc->ampdu_enable) {
- pTxFwInfo->AllowAggregation = 1;
- pTxFwInfo->RxMF = cb_desc->ampdu_factor;
- pTxFwInfo->RxAMD = cb_desc->ampdu_density;
- } else {
- pTxFwInfo->AllowAggregation = 0;
- pTxFwInfo->RxMF = 0;
- pTxFwInfo->RxAMD = 0;
- }
-
- pTxFwInfo->RtsEnable = (cb_desc->rts_enable) ? 1 : 0;
- pTxFwInfo->CtsEnable = (cb_desc->cts_enable) ? 1 : 0;
- pTxFwInfo->RtsSTBC = (cb_desc->rtsstbc) ? 1 : 0;
- pTxFwInfo->RtsHT = (cb_desc->rts_rate & 0x80) ? 1 : 0;
- pTxFwInfo->RtsRate = _rtl92e_rate_mgn_to_hw(cb_desc->rts_rate);
- pTxFwInfo->RtsBandwidth = 0;
- pTxFwInfo->RtsSubcarrier = cb_desc->RTSSC;
- pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT == 0) ?
- (cb_desc->rts_use_short_preamble ? 1 : 0) :
- (cb_desc->rts_use_short_gi ? 1 : 0);
- if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20_40) {
- if (cb_desc->packet_bw) {
- pTxFwInfo->TxBandwidth = 1;
- pTxFwInfo->TxSubCarrier = 0;
- } else {
- pTxFwInfo->TxBandwidth = 0;
- pTxFwInfo->TxSubCarrier = priv->n_cur_40mhz_prime_sc;
- }
- } else {
- pTxFwInfo->TxBandwidth = 0;
- pTxFwInfo->TxSubCarrier = 0;
- }
-
- memset((u8 *)pdesc, 0, 12);
-
- mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
- DMA_TO_DEVICE);
- if (dma_mapping_error(&priv->pdev->dev, mapping)) {
- netdev_err(dev, "%s(): DMA Mapping error\n", __func__);
- return;
- }
-
- pdesc->LINIP = 0;
- pdesc->CmdInit = 1;
- pdesc->Offset = sizeof(struct tx_fwinfo_8190pci) + 8;
- pdesc->PktSize = skb->len - sizeof(struct tx_fwinfo_8190pci);
-
- pdesc->SecCAMID = 0;
- pdesc->RATid = cb_desc->ratr_index;
-
- pdesc->NoEnc = 1;
- pdesc->SecType = 0x0;
- if (cb_desc->hw_sec) {
- static u8 tmp;
-
- if (!tmp)
- tmp = 1;
- switch (priv->rtllib->pairwise_key_type) {
- case KEY_TYPE_WEP40:
- case KEY_TYPE_WEP104:
- pdesc->SecType = 0x1;
- pdesc->NoEnc = 0;
- break;
- case KEY_TYPE_TKIP:
- pdesc->SecType = 0x2;
- pdesc->NoEnc = 0;
- break;
- case KEY_TYPE_CCMP:
- pdesc->SecType = 0x3;
- pdesc->NoEnc = 0;
- break;
- case KEY_TYPE_NA:
- pdesc->SecType = 0x0;
- pdesc->NoEnc = 1;
- break;
- }
- }
-
- pdesc->PktId = 0x0;
-
- pdesc->QueueSelect = _rtl92e_hw_queue_to_fw_queue(dev,
- cb_desc->queue_index,
- cb_desc->priority);
- pdesc->TxFWInfoSize = sizeof(struct tx_fwinfo_8190pci);
-
- pdesc->DISFB = cb_desc->tx_dis_rate_fallback;
- pdesc->USERATE = cb_desc->tx_use_drv_assinged_rate;
-
- pdesc->FirstSeg = 1;
- pdesc->LastSeg = 1;
- pdesc->TxBufferSize = skb->len;
-
- pdesc->TxBuffAddr = mapping;
-}
-
-void rtl92e_fill_tx_cmd_desc(struct net_device *dev, struct tx_desc_cmd *entry,
- struct cb_desc *cb_desc, struct sk_buff *skb)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- dma_addr_t mapping = dma_map_single(&priv->pdev->dev, skb->data,
- skb->len, DMA_TO_DEVICE);
-
- if (dma_mapping_error(&priv->pdev->dev, mapping))
- netdev_err(dev, "%s(): DMA Mapping error\n", __func__);
- memset(entry, 0, 12);
- entry->LINIP = cb_desc->last_ini_pkt;
- entry->FirstSeg = 1;
- entry->LastSeg = 1;
- if (cb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) {
- entry->CmdInit = DESC_PACKET_TYPE_INIT;
- } else {
- struct tx_desc *entry_tmp = (struct tx_desc *)entry;
-
- entry_tmp->CmdInit = DESC_PACKET_TYPE_NORMAL;
- entry_tmp->Offset = sizeof(struct tx_fwinfo_8190pci) + 8;
- entry_tmp->PktSize = cb_desc->pkt_size + entry_tmp->Offset;
- entry_tmp->QueueSelect = QSLT_CMD;
- entry_tmp->TxFWInfoSize = 0x08;
- entry_tmp->RATid = DESC_PACKET_TYPE_INIT;
- }
- entry->TxBufferSize = skb->len;
- entry->TxBuffAddr = mapping;
- entry->OWN = 1;
-}
-
-static u8 _rtl92e_rate_hw_to_mgn(bool bIsHT, u8 rate)
-{
- u8 ret_rate = 0x02;
-
- if (!bIsHT) {
- switch (rate) {
- case DESC90_RATE1M:
- ret_rate = MGN_1M;
- break;
- case DESC90_RATE2M:
- ret_rate = MGN_2M;
- break;
- case DESC90_RATE5_5M:
- ret_rate = MGN_5_5M;
- break;
- case DESC90_RATE11M:
- ret_rate = MGN_11M;
- break;
- case DESC90_RATE6M:
- ret_rate = MGN_6M;
- break;
- case DESC90_RATE9M:
- ret_rate = MGN_9M;
- break;
- case DESC90_RATE12M:
- ret_rate = MGN_12M;
- break;
- case DESC90_RATE18M:
- ret_rate = MGN_18M;
- break;
- case DESC90_RATE24M:
- ret_rate = MGN_24M;
- break;
- case DESC90_RATE36M:
- ret_rate = MGN_36M;
- break;
- case DESC90_RATE48M:
- ret_rate = MGN_48M;
- break;
- case DESC90_RATE54M:
- ret_rate = MGN_54M;
- break;
- }
-
- } else {
- switch (rate) {
- case DESC90_RATEMCS0:
- ret_rate = MGN_MCS0;
- break;
- case DESC90_RATEMCS1:
- ret_rate = MGN_MCS1;
- break;
- case DESC90_RATEMCS2:
- ret_rate = MGN_MCS2;
- break;
- case DESC90_RATEMCS3:
- ret_rate = MGN_MCS3;
- break;
- case DESC90_RATEMCS4:
- ret_rate = MGN_MCS4;
- break;
- case DESC90_RATEMCS5:
- ret_rate = MGN_MCS5;
- break;
- case DESC90_RATEMCS6:
- ret_rate = MGN_MCS6;
- break;
- case DESC90_RATEMCS7:
- ret_rate = MGN_MCS7;
- break;
- case DESC90_RATEMCS8:
- ret_rate = MGN_MCS8;
- break;
- case DESC90_RATEMCS9:
- ret_rate = MGN_MCS9;
- break;
- case DESC90_RATEMCS10:
- ret_rate = MGN_MCS10;
- break;
- case DESC90_RATEMCS11:
- ret_rate = MGN_MCS11;
- break;
- case DESC90_RATEMCS12:
- ret_rate = MGN_MCS12;
- break;
- case DESC90_RATEMCS13:
- ret_rate = MGN_MCS13;
- break;
- case DESC90_RATEMCS14:
- ret_rate = MGN_MCS14;
- break;
- case DESC90_RATEMCS15:
- ret_rate = MGN_MCS15;
- break;
- case DESC90_RATEMCS32:
- ret_rate = 0x80 | 0x20;
- break;
- }
- }
-
- return ret_rate;
-}
-
-static long _rtl92e_signal_scale_mapping(struct r8192_priv *priv, long currsig)
-{
- long retsig;
-
- if (currsig >= 61 && currsig <= 100)
- retsig = 90 + ((currsig - 60) / 4);
- else if (currsig >= 41 && currsig <= 60)
- retsig = 78 + ((currsig - 40) / 2);
- else if (currsig >= 31 && currsig <= 40)
- retsig = 66 + (currsig - 30);
- else if (currsig >= 21 && currsig <= 30)
- retsig = 54 + (currsig - 20);
- else if (currsig >= 5 && currsig <= 20)
- retsig = 42 + (((currsig - 5) * 2) / 3);
- else if (currsig == 4)
- retsig = 36;
- else if (currsig == 3)
- retsig = 27;
- else if (currsig == 2)
- retsig = 18;
- else if (currsig == 1)
- retsig = 9;
- else
- retsig = currsig;
-
- return retsig;
-}
-
-#define rx_hal_is_cck_rate(_pdrvinfo)\
- ((_pdrvinfo->RxRate == DESC90_RATE1M ||\
- _pdrvinfo->RxRate == DESC90_RATE2M ||\
- _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
- _pdrvinfo->RxRate == DESC90_RATE11M) &&\
- !_pdrvinfo->RxHT)
-
-static void _rtl92e_query_rxphystatus(struct r8192_priv *priv,
- struct rtllib_rx_stats *pstats,
- struct rx_desc *pdesc,
- struct rx_fwinfo *pdrvinfo,
- struct rtllib_rx_stats *precord_stats,
- bool bpacket_match_bssid,
- bool bpacket_toself,
- bool bPacketBeacon,
- bool bToSelfBA)
-{
- struct phy_sts_ofdm_819xpci *pofdm_buf;
- struct phy_sts_cck_819xpci *pcck_buf;
- u8 *prxpkt;
- u8 i, max_spatial_stream, tmp_rxevm;
- s8 rx_pwr[RF90_PATH_MAX], rx_pwr_all = 0;
- s8 rx_evmX;
- u8 evm, pwdb_all;
- u32 RSSI, total_rssi = 0;
- u8 is_cck_rate = 0;
- u8 rf_rx_num = 0;
- static u8 check_reg824;
- static u32 reg824_bit9;
-
- is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
- memset(precord_stats, 0, sizeof(struct rtllib_rx_stats));
- pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID =
- bpacket_match_bssid;
- pstats->packet_to_self = precord_stats->packet_to_self = bpacket_toself;
- pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;
- pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
- pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
- if (check_reg824 == 0) {
- reg824_bit9 = rtl92e_get_bb_reg(priv->rtllib->dev,
- rFPGA0_XA_HSSIParameter2,
- 0x200);
- check_reg824 = 1;
- }
-
- prxpkt = (u8 *)pdrvinfo;
-
- prxpkt += sizeof(struct rx_fwinfo);
-
- pcck_buf = (struct phy_sts_cck_819xpci *)prxpkt;
- pofdm_buf = (struct phy_sts_ofdm_819xpci *)prxpkt;
-
- pstats->RxMIMOSignalQuality[0] = -1;
- pstats->RxMIMOSignalQuality[1] = -1;
- precord_stats->RxMIMOSignalQuality[0] = -1;
- precord_stats->RxMIMOSignalQuality[1] = -1;
-
- if (is_cck_rate) {
- u8 report;
-
- if (!reg824_bit9) {
- report = pcck_buf->cck_agc_rpt & 0xc0;
- report >>= 6;
- switch (report) {
- case 0x3:
- rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt &
- 0x3e);
- break;
- case 0x2:
- rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt &
- 0x3e);
- break;
- case 0x1:
- rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt &
- 0x3e);
- break;
- case 0x0:
- rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
- break;
- }
- } else {
- report = pcck_buf->cck_agc_rpt & 0x60;
- report >>= 5;
- switch (report) {
- case 0x3:
- rx_pwr_all = -35 -
- ((pcck_buf->cck_agc_rpt &
- 0x1f) << 1);
- break;
- case 0x2:
- rx_pwr_all = -23 -
- ((pcck_buf->cck_agc_rpt &
- 0x1f) << 1);
- break;
- case 0x1:
- rx_pwr_all = -11 -
- ((pcck_buf->cck_agc_rpt &
- 0x1f) << 1);
- break;
- case 0x0:
- rx_pwr_all = -8 -
- ((pcck_buf->cck_agc_rpt &
- 0x1f) << 1);
- break;
- }
- }
-
- pwdb_all = rtl92e_rx_db_to_percent(rx_pwr_all);
- pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
- pstats->RecvSignalPower = rx_pwr_all;
-
- if (bpacket_match_bssid) {
- u8 sq;
-
- if (pstats->RxPWDBAll > 40) {
- sq = 100;
- } else {
- sq = pcck_buf->sq_rpt;
-
- if (pcck_buf->sq_rpt > 64)
- sq = 0;
- else if (pcck_buf->sq_rpt < 20)
- sq = 100;
- else
- sq = ((64 - sq) * 100) / 44;
- }
- pstats->signal_quality = sq;
- precord_stats->signal_quality = sq;
- pstats->RxMIMOSignalQuality[0] = sq;
- precord_stats->RxMIMOSignalQuality[0] = sq;
- pstats->RxMIMOSignalQuality[1] = -1;
- precord_stats->RxMIMOSignalQuality[1] = -1;
- }
- } else {
- for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
- if (priv->brfpath_rxenable[i])
- rf_rx_num++;
-
- rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i] & 0x3F) *
- 2) - 110;
-
- RSSI = rtl92e_rx_db_to_percent(rx_pwr[i]);
- if (priv->brfpath_rxenable[i])
- total_rssi += RSSI;
-
- if (bpacket_match_bssid) {
- pstats->RxMIMOSignalStrength[i] = RSSI;
- precord_stats->RxMIMOSignalStrength[i] = RSSI;
- }
- }
-
- rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1) & 0x7f) - 106;
- pwdb_all = rtl92e_rx_db_to_percent(rx_pwr_all);
-
- pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
- pstats->RecvSignalPower = rx_pwr_all;
- if (pdrvinfo->RxHT && pdrvinfo->RxRate >= DESC90_RATEMCS8 &&
- pdrvinfo->RxRate <= DESC90_RATEMCS15)
- max_spatial_stream = 2;
- else
- max_spatial_stream = 1;
-
- for (i = 0; i < max_spatial_stream; i++) {
- tmp_rxevm = pofdm_buf->rxevm_X[i];
- rx_evmX = (s8)(tmp_rxevm);
-
- rx_evmX /= 2;
-
- evm = rtl92e_evm_db_to_percent(rx_evmX);
- if (bpacket_match_bssid) {
- if (i == 0) {
- pstats->signal_quality = evm & 0xff;
- precord_stats->signal_quality = evm & 0xff;
- }
- pstats->RxMIMOSignalQuality[i] = evm & 0xff;
- precord_stats->RxMIMOSignalQuality[i] = evm & 0xff;
- }
- }
- }
-
- if (is_cck_rate) {
- pstats->signal_strength = precord_stats->signal_strength =
- _rtl92e_signal_scale_mapping(priv, (long)pwdb_all);
-
- } else {
- if (rf_rx_num != 0)
- pstats->signal_strength = precord_stats->signal_strength =
- _rtl92e_signal_scale_mapping(priv,
- (long)(total_rssi /= rf_rx_num));
- }
-}
-
-static void _rtl92e_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
- struct rtllib_rx_stats *prev_st,
- struct rtllib_rx_stats *curr_st)
-{
- bool bcheck = false;
- u8 rfpath;
- u32 ij, tmp_val;
- static u32 slide_rssi_index, slide_rssi_statistics;
- static u32 slide_evm_index, slide_evm_statistics;
- static u32 last_rssi, last_evm;
- static u32 slide_beacon_adc_pwdb_index;
- static u32 slide_beacon_adc_pwdb_statistics;
- static u32 last_beacon_adc_pwdb;
-
- if (!prev_st->bIsAMPDU)
- bcheck = true;
-
- if (slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) {
- slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
- last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
- priv->stats.slide_rssi_total -= last_rssi;
- }
- priv->stats.slide_rssi_total += prev_st->signal_strength;
-
- priv->stats.slide_signal_strength[slide_rssi_index++] =
- prev_st->signal_strength;
- if (slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
- slide_rssi_index = 0;
-
- tmp_val = priv->stats.slide_rssi_total / slide_rssi_statistics;
- priv->stats.signal_strength = rtl92e_translate_to_dbm(priv, tmp_val);
- curr_st->rssi = priv->stats.signal_strength;
- if (!prev_st->bPacketMatchBSSID) {
- if (!prev_st->bToSelfBA)
- return;
- }
-
- if (!bcheck)
- return;
-
- if (!prev_st->bIsCCK && prev_st->packet_to_self) {
- for (rfpath = RF90_PATH_A; rfpath < priv->num_total_rf_path; rfpath++) {
- if (priv->stats.rx_rssi_percentage[rfpath] == 0) {
- priv->stats.rx_rssi_percentage[rfpath] =
- prev_st->RxMIMOSignalStrength[rfpath];
- }
- if (prev_st->RxMIMOSignalStrength[rfpath] >
- priv->stats.rx_rssi_percentage[rfpath]) {
- priv->stats.rx_rssi_percentage[rfpath] =
- ((priv->stats.rx_rssi_percentage[rfpath]
- * (RX_SMOOTH - 1)) +
- (prev_st->RxMIMOSignalStrength
- [rfpath])) / (RX_SMOOTH);
- priv->stats.rx_rssi_percentage[rfpath] =
- priv->stats.rx_rssi_percentage[rfpath]
- + 1;
- } else {
- priv->stats.rx_rssi_percentage[rfpath] =
- ((priv->stats.rx_rssi_percentage[rfpath] *
- (RX_SMOOTH - 1)) +
- (prev_st->RxMIMOSignalStrength[rfpath])) /
- (RX_SMOOTH);
- }
- }
- }
-
- if (prev_st->bPacketBeacon) {
- if (slide_beacon_adc_pwdb_statistics++ >=
- PHY_Beacon_RSSI_SLID_WIN_MAX) {
- slide_beacon_adc_pwdb_statistics =
- PHY_Beacon_RSSI_SLID_WIN_MAX;
- last_beacon_adc_pwdb = priv->stats.slide_beacon_pwdb
- [slide_beacon_adc_pwdb_index];
- priv->stats.slide_beacon_total -= last_beacon_adc_pwdb;
- }
- priv->stats.slide_beacon_total += prev_st->RxPWDBAll;
- priv->stats.slide_beacon_pwdb[slide_beacon_adc_pwdb_index] =
- prev_st->RxPWDBAll;
- slide_beacon_adc_pwdb_index++;
- if (slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
- slide_beacon_adc_pwdb_index = 0;
- prev_st->RxPWDBAll = priv->stats.slide_beacon_total /
- slide_beacon_adc_pwdb_statistics;
- if (prev_st->RxPWDBAll >= 3)
- prev_st->RxPWDBAll -= 3;
- }
- if (prev_st->packet_to_self || prev_st->bPacketBeacon ||
- prev_st->bToSelfBA) {
- if (priv->undecorated_smoothed_pwdb < 0)
- priv->undecorated_smoothed_pwdb = prev_st->RxPWDBAll;
- if (prev_st->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) {
- priv->undecorated_smoothed_pwdb =
- (((priv->undecorated_smoothed_pwdb) *
- (RX_SMOOTH - 1)) +
- (prev_st->RxPWDBAll)) / (RX_SMOOTH);
- priv->undecorated_smoothed_pwdb =
- priv->undecorated_smoothed_pwdb + 1;
- } else {
- priv->undecorated_smoothed_pwdb =
- (((priv->undecorated_smoothed_pwdb) *
- (RX_SMOOTH - 1)) +
- (prev_st->RxPWDBAll)) / (RX_SMOOTH);
- }
- rtl92e_update_rx_statistics(priv, prev_st);
- }
-
- if (prev_st->signal_quality != 0) {
- if (prev_st->packet_to_self || prev_st->bPacketBeacon ||
- prev_st->bToSelfBA) {
- if (slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX) {
- slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
- last_evm =
- priv->stats.slide_evm[slide_evm_index];
- priv->stats.slide_evm_total -= last_evm;
- }
-
- priv->stats.slide_evm_total += prev_st->signal_quality;
-
- priv->stats.slide_evm[slide_evm_index++] =
- prev_st->signal_quality;
- if (slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
- slide_evm_index = 0;
-
- tmp_val = priv->stats.slide_evm_total /
- slide_evm_statistics;
- priv->stats.last_signal_strength_inpercent = tmp_val;
- }
-
- if (prev_st->packet_to_self ||
- prev_st->bPacketBeacon ||
- prev_st->bToSelfBA) {
- for (ij = 0; ij < 2; ij++) {
- if (prev_st->RxMIMOSignalQuality[ij] != -1) {
- if (priv->stats.rx_evm_percentage[ij] == 0)
- priv->stats.rx_evm_percentage[ij] =
- prev_st->RxMIMOSignalQuality[ij];
- priv->stats.rx_evm_percentage[ij] =
- ((priv->stats.rx_evm_percentage[ij] *
- (RX_SMOOTH - 1)) +
- (prev_st->RxMIMOSignalQuality[ij])) /
- (RX_SMOOTH);
- }
- }
- }
- }
-}
-
-static void _rtl92e_translate_rx_signal_stats(struct net_device *dev,
- struct sk_buff *skb,
- struct rtllib_rx_stats *pstats,
- struct rx_desc *pdesc,
- struct rx_fwinfo *pdrvinfo)
-{
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
- bool bpacket_match_bssid, bpacket_toself;
- bool bPacketBeacon = false;
- struct ieee80211_hdr_3addr *hdr;
- bool bToSelfBA = false;
- static struct rtllib_rx_stats previous_stats;
- u16 fc, type;
- u8 *tmp_buf;
- u8 *praddr;
-
- tmp_buf = skb->data + pstats->rx_drv_info_size + pstats->rx_buf_shift;
-
- hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
- fc = le16_to_cpu(hdr->frame_control);
- type = WLAN_FC_GET_TYPE(fc);
- praddr = hdr->addr1;
-
- bpacket_match_bssid =
- ((type != RTLLIB_FTYPE_CTL) &&
- ether_addr_equal(priv->rtllib->current_network.bssid,
- (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
- (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
- hdr->addr3) &&
- (!pstats->hw_error) && (!pstats->bCRC) && (!pstats->bICV));
- bpacket_toself = bpacket_match_bssid && /* check this */
- ether_addr_equal(praddr, priv->rtllib->dev->dev_addr);
- if (ieee80211_is_beacon(hdr->frame_control))
- bPacketBeacon = true;
- _rtl92e_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
- _rtl92e_query_rxphystatus(priv, pstats, pdesc, pdrvinfo,
- &previous_stats, bpacket_match_bssid,
- bpacket_toself, bPacketBeacon, bToSelfBA);
- rtl92e_copy_mpdu_stats(pstats, &previous_stats);
-}
-
-static void _rtl92e_update_received_rate_histogram_stats(struct net_device *dev,
- struct rtllib_rx_stats *pstats)
-{
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
- u32 rcvType = 1;
- u32 rate_index;
-
- if (pstats->bCRC)
- rcvType = 2;
- else if (pstats->bICV)
- rcvType = 3;
-
- switch (pstats->rate) {
- case MGN_1M:
- rate_index = 0;
- break;
- case MGN_2M:
- rate_index = 1;
- break;
- case MGN_5_5M:
- rate_index = 2;
- break;
- case MGN_11M:
- rate_index = 3;
- break;
- case MGN_6M:
- rate_index = 4;
- break;
- case MGN_9M:
- rate_index = 5;
- break;
- case MGN_12M:
- rate_index = 6;
- break;
- case MGN_18M:
- rate_index = 7;
- break;
- case MGN_24M:
- rate_index = 8;
- break;
- case MGN_36M:
- rate_index = 9;
- break;
- case MGN_48M:
- rate_index = 10;
- break;
- case MGN_54M:
- rate_index = 11;
- break;
- case MGN_MCS0:
- rate_index = 12;
- break;
- case MGN_MCS1:
- rate_index = 13;
- break;
- case MGN_MCS2:
- rate_index = 14;
- break;
- case MGN_MCS3:
- rate_index = 15;
- break;
- case MGN_MCS4:
- rate_index = 16;
- break;
- case MGN_MCS5:
- rate_index = 17;
- break;
- case MGN_MCS6:
- rate_index = 18;
- break;
- case MGN_MCS7:
- rate_index = 19;
- break;
- case MGN_MCS8:
- rate_index = 20;
- break;
- case MGN_MCS9:
- rate_index = 21;
- break;
- case MGN_MCS10:
- rate_index = 22;
- break;
- case MGN_MCS11:
- rate_index = 23;
- break;
- case MGN_MCS12:
- rate_index = 24;
- break;
- case MGN_MCS13:
- rate_index = 25;
- break;
- case MGN_MCS14:
- rate_index = 26;
- break;
- case MGN_MCS15:
- rate_index = 27;
- break;
- default:
- rate_index = 28;
- break;
- }
- priv->stats.received_rate_histogram[0][rate_index]++;
- priv->stats.received_rate_histogram[rcvType][rate_index]++;
-}
-
-bool rtl92e_get_rx_stats(struct net_device *dev, struct rtllib_rx_stats *stats,
- struct rx_desc *pdesc, struct sk_buff *skb)
-{
- struct rx_fwinfo *pDrvInfo = NULL;
-
- stats->bICV = pdesc->ICV;
- stats->bCRC = pdesc->CRC32;
- stats->hw_error = pdesc->CRC32 | pdesc->ICV;
-
- stats->Length = pdesc->Length;
- if (stats->Length < 24)
- stats->hw_error |= 1;
-
- if (stats->hw_error)
- return false;
-
- stats->rx_drv_info_size = pdesc->rx_drv_info_size;
- stats->rx_buf_shift = (pdesc->Shift) & 0x03;
- stats->decrypted = !pdesc->SWDec;
-
- pDrvInfo = (struct rx_fwinfo *)(skb->data + stats->rx_buf_shift);
-
- stats->rate = _rtl92e_rate_hw_to_mgn((bool)pDrvInfo->RxHT,
- pDrvInfo->RxRate);
-
- _rtl92e_update_received_rate_histogram_stats(dev, stats);
-
- stats->bIsAMPDU = (pDrvInfo->PartAggr == 1);
- stats->bFirstMPDU = (pDrvInfo->PartAggr == 1) &&
- (pDrvInfo->FirstAGGR == 1);
-
- stats->time_stamp_low = pDrvInfo->TSFL;
- stats->time_stamp_high = rtl92e_readl(dev, TSFR + 4);
-
- _rtl92e_translate_rx_signal_stats(dev, skb, stats, pdesc, pDrvInfo);
- skb_trim(skb, skb->len - S_CRC_LEN);
-
- return true;
-}
-
-void rtl92e_stop_adapter(struct net_device *dev, bool reset)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- int i;
- u8 op_mode;
- u8 u1bTmp;
- u32 ulRegRead;
-
- op_mode = RT_OP_MODE_NO_LINK;
- priv->rtllib->set_hw_reg_handler(dev, HW_VAR_MEDIA_STATUS, &op_mode);
-
- if (!priv->rtllib->bSupportRemoteWakeUp) {
- u1bTmp = 0x0;
- rtl92e_writeb(dev, CMDR, u1bTmp);
- }
-
- mdelay(20);
-
- if (!reset) {
- mdelay(150);
-
- priv->hw_rf_off_action = 2;
-
- if (!priv->rtllib->bSupportRemoteWakeUp) {
- rtl92e_set_rf_off(dev);
- ulRegRead = rtl92e_readl(dev, CPU_GEN);
- ulRegRead |= CPU_GEN_SYSTEM_RESET;
- rtl92e_writel(dev, CPU_GEN, ulRegRead);
- } else {
- rtl92e_writel(dev, WFCRC0, 0xffffffff);
- rtl92e_writel(dev, WFCRC1, 0xffffffff);
- rtl92e_writel(dev, WFCRC2, 0xffffffff);
-
- rtl92e_writeb(dev, PMR, 0x5);
- rtl92e_writeb(dev, MAC_BLK_CTRL, 0xa);
- }
- }
-
- for (i = 0; i < MAX_QUEUE_SIZE; i++)
- skb_queue_purge(&priv->rtllib->skb_waitq[i]);
-
- skb_queue_purge(&priv->skb_queue);
-}
-
-void rtl92e_update_ratr_table(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
- u8 *pMcsRate = ieee->dot11ht_oper_rate_set;
- u32 ratr_value = 0;
- u16 rate_config = 0;
- u8 rate_index = 0;
-
- rtl92e_config_rate(dev, &rate_config);
- ratr_value = rate_config | *pMcsRate << 12;
- switch (ieee->mode) {
- case WIRELESS_MODE_B:
- ratr_value &= 0x0000000F;
- break;
- case WIRELESS_MODE_G:
- case WIRELESS_MODE_G | WIRELESS_MODE_B:
- ratr_value &= 0x00000FF7;
- break;
- case WIRELESS_MODE_N_24G:
- ratr_value &= 0x000FF007;
- break;
- default:
- break;
- }
- ratr_value &= 0x0FFFFFFF;
- if (ieee->ht_info->cur_tx_bw40mhz &&
- ieee->ht_info->cur_short_gi_40mhz)
- ratr_value |= 0x80000000;
- else if (!ieee->ht_info->cur_tx_bw40mhz &&
- ieee->ht_info->cur_short_gi_20mhz)
- ratr_value |= 0x80000000;
- rtl92e_writel(dev, RATR0 + rate_index * 4, ratr_value);
- rtl92e_writeb(dev, UFWP, 1);
-}
-
-void
-rtl92e_init_variables(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- strscpy(priv->nick, "rtl8192E", sizeof(priv->nick));
-
- priv->rtllib->softmac_features = IEEE_SOFTMAC_SCAN |
- IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
- IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;
-
- priv->rtllib->tx_headroom = sizeof(struct tx_fwinfo_8190pci);
-
- priv->short_retry_limit = 0x30;
- priv->long_retry_limit = 0x30;
-
- priv->receive_config = RCR_ADD3 |
- RCR_AMF | RCR_ADF |
- RCR_AICV |
- RCR_AB | RCR_AM | RCR_APM |
- RCR_AAP | ((u32)7 << RCR_MXDMA_OFFSET) |
- ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
-
- priv->irq_mask[0] = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK |
- IMR_BEDOK | IMR_BKDOK | IMR_HCCADOK |
- IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |
- IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 |
- IMR_RDU | IMR_RXFOVW | IMR_TXFOVW |
- IMR_TBDOK | IMR_TBDER);
-
- priv->bfirst_after_down = false;
-}
-
-void rtl92e_irq_enable(struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-
- priv->irq_enabled = 1;
-
- rtl92e_writel(dev, INTA_MASK, priv->irq_mask[0]);
-}
-
-void rtl92e_irq_disable(struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-
- rtl92e_writel(dev, INTA_MASK, 0);
-
- priv->irq_enabled = 0;
-}
-
-void rtl92e_enable_rx(struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-
- rtl92e_writel(dev, RDQDA, priv->rx_ring_dma);
-}
-
-static const u32 TX_DESC_BASE[] = {
- BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA
-};
-
-void rtl92e_enable_tx(struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
- u32 i;
-
- for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
- rtl92e_writel(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
-}
-
-void rtl92e_ack_irq(struct net_device *dev, u32 *p_inta)
-{
- *p_inta = rtl92e_readl(dev, ISR);
- rtl92e_writel(dev, ISR, *p_inta);
-}
-
-bool rtl92e_is_rx_stuck(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u16 RegRxCounter = rtl92e_readw(dev, 0x130);
- bool bStuck = false;
- static u8 rx_chk_cnt;
- u32 slot_index = 0, TotalRxStuckCount = 0;
- u8 i;
- u8 SilentResetRxSoltNum = 4;
-
- rx_chk_cnt++;
- if (priv->undecorated_smoothed_pwdb >= (RATE_ADAPTIVE_TH_HIGH + 5)) {
- rx_chk_cnt = 0;
- } else if ((priv->undecorated_smoothed_pwdb < (RATE_ADAPTIVE_TH_HIGH + 5)) &&
- (((priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) &&
- (priv->undecorated_smoothed_pwdb >= RATE_ADAPTIVE_TH_LOW_40M))
- || ((priv->current_chnl_bw == HT_CHANNEL_WIDTH_20) &&
- (priv->undecorated_smoothed_pwdb >= RATE_ADAPTIVE_TH_LOW_20M)))) {
- if (rx_chk_cnt < 2)
- return bStuck;
- rx_chk_cnt = 0;
- } else if ((((priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) &&
- (priv->undecorated_smoothed_pwdb < RATE_ADAPTIVE_TH_LOW_40M)) ||
- ((priv->current_chnl_bw == HT_CHANNEL_WIDTH_20) &&
- (priv->undecorated_smoothed_pwdb < RATE_ADAPTIVE_TH_LOW_20M))) &&
- priv->undecorated_smoothed_pwdb >= VERY_LOW_RSSI) {
- if (rx_chk_cnt < 4)
- return bStuck;
- rx_chk_cnt = 0;
- } else {
- if (rx_chk_cnt < 8)
- return bStuck;
- rx_chk_cnt = 0;
- }
-
- slot_index = (priv->silent_reset_rx_slot_index++) % SilentResetRxSoltNum;
-
- if (priv->rx_ctr == RegRxCounter) {
- priv->silent_reset_rx_stuck_event[slot_index] = 1;
-
- for (i = 0; i < SilentResetRxSoltNum; i++)
- TotalRxStuckCount += priv->silent_reset_rx_stuck_event[i];
-
- if (TotalRxStuckCount == SilentResetRxSoltNum) {
- bStuck = true;
- for (i = 0; i < SilentResetRxSoltNum; i++)
- TotalRxStuckCount +=
- priv->silent_reset_rx_stuck_event[i];
- }
- } else {
- priv->silent_reset_rx_stuck_event[slot_index] = 0;
- }
-
- priv->rx_ctr = RegRxCounter;
-
- return bStuck;
-}
-
-bool rtl92e_is_tx_stuck(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- bool bStuck = false;
- u16 RegTxCounter = rtl92e_readw(dev, 0x128);
-
- if (priv->tx_counter == RegTxCounter)
- bStuck = true;
-
- priv->tx_counter = RegTxCounter;
-
- return bStuck;
-}
-
-bool rtl92e_get_nmode_support_by_sec(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
-
- if (ieee->rtllib_ap_sec_type &&
- (ieee->rtllib_ap_sec_type(priv->rtllib) & (SEC_ALG_WEP |
- SEC_ALG_TKIP))) {
- return false;
- } else {
- return true;
- }
-}
-
-bool rtl92e_is_halfn_supported_by_ap(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
-
- return ieee->half_wireless_n24g_mode;
-}
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h
deleted file mode 100644
index 9d9c5051c7fe..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef _RTL8192E_H
-#define _RTL8192E_H
-
-#include "r8190P_def.h"
-
-bool rtl92e_is_halfn_supported_by_ap(struct net_device *dev);
-bool rtl92e_get_nmode_support_by_sec(struct net_device *dev);
-bool rtl92e_is_tx_stuck(struct net_device *dev);
-bool rtl92e_is_rx_stuck(struct net_device *dev);
-void rtl92e_ack_irq(struct net_device *dev, u32 *p_inta);
-void rtl92e_enable_rx(struct net_device *dev);
-void rtl92e_enable_tx(struct net_device *dev);
-void rtl92e_init_variables(struct net_device *dev);
-void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val);
-void rtl92e_get_eeprom_size(struct net_device *dev);
-bool rtl92e_start_adapter(struct net_device *dev);
-void rtl92e_link_change(struct net_device *dev);
-void rtl92e_set_monitor_mode(struct net_device *dev, bool allow_all_da,
- bool write_into_reg);
-void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc,
- struct cb_desc *cb_desc, struct sk_buff *skb);
-void rtl92e_fill_tx_cmd_desc(struct net_device *dev, struct tx_desc_cmd *entry,
- struct cb_desc *cb_desc, struct sk_buff *skb);
-bool rtl92e_get_rx_stats(struct net_device *dev, struct rtllib_rx_stats *stats,
- struct rx_desc *pdesc, struct sk_buff *skb);
-void rtl92e_stop_adapter(struct net_device *dev, bool reset);
-void rtl92e_update_ratr_table(struct net_device *dev);
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c
deleted file mode 100644
index ddf998cf2041..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c
+++ /dev/null
@@ -1,189 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtl_core.h"
-#include "r8192E_hw.h"
-#include "table.h"
-#include "r8192E_firmware.h"
-#include "r8192E_cmdpkt.h"
-#include <linux/firmware.h>
-
-static bool _rtl92e_wait_for_fw(struct net_device *dev, u32 mask, u32 timeout)
-{
- unsigned long deadline = jiffies + msecs_to_jiffies(timeout);
-
- while (time_before(jiffies, deadline)) {
- if (rtl92e_readl(dev, CPU_GEN) & mask)
- return true;
- mdelay(2);
- }
- return false;
-}
-
-static bool _rtl92e_fw_boot_cpu(struct net_device *dev)
-{
- u32 CPU_status = 0;
-
- if (!_rtl92e_wait_for_fw(dev, CPU_GEN_PUT_CODE_OK, 200)) {
- netdev_err(dev, "Firmware download failed.\n");
- return false;
- }
- netdev_dbg(dev, "Download Firmware: Put code ok!\n");
-
- CPU_status = rtl92e_readl(dev, CPU_GEN);
- rtl92e_writeb(dev, CPU_GEN, (CPU_status | CPU_GEN_PWR_STB_CPU) & 0xff);
- mdelay(1);
-
- if (!_rtl92e_wait_for_fw(dev, CPU_GEN_BOOT_RDY, 200)) {
- netdev_err(dev, "Firmware boot failed.\n");
- return false;
- }
-
- netdev_dbg(dev, "Download Firmware: Boot ready!\n");
-
- return true;
-}
-
-static bool _rtl92e_fw_check_ready(struct net_device *dev,
- u8 load_fw_status)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_firmware *pfirmware = priv->fw_info;
- bool rt_status = true;
-
- switch (load_fw_status) {
- case FW_INIT_STEP0_BOOT:
- pfirmware->status = FW_STATUS_1_MOVE_BOOT_CODE;
- break;
-
- case FW_INIT_STEP1_MAIN:
- pfirmware->status = FW_STATUS_2_MOVE_MAIN_CODE;
-
- rt_status = _rtl92e_fw_boot_cpu(dev);
- if (rt_status)
- pfirmware->status = FW_STATUS_3_TURNON_CPU;
- else
- netdev_dbg(dev, "_rtl92e_fw_boot_cpu fail!\n");
-
- break;
-
- case FW_INIT_STEP2_DATA:
- pfirmware->status = FW_STATUS_4_MOVE_DATA_CODE;
- mdelay(1);
-
- rt_status = _rtl92e_wait_for_fw(dev, CPU_GEN_FIRM_RDY, 20);
- if (rt_status)
- pfirmware->status = FW_STATUS_5_READY;
- break;
- default:
- rt_status = false;
- netdev_dbg(dev, "Unknown firmware status");
- break;
- }
-
- return rt_status;
-}
-
-static bool _rtl92e_fw_prepare(struct net_device *dev, struct rt_fw_blob *blob,
- const char *name, u8 padding)
-{
- const struct firmware *fw;
- int rc, i;
- bool ret = true;
-
- rc = request_firmware(&fw, name, &dev->dev);
- if (rc < 0)
- return false;
-
- if (round_up(fw->size, 4) > MAX_FW_SIZE - padding) {
- netdev_err(dev, "Firmware image %s too big for the device.\n",
- name);
- ret = false;
- goto out;
- }
-
- if (padding)
- memset(blob->data, 0, padding);
- if (fw->size % 4)
- memset(blob->data + padding + fw->size, 0, 4);
- memcpy(blob->data + padding, fw->data, fw->size);
-
- blob->size = round_up(fw->size, 4) + padding;
-
- /* Swap endian - firmware is packaged in invalid endiannes*/
- for (i = padding; i < blob->size; i += 4) {
- u32 *data = (u32 *)(blob->data + i);
- *data = swab32p(data);
- }
-out:
- release_firmware(fw);
- return ret;
-}
-
-bool rtl92e_init_fw(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- bool rt_status = true;
-
- u32 file_length = 0;
- u8 *mapped_file = NULL;
- u8 i = 0;
- enum opt_rst_type rst_opt = OPT_SYSTEM_RESET;
- enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT;
-
- struct rt_firmware *pfirmware = priv->fw_info;
-
- netdev_dbg(dev, " PlatformInitFirmware()==>\n");
-
- if (pfirmware->status == FW_STATUS_0_INIT) {
- rst_opt = OPT_SYSTEM_RESET;
- starting_state = FW_INIT_STEP0_BOOT;
-
- } else if (pfirmware->status == FW_STATUS_5_READY) {
- rst_opt = OPT_FIRMWARE_RESET;
- starting_state = FW_INIT_STEP2_DATA;
- }
-
- for (i = starting_state; i <= FW_INIT_STEP2_DATA; i++) {
- if (rst_opt == OPT_SYSTEM_RESET) {
- if (pfirmware->blobs[i].size == 0) {
- const char *fw_name[3] = {
- RTL8192E_BOOT_IMG_FW,
- RTL8192E_MAIN_IMG_FW,
- RTL8192E_DATA_IMG_FW
- };
- int pad = 0;
-
- if (i == FW_INIT_STEP1_MAIN)
- pad = 128;
-
- if (!_rtl92e_fw_prepare(dev,
- &pfirmware->blobs[i],
- fw_name[i],
- pad))
- goto download_firmware_fail;
- }
- }
-
- mapped_file = pfirmware->blobs[i].data;
- file_length = pfirmware->blobs[i].size;
-
- rt_status = rtl92e_send_cmd_pkt(dev, DESC_PACKET_TYPE_INIT,
- mapped_file, file_length);
- if (!rt_status)
- goto download_firmware_fail;
-
- if (!_rtl92e_fw_check_ready(dev, i))
- goto download_firmware_fail;
- }
-
- netdev_dbg(dev, "Firmware Download Success\n");
- return rt_status;
-
-download_firmware_fail:
- netdev_err(dev, "%s: Failed to initialize firmware.\n", __func__);
- return false;
-}
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h
deleted file mode 100644
index b9059abc901b..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef __INC_FIRMWARE_H
-#define __INC_FIRMWARE_H
-
-#define RTL8192E_BOOT_IMG_FW "RTL8192E/boot.img"
-#define RTL8192E_MAIN_IMG_FW "RTL8192E/main.img"
-#define RTL8192E_DATA_IMG_FW "RTL8192E/data.img"
-
-enum firmware_init_step {
- FW_INIT_STEP0_BOOT = 0,
- FW_INIT_STEP1_MAIN = 1,
- FW_INIT_STEP2_DATA = 2,
-};
-
-enum opt_rst_type {
- OPT_SYSTEM_RESET = 0,
- OPT_FIRMWARE_RESET = 1,
-};
-
-enum desc_packet_type {
- DESC_PACKET_TYPE_INIT = 0,
- DESC_PACKET_TYPE_NORMAL = 1,
-};
-
-enum firmware_status {
- FW_STATUS_0_INIT = 0,
- FW_STATUS_1_MOVE_BOOT_CODE = 1,
- FW_STATUS_2_MOVE_MAIN_CODE = 2,
- FW_STATUS_3_TURNON_CPU = 3,
- FW_STATUS_4_MOVE_DATA_CODE = 4,
- FW_STATUS_5_READY = 5,
-};
-
-#define MAX_FW_SIZE 64000
-struct rt_fw_blob {
- u16 size;
- u8 data[MAX_FW_SIZE];
-};
-
-#define FW_BLOBS 3
-struct rt_firmware {
- enum firmware_status status;
- struct rt_fw_blob blobs[FW_BLOBS];
-};
-
-bool rtl92e_init_fw(struct net_device *dev);
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h
deleted file mode 100644
index e507593b939c..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef R8180_HW
-#define R8180_HW
-
-enum baseband_config {
- BB_CONFIG_PHY_REG = 0,
- BB_CONFIG_AGC_TAB = 1,
-};
-
-#define RTL8190_EEPROM_ID 0x8129
-#define EEPROM_VID 0x02
-#define EEPROM_DID 0x04
-#define EEPROM_NODE_ADDRESS_BYTE_0 0x0C
-
-#define EEPROM_Default_ThermalMeter 0x77
-#define EEPROM_Default_AntTxPowerDiff 0x0
-#define EEPROM_Default_TxPwDiff_CrystalCap 0x5
-#define EEPROM_Default_TxPower 0x1010
-#define EEPROM_ICVersion_ChannelPlan 0x7C
-#define EEPROM_Customer_ID 0x7B
-#define EEPROM_RFInd_PowerDiff 0x28
-
-#define EEPROM_ThermalMeter 0x29
-#define EEPROM_TxPwDiff_CrystalCap 0x2A
-#define EEPROM_TxPwIndex_CCK 0x2C
-#define EEPROM_TxPwIndex_OFDM_24G 0x3A
-
-#define EEPROM_CID_TOSHIBA 0x4
-#define EEPROM_CID_NetCore 0x5
-enum _RTL8192PCI_HW {
- MAC0 = 0x000,
- MAC4 = 0x004,
- PCIF = 0x009,
-#define MXDMA2_NO_LIMIT 0x7
-
-#define MXDMA2_RX_SHIFT 4
-#define MXDMA2_TX_SHIFT 0
- PMR = 0x00c,
- EPROM_CMD = 0x00e,
-
-#define EPROM_CMD_9356SEL BIT(4)
-#define EPROM_CMD_OPERATING_MODE_SHIFT 6
-#define EPROM_CMD_NORMAL 0
-#define EPROM_CMD_PROGRAM 2
-#define EPROM_CS_BIT 3
-#define EPROM_CK_BIT 2
-#define EPROM_W_BIT 1
-#define EPROM_R_BIT 0
-
- ANAPAR = 0x17,
-#define BB_GLOBAL_RESET_BIT 0x1
- BB_GLOBAL_RESET = 0x020,
- BSSIDR = 0x02E,
- CMDR = 0x037,
-#define CR_RE 0x08
-#define CR_TE 0x04
- SIFS = 0x03E,
- RCR = 0x044,
-#define RCR_ONLYERLPKT BIT(31)
-#define RCR_CBSSID BIT(23)
-#define RCR_ADD3 BIT(21)
-#define RCR_AMF BIT(20)
-#define RCR_ADF BIT(18)
-#define RCR_AICV BIT(12)
-#define RCR_AB BIT(3)
-#define RCR_AM BIT(2)
-#define RCR_APM BIT(1)
-#define RCR_AAP BIT(0)
-#define RCR_MXDMA_OFFSET 8
-#define RCR_FIFO_OFFSET 13
- SLOT_TIME = 0x049,
- ACK_TIMEOUT = 0x04c,
- EDCAPARA_BE = 0x050,
- EDCAPARA_BK = 0x054,
- EDCAPARA_VO = 0x058,
- EDCAPARA_VI = 0x05C,
-#define AC_PARAM_TXOP_LIMIT_OFFSET 16
-#define AC_PARAM_ECW_MAX_OFFSET 12
-#define AC_PARAM_ECW_MIN_OFFSET 8
-#define AC_PARAM_AIFS_OFFSET 0
- BCN_TCFG = 0x062,
-#define BCN_TCFG_CW_SHIFT 8
-#define BCN_TCFG_IFS 0
- BCN_INTERVAL = 0x070,
- ATIMWND = 0x072,
- BCN_DRV_EARLY_INT = 0x074,
- BCN_DMATIME = 0x076,
- BCN_ERR_THRESH = 0x078,
- RWCAM = 0x0A0,
-#define TOTAL_CAM_ENTRY 32
- WCAMI = 0x0A4,
- SECR = 0x0B0,
-#define SCR_TxUseDK BIT(0)
-#define SCR_RxUseDK BIT(1)
-#define SCR_TxEncEnable BIT(2)
-#define SCR_RxDecEnable BIT(3)
-#define SCR_NoSKMC BIT(5)
- SWREGULATOR = 0x0BD,
- INTA_MASK = 0x0f4,
-#define IMR_TBDOK BIT(27)
-#define IMR_TBDER BIT(26)
-#define IMR_TXFOVW BIT(15)
-#define IMR_TIMEOUT0 BIT(14)
-#define IMR_BcnInt BIT(13)
-#define IMR_RXFOVW BIT(12)
-#define IMR_RDU BIT(11)
-#define IMR_RXCMDOK BIT(10)
-#define IMR_BDOK BIT(9)
-#define IMR_HIGHDOK BIT(8)
-#define IMR_COMDOK BIT(7)
-#define IMR_MGNTDOK BIT(6)
-#define IMR_HCCADOK BIT(5)
-#define IMR_BKDOK BIT(4)
-#define IMR_BEDOK BIT(3)
-#define IMR_VIDOK BIT(2)
-#define IMR_VODOK BIT(1)
-#define IMR_ROK BIT(0)
- ISR = 0x0f8,
- TP_POLL = 0x0fd,
-#define TP_POLL_CQ BIT(5)
- PSR = 0x0ff,
- CPU_GEN = 0x100,
-#define CPU_CCK_LOOPBACK 0x00030000
-#define CPU_GEN_SYSTEM_RESET 0x00000001
-#define CPU_GEN_FIRMWARE_RESET 0x00000008
-#define CPU_GEN_BOOT_RDY 0x00000010
-#define CPU_GEN_FIRM_RDY 0x00000020
-#define CPU_GEN_PUT_CODE_OK 0x00000080
-#define CPU_GEN_BB_RST 0x00000100
-#define CPU_GEN_PWR_STB_CPU 0x00000004
-#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF
-#define CPU_GEN_NO_LOOPBACK_SET 0x00080000
- ACM_HW_CTRL = 0x171,
-#define ACM_HW_BEQ_EN BIT(1)
-#define ACM_HW_VIQ_EN BIT(2)
-#define ACM_HW_VOQ_EN BIT(3)
- RQPN1 = 0x180,
- RQPN2 = 0x184,
- RQPN3 = 0x188,
- QPNR = 0x1F0,
- BQDA = 0x200,
- HQDA = 0x204,
- CQDA = 0x208,
- MQDA = 0x20C,
- HCCAQDA = 0x210,
- VOQDA = 0x214,
- VIQDA = 0x218,
- BEQDA = 0x21C,
- BKQDA = 0x220,
- RDQDA = 0x228,
-
- WFCRC0 = 0x2f0,
- WFCRC1 = 0x2f4,
- WFCRC2 = 0x2f8,
-
- BW_OPMODE = 0x300,
-#define BW_OPMODE_20MHZ BIT(2)
- IC_VERRSION = 0x301,
- MSR = 0x303,
-#define MSR_LINK_MASK (BIT(1) | BIT(0))
-#define MSR_LINK_MANAGED 2
-#define MSR_LINK_ADHOC 1
-#define MSR_LINK_MASTER 3
-
-#define MSR_NOLINK 0x00
-#define MSR_ADHOC 0x01
-#define MSR_INFRA 0x02
-#define MSR_AP 0x03
-
- RETRY_LIMIT = 0x304,
-#define RETRY_LIMIT_SHORT_SHIFT 8
-#define RETRY_LIMIT_LONG_SHIFT 0
- TSFR = 0x308,
- RRSR = 0x310,
-#define RRSR_SHORT_OFFSET 23
-#define RRSR_1M BIT(0)
-#define RRSR_2M BIT(1)
-#define RRSR_5_5M BIT(2)
-#define RRSR_11M BIT(3)
-#define RRSR_6M BIT(4)
-#define RRSR_9M BIT(5)
-#define RRSR_12M BIT(6)
-#define RRSR_18M BIT(7)
-#define RRSR_24M BIT(8)
-#define RRSR_36M BIT(9)
-#define RRSR_48M BIT(10)
-#define RRSR_54M BIT(11)
-#define BRSR_AckShortPmb BIT(23)
- UFWP = 0x318,
- RATR0 = 0x320,
-#define RATR_1M 0x00000001
-#define RATR_2M 0x00000002
-#define RATR_55M 0x00000004
-#define RATR_11M 0x00000008
-#define RATR_6M 0x00000010
-#define RATR_9M 0x00000020
-#define RATR_12M 0x00000040
-#define RATR_18M 0x00000080
-#define RATR_24M 0x00000100
-#define RATR_36M 0x00000200
-#define RATR_48M 0x00000400
-#define RATR_54M 0x00000800
-#define RATR_MCS0 0x00001000
-#define RATR_MCS1 0x00002000
-#define RATR_MCS2 0x00004000
-#define RATR_MCS3 0x00008000
-#define RATR_MCS4 0x00010000
-#define RATR_MCS5 0x00020000
-#define RATR_MCS6 0x00040000
-#define RATR_MCS7 0x00080000
-#define RATR_MCS8 0x00100000
-#define RATR_MCS9 0x00200000
-#define RATR_MCS10 0x00400000
-#define RATR_MCS11 0x00800000
-#define RATR_MCS12 0x01000000
-#define RATR_MCS13 0x02000000
-#define RATR_MCS14 0x04000000
-#define RATR_MCS15 0x08000000
-#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
-#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M | \
- RATR_24M | RATR_36M | RATR_48M | RATR_54M)
-#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \
- RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \
- RATR_MCS6 | RATR_MCS7)
-#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \
- RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \
- RATR_MCS14 | RATR_MCS15)
-
- DRIVER_RSSI = 0x32c,
- MCS_TXAGC = 0x340,
- CCK_TXAGC = 0x348,
- MAC_BLK_CTRL = 0x403,
-};
-
-#define GPI 0x108
-
-#define ANAPAR_FOR_8192PCIE 0x17
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c
deleted file mode 100644
index fbe624e235df..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c
+++ /dev/null
@@ -1,1110 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include <linux/bitops.h>
-#include "rtl_core.h"
-#include "r8192E_hw.h"
-#include "r8192E_phyreg.h"
-#include "r8190P_rtl8256.h"
-#include "r8192E_phy.h"
-#include "rtl_dm.h"
-
-#include "table.h"
-
-/*************************Define local function prototype**********************/
-
-static u32 _rtl92e_phy_rf_fw_read(struct net_device *dev,
- enum rf90_radio_path eRFPath, u32 Offset);
-static void _rtl92e_phy_rf_fw_write(struct net_device *dev,
- enum rf90_radio_path eRFPath, u32 Offset,
- u32 Data);
-
-static u32 _rtl92e_calculate_bit_shift(u32 dwBitMask)
-{
- if (!dwBitMask)
- return 32;
- return ffs(dwBitMask) - 1;
-}
-
-void rtl92e_set_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask,
- u32 dwData)
-{
- u32 OriginalValue, BitShift, NewValue;
-
- if (dwBitMask != bMaskDWord) {
- OriginalValue = rtl92e_readl(dev, dwRegAddr);
- BitShift = _rtl92e_calculate_bit_shift(dwBitMask);
- NewValue = (OriginalValue & ~dwBitMask) | (dwData << BitShift);
- rtl92e_writel(dev, dwRegAddr, NewValue);
- } else {
- rtl92e_writel(dev, dwRegAddr, dwData);
- }
-}
-
-u32 rtl92e_get_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask)
-{
- u32 OriginalValue, BitShift;
-
- OriginalValue = rtl92e_readl(dev, dwRegAddr);
- BitShift = _rtl92e_calculate_bit_shift(dwBitMask);
-
- return (OriginalValue & dwBitMask) >> BitShift;
-}
-
-static u32 _rtl92e_phy_rf_read(struct net_device *dev,
- enum rf90_radio_path eRFPath, u32 Offset)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 ret = 0;
- u32 NewOffset = 0;
- struct bb_reg_definition *pPhyReg = &priv->phy_reg_def[eRFPath];
-
- Offset &= 0x3f;
-
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);
- if (Offset >= 31) {
- priv->rf_reg_0value[eRFPath] |= 0x140;
- rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset,
- bMaskDWord,
- (priv->rf_reg_0value[eRFPath] << 16));
- NewOffset = Offset - 30;
- } else if (Offset >= 16) {
- priv->rf_reg_0value[eRFPath] |= 0x100;
- priv->rf_reg_0value[eRFPath] &= (~0x40);
- rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset,
- bMaskDWord,
- (priv->rf_reg_0value[eRFPath] << 16));
- NewOffset = Offset - 15;
- } else {
- NewOffset = Offset;
- }
- rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress,
- NewOffset);
- rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0);
- rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1);
-
- mdelay(1);
-
- ret = rtl92e_get_bb_reg(dev, pPhyReg->rfLSSIReadBack,
- bLSSIReadBackData);
-
- priv->rf_reg_0value[eRFPath] &= 0xebf;
-
- rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset, bMaskDWord,
- (priv->rf_reg_0value[eRFPath] << 16));
-
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);
-
- return ret;
-}
-
-static void _rtl92e_phy_rf_write(struct net_device *dev,
- enum rf90_radio_path eRFPath, u32 Offset,
- u32 Data)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 DataAndAddr = 0, NewOffset = 0;
- struct bb_reg_definition *pPhyReg = &priv->phy_reg_def[eRFPath];
-
- Offset &= 0x3f;
-
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);
-
- if (Offset >= 31) {
- priv->rf_reg_0value[eRFPath] |= 0x140;
- rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset,
- bMaskDWord,
- (priv->rf_reg_0value[eRFPath] << 16));
- NewOffset = Offset - 30;
- } else if (Offset >= 16) {
- priv->rf_reg_0value[eRFPath] |= 0x100;
- priv->rf_reg_0value[eRFPath] &= (~0x40);
- rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset,
- bMaskDWord,
- (priv->rf_reg_0value[eRFPath] << 16));
- NewOffset = Offset - 15;
- } else {
- NewOffset = Offset;
- }
-
- DataAndAddr = (NewOffset & 0x3f) | (Data << 16);
-
- rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
-
- if (Offset == 0x0)
- priv->rf_reg_0value[eRFPath] = Data;
-
- if (Offset != 0) {
- priv->rf_reg_0value[eRFPath] &= 0xebf;
- rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset,
- bMaskDWord,
- (priv->rf_reg_0value[eRFPath] << 16));
- }
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);
-}
-
-void rtl92e_set_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath,
- u32 RegAddr, u32 BitMask, u32 Data)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 Original_Value, BitShift, New_Value;
-
- if (priv->rtllib->rf_power_state != rf_on && !priv->being_init_adapter)
- return;
-
- if (priv->rf_mode == RF_OP_By_FW) {
- if (BitMask != bMask12Bits) {
- Original_Value = _rtl92e_phy_rf_fw_read(dev, eRFPath,
- RegAddr);
- BitShift = _rtl92e_calculate_bit_shift(BitMask);
- New_Value = (Original_Value & ~BitMask) | (Data << BitShift);
-
- _rtl92e_phy_rf_fw_write(dev, eRFPath, RegAddr,
- New_Value);
- } else {
- _rtl92e_phy_rf_fw_write(dev, eRFPath, RegAddr, Data);
- }
- udelay(200);
- } else {
- if (BitMask != bMask12Bits) {
- Original_Value = _rtl92e_phy_rf_read(dev, eRFPath,
- RegAddr);
- BitShift = _rtl92e_calculate_bit_shift(BitMask);
- New_Value = (Original_Value & ~BitMask) | (Data << BitShift);
-
- _rtl92e_phy_rf_write(dev, eRFPath, RegAddr, New_Value);
- } else {
- _rtl92e_phy_rf_write(dev, eRFPath, RegAddr, Data);
- }
- }
-}
-
-u32 rtl92e_get_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath,
- u32 RegAddr, u32 BitMask)
-{
- u32 Original_Value, Readback_Value, BitShift;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->rtllib->rf_power_state != rf_on && !priv->being_init_adapter)
- return 0;
- mutex_lock(&priv->rf_mutex);
- if (priv->rf_mode == RF_OP_By_FW) {
- Original_Value = _rtl92e_phy_rf_fw_read(dev, eRFPath, RegAddr);
- udelay(200);
- } else {
- Original_Value = _rtl92e_phy_rf_read(dev, eRFPath, RegAddr);
- }
- BitShift = _rtl92e_calculate_bit_shift(BitMask);
- Readback_Value = (Original_Value & BitMask) >> BitShift;
- mutex_unlock(&priv->rf_mutex);
- return Readback_Value;
-}
-
-static u32 _rtl92e_phy_rf_fw_read(struct net_device *dev,
- enum rf90_radio_path eRFPath, u32 Offset)
-{
- u32 Data = 0;
- u8 time = 0;
-
- Data |= ((Offset & 0xFF) << 12);
- Data |= ((eRFPath & 0x3) << 20);
- Data |= 0x80000000;
- while (rtl92e_readl(dev, QPNR) & 0x80000000) {
- if (time++ < 100)
- udelay(10);
- else
- break;
- }
- rtl92e_writel(dev, QPNR, Data);
- while (rtl92e_readl(dev, QPNR) & 0x80000000) {
- if (time++ < 100)
- udelay(10);
- else
- return 0;
- }
- return rtl92e_readl(dev, RF_DATA);
-}
-
-static void _rtl92e_phy_rf_fw_write(struct net_device *dev,
- enum rf90_radio_path eRFPath, u32 Offset,
- u32 Data)
-{
- u8 time = 0;
-
- Data |= ((Offset & 0xFF) << 12);
- Data |= ((eRFPath & 0x3) << 20);
- Data |= 0x400000;
- Data |= 0x80000000;
-
- while (rtl92e_readl(dev, QPNR) & 0x80000000) {
- if (time++ < 100)
- udelay(10);
- else
- break;
- }
- rtl92e_writel(dev, QPNR, Data);
-}
-
-void rtl92e_config_mac(struct net_device *dev)
-{
- u32 dwArrayLen = 0, i = 0;
- u32 *pdwArray = NULL;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->tx_pwr_data_read_from_eeprom) {
- dwArrayLen = RTL8192E_MACPHY_ARR_PG_LEN;
- pdwArray = RTL8192E_MACPHY_ARR_PG;
-
- } else {
- dwArrayLen = RTL8192E_MACPHY_ARR_LEN;
- pdwArray = RTL8192E_MACPHY_ARR;
- }
- for (i = 0; i < dwArrayLen; i += 3) {
- if (pdwArray[i] == 0x318)
- pdwArray[i + 2] = 0x00000800;
- rtl92e_set_bb_reg(dev, pdwArray[i], pdwArray[i + 1],
- pdwArray[i + 2]);
- }
-}
-
-static void _rtl92e_phy_config_bb(struct net_device *dev, u8 ConfigType)
-{
- int i;
- u32 *Rtl819XPHY_REGArray_Table = NULL;
- u32 *Rtl819XAGCTAB_Array_Table = NULL;
- u16 AGCTAB_ArrayLen, PHY_REGArrayLen = 0;
-
- AGCTAB_ArrayLen = RTL8192E_AGCTAB_ARR_LEN;
- Rtl819XAGCTAB_Array_Table = RTL8192E_AGCTAB_ARR;
- PHY_REGArrayLen = RTL8192E_PHY_REG_1T2R_ARR_LEN;
- Rtl819XPHY_REGArray_Table = RTL8192E_PHY_REG_1T2R_ARR;
-
- if (ConfigType == BB_CONFIG_PHY_REG) {
- for (i = 0; i < PHY_REGArrayLen; i += 2) {
- rtl92e_set_bb_reg(dev, Rtl819XPHY_REGArray_Table[i],
- bMaskDWord,
- Rtl819XPHY_REGArray_Table[i + 1]);
- }
- } else if (ConfigType == BB_CONFIG_AGC_TAB) {
- for (i = 0; i < AGCTAB_ArrayLen; i += 2) {
- rtl92e_set_bb_reg(dev, Rtl819XAGCTAB_Array_Table[i],
- bMaskDWord,
- Rtl819XAGCTAB_Array_Table[i + 1]);
- }
- }
-}
-
-static void _rtl92e_init_bb_rf_reg_def(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- priv->phy_reg_def[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW;
- priv->phy_reg_def[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW;
-
- priv->phy_reg_def[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE;
- priv->phy_reg_def[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE;
-
- priv->phy_reg_def[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE;
- priv->phy_reg_def[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE;
-
- priv->phy_reg_def[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter;
- priv->phy_reg_def[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
-
- priv->phy_reg_def[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;
- priv->phy_reg_def[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;
-
- priv->phy_reg_def[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
- priv->phy_reg_def[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
-}
-
-bool rtl92e_check_bb_and_rf(struct net_device *dev, enum hw90_block CheckBlock,
- enum rf90_radio_path eRFPath)
-{
- bool ret = true;
- u32 i, CheckTimes = 4, dwRegRead = 0;
- u32 WriteAddr[4];
- u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f};
-
- WriteAddr[HW90_BLOCK_MAC] = 0x100;
- WriteAddr[HW90_BLOCK_PHY0] = 0x900;
- WriteAddr[HW90_BLOCK_PHY1] = 0x800;
- WriteAddr[HW90_BLOCK_RF] = 0x3;
-
- if (CheckBlock == HW90_BLOCK_MAC) {
- netdev_warn(dev, "%s(): No checks available for MAC block.\n",
- __func__);
- return ret;
- }
-
- for (i = 0; i < CheckTimes; i++) {
- switch (CheckBlock) {
- case HW90_BLOCK_PHY0:
- case HW90_BLOCK_PHY1:
- rtl92e_writel(dev, WriteAddr[CheckBlock],
- WriteData[i]);
- dwRegRead = rtl92e_readl(dev, WriteAddr[CheckBlock]);
- break;
-
- case HW90_BLOCK_RF:
- WriteData[i] &= 0xfff;
- rtl92e_set_rf_reg(dev, eRFPath,
- WriteAddr[HW90_BLOCK_RF],
- bMask12Bits, WriteData[i]);
- mdelay(10);
- dwRegRead = rtl92e_get_rf_reg(dev, eRFPath,
- WriteAddr[HW90_BLOCK_RF],
- bMaskDWord);
- mdelay(10);
- break;
-
- default:
- ret = false;
- break;
- }
-
- if (dwRegRead != WriteData[i]) {
- netdev_warn(dev, "%s(): Check failed.\n", __func__);
- ret = false;
- break;
- }
- }
-
- return ret;
-}
-
-static bool _rtl92e_bb_config_para_file(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- bool rtStatus = true;
- u8 bRegValue = 0, eCheckItem = 0;
- u32 dwRegValue = 0;
-
- bRegValue = rtl92e_readb(dev, BB_GLOBAL_RESET);
- rtl92e_writeb(dev, BB_GLOBAL_RESET, (bRegValue | BB_GLOBAL_RESET_BIT));
-
- dwRegValue = rtl92e_readl(dev, CPU_GEN);
- rtl92e_writel(dev, CPU_GEN, (dwRegValue & (~CPU_GEN_BB_RST)));
-
- for (eCheckItem = (enum hw90_block)HW90_BLOCK_PHY0;
- eCheckItem <= HW90_BLOCK_PHY1; eCheckItem++) {
- rtStatus = rtl92e_check_bb_and_rf(dev,
- (enum hw90_block)eCheckItem,
- (enum rf90_radio_path)0);
- if (!rtStatus)
- return rtStatus;
- }
- rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bCCKEn | bOFDMEn, 0x0);
- _rtl92e_phy_config_bb(dev, BB_CONFIG_PHY_REG);
-
- dwRegValue = rtl92e_readl(dev, CPU_GEN);
- rtl92e_writel(dev, CPU_GEN, (dwRegValue | CPU_GEN_BB_RST));
-
- _rtl92e_phy_config_bb(dev, BB_CONFIG_AGC_TAB);
-
- if (priv->ic_cut > VERSION_8190_BD) {
- dwRegValue = 0x0;
- rtl92e_set_bb_reg(dev, rFPGA0_TxGainStage,
- (bXBTxAGC | bXCTxAGC | bXDTxAGC), dwRegValue);
-
- dwRegValue = priv->crystal_cap;
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, bXtalCap92x,
- dwRegValue);
- }
-
- return rtStatus;
-}
-
-bool rtl92e_config_bb(struct net_device *dev)
-{
- _rtl92e_init_bb_rf_reg_def(dev);
- return _rtl92e_bb_config_para_file(dev);
-}
-
-void rtl92e_get_tx_power(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- priv->mcs_tx_pwr_level_org_offset[0] =
- rtl92e_readl(dev, rTxAGC_Rate18_06);
- priv->mcs_tx_pwr_level_org_offset[1] =
- rtl92e_readl(dev, rTxAGC_Rate54_24);
- priv->mcs_tx_pwr_level_org_offset[2] =
- rtl92e_readl(dev, rTxAGC_Mcs03_Mcs00);
- priv->mcs_tx_pwr_level_org_offset[3] =
- rtl92e_readl(dev, rTxAGC_Mcs07_Mcs04);
- priv->mcs_tx_pwr_level_org_offset[4] =
- rtl92e_readl(dev, rTxAGC_Mcs11_Mcs08);
- priv->mcs_tx_pwr_level_org_offset[5] =
- rtl92e_readl(dev, rTxAGC_Mcs15_Mcs12);
-
- priv->def_initial_gain[0] = rtl92e_readb(dev, rOFDM0_XAAGCCore1);
- priv->def_initial_gain[1] = rtl92e_readb(dev, rOFDM0_XBAGCCore1);
- priv->def_initial_gain[2] = rtl92e_readb(dev, rOFDM0_XCAGCCore1);
- priv->def_initial_gain[3] = rtl92e_readb(dev, rOFDM0_XDAGCCore1);
-
- priv->framesync = rtl92e_readb(dev, rOFDM0_RxDetector3);
-}
-
-void rtl92e_set_tx_power(struct net_device *dev, u8 channel)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 powerlevel = 0, powerlevelOFDM24G = 0;
-
- if (priv->epromtype == EEPROM_93C46) {
- powerlevel = priv->tx_pwr_level_cck[channel - 1];
- powerlevelOFDM24G = priv->tx_pwr_level_ofdm_24g[channel - 1];
- }
-
- rtl92e_set_cck_tx_power(dev, powerlevel);
- rtl92e_set_ofdm_tx_power(dev, powerlevelOFDM24G);
-}
-
-u8 rtl92e_config_rf_path(struct net_device *dev, enum rf90_radio_path eRFPath)
-{
- int i;
-
- switch (eRFPath) {
- case RF90_PATH_A:
- for (i = 0; i < RTL8192E_RADIO_A_ARR_LEN; i += 2) {
- if (RTL8192E_RADIO_A_ARR[i] == 0xfe) {
- msleep(100);
- continue;
- }
- rtl92e_set_rf_reg(dev, eRFPath, RTL8192E_RADIO_A_ARR[i],
- bMask12Bits,
- RTL8192E_RADIO_A_ARR[i + 1]);
- }
- break;
- case RF90_PATH_B:
- for (i = 0; i < RTL8192E_RADIO_B_ARR_LEN; i += 2) {
- if (RTL8192E_RADIO_B_ARR[i] == 0xfe) {
- msleep(100);
- continue;
- }
- rtl92e_set_rf_reg(dev, eRFPath, RTL8192E_RADIO_B_ARR[i],
- bMask12Bits,
- RTL8192E_RADIO_B_ARR[i + 1]);
- }
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static void _rtl92e_set_tx_power_level(struct net_device *dev, u8 channel)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 powerlevel = priv->tx_pwr_level_cck[channel - 1];
- u8 powerlevelOFDM24G = priv->tx_pwr_level_ofdm_24g[channel - 1];
-
- rtl92e_set_cck_tx_power(dev, powerlevel);
- rtl92e_set_ofdm_tx_power(dev, powerlevelOFDM24G);
-}
-
-static u8 _rtl92e_phy_set_sw_chnl_cmd_array(struct net_device *dev,
- struct sw_chnl_cmd *CmdTable,
- u32 CmdTableIdx, u32 CmdTableSz,
- enum sw_chnl_cmd_id cmd_id,
- u32 para1, u32 para2, u32 ms_delay)
-{
- struct sw_chnl_cmd *pCmd;
-
- if (!CmdTable) {
- netdev_err(dev, "%s(): CmdTable cannot be NULL.\n", __func__);
- return false;
- }
- if (CmdTableIdx >= CmdTableSz) {
- netdev_err(dev, "%s(): Invalid index requested.\n", __func__);
- return false;
- }
-
- pCmd = CmdTable + CmdTableIdx;
- pCmd->cmd_id = cmd_id;
- pCmd->para1 = para1;
- pCmd->para2 = para2;
- pCmd->ms_delay = ms_delay;
-
- return true;
-}
-
-static u8 _rtl92e_phy_switch_channel_step(struct net_device *dev, u8 channel,
- u8 *stage, u8 *step, u32 *delay)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
- u32 PreCommonCmdCnt;
- u32 PostCommonCmdCnt;
- u32 RfDependCmdCnt;
- struct sw_chnl_cmd *CurrentCmd = NULL;
- u8 eRFPath;
-
- if (!rtllib_legal_channel(priv->rtllib, channel)) {
- netdev_err(dev, "Invalid channel requested: %d\n", channel);
- return true;
- }
-
- {
- PreCommonCmdCnt = 0;
- _rtl92e_phy_set_sw_chnl_cmd_array(dev, ieee->PreCommonCmd,
- PreCommonCmdCnt++,
- MAX_PRECMD_CNT,
- cmd_id_set_tx_power_level,
- 0, 0, 0);
- _rtl92e_phy_set_sw_chnl_cmd_array(dev, ieee->PreCommonCmd,
- PreCommonCmdCnt++,
- MAX_PRECMD_CNT, cmd_id_end,
- 0, 0, 0);
-
- PostCommonCmdCnt = 0;
-
- _rtl92e_phy_set_sw_chnl_cmd_array(dev, ieee->PostCommonCmd,
- PostCommonCmdCnt++,
- MAX_POSTCMD_CNT, cmd_id_end,
- 0, 0, 0);
-
- RfDependCmdCnt = 0;
-
- if (!(channel >= 1 && channel <= 14)) {
- netdev_err(dev,
- "Invalid channel requested for 8256: %d\n",
- channel);
- return false;
- }
- _rtl92e_phy_set_sw_chnl_cmd_array(dev,
- ieee->RfDependCmd,
- RfDependCmdCnt++,
- MAX_RFDEPENDCMD_CNT,
- cmd_id_rf_write_reg,
- rZebra1_Channel,
- channel, 10);
- _rtl92e_phy_set_sw_chnl_cmd_array(dev,
- ieee->RfDependCmd,
- RfDependCmdCnt++,
- MAX_RFDEPENDCMD_CNT,
- cmd_id_end, 0, 0, 0);
-
- do {
- switch (*stage) {
- case 0:
- CurrentCmd = &ieee->PreCommonCmd[*step];
- break;
- case 1:
- CurrentCmd = &ieee->RfDependCmd[*step];
- break;
- case 2:
- CurrentCmd = &ieee->PostCommonCmd[*step];
- break;
- }
-
- if (CurrentCmd && CurrentCmd->cmd_id == cmd_id_end) {
- if ((*stage) == 2)
- return true;
- (*stage)++;
- (*step) = 0;
- continue;
- }
-
- if (!CurrentCmd)
- continue;
- switch (CurrentCmd->cmd_id) {
- case cmd_id_set_tx_power_level:
- if (priv->ic_cut > VERSION_8190_BD)
- _rtl92e_set_tx_power_level(dev,
- channel);
- break;
- case cmd_id_write_port_ulong:
- rtl92e_writel(dev, CurrentCmd->para1,
- CurrentCmd->para2);
- break;
- case cmd_id_write_port_ushort:
- rtl92e_writew(dev, CurrentCmd->para1,
- CurrentCmd->para2);
- break;
- case cmd_id_write_port_uchar:
- rtl92e_writeb(dev, CurrentCmd->para1,
- CurrentCmd->para2);
- break;
- case cmd_id_rf_write_reg:
- for (eRFPath = 0; eRFPath <
- priv->num_total_rf_path; eRFPath++)
- rtl92e_set_rf_reg(dev,
- (enum rf90_radio_path)eRFPath,
- CurrentCmd->para1, bMask12Bits,
- CurrentCmd->para2 << 7);
- break;
- default:
- break;
- }
-
- break;
- } while (true);
- } /*for (Number of RF paths)*/
-
- (*delay) = CurrentCmd->ms_delay;
- (*step)++;
- return false;
-}
-
-static void _rtl92e_phy_switch_channel(struct net_device *dev, u8 channel)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 delay = 0;
-
- while (!_rtl92e_phy_switch_channel_step(dev, channel,
- &priv->sw_chnl_stage,
- &priv->sw_chnl_step, &delay)) {
- if (delay > 0)
- msleep(delay);
- if (!priv->up)
- break;
- }
-}
-
-static void _rtl92e_phy_switch_channel_work_item(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- _rtl92e_phy_switch_channel(dev, priv->chan);
-}
-
-void rtl92e_set_channel(struct net_device *dev, u8 channel)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (!priv->up) {
- netdev_err(dev, "%s(): Driver is not initialized\n", __func__);
- return;
- }
- if (priv->sw_chnl_in_progress)
- return;
-
- switch (priv->rtllib->mode) {
- case WIRELESS_MODE_B:
- if (channel > 14) {
- netdev_warn(dev,
- "Channel %d not available in 802.11b.\n",
- channel);
- return;
- }
- break;
- case WIRELESS_MODE_G:
- case WIRELESS_MODE_N_24G:
- if (channel > 14) {
- netdev_warn(dev,
- "Channel %d not available in 802.11g.\n",
- channel);
- return;
- }
- break;
- }
-
- priv->sw_chnl_in_progress = true;
- if (channel == 0)
- channel = 1;
-
- priv->chan = channel;
-
- priv->sw_chnl_stage = 0;
- priv->sw_chnl_step = 0;
-
- if (priv->up)
- _rtl92e_phy_switch_channel_work_item(dev);
- priv->sw_chnl_in_progress = false;
-}
-
-static void _rtl92e_cck_tx_power_track_bw_switch_tssi(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- switch (priv->current_chnl_bw) {
- case HT_CHANNEL_WIDTH_20:
- priv->cck_present_attn =
- priv->cck_present_attn_20m_def +
- priv->cck_present_attn_diff;
-
- if (priv->cck_present_attn >
- (CCK_TX_BB_GAIN_TABLE_LEN - 1))
- priv->cck_present_attn =
- CCK_TX_BB_GAIN_TABLE_LEN - 1;
- if (priv->cck_present_attn < 0)
- priv->cck_present_attn = 0;
-
- if (priv->rtllib->current_network.channel == 14 &&
- !priv->bcck_in_ch14) {
- priv->bcck_in_ch14 = true;
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- } else if (priv->rtllib->current_network.channel !=
- 14 && priv->bcck_in_ch14) {
- priv->bcck_in_ch14 = false;
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- } else {
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- }
- break;
-
- case HT_CHANNEL_WIDTH_20_40:
- priv->cck_present_attn =
- priv->cck_present_attn_40m_def +
- priv->cck_present_attn_diff;
-
- if (priv->cck_present_attn >
- (CCK_TX_BB_GAIN_TABLE_LEN - 1))
- priv->cck_present_attn =
- CCK_TX_BB_GAIN_TABLE_LEN - 1;
- if (priv->cck_present_attn < 0)
- priv->cck_present_attn = 0;
-
- if (priv->rtllib->current_network.channel == 14 &&
- !priv->bcck_in_ch14) {
- priv->bcck_in_ch14 = true;
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- } else if (priv->rtllib->current_network.channel != 14
- && priv->bcck_in_ch14) {
- priv->bcck_in_ch14 = false;
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- } else {
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- }
- break;
- }
-}
-
-static void _rtl92e_cck_tx_power_track_bw_switch_thermal(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->rtllib->current_network.channel == 14 &&
- !priv->bcck_in_ch14)
- priv->bcck_in_ch14 = true;
- else if (priv->rtllib->current_network.channel != 14 &&
- priv->bcck_in_ch14)
- priv->bcck_in_ch14 = false;
-
- switch (priv->current_chnl_bw) {
- case HT_CHANNEL_WIDTH_20:
- if (priv->rec_cck_20m_idx == 0)
- priv->rec_cck_20m_idx = 6;
- priv->cck_index = priv->rec_cck_20m_idx;
- break;
-
- case HT_CHANNEL_WIDTH_20_40:
- priv->cck_index = priv->rec_cck_40m_idx;
- break;
- }
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
-}
-
-static void _rtl92e_cck_tx_power_track_bw_switch(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->ic_cut >= IC_VersionCut_D)
- _rtl92e_cck_tx_power_track_bw_switch_tssi(dev);
- else
- _rtl92e_cck_tx_power_track_bw_switch_thermal(dev);
-}
-
-static void _rtl92e_set_bw_mode_work_item(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 regBwOpMode;
-
- if (!priv->up) {
- netdev_err(dev, "%s(): Driver is not initialized\n", __func__);
- return;
- }
- regBwOpMode = rtl92e_readb(dev, BW_OPMODE);
-
- switch (priv->current_chnl_bw) {
- case HT_CHANNEL_WIDTH_20:
- regBwOpMode |= BW_OPMODE_20MHZ;
- rtl92e_writeb(dev, BW_OPMODE, regBwOpMode);
- break;
-
- case HT_CHANNEL_WIDTH_20_40:
- regBwOpMode &= ~BW_OPMODE_20MHZ;
- rtl92e_writeb(dev, BW_OPMODE, regBwOpMode);
- break;
-
- default:
- netdev_err(dev, "%s(): unknown Bandwidth: %#X\n", __func__,
- priv->current_chnl_bw);
- break;
- }
-
- switch (priv->current_chnl_bw) {
- case HT_CHANNEL_WIDTH_20:
- rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
- rtl92e_set_bb_reg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
-
- if (!priv->btxpower_tracking) {
- rtl92e_writel(dev, rCCK0_TxFilter1, 0x1a1b0000);
- rtl92e_writel(dev, rCCK0_TxFilter2, 0x090e1317);
- rtl92e_writel(dev, rCCK0_DebugPort, 0x00000204);
- } else {
- _rtl92e_cck_tx_power_track_bw_switch(dev);
- }
-
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1);
-
- break;
- case HT_CHANNEL_WIDTH_20_40:
- rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
- rtl92e_set_bb_reg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
-
- if (!priv->btxpower_tracking) {
- rtl92e_writel(dev, rCCK0_TxFilter1, 0x35360000);
- rtl92e_writel(dev, rCCK0_TxFilter2, 0x121c252e);
- rtl92e_writel(dev, rCCK0_DebugPort, 0x00000409);
- } else {
- _rtl92e_cck_tx_power_track_bw_switch(dev);
- }
-
- rtl92e_set_bb_reg(dev, rCCK0_System, bCCKSideBand,
- (priv->n_cur_40mhz_prime_sc >> 1));
- rtl92e_set_bb_reg(dev, rOFDM1_LSTF, 0xC00,
- priv->n_cur_40mhz_prime_sc);
-
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0);
- break;
- default:
- netdev_err(dev, "%s(): unknown Bandwidth: %#X\n", __func__,
- priv->current_chnl_bw);
- break;
- }
-
- rtl92e_set_bandwidth(dev, priv->current_chnl_bw);
-
- atomic_dec(&(priv->rtllib->atm_swbw));
- priv->set_bw_mode_in_progress = false;
-}
-
-void rtl92e_set_bw_mode(struct net_device *dev, enum ht_channel_width bandwidth,
- enum ht_extchnl_offset Offset)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->set_bw_mode_in_progress)
- return;
-
- atomic_inc(&(priv->rtllib->atm_swbw));
- priv->set_bw_mode_in_progress = true;
-
- priv->current_chnl_bw = bandwidth;
-
- if (Offset == HT_EXTCHNL_OFFSET_LOWER)
- priv->n_cur_40mhz_prime_sc = HAL_PRIME_CHNL_OFFSET_UPPER;
- else if (Offset == HT_EXTCHNL_OFFSET_UPPER)
- priv->n_cur_40mhz_prime_sc = HAL_PRIME_CHNL_OFFSET_LOWER;
- else
- priv->n_cur_40mhz_prime_sc = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
- _rtl92e_set_bw_mode_work_item(dev);
-}
-
-void rtl92e_init_gain(struct net_device *dev, u8 Operation)
-{
-#define SCAN_RX_INITIAL_GAIN 0x17
-#define POWER_DETECTION_TH 0x08
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 BitMask;
- u8 initial_gain;
-
- if (priv->up) {
- switch (Operation) {
- case IG_Backup:
- initial_gain = SCAN_RX_INITIAL_GAIN;
- BitMask = bMaskByte0;
- priv->initgain_backup.xaagccore1 =
- rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1,
- BitMask);
- priv->initgain_backup.xbagccore1 =
- rtl92e_get_bb_reg(dev, rOFDM0_XBAGCCore1,
- BitMask);
- priv->initgain_backup.xcagccore1 =
- rtl92e_get_bb_reg(dev, rOFDM0_XCAGCCore1,
- BitMask);
- priv->initgain_backup.xdagccore1 =
- rtl92e_get_bb_reg(dev, rOFDM0_XDAGCCore1,
- BitMask);
- BitMask = bMaskByte2;
- priv->initgain_backup.cca = (u8)rtl92e_get_bb_reg(dev,
- rCCK0_CCA, BitMask);
-
- rtl92e_writeb(dev, rOFDM0_XAAGCCore1, initial_gain);
- rtl92e_writeb(dev, rOFDM0_XBAGCCore1, initial_gain);
- rtl92e_writeb(dev, rOFDM0_XCAGCCore1, initial_gain);
- rtl92e_writeb(dev, rOFDM0_XDAGCCore1, initial_gain);
- rtl92e_writeb(dev, 0xa0a, POWER_DETECTION_TH);
- break;
- case IG_Restore:
- BitMask = 0x7f;
- rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, BitMask,
- (u32)priv->initgain_backup.xaagccore1);
- rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, BitMask,
- (u32)priv->initgain_backup.xbagccore1);
- rtl92e_set_bb_reg(dev, rOFDM0_XCAGCCore1, BitMask,
- (u32)priv->initgain_backup.xcagccore1);
- rtl92e_set_bb_reg(dev, rOFDM0_XDAGCCore1, BitMask,
- (u32)priv->initgain_backup.xdagccore1);
- BitMask = bMaskByte2;
- rtl92e_set_bb_reg(dev, rCCK0_CCA, BitMask,
- (u32)priv->initgain_backup.cca);
-
- rtl92e_set_tx_power(dev,
- priv->rtllib->current_network.channel);
- break;
- }
- }
-}
-
-void rtl92e_set_rf_off(struct net_device *dev)
-{
- rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, BIT(4), 0x0);
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0);
- rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
- rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0);
- rtl92e_writeb(dev, ANAPAR_FOR_8192PCIE, 0x07);
-}
-
-static bool _rtl92e_set_rf_power_state(struct net_device *dev,
- enum rt_rf_power_state rf_power_state)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
- (&priv->rtllib->pwr_save_ctrl);
- bool bResult = true;
- u8 i = 0, QueueID = 0;
- struct rtl8192_tx_ring *ring = NULL;
-
- if (priv->set_rf_pwr_state_in_progress)
- return false;
- priv->set_rf_pwr_state_in_progress = true;
-
- switch (rf_power_state) {
- case rf_on:
- if ((priv->rtllib->rf_power_state == rf_off) &&
- RT_IN_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC)) {
- bool rtstatus;
- u32 InitilizeCount = 3;
-
- do {
- InitilizeCount--;
- rtstatus = rtl92e_enable_nic(dev);
- } while (!rtstatus && (InitilizeCount > 0));
- if (!rtstatus) {
- netdev_err(dev,
- "%s(): Failed to initialize Adapter.\n",
- __func__);
- priv->set_rf_pwr_state_in_progress = false;
- return false;
- }
- RT_CLEAR_PS_LEVEL(psc,
- RT_RF_OFF_LEVL_HALT_NIC);
- } else {
- rtl92e_writeb(dev, ANAPAR, 0x37);
- mdelay(1);
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1,
- 0x4, 0x1);
- priv->hw_rf_off_action = 0;
- rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE,
- BIT(4), 0x1);
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4,
- 0x300, 0x3);
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1,
- 0x18, 0x3);
- rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable,
- 0x3, 0x3);
- rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable,
- 0x3, 0x3);
- rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1,
- 0x60, 0x3);
- }
- break;
- case rf_sleep:
- if (priv->rtllib->rf_power_state == rf_off)
- break;
- for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) {
- ring = &priv->tx_ring[QueueID];
- if (skb_queue_len(&ring->queue) == 0) {
- QueueID++;
- continue;
- } else {
- udelay(10);
- i++;
- }
- if (i >= MAX_DOZE_WAITING_TIMES_9x)
- break;
- }
- rtl92e_set_rf_off(dev);
- break;
- case rf_off:
- for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) {
- ring = &priv->tx_ring[QueueID];
- if (skb_queue_len(&ring->queue) == 0) {
- QueueID++;
- continue;
- } else {
- udelay(10);
- i++;
- }
- if (i >= MAX_DOZE_WAITING_TIMES_9x)
- break;
- }
- rtl92e_set_rf_off(dev);
- break;
- default:
- bResult = false;
- netdev_warn(dev,
- "%s(): Unknown state requested: 0x%X.\n",
- __func__, rf_power_state);
- break;
- }
-
- if (bResult)
- priv->rtllib->rf_power_state = rf_power_state;
-
- priv->set_rf_pwr_state_in_progress = false;
- return bResult;
-}
-
-bool rtl92e_set_rf_power_state(struct net_device *dev,
- enum rt_rf_power_state rf_power_state)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- bool bResult = false;
-
- if (rf_power_state == priv->rtllib->rf_power_state &&
- priv->hw_rf_off_action == 0) {
- return bResult;
- }
-
- bResult = _rtl92e_set_rf_power_state(dev, rf_power_state);
- return bResult;
-}
-
-void rtl92e_scan_op_backup(struct net_device *dev, u8 Operation)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->up) {
- switch (Operation) {
- case SCAN_OPT_BACKUP:
- priv->rtllib->init_gain_handler(dev, IG_Backup);
- break;
-
- case SCAN_OPT_RESTORE:
- priv->rtllib->init_gain_handler(dev, IG_Restore);
- break;
- }
- }
-}
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h
deleted file mode 100644
index 956dfbdd5b68..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef _R819XU_PHY_H
-#define _R819XU_PHY_H
-
-#define MAX_DOZE_WAITING_TIMES_9x 64
-
-enum hw90_block {
- HW90_BLOCK_MAC = 0,
- HW90_BLOCK_PHY0 = 1,
- HW90_BLOCK_PHY1 = 2,
- HW90_BLOCK_RF = 3,
- HW90_BLOCK_MAXIMUM = 4,
-};
-
-enum rf90_radio_path {
- RF90_PATH_A = 0,
- RF90_PATH_B = 1,
- RF90_PATH_MAX
-};
-
-void rtl92e_set_bb_reg(struct net_device *dev, u32 dwRegAddr,
- u32 dwBitMask, u32 dwData);
-u32 rtl92e_get_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask);
-void rtl92e_set_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath,
- u32 RegAddr, u32 BitMask, u32 Data);
-u32 rtl92e_get_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath,
- u32 RegAddr, u32 BitMask);
-void rtl92e_config_mac(struct net_device *dev);
-bool rtl92e_check_bb_and_rf(struct net_device *dev,
- enum hw90_block CheckBlock,
- enum rf90_radio_path eRFPath);
-bool rtl92e_config_bb(struct net_device *dev);
-void rtl92e_get_tx_power(struct net_device *dev);
-void rtl92e_set_tx_power(struct net_device *dev, u8 channel);
-u8 rtl92e_config_rf_path(struct net_device *dev, enum rf90_radio_path eRFPath);
-
-void rtl92e_set_channel(struct net_device *dev, u8 channel);
-void rtl92e_set_bw_mode(struct net_device *dev,
- enum ht_channel_width bandwidth,
- enum ht_extchnl_offset Offset);
-void rtl92e_init_gain(struct net_device *dev, u8 operation);
-
-void rtl92e_set_rf_off(struct net_device *dev);
-
-bool rtl92e_set_rf_power_state(struct net_device *dev,
- enum rt_rf_power_state rf_power_state);
-
-void rtl92e_scan_op_backup(struct net_device *dev, u8 operation);
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h
deleted file mode 100644
index c48c56869c19..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h
+++ /dev/null
@@ -1,773 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef _R819XU_PHYREG_H
-#define _R819XU_PHYREG_H
-
-#define RF_DATA 0x1d4
-
-#define rPMAC_Reset 0x100
-#define rPMAC_TxStart 0x104
-#define rPMAC_TxLegacySIG 0x108
-#define rPMAC_TxHTSIG1 0x10c
-#define rPMAC_TxHTSIG2 0x110
-#define rPMAC_PHYDebug 0x114
-#define rPMAC_TxPacketNum 0x118
-#define rPMAC_TxIdle 0x11c
-#define rPMAC_TxMACHeader0 0x120
-#define rPMAC_TxMACHeader1 0x124
-#define rPMAC_TxMACHeader2 0x128
-#define rPMAC_TxMACHeader3 0x12c
-#define rPMAC_TxMACHeader4 0x130
-#define rPMAC_TxMACHeader5 0x134
-#define rPMAC_TxDataType 0x138
-#define rPMAC_TxRandomSeed 0x13c
-#define rPMAC_CCKPLCPPreamble 0x140
-#define rPMAC_CCKPLCPHeader 0x144
-#define rPMAC_CCKCRC16 0x148
-#define rPMAC_OFDMRxCRC32OK 0x170
-#define rPMAC_OFDMRxCRC32Er 0x174
-#define rPMAC_OFDMRxParityEr 0x178
-#define rPMAC_OFDMRxCRC8Er 0x17c
-#define rPMAC_CCKCRxRC16Er 0x180
-#define rPMAC_CCKCRxRC32Er 0x184
-#define rPMAC_CCKCRxRC32OK 0x188
-#define rPMAC_TxStatus 0x18c
-
-#define MCS_TXAGC 0x340
-#define CCK_TXAGC 0x348
-
-/* Mac block on/off control register */
-#define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC */
-#define rFPGA0_TxInfo 0x804
-#define rFPGA0_PSDFunction 0x808
-#define rFPGA0_TxGainStage 0x80c
-#define rFPGA0_RFTiming1 0x810
-#define rFPGA0_RFTiming2 0x814
-#define rFPGA0_XA_HSSIParameter2 0x824
-#define rFPGA0_XB_HSSIParameter2 0x82c
-#define rFPGA0_XA_LSSIParameter 0x840
-#define rFPGA0_XB_LSSIParameter 0x844
-#define rFPGA0_RFWakeUpParameter 0x850
-#define rFPGA0_RFSleepUpParameter 0x854
-#define rFPGA0_XA_RFInterfaceOE 0x860
-#define rFPGA0_XB_RFInterfaceOE 0x864
-#define rFPGA0_XAB_RFInterfaceSW 0x870
-#define rFPGA0_AnalogParameter1 0x880
-#define rFPGA0_AnalogParameter2 0x884
-#define rFPGA0_AnalogParameter3 0x888
-#define rFPGA0_AnalogParameter4 0x88c
-#define rFPGA0_XA_LSSIReadBack 0x8a0
-#define rFPGA0_XB_LSSIReadBack 0x8a4
-#define rFPGA0_PSDReport 0x8b4
-
-/* Page 9 - RF mode & OFDM TxSC */
-#define rFPGA1_RFMOD 0x900
-#define rFPGA1_TxBlock 0x904
-#define rFPGA1_DebugSelect 0x908
-#define rFPGA1_TxInfo 0x90c
-
-#define rCCK0_System 0xa00
-#define rCCK0_AFESetting 0xa04
-#define rCCK0_CCA 0xa08
-/* AGC default value, saturation level */
-#define rCCK0_RxAGC1 0xa0c
-#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */
-#define rCCK0_RxHP 0xa14
-/* Timing recovery & channel estimation threshold */
-#define rCCK0_DSPParameter1 0xa18
-#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */
-#define rCCK0_TxFilter1 0xa20
-#define rCCK0_TxFilter2 0xa24
-#define rCCK0_DebugPort 0xa28 /* Debug port and TX filter 3 */
-#define rCCK0_FalseAlarmReport 0xa2c
-#define rCCK0_TRSSIReport 0xa50
-#define rCCK0_RxReport 0xa54
-#define rCCK0_FACounterLower 0xa5c
-#define rCCK0_FACounterUpper 0xa58
-
-#define rOFDM0_LSTF 0xc00
-#define rOFDM0_TRxPathEnable 0xc04
-#define rOFDM0_TRMuxPar 0xc08
-#define rOFDM0_TRSWIsolation 0xc0c
-#define rOFDM0_RxDetector1 0xc30 /* PD, BW & SBD */
-#define rOFDM0_RxDetector2 0xc34 /* SBD */
-#define rOFDM0_RxDetector3 0xc38 /* Frame Sync */
-/* PD, SBD, Frame Sync & Short-GI */
-#define rOFDM0_RxDetector4 0xc3c
-#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */
-#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */
-#define rOFDM0_CCADropThreshold 0xc48
-#define rOFDM0_ECCAThreshold 0xc4c /* Energy CCA */
-#define rOFDM0_XAAGCCore1 0xc50
-#define rOFDM0_XBAGCCore1 0xc58
-#define rOFDM0_XCAGCCore1 0xc60
-#define rOFDM0_XDAGCCore1 0xc68
-#define rOFDM0_AGCParameter1 0xc70
-#define rOFDM0_AGCParameter2 0xc74
-#define rOFDM0_AGCRSSITable 0xc78
-#define rOFDM0_HTSTFAGC 0xc7c
-#define rOFDM0_XATxIQImbalance 0xc80
-#define rOFDM0_XATxAFE 0xc84
-#define rOFDM0_XCTxIQImbalance 0xc90
-#define rOFDM0_RxHPParameter 0xce0
-#define rOFDM0_TxPseudoNoiseWgt 0xce4
-#define rOFDM0_FrameSync 0xcf0
-#define rOFDM0_DFSReport 0xcf4
-#define rOFDM0_TxCoeff1 0xca4
-#define rOFDM0_TxCoeff2 0xca8
-#define rOFDM0_TxCoeff3 0xcac
-#define rOFDM0_TxCoeff4 0xcb0
-#define rOFDM0_TxCoeff5 0xcb4
-#define rOFDM0_TxCoeff6 0xcb8
-
-#define rOFDM1_LSTF 0xd00
-#define rOFDM1_TRxPathEnable 0xd04
-#define rOFDM1_CFO 0xd08
-#define rOFDM1_CSI1 0xd10
-#define rOFDM1_SBD 0xd14
-#define rOFDM1_CSI2 0xd18
-#define rOFDM1_CFOTracking 0xd2c
-#define rOFDM1_TRxMesaure1 0xd34
-#define rOFDM1_IntfDet 0xd3c
-#define rOFDM1_PseudoNoiseStateAB 0xd50
-#define rOFDM1_PseudoNoiseStateCD 0xd54
-#define rOFDM1_RxPseudoNoiseWgt 0xd58
-#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */
-#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */
-#define rOFDM_PHYCounter3 0xda8 /* MCS not supported */
-#define rOFDM_ShortCFOAB 0xdac
-#define rOFDM_ShortCFOCD 0xdb0
-#define rOFDM_LongCFOAB 0xdb4
-#define rOFDM_LongCFOCD 0xdb8
-#define rOFDM_TailCFOAB 0xdbc
-#define rOFDM_TailCFOCD 0xdc0
-#define rOFDM_PWMeasure1 0xdc4
-#define rOFDM_PWMeasure2 0xdc8
-#define rOFDM_BWReport 0xdcc
-#define rOFDM_AGCReport 0xdd0
-#define rOFDM_RxSNR 0xdd4
-#define rOFDM_RxEVMCSI 0xdd8
-#define rOFDM_SIGReport 0xddc
-
-#define rTxAGC_Rate18_06 0xe00
-#define rTxAGC_Rate54_24 0xe04
-#define rTxAGC_CCK_Mcs32 0xe08
-#define rTxAGC_Mcs03_Mcs00 0xe10
-#define rTxAGC_Mcs07_Mcs04 0xe14
-#define rTxAGC_Mcs11_Mcs08 0xe18
-#define rTxAGC_Mcs15_Mcs12 0xe1c
-
-#define rZebra1_HSSIEnable 0x0
-#define rZebra1_TRxEnable1 0x1
-#define rZebra1_TRxEnable2 0x2
-#define rZebra1_AGC 0x4
-#define rZebra1_ChargePump 0x5
-#define rZebra1_Channel 0x7
-#define rZebra1_TxGain 0x8
-#define rZebra1_TxLPF 0x9
-#define rZebra1_RxLPF 0xb
-#define rZebra1_RxHPFCorner 0xc
-
-/* Zebra 4 */
-#define rGlobalCtrl 0
-#define rRTL8256_TxLPF 19
-#define rRTL8256_RxLPF 11
-
-/* RTL8258 */
-#define rRTL8258_TxLPF 0x11
-#define rRTL8258_RxLPF 0x13
-#define rRTL8258_RSSILPF 0xa
-
-/* Bit Mask - Page 1*/
-#define bBBResetB 0x100
-#define bGlobalResetB 0x200
-#define bOFDMTxStart 0x4
-#define bCCKTxStart 0x8
-#define bCRC32Debug 0x100
-#define bPMACLoopback 0x10
-#define bTxLSIG 0xffffff
-#define bOFDMTxRate 0xf
-#define bOFDMTxReserved 0x10
-#define bOFDMTxLength 0x1ffe0
-#define bOFDMTxParity 0x20000
-#define bTxHTSIG1 0xffffff
-#define bTxHTMCSRate 0x7f
-#define bTxHTBW 0x80
-#define bTxHTLength 0xffff00
-#define bTxHTSIG2 0xffffff
-#define bTxHTSmoothing 0x1
-#define bTxHTSounding 0x2
-#define bTxHTReserved 0x4
-#define bTxHTAggreation 0x8
-#define bTxHTSTBC 0x30
-#define bTxHTAdvanceCoding 0x40
-#define bTxHTShortGI 0x80
-#define bTxHTNumberHT_LTF 0x300
-#define bTxHTCRC8 0x3fc00
-#define bCounterReset 0x10000
-#define bNumOfOFDMTx 0xffff
-#define bNumOfCCKTx 0xffff0000
-#define bTxIdleInterval 0xffff
-#define bOFDMService 0xffff0000
-#define bTxMACHeader 0xffffffff
-#define bTxDataInit 0xff
-#define bTxHTMode 0x100
-#define bTxDataType 0x30000
-#define bTxRandomSeed 0xffffffff
-#define bCCKTxPreamble 0x1
-#define bCCKTxSFD 0xffff0000
-#define bCCKTxSIG 0xff
-#define bCCKTxService 0xff00
-#define bCCKLengthExt 0x8000
-#define bCCKTxLength 0xffff0000
-#define bCCKTxCRC16 0xffff
-#define bCCKTxStatus 0x1
-#define bOFDMTxStatus 0x2
-/* Bit Mask - Page 8 */
-#define bRFMOD 0x1
-#define bJapanMode 0x2
-#define bCCKTxSC 0x30
-#define bCCKEn 0x1000000
-#define bOFDMEn 0x2000000
-#define bOFDMRxADCPhase 0x10000
-#define bOFDMTxDACPhase 0x40000
-#define bXATxAGC 0x3f
-#define bXBTxAGC 0xf00
-#define bXCTxAGC 0xf000
-#define bXDTxAGC 0xf0000
-#define bPAStart 0xf0000000
-#define bTRStart 0x00f00000
-#define bRFStart 0x0000f000
-#define bBBStart 0x000000f0
-#define bBBCCKStart 0x0000000f
-/* Bit Mask - rFPGA0_RFTiming2 */
-#define bPAEnd 0xf
-#define bTREnd 0x0f000000
-#define bRFEnd 0x000f0000
-/* Channel gain at continue TX. */
-#define b3WireDataLength 0x800
-#define b3WireAddressLength 0x400
-/* 3-wire total control */
-#define bRFSI_RFENV 0x10
-#define bLSSIReadAddress 0x3f000000 /* LSSI "read" address */
-#define bLSSIReadEdge 0x80000000 /* LSSI "read" edge signal */
-#define bLSSIReadBackData 0xfff
-
-#define bDA6Swing 0x380000
-#define bADClkPhase 0x4000000
-#define b80MClkDelay 0x18000000
-#define bAFEWatchDogEnable 0x20000000
-#define bXtalCap 0x0f000000
-#define bXtalCap01 0xc0000000
-#define bXtalCap23 0x3
-#define bXtalCap92x 0x0f000000
-#define bIntDifClkEnable 0x400
-#define bExtSigClkEnable 0x800
-#define bBandgapMbiasPowerUp 0x10000
-#define bAD11SHGain 0xc0000
-#define bAD11InputRange 0x700000
-#define bAD11OPCurrent 0x3800000
-#define bIPathLoopback 0x4000000
-#define bQPathLoopback 0x8000000
-#define bAFELoopback 0x10000000
-#define bDA10Swing 0x7e0
-#define bDA10Reverse 0x800
-#define bDAClkSource 0x1000
-#define bAD7InputRange 0x6000
-#define bAD7Gain 0x38000
-#define bAD7OutputCMMode 0x40000
-#define bAD7InputCMMode 0x380000
-#define bAD7Current 0xc00000
-#define bRegulatorAdjust 0x7000000
-#define bAD11PowerUpAtTx 0x1
-#define bDA10PSAtTx 0x10
-#define bAD11PowerUpAtRx 0x100
-#define bDA10PSAtRx 0x1000
-
-#define bCCKRxAGCFormat 0x200
-
-#define bPSDFFTSamplepPoint 0xc000
-#define bPSDAverageNum 0x3000
-#define bIQPathControl 0xc00
-#define bPSDFreq 0x3ff
-#define bPSDAntennaPath 0x30
-#define bPSDIQSwitch 0x40
-#define bPSDRxTrigger 0x400000
-#define bPSDTxTrigger 0x80000000
-#define bPSDSineToneScale 0x7f000000
-#define bPSDReport 0xffff
-
-/* Page 8 */
-#define bOFDMTxSC 0x30000000
-#define bCCKTxOn 0x1
-#define bOFDMTxOn 0x2
-/* Reset debug page and also HWord, LWord */
-#define bDebugPage 0xfff
-/* Reset debug page and LWord */
-#define bDebugItem 0xff
-#define bAntL 0x10
-#define bAntNonHT 0x100
-#define bAntHT1 0x1000
-#define bAntHT2 0x10000
-#define bAntHT1S1 0x100000
-#define bAntNonHTS1 0x1000000
-
-/* Page a */
-#define bCCKBBMode 0x3
-#define bCCKTxPowerSaving 0x80
-#define bCCKRxPowerSaving 0x40
-#define bCCKSideBand 0x10
-#define bCCKScramble 0x8
-#define bCCKAntDiversity 0x8000
-#define bCCKCarrierRecovery 0x4000
-#define bCCKTxRate 0x3000
-#define bCCKDCCancel 0x0800
-#define bCCKISICancel 0x0400
-#define bCCKMatchFilter 0x0200
-#define bCCKEqualizer 0x0100
-#define bCCKPreambleDetect 0x800000
-#define bCCKFastFalseCCA 0x400000
-#define bCCKChEstStart 0x300000
-#define bCCKCCACount 0x080000
-#define bCCKcs_lim 0x070000
-#define bCCKBistMode 0x80000000
-#define bCCKCCAMask 0x40000000
-#define bCCKTxDACPhase 0x4
-#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */
-#define bCCKr_cp_mode0 0x0100
-#define bCCKTxDCOffset 0xf0
-#define bCCKRxDCOffset 0xf
-#define bCCKCCAMode 0xc000
-#define bCCKFalseCS_lim 0x3f00
-#define bCCKCS_ratio 0xc00000
-#define bCCKCorgBit_sel 0x300000
-#define bCCKPD_lim 0x0f0000
-#define bCCKNewCCA 0x80000000
-#define bCCKRxHPofIG 0x8000
-#define bCCKRxIG 0x7f00
-#define bCCKLNAPolarity 0x800000
-#define bCCKRx1stGain 0x7f0000
-/* CCK Rx Initial gain polarity */
-#define bCCKRFExtend 0x20000000
-#define bCCKRxAGCSatLevel 0x1f000000
-#define bCCKRxAGCSatCount 0xe0
-/* AGCSAmp_dly */
-#define bCCKRxRFSettle 0x1f
-#define bCCKFixedRxAGC 0x8000
-/*#define bCCKRxAGCFormat 0x4000 remove to HSSI register 0x824 */
-#define bCCKAntennaPolarity 0x2000
-#define bCCKTxFilterType 0x0c00
-#define bCCKRxAGCReportType 0x0300
-#define bCCKRxDAGCEn 0x80000000
-#define bCCKRxDAGCPeriod 0x20000000
-#define bCCKRxDAGCSatLevel 0x1f000000
-#define bCCKTimingRecovery 0x800000
-#define bCCKTxC0 0x3f0000
-#define bCCKTxC1 0x3f000000
-#define bCCKTxC2 0x3f
-#define bCCKTxC3 0x3f00
-#define bCCKTxC4 0x3f0000
-#define bCCKTxC5 0x3f000000
-#define bCCKTxC6 0x3f
-#define bCCKTxC7 0x3f00
-#define bCCKDebugPort 0xff0000
-#define bCCKDACDebug 0x0f000000
-#define bCCKFalseAlarmEnable 0x8000
-#define bCCKFalseAlarmRead 0x4000
-#define bCCKTRSSI 0x7f
-#define bCCKRxAGCReport 0xfe
-#define bCCKRxReport_AntSel 0x80000000
-#define bCCKRxReport_MFOff 0x40000000
-#define bCCKRxRxReport_SQLoss 0x20000000
-#define bCCKRxReport_Pktloss 0x10000000
-#define bCCKRxReport_Lockedbit 0x08000000
-#define bCCKRxReport_RateError 0x04000000
-#define bCCKRxReport_RxRate 0x03000000
-#define bCCKRxFACounterLower 0xff
-#define bCCKRxFACounterUpper 0xff000000
-#define bCCKRxHPAGCStart 0xe000
-#define bCCKRxHPAGCFinal 0x1c00
-
-#define bCCKRxFalseAlarmEnable 0x8000
-#define bCCKFACounterFreeze 0x4000
-
-#define bCCKTxPathSel 0x10000000
-#define bCCKDefaultRxPath 0xc000000
-#define bCCKOptionRxPath 0x3000000
-
-/* Page c */
-#define bNumOfSTF 0x3
-#define bShift_L 0xc0
-#define bGI_TH 0xc
-#define bRxPathA 0x1
-#define bRxPathB 0x2
-#define bRxPathC 0x4
-#define bRxPathD 0x8
-#define bTxPathA 0x1
-#define bTxPathB 0x2
-#define bTxPathC 0x4
-#define bTxPathD 0x8
-#define bTRSSIFreq 0x200
-#define bADCBackoff 0x3000
-#define bDFIRBackoff 0xc000
-#define bTRSSILatchPhase 0x10000
-#define bRxIDCOffset 0xff
-#define bRxQDCOffset 0xff00
-#define bRxDFIRMode 0x1800000
-#define bRxDCNFType 0xe000000
-#define bRXIQImb_A 0x3ff
-#define bRXIQImb_B 0xfc00
-#define bRXIQImb_C 0x3f0000
-#define bRXIQImb_D 0xffc00000
-#define bDC_dc_Notch 0x60000
-#define bRxNBINotch 0x1f000000
-#define bPD_TH 0xf
-#define bPD_TH_Opt2 0xc000
-#define bPWED_TH 0x700
-#define bIfMF_Win_L 0x800
-#define bPD_Option 0x1000
-#define bMF_Win_L 0xe000
-#define bBW_Search_L 0x30000
-#define bwin_enh_L 0xc0000
-#define bBW_TH 0x700000
-#define bED_TH2 0x3800000
-#define bBW_option 0x4000000
-#define bRatio_TH 0x18000000
-#define bWindow_L 0xe0000000
-#define bSBD_Option 0x1
-#define bFrame_TH 0x1c
-#define bFS_Option 0x60
-#define bDC_Slope_check 0x80
-#define bFGuard_Counter_DC_L 0xe00
-#define bFrame_Weight_Short 0x7000
-#define bSub_Tune 0xe00000
-#define bFrame_DC_Length 0xe000000
-#define bSBD_start_offset 0x30000000
-#define bFrame_TH_2 0x7
-#define bFrame_GI2_TH 0x38
-#define bGI2_Sync_en 0x40
-#define bSarch_Short_Early 0x300
-#define bSarch_Short_Late 0xc00
-#define bSarch_GI2_Late 0x70000
-#define bCFOAntSum 0x1
-#define bCFOAcc 0x2
-#define bCFOStartOffset 0xc
-#define bCFOLookBack 0x70
-#define bCFOSumWeight 0x80
-#define bDAGCEnable 0x10000
-#define bTXIQImb_A 0x3ff
-#define bTXIQImb_B 0xfc00
-#define bTXIQImb_C 0x3f0000
-#define bTXIQImb_D 0xffc00000
-#define bTxIDCOffset 0xff
-#define bTxQDCOffset 0xff00
-#define bTxDFIRMode 0x10000
-#define bTxPesudoNoiseOn 0x4000000
-#define bTxPesudoNoise_A 0xff
-#define bTxPesudoNoise_B 0xff00
-#define bTxPesudoNoise_C 0xff0000
-#define bTxPesudoNoise_D 0xff000000
-#define bCCADropOption 0x20000
-#define bCCADropThres 0xfff00000
-#define bEDCCA_H 0xf
-#define bEDCCA_L 0xf0
-#define bLambda_ED 0x300
-#define bRxInitialGain 0x7f
-#define bRxAntDivEn 0x80
-#define bRxAGCAddressForLNA 0x7f00
-#define bRxHighPowerFlow 0x8000
-#define bRxAGCFreezeThres 0xc0000
-#define bRxFreezeStep_AGC1 0x300000
-#define bRxFreezeStep_AGC2 0xc00000
-#define bRxFreezeStep_AGC3 0x3000000
-#define bRxFreezeStep_AGC0 0xc000000
-#define bRxRssi_Cmp_En 0x10000000
-#define bRxQuickAGCEn 0x20000000
-#define bRxAGCFreezeThresMode 0x40000000
-#define bRxOverFlowCheckType 0x80000000
-#define bRxAGCShift 0x7f
-#define bTRSW_Tri_Only 0x80
-#define bPowerThres 0x300
-#define bRxAGCEn 0x1
-#define bRxAGCTogetherEn 0x2
-#define bRxAGCMin 0x4
-#define bRxHP_Ini 0x7
-#define bRxHP_TRLNA 0x70
-#define bRxHP_RSSI 0x700
-#define bRxHP_BBP1 0x7000
-#define bRxHP_BBP2 0x70000
-#define bRxHP_BBP3 0x700000
-/* The threshold for high power */
-#define bRSSI_H 0x7f0000
-/* The threshold for ant diversity */
-#define bRSSI_Gen 0x7f000000
-#define bRxSettle_TRSW 0x7
-#define bRxSettle_LNA 0x38
-#define bRxSettle_RSSI 0x1c0
-#define bRxSettle_BBP 0xe00
-#define bRxSettle_RxHP 0x7000
-#define bRxSettle_AntSW_RSSI 0x38000
-#define bRxSettle_AntSW 0xc0000
-#define bRxProcessTime_DAGC 0x300000
-#define bRxSettle_HSSI 0x400000
-#define bRxProcessTime_BBPPW 0x800000
-#define bRxAntennaPowerShift 0x3000000
-#define bRSSITableSelect 0xc000000
-#define bRxHP_Final 0x7000000
-#define bRxHTSettle_BBP 0x7
-#define bRxHTSettle_HSSI 0x8
-#define bRxHTSettle_RxHP 0x70
-#define bRxHTSettle_BBPPW 0x80
-#define bRxHTSettle_Idle 0x300
-#define bRxHTSettle_Reserved 0x1c00
-#define bRxHTRxHPEn 0x8000
-#define bRxHTAGCFreezeThres 0x30000
-#define bRxHTAGCTogetherEn 0x40000
-#define bRxHTAGCMin 0x80000
-#define bRxHTAGCEn 0x100000
-#define bRxHTDAGCEn 0x200000
-#define bRxHTRxHP_BBP 0x1c00000
-#define bRxHTRxHP_Final 0xe0000000
-#define bRxPWRatioTH 0x3
-#define bRxPWRatioEn 0x4
-#define bRxMFHold 0x3800
-#define bRxPD_Delay_TH1 0x38
-#define bRxPD_Delay_TH2 0x1c0
-#define bRxPD_DC_COUNT_MAX 0x600
-/*#define bRxMF_Hold 0x3800*/
-#define bRxPD_Delay_TH 0x8000
-#define bRxProcess_Delay 0xf0000
-#define bRxSearchrange_GI2_Early 0x700000
-#define bRxFrame_Guard_Counter_L 0x3800000
-#define bRxSGI_Guard_L 0xc000000
-#define bRxSGI_Search_L 0x30000000
-#define bRxSGI_TH 0xc0000000
-#define bDFSCnt0 0xff
-#define bDFSCnt1 0xff00
-#define bDFSFlag 0xf0000
-
-#define bMFWeightSum 0x300000
-#define bMinIdxTH 0x7f000000
-
-#define bDAFormat 0x40000
-
-#define bTxChEmuEnable 0x01000000
-
-#define bTRSWIsolation_A 0x7f
-#define bTRSWIsolation_B 0x7f00
-#define bTRSWIsolation_C 0x7f0000
-#define bTRSWIsolation_D 0x7f000000
-
-#define bExtLNAGain 0x7c00
-
-/* Page d */
-#define bSTBCEn 0x4
-#define bAntennaMapping 0x10
-#define bNss 0x20
-#define bCFOAntSumD 0x200
-#define bPHYCounterReset 0x8000000
-#define bCFOReportGet 0x4000000
-#define bOFDMContinueTx 0x10000000
-#define bOFDMSingleCarrier 0x20000000
-#define bOFDMSingleTone 0x40000000
-/* #define bRxPath1 0x01
- * #define bRxPath2 0x02
- * #define bRxPath3 0x04
- * #define bRxPath4 0x08
- * #define bTxPath1 0x10
- * #define bTxPath2 0x20
- */
-#define bHTDetect 0x100
-#define bCFOEn 0x10000
-#define bCFOValue 0xfff00000
-#define bSigTone_Re 0x3f
-#define bSigTone_Im 0x7f00
-#define bCounter_CCA 0xffff
-#define bCounter_ParityFail 0xffff0000
-#define bCounter_RateIllegal 0xffff
-#define bCounter_CRC8Fail 0xffff0000
-#define bCounter_MCSNoSupport 0xffff
-#define bCounter_FastSync 0xffff
-#define bShortCFO 0xfff
-#define bShortCFOTLength 12 /* total */
-#define bShortCFOFLength 11 /* fraction */
-#define bLongCFO 0x7ff
-#define bLongCFOTLength 11
-#define bLongCFOFLength 11
-#define bTailCFO 0x1fff
-#define bTailCFOTLength 13
-#define bTailCFOFLength 12
-
-#define bmax_en_pwdB 0xffff
-#define bCC_power_dB 0xffff0000
-#define bnoise_pwdB 0xffff
-#define bPowerMeasTLength 10
-#define bPowerMeasFLength 3
-#define bRx_HT_BW 0x1
-#define bRxSC 0x6
-#define bRx_HT 0x8
-
-#define bNB_intf_det_on 0x1
-#define bIntf_win_len_cfg 0x30
-#define bNB_Intf_TH_cfg 0x1c0
-
-#define bRFGain 0x3f
-#define bTableSel 0x40
-#define bTRSW 0x80
-
-#define bRxSNR_A 0xff
-#define bRxSNR_B 0xff00
-#define bRxSNR_C 0xff0000
-#define bRxSNR_D 0xff000000
-#define bSNREVMTLength 8
-#define bSNREVMFLength 1
-
-#define bCSI1st 0xff
-#define bCSI2nd 0xff00
-#define bRxEVM1st 0xff0000
-#define bRxEVM2nd 0xff000000
-
-#define bSIGEVM 0xff
-#define bPWDB 0xff00
-#define bSGIEN 0x10000
-
-#define bSFactorQAM1 0xf
-#define bSFactorQAM2 0xf0
-#define bSFactorQAM3 0xf00
-#define bSFactorQAM4 0xf000
-#define bSFactorQAM5 0xf0000
-#define bSFactorQAM6 0xf0000
-#define bSFactorQAM7 0xf00000
-#define bSFactorQAM8 0xf000000
-#define bSFactorQAM9 0xf0000000
-#define bCSIScheme 0x100000
-
-#define bNoiseLvlTopSet 0x3
-#define bChSmooth 0x4
-#define bChSmoothCfg1 0x38
-#define bChSmoothCfg2 0x1c0
-#define bChSmoothCfg3 0xe00
-#define bChSmoothCfg4 0x7000
-#define bMRCMode 0x800000
-#define bTHEVMCfg 0x7000000
-
-#define bLoopFitType 0x1
-#define bUpdCFO 0x40
-#define bUpdCFOOffData 0x80
-#define bAdvUpdCFO 0x100
-#define bAdvTimeCtrl 0x800
-#define bUpdClko 0x1000
-#define bFC 0x6000
-#define bTrackingMode 0x8000
-#define bPhCmpEnable 0x10000
-#define bUpdClkoLTF 0x20000
-#define bComChCFO 0x40000
-#define bCSIEstiMode 0x80000
-#define bAdvUpdEqz 0x100000
-#define bUChCfg 0x7000000
-#define bUpdEqz 0x8000000
-
-/* Page e */
-#define bTxAGCRate18_06 0x7f7f7f7f
-#define bTxAGCRate54_24 0x7f7f7f7f
-#define bTxAGCRateMCS32 0x7f
-#define bTxAGCRateCCK 0x7f00
-#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f
-#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f
-#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f
-#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f
-
-#define bRxPesudoNoiseOn 0x20000000 /* Rx Pseduo noise */
-#define bRxPesudoNoise_A 0xff
-#define bRxPesudoNoise_B 0xff00
-#define bRxPesudoNoise_C 0xff0000
-#define bRxPesudoNoise_D 0xff000000
-#define bPesudoNoiseState_A 0xffff
-#define bPesudoNoiseState_B 0xffff0000
-#define bPesudoNoiseState_C 0xffff
-#define bPesudoNoiseState_D 0xffff0000
-
-/* RF Zebra 1 */
-#define bZebra1_HSSIEnable 0x8
-#define bZebra1_TRxControl 0xc00
-#define bZebra1_TRxGainSetting 0x07f
-#define bZebra1_RxCorner 0xc00
-#define bZebra1_TxChargePump 0x38
-#define bZebra1_RxChargePump 0x7
-#define bZebra1_ChannelNum 0xf80
-#define bZebra1_TxLPFBW 0x400
-#define bZebra1_RxLPFBW 0x600
-
-/* Zebra4 */
-#define bRTL8256RegModeCtrl1 0x100
-#define bRTL8256RegModeCtrl0 0x40
-#define bRTL8256_TxLPFBW 0x18
-#define bRTL8256_RxLPFBW 0x600
-
-/* RTL8258 */
-#define bRTL8258_TxLPFBW 0xc
-#define bRTL8258_RxLPFBW 0xc00
-#define bRTL8258_RSSILPFBW 0xc0
-
-/* byte enable for sb_write */
-#define bByte0 0x1
-#define bByte1 0x2
-#define bByte2 0x4
-#define bByte3 0x8
-#define bWord0 0x3
-#define bWord1 0xc
-#define bDWord 0xf
-
-/* for PutRegsetting & GetRegSetting BitMask */
-#define bMaskByte0 0xff
-#define bMaskByte1 0xff00
-#define bMaskByte2 0xff0000
-#define bMaskByte3 0xff000000
-#define bMaskHWord 0xffff0000
-#define bMaskLWord 0x0000ffff
-#define bMaskDWord 0xffffffff
-
-/* for PutRFRegsetting & GetRFRegSetting BitMask */
-#define bMask12Bits 0xfff
-
-#define bEnable 0x1
-#define bDisable 0x0
-
-#define LeftAntenna 0x0
-#define RightAntenna 0x1
-
-#define tCheckTxStatus 500 /* 500 ms */
-#define tUpdateRxCounter 100 /* 100 ms */
-
-#define rateCCK 0
-#define rateOFDM 1
-#define rateHT 2
-
-#define bPMAC_End 0x1ff /* define Register-End */
-#define bFPGAPHY0_End 0x8ff
-#define bFPGAPHY1_End 0x9ff
-#define bCCKPHY0_End 0xaff
-#define bOFDMPHY0_End 0xcff
-#define bOFDMPHY1_End 0xdff
-
-#define bPMACControl 0x0
-#define bWMACControl 0x1
-#define bWNICControl 0x2
-
-#define PathA 0x0
-#define PathB 0x1
-#define PathC 0x2
-#define PathD 0x3
-
-#define rRTL8256RxMixerPole 0xb
-#define bZebraRxMixerPole 0x6
-#define rRTL8256TxBBOPBias 0x9
-#define bRTL8256TxBBOPBias 0x400
-#define rRTL8256TxBBBW 19
-#define bRTL8256TxBBBW 0x18
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
deleted file mode 100644
index 69298c7c129a..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
+++ /dev/null
@@ -1,123 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtl_core.h"
-#include "r8192E_phy.h"
-#include "r8192E_phyreg.h"
-#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
-#include "r8192E_cmdpkt.h"
-
-void rtl92e_cam_reset(struct net_device *dev)
-{
- u32 ulcommand = 0;
-
- ulcommand |= BIT(31) | BIT(30);
- rtl92e_writel(dev, RWCAM, ulcommand);
-}
-
-void rtl92e_enable_hw_security_config(struct net_device *dev)
-{
- u8 SECR_value = 0x0;
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
-
- SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
- if (((ieee->pairwise_key_type == KEY_TYPE_WEP40) ||
- (ieee->pairwise_key_type == KEY_TYPE_WEP104)) &&
- (priv->rtllib->auth_mode != 2)) {
- SECR_value |= SCR_RxUseDK;
- SECR_value |= SCR_TxUseDK;
- }
-
- ieee->hwsec_active = 1;
- if ((ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE) || !hwwep) {
- ieee->hwsec_active = 0;
- SECR_value &= ~SCR_RxDecEnable;
- }
- rtl92e_writeb(dev, SECR, SECR_value);
-}
-
-void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
- u16 KeyType, const u8 *MacAddr, u32 *KeyContent)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
-
- if (EntryNo >= TOTAL_CAM_ENTRY)
- return;
-
- ieee->swcamtable[EntryNo].bused = true;
- ieee->swcamtable[EntryNo].key_index = KeyIndex;
- ieee->swcamtable[EntryNo].key_type = KeyType;
- memcpy(ieee->swcamtable[EntryNo].macaddr, MacAddr, 6);
- ieee->swcamtable[EntryNo].useDK = 0;
- memcpy(ieee->swcamtable[EntryNo].key_buf, (u8 *)KeyContent, 16);
-}
-
-void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
- u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
- u32 *KeyContent)
-{
- u32 TargetCommand = 0;
- u32 TargetContent = 0;
- u16 usConfig = 0;
- u8 i;
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
- enum rt_rf_power_state rt_state;
-
- rt_state = priv->rtllib->rf_power_state;
- if (rt_state == rf_off) {
- if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) {
- netdev_warn(dev, "%s(): RF is OFF.\n",
- __func__);
- return;
- }
- mutex_lock(&priv->rtllib->ips_mutex);
- rtl92e_ips_leave(dev);
- mutex_unlock(&priv->rtllib->ips_mutex);
- }
- priv->rtllib->is_set_key = true;
- if (EntryNo >= TOTAL_CAM_ENTRY) {
- netdev_info(dev, "%s(): Invalid CAM entry\n", __func__);
- return;
- }
-
- if (DefaultKey)
- usConfig |= BIT(15) | (KeyType << 2);
- else
- usConfig |= BIT(15) | (KeyType << 2) | KeyIndex;
-
- for (i = 0; i < CAM_CONTENT_COUNT; i++) {
- TargetCommand = i + CAM_CONTENT_COUNT * EntryNo;
- TargetCommand |= BIT(31) | BIT(16);
-
- if (i == 0) {
- TargetContent = (u32)(*(MacAddr + 0)) << 16 |
- (u32)(*(MacAddr + 1)) << 24 |
- (u32)usConfig;
-
- rtl92e_writel(dev, WCAMI, TargetContent);
- rtl92e_writel(dev, RWCAM, TargetCommand);
- } else if (i == 1) {
- TargetContent = (u32)(*(MacAddr + 2)) |
- (u32)(*(MacAddr + 3)) << 8 |
- (u32)(*(MacAddr + 4)) << 16 |
- (u32)(*(MacAddr + 5)) << 24;
- rtl92e_writel(dev, WCAMI, TargetContent);
- rtl92e_writel(dev, RWCAM, TargetCommand);
- } else {
- if (KeyContent) {
- rtl92e_writel(dev, WCAMI,
- (u32)(*(KeyContent + i - 2)));
- rtl92e_writel(dev, RWCAM, TargetCommand);
- udelay(100);
- }
- }
- }
-}
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h
deleted file mode 100644
index 9deffdf96072..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef _RTL_CAM_H
-#define _RTL_CAM_H
-
-#include <linux/types.h>
-
-struct net_device;
-
-void rtl92e_cam_reset(struct net_device *dev);
-void rtl92e_enable_hw_security_config(struct net_device *dev);
-void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
- u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
- u32 *KeyContent);
-void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
- u16 KeyType, const u8 *MacAddr, u32 *KeyContent);
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
deleted file mode 100644
index dc1301f1a0c1..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
+++ /dev/null
@@ -1,2016 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include <linux/uaccess.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/ieee80211.h>
-#include "rtl_core.h"
-#include "r8192E_phy.h"
-#include "r8192E_phyreg.h"
-#include "r8190P_rtl8256.h"
-#include "r8192E_cmdpkt.h"
-
-#include "rtl_wx.h"
-#include "rtl_dm.h"
-
-#include "rtl_pm.h"
-
-int hwwep = 1;
-static char *ifname = "wlan%d";
-
-static const struct pci_device_id rtl8192_pci_id_tbl[] = {
- {PCI_DEVICE(0x10ec, 0x8192)},
- {PCI_DEVICE(0x07aa, 0x0044)},
- {PCI_DEVICE(0x07aa, 0x0047)},
- {}
-};
-
-MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
-
-static int _rtl92e_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id);
-static void _rtl92e_pci_disconnect(struct pci_dev *pdev);
-static irqreturn_t _rtl92e_irq(int irq, void *netdev);
-
-static SIMPLE_DEV_PM_OPS(rtl92e_pm_ops, rtl92e_suspend, rtl92e_resume);
-
-static struct pci_driver rtl8192_pci_driver = {
- .name = DRV_NAME, /* Driver name */
- .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */
- .probe = _rtl92e_pci_probe, /* probe fn */
- .remove = _rtl92e_pci_disconnect, /* remove fn */
- .driver.pm = &rtl92e_pm_ops,
-};
-
-static short _rtl92e_is_tx_queue_empty(struct net_device *dev);
-static void _rtl92e_watchdog_wq_cb(void *data);
-static void _rtl92e_watchdog_timer_cb(struct timer_list *t);
-static void _rtl92e_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
- int rate);
-static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static void _rtl92e_tx_cmd(struct net_device *dev, struct sk_buff *skb);
-static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb);
-static short _rtl92e_pci_initdescring(struct net_device *dev);
-static void _rtl92e_irq_tx_tasklet(struct tasklet_struct *t);
-static void _rtl92e_irq_rx_tasklet(struct tasklet_struct *t);
-static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv);
-static int _rtl92e_up(struct net_device *dev);
-static int _rtl92e_try_up(struct net_device *dev);
-static int _rtl92e_down(struct net_device *dev, bool shutdownrf);
-static void _rtl92e_restart(void *data);
-
-/****************************************************************************
- * -----------------------------IO STUFF-------------------------
- ****************************************************************************/
-
-u8 rtl92e_readb(struct net_device *dev, int x)
-{
- return 0xff & readb((u8 __iomem *)dev->mem_start + x);
-}
-
-u32 rtl92e_readl(struct net_device *dev, int x)
-{
- return readl((u8 __iomem *)dev->mem_start + x);
-}
-
-u16 rtl92e_readw(struct net_device *dev, int x)
-{
- return readw((u8 __iomem *)dev->mem_start + x);
-}
-
-void rtl92e_writeb(struct net_device *dev, int x, u8 y)
-{
- writeb(y, (u8 __iomem *)dev->mem_start + x);
-
- udelay(20);
-}
-
-void rtl92e_writel(struct net_device *dev, int x, u32 y)
-{
- writel(y, (u8 __iomem *)dev->mem_start + x);
-
- udelay(20);
-}
-
-void rtl92e_writew(struct net_device *dev, int x, u16 y)
-{
- writew(y, (u8 __iomem *)dev->mem_start + x);
-
- udelay(20);
-}
-
-/****************************************************************************
- * -----------------------------GENERAL FUNCTION-------------------------
- ****************************************************************************/
-bool rtl92e_set_rf_state(struct net_device *dev,
- enum rt_rf_power_state state_to_set,
- RT_RF_CHANGE_SOURCE change_source)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
- bool action_allowed = false;
- bool connect_by_ssid = false;
- enum rt_rf_power_state rt_state;
- u16 rf_wait_counter = 0;
- unsigned long flag;
-
- while (true) {
- spin_lock_irqsave(&priv->rf_ps_lock, flag);
- if (priv->rf_change_in_progress) {
- spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
-
- while (priv->rf_change_in_progress) {
- rf_wait_counter++;
- mdelay(1);
-
- if (rf_wait_counter > 100) {
- netdev_warn(dev,
- "%s(): Timeout waiting for RF change.\n",
- __func__);
- return false;
- }
- }
- } else {
- priv->rf_change_in_progress = true;
- spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
- break;
- }
- }
-
- rt_state = priv->rtllib->rf_power_state;
-
- switch (state_to_set) {
- case rf_on:
- priv->rtllib->rf_off_reason &= (~change_source);
-
- if ((change_source == RF_CHANGE_BY_HW) && priv->hw_radio_off)
- priv->hw_radio_off = false;
-
- if (!priv->rtllib->rf_off_reason) {
- priv->rtllib->rf_off_reason = 0;
- action_allowed = true;
-
- if (rt_state == rf_off &&
- change_source >= RF_CHANGE_BY_HW)
- connect_by_ssid = true;
- }
- break;
-
- case rf_off:
-
- if (priv->rtllib->iw_mode == IW_MODE_INFRA) {
- if ((priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) ||
- (change_source > RF_CHANGE_BY_IPS)) {
- if (ieee->link_state == MAC80211_LINKED)
- priv->blinked_ingpio = true;
- else
- priv->blinked_ingpio = false;
- rtllib_mgnt_disconnect(priv->rtllib,
- WLAN_REASON_DISASSOC_STA_HAS_LEFT);
- }
- }
- if ((change_source == RF_CHANGE_BY_HW) && !priv->hw_radio_off)
- priv->hw_radio_off = true;
- priv->rtllib->rf_off_reason |= change_source;
- action_allowed = true;
- break;
-
- case rf_sleep:
- priv->rtllib->rf_off_reason |= change_source;
- action_allowed = true;
- break;
-
- default:
- break;
- }
-
- if (action_allowed) {
- rtl92e_set_rf_power_state(dev, state_to_set);
- if (state_to_set == rf_on) {
- if (connect_by_ssid && priv->blinked_ingpio) {
- schedule_delayed_work(
- &ieee->associate_procedure_wq, 0);
- priv->blinked_ingpio = false;
- }
- }
- }
-
- spin_lock_irqsave(&priv->rf_ps_lock, flag);
- priv->rf_change_in_progress = false;
- spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
- return action_allowed;
-}
-
-static short _rtl92e_check_nic_enough_desc(struct net_device *dev, int prio)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
-
- if (ring->entries - skb_queue_len(&ring->queue) >= 2)
- return 1;
- return 0;
-}
-
-static void _rtl92e_tx_timeout(struct net_device *dev, unsigned int txqueue)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- schedule_work(&priv->reset_wq);
- netdev_info(dev, "TXTIMEOUT");
-}
-
-static void _rtl92e_update_cap(struct net_device *dev, u16 cap)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_network *net = &priv->rtllib->current_network;
- bool ShortPreamble;
-
- if (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) {
- if (priv->dot11_current_preamble_mode != PREAMBLE_SHORT) {
- ShortPreamble = true;
- priv->dot11_current_preamble_mode = PREAMBLE_SHORT;
- priv->rtllib->set_hw_reg_handler(dev, HW_VAR_ACK_PREAMBLE,
- (unsigned char *)&ShortPreamble);
- }
- } else {
- if (priv->dot11_current_preamble_mode != PREAMBLE_LONG) {
- ShortPreamble = false;
- priv->dot11_current_preamble_mode = PREAMBLE_LONG;
- priv->rtllib->set_hw_reg_handler(dev, HW_VAR_ACK_PREAMBLE,
- (unsigned char *)&ShortPreamble);
- }
- }
-
- if (net->mode & (WIRELESS_MODE_G | WIRELESS_MODE_N_24G)) {
- u8 slot_time_val;
- u8 cur_slot_time = priv->slot_time;
-
- if ((cap & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
- (!priv->rtllib->ht_info->current_rt2rt_long_slot_time)) {
- if (cur_slot_time != SHORT_SLOT_TIME) {
- slot_time_val = SHORT_SLOT_TIME;
- priv->rtllib->set_hw_reg_handler(dev,
- HW_VAR_SLOT_TIME, &slot_time_val);
- }
- } else {
- if (cur_slot_time != NON_SHORT_SLOT_TIME) {
- slot_time_val = NON_SHORT_SLOT_TIME;
- priv->rtllib->set_hw_reg_handler(dev,
- HW_VAR_SLOT_TIME, &slot_time_val);
- }
- }
- }
-}
-
-static const struct rtllib_qos_parameters def_qos_parameters = {
- {cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3)},
- {cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7)},
- {2, 2, 2, 2},
- {0, 0, 0, 0},
- {0, 0, 0, 0}
-};
-
-static void _rtl92e_update_beacon(void *data)
-{
- struct r8192_priv *priv = container_of(data, struct r8192_priv, update_beacon_wq.work);
- struct net_device *dev = priv->rtllib->dev;
- struct rtllib_device *ieee = priv->rtllib;
- struct rtllib_network *net = &ieee->current_network;
-
- if (ieee->ht_info->current_ht_support)
- HT_update_self_and_peer_setting(ieee, net);
- ieee->ht_info->current_rt2rt_long_slot_time = net->bssht.bd_rt2rt_long_slot_time;
- _rtl92e_update_cap(dev, net->capability);
-}
-
-static void _rtl92e_qos_activate(void *data)
-{
- struct r8192_priv *priv = container_of(data, struct r8192_priv, qos_activate);
- struct net_device *dev = priv->rtllib->dev;
- int i;
-
- mutex_lock(&priv->mutex);
- if (priv->rtllib->link_state != MAC80211_LINKED)
- goto success;
-
- for (i = 0; i < QOS_QUEUE_NUM; i++)
- priv->rtllib->set_hw_reg_handler(dev, HW_VAR_AC_PARAM, (u8 *)(&i));
-
-success:
- mutex_unlock(&priv->mutex);
-}
-
-static int _rtl92e_qos_handle_probe_response(struct r8192_priv *priv,
- int active_network,
- struct rtllib_network *network)
-{
- int ret = 0;
- u32 size = sizeof(struct rtllib_qos_parameters);
-
- if (priv->rtllib->link_state != MAC80211_LINKED)
- return ret;
-
- if (priv->rtllib->iw_mode != IW_MODE_INFRA)
- return ret;
-
- if (network->flags & NETWORK_HAS_QOS_MASK) {
- if (active_network &&
- (network->flags & NETWORK_HAS_QOS_PARAMETERS))
- network->qos_data.active = network->qos_data.supported;
-
- if ((network->qos_data.active == 1) && (active_network == 1) &&
- (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
- (network->qos_data.old_param_count !=
- network->qos_data.param_count)) {
- network->qos_data.old_param_count =
- network->qos_data.param_count;
- priv->rtllib->wmm_acm = network->qos_data.wmm_acm;
- schedule_work(&priv->qos_activate);
- }
- } else {
- memcpy(&priv->rtllib->current_network.qos_data.parameters,
- &def_qos_parameters, size);
-
- if ((network->qos_data.active == 1) && (active_network == 1))
- schedule_work(&priv->qos_activate);
-
- network->qos_data.active = 0;
- network->qos_data.supported = 0;
- }
-
- return 0;
-}
-
-static int _rtl92e_handle_beacon(struct net_device *dev,
- struct rtllib_beacon *beacon,
- struct rtllib_network *network)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- _rtl92e_qos_handle_probe_response(priv, 1, network);
-
- schedule_delayed_work(&priv->update_beacon_wq, 0);
- return 0;
-}
-
-static int _rtl92e_qos_assoc_resp(struct r8192_priv *priv,
- struct rtllib_network *network)
-{
- unsigned long flags;
- u32 size = sizeof(struct rtllib_qos_parameters);
- int set_qos_param = 0;
-
- if (!priv || !network)
- return 0;
-
- if (priv->rtllib->link_state != MAC80211_LINKED)
- return 0;
-
- if (priv->rtllib->iw_mode != IW_MODE_INFRA)
- return 0;
-
- spin_lock_irqsave(&priv->rtllib->lock, flags);
- if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
- memcpy(&priv->rtllib->current_network.qos_data.parameters,
- &network->qos_data.parameters,
- sizeof(struct rtllib_qos_parameters));
- priv->rtllib->current_network.qos_data.active = 1;
- priv->rtllib->wmm_acm = network->qos_data.wmm_acm;
- set_qos_param = 1;
- priv->rtllib->current_network.qos_data.old_param_count =
- priv->rtllib->current_network.qos_data.param_count;
- priv->rtllib->current_network.qos_data.param_count =
- network->qos_data.param_count;
- } else {
- memcpy(&priv->rtllib->current_network.qos_data.parameters,
- &def_qos_parameters, size);
- priv->rtllib->current_network.qos_data.active = 0;
- priv->rtllib->current_network.qos_data.supported = 0;
- set_qos_param = 1;
- }
-
- spin_unlock_irqrestore(&priv->rtllib->lock, flags);
-
- if (set_qos_param == 1) {
- rtl92e_dm_init_edca_turbo(priv->rtllib->dev);
- schedule_work(&priv->qos_activate);
- }
- return 0;
-}
-
-static int _rtl92e_handle_assoc_response(struct net_device *dev,
- struct rtllib_assoc_response_frame *resp,
- struct rtllib_network *network)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- _rtl92e_qos_assoc_resp(priv, network);
- return 0;
-}
-
-void rtl92e_config_rate(struct net_device *dev, u16 *rate_config)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_network *net;
- u8 i = 0, basic_rate = 0;
-
- net = &priv->rtllib->current_network;
-
- for (i = 0; i < net->rates_len; i++) {
- basic_rate = net->rates[i] & 0x7f;
- switch (basic_rate) {
- case MGN_1M:
- *rate_config |= RRSR_1M;
- break;
- case MGN_2M:
- *rate_config |= RRSR_2M;
- break;
- case MGN_5_5M:
- *rate_config |= RRSR_5_5M;
- break;
- case MGN_11M:
- *rate_config |= RRSR_11M;
- break;
- case MGN_6M:
- *rate_config |= RRSR_6M;
- break;
- case MGN_9M:
- *rate_config |= RRSR_9M;
- break;
- case MGN_12M:
- *rate_config |= RRSR_12M;
- break;
- case MGN_18M:
- *rate_config |= RRSR_18M;
- break;
- case MGN_24M:
- *rate_config |= RRSR_24M;
- break;
- case MGN_36M:
- *rate_config |= RRSR_36M;
- break;
- case MGN_48M:
- *rate_config |= RRSR_48M;
- break;
- case MGN_54M:
- *rate_config |= RRSR_54M;
- break;
- }
- }
-
- for (i = 0; i < net->rates_ex_len; i++) {
- basic_rate = net->rates_ex[i] & 0x7f;
- switch (basic_rate) {
- case MGN_1M:
- *rate_config |= RRSR_1M;
- break;
- case MGN_2M:
- *rate_config |= RRSR_2M;
- break;
- case MGN_5_5M:
- *rate_config |= RRSR_5_5M;
- break;
- case MGN_11M:
- *rate_config |= RRSR_11M;
- break;
- case MGN_6M:
- *rate_config |= RRSR_6M;
- break;
- case MGN_9M:
- *rate_config |= RRSR_9M;
- break;
- case MGN_12M:
- *rate_config |= RRSR_12M;
- break;
- case MGN_18M:
- *rate_config |= RRSR_18M;
- break;
- case MGN_24M:
- *rate_config |= RRSR_24M;
- break;
- case MGN_36M:
- *rate_config |= RRSR_36M;
- break;
- case MGN_48M:
- *rate_config |= RRSR_48M;
- break;
- case MGN_54M:
- *rate_config |= RRSR_54M;
- break;
- }
- }
-}
-
-static void _rtl92e_refresh_support_rate(struct r8192_priv *priv)
-{
- struct rtllib_device *ieee = priv->rtllib;
-
- if (ieee->mode == WIRELESS_MODE_N_24G) {
- memcpy(ieee->reg_dot11ht_oper_rate_set,
- ieee->reg_ht_supp_rate_set, 16);
- memcpy(ieee->reg_dot11tx_ht_oper_rate_set,
- ieee->reg_ht_supp_rate_set, 16);
-
- } else {
- memset(ieee->reg_dot11ht_oper_rate_set, 0, 16);
- }
-}
-
-void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 support_mode = (WIRELESS_MODE_N_24G | WIRELESS_MODE_G | WIRELESS_MODE_B);
-
- if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode & support_mode) == 0))
- wireless_mode = WIRELESS_MODE_N_24G;
-
- if ((wireless_mode & (WIRELESS_MODE_B | WIRELESS_MODE_G)) ==
- (WIRELESS_MODE_G | WIRELESS_MODE_B))
- wireless_mode = WIRELESS_MODE_G;
-
- priv->rtllib->mode = wireless_mode;
-
- if (wireless_mode == WIRELESS_MODE_N_24G)
- priv->rtllib->ht_info->enable_ht = 1;
- else
- priv->rtllib->ht_info->enable_ht = 0;
-
- _rtl92e_refresh_support_rate(priv);
-}
-
-static int _rtl92e_sta_up(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
- (&priv->rtllib->pwr_save_ctrl);
- bool init_status;
-
- priv->up = 1;
- priv->rtllib->ieee_up = 1;
-
- priv->up_first_time = 0;
- init_status = rtl92e_start_adapter(dev);
- if (!init_status) {
- netdev_err(dev, "%s(): Initialization failed!\n", __func__);
- return -1;
- }
-
- RT_CLEAR_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC);
-
- if (priv->polling_timer_on == 0)
- rtl92e_check_rfctrl_gpio_timer(&priv->gpio_polling_timer);
-
- if (priv->rtllib->link_state != MAC80211_LINKED)
- rtllib_softmac_start_protocol(priv->rtllib);
- rtllib_reset_queue(priv->rtllib);
- _rtl92e_watchdog_timer_cb(&priv->watch_dog_timer);
-
- if (!netif_queue_stopped(dev))
- netif_start_queue(dev);
- else
- netif_wake_queue(dev);
-
- priv->bfirst_after_down = false;
- return 0;
-}
-
-static int _rtl92e_sta_down(struct net_device *dev, bool shutdownrf)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- unsigned long flags = 0;
- u8 rf_in_progress_timeout = 0;
-
- if (priv->up == 0)
- return -1;
-
- priv->rtllib->rtllib_ips_leave(dev);
-
- if (priv->rtllib->link_state == MAC80211_LINKED)
- rtl92e_leisure_ps_leave(dev);
-
- priv->up = 0;
- priv->rtllib->ieee_up = 0;
- priv->bfirst_after_down = true;
- if (!netif_queue_stopped(dev))
- netif_stop_queue(dev);
-
- priv->rtllib->wpa_ie_len = 0;
- kfree(priv->rtllib->wpa_ie);
- priv->rtllib->wpa_ie = NULL;
- rtl92e_cam_reset(dev);
- memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
- rtl92e_irq_disable(dev);
-
- del_timer_sync(&priv->watch_dog_timer);
- _rtl92e_cancel_deferred_work(priv);
- cancel_delayed_work(&priv->rtllib->hw_wakeup_wq);
-
- rtllib_softmac_stop_protocol(priv->rtllib);
- spin_lock_irqsave(&priv->rf_ps_lock, flags);
- while (priv->rf_change_in_progress) {
- spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
- if (rf_in_progress_timeout > 100) {
- spin_lock_irqsave(&priv->rf_ps_lock, flags);
- break;
- }
- mdelay(1);
- rf_in_progress_timeout++;
- spin_lock_irqsave(&priv->rf_ps_lock, flags);
- }
- priv->rf_change_in_progress = true;
- spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
- rtl92e_stop_adapter(dev, false);
- spin_lock_irqsave(&priv->rf_ps_lock, flags);
- priv->rf_change_in_progress = false;
- spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
- udelay(100);
- memset(&priv->rtllib->current_network, 0,
- offsetof(struct rtllib_network, list));
-
- return 0;
-}
-
-static void _rtl92e_init_priv_handler(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- priv->rtllib->softmac_hard_start_xmit = _rtl92e_hard_start_xmit;
- priv->rtllib->set_chan = rtl92e_set_channel;
- priv->rtllib->link_change = rtl92e_link_change;
- priv->rtllib->softmac_data_hard_start_xmit = _rtl92e_hard_data_xmit;
- priv->rtllib->check_nic_enough_desc = _rtl92e_check_nic_enough_desc;
- priv->rtllib->handle_assoc_response = _rtl92e_handle_assoc_response;
- priv->rtllib->handle_beacon = _rtl92e_handle_beacon;
- priv->rtllib->set_wireless_mode = rtl92e_set_wireless_mode;
- priv->rtllib->leisure_ps_leave = rtl92e_leisure_ps_leave;
- priv->rtllib->set_bw_mode_handler = rtl92e_set_bw_mode;
-
- priv->rtllib->sta_wake_up = rtl92e_hw_wakeup;
- priv->rtllib->enter_sleep_state = rtl92e_enter_sleep;
- priv->rtllib->ps_is_queue_empty = _rtl92e_is_tx_queue_empty;
-
- priv->rtllib->get_nmode_support_by_sec_cfg = rtl92e_get_nmode_support_by_sec;
- priv->rtllib->get_half_nmode_support_by_aps_handler =
- rtl92e_is_halfn_supported_by_ap;
-
- priv->rtllib->set_hw_reg_handler = rtl92e_set_reg;
- priv->rtllib->allow_all_dest_addr_handler = rtl92e_set_monitor_mode;
- priv->rtllib->init_gain_handler = rtl92e_init_gain;
- priv->rtllib->rtllib_ips_leave_wq = rtl92e_rtllib_ips_leave_wq;
- priv->rtllib->rtllib_ips_leave = rtl92e_rtllib_ips_leave;
- priv->rtllib->scan_operation_backup_handler = rtl92e_scan_op_backup;
-}
-
-static void _rtl92e_init_priv_variable(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 i;
-
- priv->dot11_current_preamble_mode = PREAMBLE_AUTO;
- priv->rtllib->status = 0;
- priv->polling_timer_on = 0;
- priv->up_first_time = 1;
- priv->blinked_ingpio = false;
- priv->being_init_adapter = false;
- priv->txringcount = 64;
- priv->rxbuffersize = 9100;
- priv->rxringcount = MAX_RX_COUNT;
- priv->irq_enabled = 0;
- priv->chan = 1;
- priv->rtllib->mode = WIRELESS_MODE_AUTO;
- priv->rtllib->iw_mode = IW_MODE_INFRA;
- priv->rtllib->ieee_up = 0;
- priv->retry_rts = DEFAULT_RETRY_RTS;
- priv->retry_data = DEFAULT_RETRY_DATA;
- priv->rtllib->rts = DEFAULT_RTS_THRESHOLD;
- priv->rtllib->rate = 110;
- priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
- priv->bcck_in_ch14 = false;
- priv->cck_present_attn = 0;
- priv->rfa_txpowertrackingindex = 0;
- priv->cck_pwr_enl = 6;
- memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
- priv->rx_ctr = 0;
- priv->rtllib->wx_set_enc = 0;
- priv->hw_radio_off = false;
- priv->rtllib->rf_off_reason = 0;
- priv->rf_change_in_progress = false;
- priv->hw_rf_off_action = 0;
- priv->set_rf_pwr_state_in_progress = false;
- priv->rtllib->pwr_save_ctrl.bLeisurePs = true;
- priv->rtllib->lps_delay_cnt = 0;
- priv->rtllib->sta_sleep = LPS_IS_WAKE;
- priv->rtllib->rf_power_state = rf_on;
-
- priv->rtllib->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
- priv->rtllib->iw_mode = IW_MODE_INFRA;
- priv->rtllib->be_scan_inprogress = false;
-
- priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD;
-
- priv->fw_info = vzalloc(sizeof(struct rt_firmware));
- if (!priv->fw_info)
- netdev_err(dev,
- "rtl8192e: Unable to allocate space for firmware\n");
-
- skb_queue_head_init(&priv->skb_queue);
-
- for (i = 0; i < MAX_QUEUE_SIZE; i++)
- skb_queue_head_init(&priv->rtllib->skb_waitq[i]);
-}
-
-static void _rtl92e_init_priv_lock(struct r8192_priv *priv)
-{
- spin_lock_init(&priv->tx_lock);
- spin_lock_init(&priv->irq_th_lock);
- spin_lock_init(&priv->rf_ps_lock);
- spin_lock_init(&priv->ps_lock);
- mutex_init(&priv->wx_mutex);
- mutex_init(&priv->rf_mutex);
- mutex_init(&priv->mutex);
-}
-
-static void _rtl92e_init_priv_task(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- INIT_WORK(&priv->reset_wq, (void *)_rtl92e_restart);
- INIT_WORK(&priv->rtllib->ips_leave_wq, (void *)rtl92e_ips_leave_wq);
- INIT_DELAYED_WORK(&priv->watch_dog_wq, (void *)_rtl92e_watchdog_wq_cb);
- INIT_DELAYED_WORK(&priv->txpower_tracking_wq, (void *)rtl92e_dm_txpower_tracking_wq);
- INIT_DELAYED_WORK(&priv->rfpath_check_wq, (void *)rtl92e_dm_rf_pathcheck_wq);
- INIT_DELAYED_WORK(&priv->update_beacon_wq, (void *)_rtl92e_update_beacon);
- INIT_WORK(&priv->qos_activate, (void *)_rtl92e_qos_activate);
- INIT_DELAYED_WORK(&priv->rtllib->hw_wakeup_wq, (void *)rtl92e_hw_wakeup_wq);
- INIT_DELAYED_WORK(&priv->rtllib->hw_sleep_wq, (void *)rtl92e_hw_sleep_wq);
- tasklet_setup(&priv->irq_rx_tasklet, _rtl92e_irq_rx_tasklet);
- tasklet_setup(&priv->irq_tx_tasklet, _rtl92e_irq_tx_tasklet);
-}
-
-static short _rtl92e_get_channel_map(struct net_device *dev)
-{
- int i;
-
- struct r8192_priv *priv = rtllib_priv(dev);
-
- for (i = 1; i <= 11; i++)
- (priv->rtllib->active_channel_map)[i] = 1;
- (priv->rtllib->active_channel_map)[12] = 2;
- (priv->rtllib->active_channel_map)[13] = 2;
-
- return 0;
-}
-
-static short _rtl92e_init(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- memset(&priv->stats, 0, sizeof(struct rt_stats));
-
- _rtl92e_init_priv_handler(dev);
- _rtl92e_init_priv_variable(dev);
- _rtl92e_init_priv_lock(priv);
- _rtl92e_init_priv_task(dev);
- rtl92e_get_eeprom_size(dev);
- rtl92e_init_variables(dev);
- _rtl92e_get_channel_map(dev);
-
- rtl92e_dm_init(dev);
-
- timer_setup(&priv->watch_dog_timer, _rtl92e_watchdog_timer_cb, 0);
-
- timer_setup(&priv->gpio_polling_timer, rtl92e_check_rfctrl_gpio_timer,
- 0);
-
- rtl92e_irq_disable(dev);
- if (request_irq(dev->irq, _rtl92e_irq, IRQF_SHARED, dev->name, dev)) {
- netdev_err(dev, "Error allocating IRQ %d", dev->irq);
- return -1;
- }
-
- priv->irq = dev->irq;
-
- if (_rtl92e_pci_initdescring(dev) != 0) {
- netdev_err(dev, "Endopoints initialization failed");
- free_irq(dev->irq, dev);
- return -1;
- }
-
- return 0;
-}
-
-/***************************************************************************
- * -------------------------------WATCHDOG STUFF---------------------------
- **************************************************************************/
-static short _rtl92e_is_tx_queue_empty(struct net_device *dev)
-{
- int i = 0;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- for (i = 0; i <= MGNT_QUEUE; i++) {
- if ((i == TXCMD_QUEUE) || (i == HCCA_QUEUE))
- continue;
- if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0) {
- netdev_info(dev, "===>tx queue is not empty:%d, %d\n",
- i, skb_queue_len(&(&priv->tx_ring[i])->queue));
- return 0;
- }
- }
- return 1;
-}
-
-static enum reset_type _rtl92e_tx_check_stuck(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 QueueID;
- bool bCheckFwTxCnt = false;
- struct rtl8192_tx_ring *ring = NULL;
- struct sk_buff *skb = NULL;
- struct cb_desc *tcb_desc = NULL;
- unsigned long flags = 0;
-
- switch (priv->rtllib->ps) {
- case RTLLIB_PS_DISABLED:
- break;
- case (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST):
- break;
- default:
- break;
- }
- spin_lock_irqsave(&priv->irq_th_lock, flags);
- for (QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++) {
- if (QueueID == TXCMD_QUEUE)
- continue;
-
- if (QueueID == BEACON_QUEUE)
- continue;
-
- ring = &priv->tx_ring[QueueID];
-
- if (skb_queue_len(&ring->queue) == 0) {
- continue;
- } else {
- skb = __skb_peek(&ring->queue);
- tcb_desc = (struct cb_desc *)(skb->cb +
- MAX_DEV_ADDR_SIZE);
- tcb_desc->stuck_count++;
- bCheckFwTxCnt = true;
- if (tcb_desc->stuck_count > 1)
- netdev_info(dev,
- "%s: QueueID=%d tcb_desc->stuck_count=%d\n",
- __func__, QueueID,
- tcb_desc->stuck_count);
- }
- }
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
-
- if (bCheckFwTxCnt) {
- if (rtl92e_is_tx_stuck(dev))
- return RESET_TYPE_SILENT;
- }
-
- return RESET_TYPE_NORESET;
-}
-
-static enum reset_type _rtl92e_rx_check_stuck(struct net_device *dev)
-{
- if (rtl92e_is_rx_stuck(dev))
- return RESET_TYPE_SILENT;
-
- return RESET_TYPE_NORESET;
-}
-
-static void _rtl92e_if_check_reset(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- enum reset_type TxResetType = RESET_TYPE_NORESET;
- enum reset_type RxResetType = RESET_TYPE_NORESET;
- enum rt_rf_power_state rfState;
-
- rfState = priv->rtllib->rf_power_state;
-
- if (rfState == rf_on)
- TxResetType = _rtl92e_tx_check_stuck(dev);
-
- if (rfState == rf_on &&
- (priv->rtllib->iw_mode == IW_MODE_INFRA) &&
- (priv->rtllib->link_state == MAC80211_LINKED))
- RxResetType = _rtl92e_rx_check_stuck(dev);
-
- if (TxResetType == RESET_TYPE_SILENT ||
- RxResetType == RESET_TYPE_SILENT) {
- netdev_info(dev, "%s(): TxResetType is %d, RxResetType is %d\n",
- __func__, TxResetType, RxResetType);
- }
-}
-
-static void _rtl92e_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum,
- u32 *TotalRxDataNum)
-{
- u16 slot_index;
- u8 i;
-
- *TotalRxBcnNum = 0;
- *TotalRxDataNum = 0;
-
- slot_index = (priv->rtllib->link_detect_info.slot_index++) %
- (priv->rtllib->link_detect_info.slot_num);
- priv->rtllib->link_detect_info.RxBcnNum[slot_index] =
- priv->rtllib->link_detect_info.num_recv_bcn_in_period;
- priv->rtllib->link_detect_info.RxDataNum[slot_index] =
- priv->rtllib->link_detect_info.num_recv_data_in_period;
- for (i = 0; i < priv->rtllib->link_detect_info.slot_num; i++) {
- *TotalRxBcnNum += priv->rtllib->link_detect_info.RxBcnNum[i];
- *TotalRxDataNum += priv->rtllib->link_detect_info.RxDataNum[i];
- }
-}
-
-static void _rtl92e_watchdog_wq_cb(void *data)
-{
- struct r8192_priv *priv = container_of_dwork_rsl(data,
- struct r8192_priv, watch_dog_wq);
- struct net_device *dev = priv->rtllib->dev;
- struct rtllib_device *ieee = priv->rtllib;
- static u8 check_reset_cnt;
- unsigned long flags;
- struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
- (&priv->rtllib->pwr_save_ctrl);
- bool busy_traffic = false;
- bool bHigherBusyTraffic = false;
- bool bHigherBusyRxTraffic = false;
- bool bEnterPS = false;
-
- if (!priv->up || priv->hw_radio_off)
- return;
-
- if (priv->rtllib->link_state >= MAC80211_LINKED) {
- if (priv->rtllib->cnt_after_link < 2)
- priv->rtllib->cnt_after_link++;
- } else {
- priv->rtllib->cnt_after_link = 0;
- }
-
- rtl92e_dm_watchdog(dev);
-
- if (!rtllib_act_scanning(priv->rtllib, false)) {
- if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->link_state ==
- MAC80211_NOLINK) &&
- (ieee->rf_power_state == rf_on) && !ieee->is_set_key &&
- (!ieee->proto_stoppping) && !ieee->wx_set_enc) {
- if (ieee->pwr_save_ctrl.return_point == IPS_CALLBACK_NONE)
- rtl92e_ips_enter(dev);
- }
- }
- if ((ieee->link_state == MAC80211_LINKED) && (ieee->iw_mode == IW_MODE_INFRA)) {
- if (ieee->link_detect_info.num_rx_ok_in_period > 100 ||
- ieee->link_detect_info.num_tx_ok_in_period > 100)
- busy_traffic = true;
-
- if (ieee->link_detect_info.num_rx_ok_in_period > 4000 ||
- ieee->link_detect_info.num_tx_ok_in_period > 4000) {
- bHigherBusyTraffic = true;
- if (ieee->link_detect_info.num_rx_ok_in_period > 5000)
- bHigherBusyRxTraffic = true;
- else
- bHigherBusyRxTraffic = false;
- }
-
- if (((ieee->link_detect_info.num_rx_unicast_ok_in_period +
- ieee->link_detect_info.num_tx_ok_in_period) > 8) ||
- (ieee->link_detect_info.num_rx_unicast_ok_in_period > 2))
- bEnterPS = false;
- else
- bEnterPS = true;
-
- if (ieee->current_network.beacon_interval < 95)
- bEnterPS = false;
-
- if (bEnterPS)
- rtl92e_leisure_ps_enter(dev);
- else
- rtl92e_leisure_ps_leave(dev);
-
- } else {
- rtl92e_leisure_ps_leave(dev);
- }
-
- ieee->link_detect_info.num_rx_ok_in_period = 0;
- ieee->link_detect_info.num_tx_ok_in_period = 0;
- ieee->link_detect_info.num_rx_unicast_ok_in_period = 0;
- ieee->link_detect_info.busy_traffic = busy_traffic;
-
- ieee->link_detect_info.bHigherBusyTraffic = bHigherBusyTraffic;
- ieee->link_detect_info.bHigherBusyRxTraffic = bHigherBusyRxTraffic;
-
- if (ieee->link_state == MAC80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) {
- u32 TotalRxBcnNum = 0;
- u32 TotalRxDataNum = 0;
-
- _rtl92e_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
-
- if ((TotalRxBcnNum + TotalRxDataNum) == 0)
- priv->check_roaming_cnt++;
- else
- priv->check_roaming_cnt = 0;
-
- if (priv->check_roaming_cnt > 0) {
- if (ieee->rf_power_state == rf_off)
- netdev_info(dev, "%s(): RF is off\n", __func__);
-
- netdev_info(dev,
- "===>%s(): AP is power off, chan:%d, connect another one\n",
- __func__, priv->chan);
-
- ieee->link_state = RTLLIB_ASSOCIATING;
-
- remove_peer_ts(priv->rtllib,
- priv->rtllib->current_network.bssid);
- ieee->is_roaming = true;
- ieee->is_set_key = false;
- ieee->link_change(dev);
- notify_wx_assoc_event(ieee);
-
- if (!(ieee->rtllib_ap_sec_type(ieee) &
- (SEC_ALG_CCMP | SEC_ALG_TKIP)))
- schedule_delayed_work(
- &ieee->associate_procedure_wq, 0);
-
- priv->check_roaming_cnt = 0;
- }
- ieee->link_detect_info.num_recv_bcn_in_period = 0;
- ieee->link_detect_info.num_recv_data_in_period = 0;
- }
-
- spin_lock_irqsave(&priv->tx_lock, flags);
- if ((check_reset_cnt++ >= 3) && (!ieee->is_roaming) &&
- (!priv->rf_change_in_progress) && (!psc->bSwRfProcessing)) {
- _rtl92e_if_check_reset(dev);
- check_reset_cnt = 3;
- }
- spin_unlock_irqrestore(&priv->tx_lock, flags);
-}
-
-static void _rtl92e_watchdog_timer_cb(struct timer_list *t)
-{
- struct r8192_priv *priv = from_timer(priv, t, watch_dog_timer);
-
- schedule_delayed_work(&priv->watch_dog_wq, 0);
- mod_timer(&priv->watch_dog_timer, jiffies +
- msecs_to_jiffies(RTLLIB_WATCH_DOG_TIME));
-}
-
-/****************************************************************************
- * ---------------------------- NIC TX/RX STUFF---------------------------
- ****************************************************************************/
-void rtl92e_rx_enable(struct net_device *dev)
-{
- rtl92e_enable_rx(dev);
-}
-
-void rtl92e_tx_enable(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- rtl92e_enable_tx(dev);
-
- rtllib_reset_queue(priv->rtllib);
-}
-
-static void _rtl92e_free_rx_ring(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- int i;
-
- for (i = 0; i < priv->rxringcount; i++) {
- struct sk_buff *skb = priv->rx_buf[i];
-
- if (!skb)
- continue;
-
- dma_unmap_single(&priv->pdev->dev,
- *((dma_addr_t *)skb->cb),
- priv->rxbuffersize, DMA_FROM_DEVICE);
- kfree_skb(skb);
- }
-
- dma_free_coherent(&priv->pdev->dev,
- sizeof(*priv->rx_ring) * priv->rxringcount,
- priv->rx_ring,
- priv->rx_ring_dma);
- priv->rx_ring = NULL;
-}
-
-static void _rtl92e_free_tx_ring(struct net_device *dev, unsigned int prio)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
-
- while (skb_queue_len(&ring->queue)) {
- struct tx_desc *entry = &ring->desc[ring->idx];
- struct sk_buff *skb = __skb_dequeue(&ring->queue);
-
- dma_unmap_single(&priv->pdev->dev, entry->TxBuffAddr,
- skb->len, DMA_TO_DEVICE);
- kfree_skb(skb);
- ring->idx = (ring->idx + 1) % ring->entries;
- }
-
- dma_free_coherent(&priv->pdev->dev,
- sizeof(*ring->desc) * ring->entries, ring->desc,
- ring->dma);
- ring->desc = NULL;
-}
-
-static void _rtl92e_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
- int rate)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- int ret;
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
- MAX_DEV_ADDR_SIZE);
- u8 queue_index = tcb_desc->queue_index;
-
- if ((priv->rtllib->rf_power_state == rf_off) || !priv->up) {
- kfree_skb(skb);
- return;
- }
-
- if (queue_index == TXCMD_QUEUE)
- netdev_warn(dev, "%s(): queue index == TXCMD_QUEUE\n",
- __func__);
-
- memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
- skb_push(skb, priv->rtllib->tx_headroom);
- ret = _rtl92e_tx(dev, skb);
-
- if (queue_index != MGNT_QUEUE) {
- priv->rtllib->stats.tx_bytes += (skb->len -
- priv->rtllib->tx_headroom);
- priv->rtllib->stats.tx_packets++;
- }
-
- if (ret != 0)
- kfree_skb(skb);
-}
-
-static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- int ret;
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
- MAX_DEV_ADDR_SIZE);
- u8 queue_index = tcb_desc->queue_index;
-
- if (queue_index != TXCMD_QUEUE) {
- if ((priv->rtllib->rf_power_state == rf_off) ||
- !priv->up) {
- kfree_skb(skb);
- return 0;
- }
- }
-
- memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
- if (queue_index == TXCMD_QUEUE) {
- _rtl92e_tx_cmd(dev, skb);
- return 0;
- }
-
- tcb_desc->ratr_index = 7;
- tcb_desc->tx_dis_rate_fallback = 1;
- tcb_desc->tx_use_drv_assinged_rate = 1;
- tcb_desc->tx_enable_fw_calc_dur = 1;
- skb_push(skb, priv->rtllib->tx_headroom);
- ret = _rtl92e_tx(dev, skb);
- if (ret != 0)
- kfree_skb(skb);
- return ret;
-}
-
-static void _rtl92e_tx_isr(struct net_device *dev, int prio)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
-
- while (skb_queue_len(&ring->queue)) {
- struct tx_desc *entry = &ring->desc[ring->idx];
- struct sk_buff *skb;
-
- if (prio != BEACON_QUEUE) {
- if (entry->OWN)
- return;
- ring->idx = (ring->idx + 1) % ring->entries;
- }
-
- skb = __skb_dequeue(&ring->queue);
- dma_unmap_single(&priv->pdev->dev, entry->TxBuffAddr,
- skb->len, DMA_TO_DEVICE);
-
- kfree_skb(skb);
- }
- if (prio != BEACON_QUEUE)
- tasklet_schedule(&priv->irq_tx_tasklet);
-}
-
-static void _rtl92e_tx_cmd(struct net_device *dev, struct sk_buff *skb)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtl8192_tx_ring *ring;
- struct tx_desc_cmd *entry;
- unsigned int idx;
- struct cb_desc *tcb_desc;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->irq_th_lock, flags);
- ring = &priv->tx_ring[TXCMD_QUEUE];
-
- idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
- entry = (struct tx_desc_cmd *)&ring->desc[idx];
-
- tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-
- rtl92e_fill_tx_cmd_desc(dev, entry, tcb_desc, skb);
-
- __skb_queue_tail(&ring->queue, skb);
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
-}
-
-static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtl8192_tx_ring *ring;
- unsigned long flags;
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
- MAX_DEV_ADDR_SIZE);
- struct tx_desc *pdesc = NULL;
- struct ieee80211_hdr *header = NULL;
- u8 *pda_addr = NULL;
- int idx;
- u32 fwinfo_size = 0;
-
- priv->rtllib->awake_pkt_sent = true;
-
- fwinfo_size = sizeof(struct tx_fwinfo_8190pci);
-
- header = (struct ieee80211_hdr *)(((u8 *)skb->data) + fwinfo_size);
- pda_addr = header->addr1;
-
- if (!is_broadcast_ether_addr(pda_addr) && !is_multicast_ether_addr(pda_addr))
- priv->stats.txbytesunicast += skb->len - fwinfo_size;
-
- spin_lock_irqsave(&priv->irq_th_lock, flags);
- ring = &priv->tx_ring[tcb_desc->queue_index];
- if (tcb_desc->queue_index != BEACON_QUEUE)
- idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
- else
- idx = 0;
-
- pdesc = &ring->desc[idx];
- if ((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
- netdev_warn(dev,
- "No more TX desc@%d, ring->idx = %d, idx = %d, skblen = 0x%x queuelen=%d",
- tcb_desc->queue_index, ring->idx, idx, skb->len,
- skb_queue_len(&ring->queue));
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- return skb->len;
- }
- rtl92e_fill_tx_desc(dev, pdesc, tcb_desc, skb);
- __skb_queue_tail(&ring->queue, skb);
- pdesc->OWN = 1;
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- netif_trans_update(dev);
-
- rtl92e_writew(dev, TP_POLL, 0x01 << tcb_desc->queue_index);
- return 0;
-}
-
-static short _rtl92e_alloc_rx_ring(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rx_desc *entry = NULL;
- int i;
-
- priv->rx_ring = dma_alloc_coherent(&priv->pdev->dev,
- sizeof(*priv->rx_ring) * priv->rxringcount,
- &priv->rx_ring_dma,
- GFP_ATOMIC);
- if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
- netdev_warn(dev, "Cannot allocate RX ring\n");
- return -ENOMEM;
- }
-
- priv->rx_idx = 0;
-
- for (i = 0; i < priv->rxringcount; i++) {
- struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
- dma_addr_t *mapping;
-
- entry = &priv->rx_ring[i];
- if (!skb)
- return 0;
- skb->dev = dev;
- priv->rx_buf[i] = skb;
- mapping = (dma_addr_t *)skb->cb;
- *mapping = dma_map_single(&priv->pdev->dev,
- skb_tail_pointer(skb),
- priv->rxbuffersize, DMA_FROM_DEVICE);
- if (dma_mapping_error(&priv->pdev->dev, *mapping)) {
- dev_kfree_skb_any(skb);
- return -1;
- }
- entry->BufferAddress = *mapping;
-
- entry->Length = priv->rxbuffersize;
- entry->OWN = 1;
- }
-
- if (entry)
- entry->EOR = 1;
- return 0;
-}
-
-static int _rtl92e_alloc_tx_ring(struct net_device *dev, unsigned int prio,
- unsigned int entries)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct tx_desc *ring;
- dma_addr_t dma;
- int i;
-
- ring = dma_alloc_coherent(&priv->pdev->dev, sizeof(*ring) * entries,
- &dma, GFP_ATOMIC);
- if (!ring || (unsigned long)ring & 0xFF) {
- netdev_warn(dev, "Cannot allocate TX ring (prio = %d)\n", prio);
- return -ENOMEM;
- }
-
- priv->tx_ring[prio].desc = ring;
- priv->tx_ring[prio].dma = dma;
- priv->tx_ring[prio].idx = 0;
- priv->tx_ring[prio].entries = entries;
- skb_queue_head_init(&priv->tx_ring[prio].queue);
-
- for (i = 0; i < entries; i++)
- ring[i].NextDescAddress =
- (u32)dma + ((i + 1) % entries) *
- sizeof(*ring);
-
- return 0;
-}
-
-static short _rtl92e_pci_initdescring(struct net_device *dev)
-{
- u32 ret;
- int i;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- ret = _rtl92e_alloc_rx_ring(dev);
- if (ret)
- return ret;
-
- for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
- ret = _rtl92e_alloc_tx_ring(dev, i, priv->txringcount);
- if (ret)
- goto err_free_rings;
- }
-
- return 0;
-
-err_free_rings:
- _rtl92e_free_rx_ring(dev);
- for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
- if (priv->tx_ring[i].desc)
- _rtl92e_free_tx_ring(dev, i);
- return 1;
-}
-
-void rtl92e_reset_desc_ring(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- int i;
- unsigned long flags = 0;
-
- if (priv->rx_ring) {
- struct rx_desc *entry = NULL;
-
- for (i = 0; i < priv->rxringcount; i++) {
- entry = &priv->rx_ring[i];
- entry->OWN = 1;
- }
- priv->rx_idx = 0;
- }
-
- spin_lock_irqsave(&priv->irq_th_lock, flags);
- for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
- if (priv->tx_ring[i].desc) {
- struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
-
- while (skb_queue_len(&ring->queue)) {
- struct tx_desc *entry = &ring->desc[ring->idx];
- struct sk_buff *skb =
- __skb_dequeue(&ring->queue);
-
- dma_unmap_single(&priv->pdev->dev,
- entry->TxBuffAddr, skb->len,
- DMA_TO_DEVICE);
- kfree_skb(skb);
- ring->idx = (ring->idx + 1) % ring->entries;
- }
- ring->idx = 0;
- }
- }
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
-}
-
-long rtl92e_translate_to_dbm(struct r8192_priv *priv, u8 signal_strength_index)
-{
- long signal_power;
-
- signal_power = (long)((signal_strength_index + 1) >> 1);
- signal_power -= 95;
-
- return signal_power;
-}
-
-void rtl92e_update_rx_statistics(struct r8192_priv *priv,
- struct rtllib_rx_stats *pprevious_stats)
-{
- int weighting = 0;
-
- if (priv->stats.recv_signal_power == 0)
- priv->stats.recv_signal_power =
- pprevious_stats->RecvSignalPower;
-
- if (pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
- weighting = 5;
- else if (pprevious_stats->RecvSignalPower <
- priv->stats.recv_signal_power)
- weighting = (-5);
- priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 +
- pprevious_stats->RecvSignalPower +
- weighting) / 6;
-}
-
-u8 rtl92e_rx_db_to_percent(s8 antpower)
-{
- if ((antpower <= -100) || (antpower >= 20))
- return 0;
- else if (antpower >= 0)
- return 100;
- else
- return 100 + antpower;
-
-} /* QueryRxPwrPercentage */
-
-u8 rtl92e_evm_db_to_percent(s8 value)
-{
- s8 ret_val = clamp(-value, 0, 33) * 3;
-
- if (ret_val == 99)
- ret_val = 100;
-
- return ret_val;
-}
-
-void rtl92e_copy_mpdu_stats(struct rtllib_rx_stats *psrc_stats,
- struct rtllib_rx_stats *ptarget_stats)
-{
- ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
- ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
-}
-
-static void _rtl92e_rx_normal(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct ieee80211_hdr *rtllib_hdr = NULL;
- bool unicast_packet = false;
- u32 skb_len = 0;
-
- struct rtllib_rx_stats stats = {
- .signal = 0,
- .noise = (u8)-98,
- .rate = 0,
- };
- unsigned int count = priv->rxringcount;
-
- while (count--) {
- struct rx_desc *pdesc = &priv->rx_ring
- [priv->rx_idx];
- struct sk_buff *skb = priv->rx_buf
- [priv->rx_idx];
- struct sk_buff *new_skb;
-
- if (pdesc->OWN)
- return;
- if (!rtl92e_get_rx_stats(dev, &stats, pdesc, skb))
- goto done;
- new_skb = dev_alloc_skb(priv->rxbuffersize);
- /* if allocation of new skb failed - drop current packet
- * and reuse skb
- */
- if (unlikely(!new_skb))
- goto done;
-
- dma_unmap_single(&priv->pdev->dev, *((dma_addr_t *)skb->cb),
- priv->rxbuffersize, DMA_FROM_DEVICE);
-
- skb_put(skb, pdesc->Length);
- skb_reserve(skb, stats.rx_drv_info_size +
- stats.rx_buf_shift);
- skb_trim(skb, skb->len - S_CRC_LEN);
- rtllib_hdr = (struct ieee80211_hdr *)skb->data;
- if (!is_multicast_ether_addr(rtllib_hdr->addr1)) {
- /* unicast packet */
- unicast_packet = true;
- }
- skb_len = skb->len;
-
- if (!rtllib_rx(priv->rtllib, skb, &stats)) {
- dev_kfree_skb_any(skb);
- } else {
- if (unicast_packet)
- priv->stats.rxbytesunicast += skb_len;
- }
-
- skb = new_skb;
- skb->dev = dev;
-
- priv->rx_buf[priv->rx_idx] = skb;
- *((dma_addr_t *)skb->cb) = dma_map_single(&priv->pdev->dev,
- skb_tail_pointer(skb),
- priv->rxbuffersize, DMA_FROM_DEVICE);
- if (dma_mapping_error(&priv->pdev->dev, *((dma_addr_t *)skb->cb))) {
- dev_kfree_skb_any(skb);
- return;
- }
-done:
- pdesc->BufferAddress = *((dma_addr_t *)skb->cb);
- pdesc->OWN = 1;
- pdesc->Length = priv->rxbuffersize;
- if (priv->rx_idx == priv->rxringcount - 1)
- pdesc->EOR = 1;
- priv->rx_idx = (priv->rx_idx + 1) %
- priv->rxringcount;
- }
-}
-
-static void _rtl92e_tx_resume(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
- struct sk_buff *skb;
- int queue_index;
-
- for (queue_index = BK_QUEUE;
- queue_index < MAX_QUEUE_SIZE; queue_index++) {
- while ((!skb_queue_empty(&ieee->skb_waitq[queue_index])) &&
- (priv->rtllib->check_nic_enough_desc(dev, queue_index) > 0)) {
- skb = skb_dequeue(&ieee->skb_waitq[queue_index]);
- ieee->softmac_data_hard_start_xmit(skb, dev, 0);
- }
- }
-}
-
-static void _rtl92e_irq_tx_tasklet(struct tasklet_struct *t)
-{
- struct r8192_priv *priv = from_tasklet(priv, t, irq_tx_tasklet);
-
- _rtl92e_tx_resume(priv->rtllib->dev);
-}
-
-static void _rtl92e_irq_rx_tasklet(struct tasklet_struct *t)
-{
- struct r8192_priv *priv = from_tasklet(priv, t, irq_rx_tasklet);
-
- _rtl92e_rx_normal(priv->rtllib->dev);
-
- rtl92e_writel(priv->rtllib->dev, INTA_MASK,
- rtl92e_readl(priv->rtllib->dev, INTA_MASK) | IMR_RDU);
-}
-
-/****************************************************************************
- * ---------------------------- NIC START/CLOSE STUFF---------------------------
- ****************************************************************************/
-static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv)
-{
- cancel_delayed_work_sync(&priv->watch_dog_wq);
- cancel_delayed_work_sync(&priv->update_beacon_wq);
- cancel_delayed_work(&priv->rtllib->hw_sleep_wq);
- cancel_work_sync(&priv->reset_wq);
- cancel_work_sync(&priv->qos_activate);
-}
-
-static int _rtl92e_up(struct net_device *dev)
-{
- if (_rtl92e_sta_up(dev) == -1)
- return -1;
- return 0;
-}
-
-static int _rtl92e_open(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- int ret;
-
- mutex_lock(&priv->wx_mutex);
- ret = _rtl92e_try_up(dev);
- mutex_unlock(&priv->wx_mutex);
- return ret;
-}
-
-static int _rtl92e_try_up(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->up == 1)
- return -1;
- return _rtl92e_up(dev);
-}
-
-static int _rtl92e_close(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- int ret;
-
- if ((rtllib_act_scanning(priv->rtllib, false)) &&
- !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) {
- rtllib_stop_scan(priv->rtllib);
- }
-
- mutex_lock(&priv->wx_mutex);
-
- ret = _rtl92e_down(dev, true);
-
- mutex_unlock(&priv->wx_mutex);
-
- return ret;
-}
-
-static int _rtl92e_down(struct net_device *dev, bool shutdownrf)
-{
- if (_rtl92e_sta_down(dev, shutdownrf) == -1)
- return -1;
-
- return 0;
-}
-
-void rtl92e_commit(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->up == 0)
- return;
- rtllib_softmac_stop_protocol(priv->rtllib);
- rtl92e_irq_disable(dev);
- rtl92e_stop_adapter(dev, true);
- _rtl92e_up(dev);
-}
-
-static void _rtl92e_restart(void *data)
-{
- struct r8192_priv *priv = container_of(data, struct r8192_priv, reset_wq);
- struct net_device *dev = priv->rtllib->dev;
-
- mutex_lock(&priv->wx_mutex);
-
- rtl92e_commit(dev);
-
- mutex_unlock(&priv->wx_mutex);
-}
-
-static void _rtl92e_set_multicast(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- short promisc;
-
- promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
- priv->promisc = promisc;
-}
-
-static int _rtl92e_set_mac_adr(struct net_device *dev, void *mac)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct sockaddr *addr = mac;
-
- mutex_lock(&priv->wx_mutex);
-
- eth_hw_addr_set(dev, addr->sa_data);
-
- schedule_work(&priv->reset_wq);
- mutex_unlock(&priv->wx_mutex);
-
- return 0;
-}
-
-static irqreturn_t _rtl92e_irq(int irq, void *netdev)
-{
- struct net_device *dev = netdev;
- struct r8192_priv *priv = rtllib_priv(dev);
- unsigned long flags;
- u32 inta;
-
- if (priv->irq_enabled == 0)
- goto done;
-
- spin_lock_irqsave(&priv->irq_th_lock, flags);
-
- rtl92e_ack_irq(dev, &inta);
-
- if (!inta) {
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- goto done;
- }
-
- if (inta == 0xffff) {
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- goto done;
- }
-
- if (!netif_running(dev)) {
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- goto done;
- }
-
- if (inta & IMR_MGNTDOK) {
- _rtl92e_tx_isr(dev, MGNT_QUEUE);
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- if (priv->rtllib->ack_tx_to_ieee) {
- if (_rtl92e_is_tx_queue_empty(dev)) {
- priv->rtllib->ack_tx_to_ieee = 0;
- rtllib_ps_tx_ack(priv->rtllib, 1);
- }
- }
- spin_lock_irqsave(&priv->irq_th_lock, flags);
- }
-
- if (inta & IMR_COMDOK)
- _rtl92e_tx_isr(dev, TXCMD_QUEUE);
-
- if (inta & IMR_HIGHDOK)
- _rtl92e_tx_isr(dev, HIGH_QUEUE);
-
- if (inta & IMR_ROK)
- tasklet_schedule(&priv->irq_rx_tasklet);
-
- if (inta & IMR_RDU) {
- rtl92e_writel(dev, INTA_MASK,
- rtl92e_readl(dev, INTA_MASK) & ~IMR_RDU);
- tasklet_schedule(&priv->irq_rx_tasklet);
- }
-
- if (inta & IMR_RXFOVW)
- tasklet_schedule(&priv->irq_rx_tasklet);
-
- if (inta & IMR_BKDOK) {
- priv->rtllib->link_detect_info.num_tx_ok_in_period++;
- _rtl92e_tx_isr(dev, BK_QUEUE);
- }
-
- if (inta & IMR_BEDOK) {
- priv->rtllib->link_detect_info.num_tx_ok_in_period++;
- _rtl92e_tx_isr(dev, BE_QUEUE);
- }
-
- if (inta & IMR_VIDOK) {
- priv->rtllib->link_detect_info.num_tx_ok_in_period++;
- _rtl92e_tx_isr(dev, VI_QUEUE);
- }
-
- if (inta & IMR_VODOK) {
- priv->rtllib->link_detect_info.num_tx_ok_in_period++;
- _rtl92e_tx_isr(dev, VO_QUEUE);
- }
-
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
-
-done:
-
- return IRQ_HANDLED;
-}
-
-/****************************************************************************
- * ---------------------------- PCI_STUFF---------------------------
- ****************************************************************************/
-static const struct net_device_ops rtl8192_netdev_ops = {
- .ndo_open = _rtl92e_open,
- .ndo_stop = _rtl92e_close,
- .ndo_tx_timeout = _rtl92e_tx_timeout,
- .ndo_set_rx_mode = _rtl92e_set_multicast,
- .ndo_set_mac_address = _rtl92e_set_mac_adr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_start_xmit = rtllib_xmit,
-};
-
-static int _rtl92e_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- unsigned long ioaddr = 0;
- struct net_device *dev = NULL;
- struct r8192_priv *priv = NULL;
- unsigned long pmem_start, pmem_len, pmem_flags;
- int err = -ENOMEM;
-
- if (pci_enable_device(pdev)) {
- dev_err(&pdev->dev, "Failed to enable PCI device");
- return -EIO;
- }
-
- pci_set_master(pdev);
-
- if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
- if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) {
- dev_info(&pdev->dev,
- "Unable to obtain 32bit DMA for consistent allocations\n");
- goto err_pci_disable;
- }
- }
- dev = alloc_rtllib(sizeof(struct r8192_priv));
- if (!dev)
- goto err_pci_disable;
-
- err = -ENODEV;
-
- pci_set_drvdata(pdev, dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
- priv = rtllib_priv(dev);
- priv->rtllib = (struct rtllib_device *)netdev_priv_rsl(dev);
- priv->pdev = pdev;
- priv->rtllib->pdev = pdev;
- if ((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK) &&
- (pdev->subsystem_device == 0x3304))
- priv->rtllib->bSupportRemoteWakeUp = 1;
- else
- priv->rtllib->bSupportRemoteWakeUp = 0;
-
- pmem_start = pci_resource_start(pdev, 1);
- pmem_len = pci_resource_len(pdev, 1);
- pmem_flags = pci_resource_flags(pdev, 1);
-
- if (!(pmem_flags & IORESOURCE_MEM)) {
- netdev_err(dev, "region #1 not a MMIO resource, aborting");
- goto err_rel_rtllib;
- }
-
- dev_info(&pdev->dev, "Memory mapped space start: 0x%08lx\n",
- pmem_start);
- if (!request_mem_region(pmem_start, pmem_len, DRV_NAME)) {
- netdev_err(dev, "request_mem_region failed!");
- goto err_rel_rtllib;
- }
-
- ioaddr = (unsigned long)ioremap(pmem_start, pmem_len);
- if (ioaddr == (unsigned long)NULL) {
- netdev_err(dev, "ioremap failed!");
- goto err_rel_mem;
- }
-
- dev->mem_start = ioaddr;
- dev->mem_end = ioaddr + pci_resource_len(pdev, 0);
-
- if (!rtl92e_check_adapter(pdev, dev))
- goto err_unmap;
-
- dev->irq = pdev->irq;
- priv->irq = 0;
-
- dev->netdev_ops = &rtl8192_netdev_ops;
-
- dev->wireless_handlers = &r8192_wx_handlers_def;
- dev->ethtool_ops = &rtl819x_ethtool_ops;
-
- dev->type = ARPHRD_ETHER;
- dev->watchdog_timeo = HZ * 3;
-
- if (dev_alloc_name(dev, ifname) < 0)
- dev_alloc_name(dev, ifname);
-
- if (_rtl92e_init(dev) != 0) {
- netdev_warn(dev, "Initialization failed");
- goto err_free_irq;
- }
-
- netif_carrier_off(dev);
- netif_stop_queue(dev);
-
- if (register_netdev(dev))
- goto err_free_irq;
-
- if (priv->polling_timer_on == 0)
- rtl92e_check_rfctrl_gpio_timer(&priv->gpio_polling_timer);
-
- return 0;
-
-err_free_irq:
- free_irq(dev->irq, dev);
- priv->irq = 0;
-err_unmap:
- iounmap((void __iomem *)ioaddr);
-err_rel_mem:
- release_mem_region(pmem_start, pmem_len);
-err_rel_rtllib:
- free_rtllib(dev);
-err_pci_disable:
- pci_disable_device(pdev);
- return err;
-}
-
-static void _rtl92e_pci_disconnect(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct r8192_priv *priv;
- u32 i;
-
- if (dev) {
- unregister_netdev(dev);
-
- priv = rtllib_priv(dev);
-
- del_timer_sync(&priv->gpio_polling_timer);
- cancel_delayed_work_sync(&priv->gpio_change_rf_wq);
- priv->polling_timer_on = 0;
- _rtl92e_down(dev, true);
- rtl92e_dm_deinit(dev);
- vfree(priv->fw_info);
- priv->fw_info = NULL;
- _rtl92e_free_rx_ring(dev);
- for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
- _rtl92e_free_tx_ring(dev, i);
-
- if (priv->irq) {
- dev_info(&pdev->dev, "Freeing irq %d\n", dev->irq);
- free_irq(dev->irq, dev);
- priv->irq = 0;
- }
-
- if (dev->mem_start != 0) {
- iounmap((void __iomem *)dev->mem_start);
- release_mem_region(pci_resource_start(pdev, 1),
- pci_resource_len(pdev, 1));
- }
-
- free_rtllib(dev);
- }
-
- pci_disable_device(pdev);
-}
-
-bool rtl92e_enable_nic(struct net_device *dev)
-{
- bool init_status = true;
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
- (&priv->rtllib->pwr_save_ctrl);
-
- if (!priv->up) {
- netdev_warn(dev, "%s(): Driver is already down!\n", __func__);
- return false;
- }
-
- init_status = rtl92e_start_adapter(dev);
- if (!init_status) {
- netdev_warn(dev, "%s(): Initialization failed!\n", __func__);
- return false;
- }
- RT_CLEAR_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC);
-
- rtl92e_irq_enable(dev);
- return init_status;
-}
-
-module_pci_driver(rtl8192_pci_driver);
-
-void rtl92e_check_rfctrl_gpio_timer(struct timer_list *t)
-{
- struct r8192_priv *priv = from_timer(priv, t, gpio_polling_timer);
-
- priv->polling_timer_on = 1;
-
- schedule_delayed_work(&priv->gpio_change_rf_wq, 0);
-
- mod_timer(&priv->gpio_polling_timer, jiffies +
- msecs_to_jiffies(RTLLIB_WATCH_DOG_TIME));
-}
-
-/***************************************************************************
- * ------------------- module init / exit stubs ----------------
- ***************************************************************************/
-MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
-MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
-MODULE_VERSION(DRV_VERSION);
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(RTL8192E_BOOT_IMG_FW);
-MODULE_FIRMWARE(RTL8192E_MAIN_IMG_FW);
-MODULE_FIRMWARE(RTL8192E_DATA_IMG_FW);
-
-module_param(ifname, charp, 0644);
-module_param(hwwep, int, 0644);
-
-MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default");
-MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support(default use hw. set 0 to use software security)");
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h
deleted file mode 100644
index 8297d7e59415..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h
+++ /dev/null
@@ -1,402 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef _RTL_CORE_H
-#define _RTL_CORE_H
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/etherdevice.h>
-#include <linux/delay.h>
-#include <linux/rtnetlink.h>
-#include <linux/wireless.h>
-#include <linux/timer.h>
-#include <linux/proc_fs.h>
-#include <linux/if_arp.h>
-#include <linux/random.h>
-#include <linux/io.h>
-
-/* Need this defined before including local include files */
-#define DRV_NAME "rtl819xE"
-
-#include "../rtllib.h"
-
-#include "r8192E_firmware.h"
-#include "r8192E_hw.h"
-
-#include "r8190P_def.h"
-#include "r8192E_dev.h"
-
-#include "rtl_eeprom.h"
-#include "rtl_ps.h"
-#include "rtl_pci.h"
-#include "rtl_cam.h"
-
-#define DRV_COPYRIGHT \
- "Copyright(c) 2008 - 2010 Realsil Semiconductor Corporation"
-#define DRV_AUTHOR "<wlanfae@realtek.com>"
-#define DRV_VERSION "0014.0401.2010"
-
-#define TOTAL_CAM_ENTRY 32
-#define CAM_CONTENT_COUNT 8
-
-#define HAL_HW_PCI_REVISION_ID_8192PCIE 0x01
-#define HAL_HW_PCI_REVISION_ID_8192SE 0x10
-
-#define RTLLIB_WATCH_DOG_TIME 2000
-
-#define MAX_DEV_ADDR_SIZE 8 /*support till 64 bit bus width OS*/
-#define MAX_FIRMWARE_INFORMATION_SIZE 32
-#define MAX_802_11_HEADER_LENGTH (40 + MAX_FIRMWARE_INFORMATION_SIZE)
-#define ENCRYPTION_MAX_OVERHEAD 128
-#define MAX_FRAGMENT_COUNT 8
-#define MAX_TRANSMIT_BUFFER_SIZE \
- (1600 + (MAX_802_11_HEADER_LENGTH + ENCRYPTION_MAX_OVERHEAD) * \
- MAX_FRAGMENT_COUNT)
-
-#define CMDPACKET_FRAG_SIZE (4 * (MAX_TRANSMIT_BUFFER_SIZE / 4) - 8)
-
-#define DEFAULT_FRAG_THRESHOLD 2342U
-#define MIN_FRAG_THRESHOLD 256U
-#define DEFAULT_BEACONINTERVAL 0x64U
-
-#define DEFAULT_RETRY_RTS 7
-#define DEFAULT_RETRY_DATA 7
-
-#define PHY_RSSI_SLID_WIN_MAX 100
-
-#define TX_BB_GAIN_TABLE_LEN 37
-#define CCK_TX_BB_GAIN_TABLE_LEN 23
-
-#define CHANNEL_PLAN_LEN 10
-#define S_CRC_LEN 4
-
-#define NIC_SEND_HANG_THRESHOLD_NORMAL 4
-#define NIC_SEND_HANG_THRESHOLD_POWERSAVE 8
-
-#define MAX_TX_QUEUE 9
-
-#define MAX_RX_COUNT 64
-#define MAX_TX_QUEUE_COUNT 9
-
-extern int hwwep;
-
-enum nic_t {
- NIC_UNKNOWN = 0,
- NIC_8192E = 1,
- NIC_8190P = 2,
- NIC_8192SE = 4,
- NIC_8192CE = 5,
- NIC_8192CU = 6,
- NIC_8192DE = 7,
- NIC_8192DU = 8,
-};
-
-enum rt_eeprom_type {
- EEPROM_93C46,
- EEPROM_93C56,
-};
-
-enum dcmg_txcmd_op {
- TXCMD_TXRA_HISTORY_CTRL = 0xFF900000,
- TXCMD_RESET_TX_PKT_BUFF = 0xFF900001,
- TXCMD_RESET_RX_PKT_BUFF = 0xFF900002,
- TXCMD_SET_TX_DURATION = 0xFF900003,
- TXCMD_SET_RX_RSSI = 0xFF900004,
- TXCMD_SET_TX_PWR_TRACKING = 0xFF900005,
- TXCMD_XXXX_CTRL,
-};
-
-enum rt_customer_id {
- RT_CID_DEFAULT = 0,
- RT_CID_TOSHIBA = 9,
- RT_CID_819X_NETCORE = 10,
-};
-
-enum reset_type {
- RESET_TYPE_NORESET = 0x00,
- RESET_TYPE_SILENT = 0x02
-};
-
-struct rt_stats {
- unsigned long received_rate_histogram[4][32];
- unsigned long txbytesunicast;
- unsigned long rxbytesunicast;
- unsigned long txretrycount;
- u8 last_packet_rate;
- unsigned long slide_signal_strength[100];
- unsigned long slide_evm[100];
- unsigned long slide_rssi_total;
- unsigned long slide_evm_total;
- long signal_strength;
- long last_signal_strength_inpercent;
- long recv_signal_power;
- u8 rx_rssi_percentage[4];
- u8 rx_evm_percentage[2];
- u32 slide_beacon_pwdb[100];
- u32 slide_beacon_total;
- u32 CurrentShowTxate;
-};
-
-struct init_gain {
- u8 xaagccore1;
- u8 xbagccore1;
- u8 xcagccore1;
- u8 xdagccore1;
- u8 cca;
-
-};
-
-struct tx_ring {
- u32 *desc;
- u8 nStuckCount;
- struct tx_ring *next;
-} __packed;
-
-struct rtl8192_tx_ring {
- struct tx_desc *desc;
- dma_addr_t dma;
- unsigned int idx;
- unsigned int entries;
- struct sk_buff_head queue;
-};
-
-struct r8192_priv {
- struct pci_dev *pdev;
- struct pci_dev *bridge_pdev;
-
- bool bfirst_after_down;
- bool being_init_adapter;
-
- int irq;
- short irq_enabled;
-
- short up;
- short up_first_time;
- struct delayed_work update_beacon_wq;
- struct delayed_work watch_dog_wq;
- struct delayed_work txpower_tracking_wq;
- struct delayed_work rfpath_check_wq;
- struct delayed_work gpio_change_rf_wq;
- struct rtllib_device *rtllib;
-
- struct work_struct reset_wq;
-
- enum rt_customer_id customer_id;
-
- enum ht_channel_width current_chnl_bw;
- struct bb_reg_definition phy_reg_def[4];
- struct rate_adaptive rate_adaptive;
-
- struct rt_firmware *fw_info;
- enum rtl819x_loopback loopback_mode;
-
- struct timer_list watch_dog_timer;
- struct timer_list fsync_timer;
- struct timer_list gpio_polling_timer;
-
- spinlock_t irq_th_lock;
- spinlock_t tx_lock;
- spinlock_t rf_ps_lock;
- spinlock_t ps_lock;
-
- struct sk_buff_head skb_queue;
-
- struct tasklet_struct irq_rx_tasklet;
- struct tasklet_struct irq_tx_tasklet;
-
- struct mutex wx_mutex;
- struct mutex rf_mutex;
- struct mutex mutex;
-
- struct rt_stats stats;
- struct iw_statistics wstats;
-
- struct rx_desc *rx_ring;
- struct sk_buff *rx_buf[MAX_RX_COUNT];
- dma_addr_t rx_ring_dma;
- unsigned int rx_idx;
- int rxringcount;
- u16 rxbuffersize;
-
- u32 receive_config;
- u8 retry_data;
- u8 retry_rts;
- u16 rts;
-
- struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT];
- int txringcount;
- atomic_t tx_pending[0x10];
-
- u16 short_retry_limit;
- u16 long_retry_limit;
-
- bool hw_radio_off;
- bool blinked_ingpio;
- u8 polling_timer_on;
-
- /**********************************************************/
- struct work_struct qos_activate;
-
- short promisc;
-
- short chan;
-
- u32 irq_mask[2];
-
- u8 rf_mode;
- enum nic_t card_8192;
- u8 card_8192_version;
-
- u8 ic_cut;
- char nick[IW_ESSID_MAX_SIZE + 1];
- u8 check_roaming_cnt;
-
- u32 silent_reset_rx_slot_index;
- u32 silent_reset_rx_stuck_event[MAX_SILENT_RESET_RX_SLOT_NUM];
-
- u16 basic_rate;
- u8 short_preamble;
- u8 dot11_current_preamble_mode;
- u8 slot_time;
-
- bool autoload_fail_flag;
-
- short epromtype;
- u16 eeprom_vid;
- u16 eeprom_did;
- u8 eeprom_customer_id;
-
- u8 eeprom_tx_pwr_level_cck[14];
- u8 eeprom_tx_pwr_level_ofdm24g[14];
- u16 eeprom_ant_pwr_diff;
- u8 eeprom_thermal_meter;
- u8 eeprom_crystal_cap;
-
- u8 eeprom_legacy_ht_tx_pwr_diff;
-
- u8 crystal_cap;
- u8 thermal_meter[2];
-
- u8 sw_chnl_in_progress;
- u8 sw_chnl_stage;
- u8 sw_chnl_step;
- u8 set_bw_mode_in_progress;
-
- u8 n_cur_40mhz_prime_sc;
-
- u32 rf_reg_0value[4];
- u8 num_total_rf_path;
- bool brfpath_rxenable[RF90_PATH_MAX];
-
- bool tx_pwr_data_read_from_eeprom;
-
- u8 hw_rf_off_action;
-
- bool rf_change_in_progress;
- bool set_rf_pwr_state_in_progress;
-
- u8 cck_pwr_enl;
- u16 tssi_13dBm;
- u32 pwr_track;
- u8 cck_present_attn_20m_def;
- u8 cck_present_attn_40m_def;
- s8 cck_present_attn_diff;
- s8 cck_present_attn;
- long undecorated_smoothed_pwdb;
-
- u32 mcs_tx_pwr_level_org_offset[6];
- u8 tx_pwr_level_cck[14];
- u8 tx_pwr_level_ofdm_24g[14];
- u8 legacy_ht_tx_pwr_diff;
- u8 antenna_tx_pwr_diff[3];
-
- bool dynamic_tx_high_pwr;
- bool dynamic_tx_low_pwr;
- bool last_dtp_flag_high;
- bool last_dtp_flag_low;
-
- u8 rfa_txpowertrackingindex;
- u8 rfa_txpowertrackingindex_real;
- u8 rfa_txpowertracking_default;
- bool btxpower_tracking;
- bool bcck_in_ch14;
-
- u8 txpower_count;
- bool tx_pwr_tracking_init;
-
- u8 ofdm_index[2];
- u8 cck_index;
-
- u8 rec_cck_20m_idx;
- u8 rec_cck_40m_idx;
-
- struct init_gain initgain_backup;
- u8 def_initial_gain[4];
- bool bis_any_nonbepkts;
- bool bcurrent_turbo_EDCA;
- bool bis_cur_rdlstate;
-
- u32 rate_record;
- u32 rate_count_diff_rec;
- u32 continue_diff_count;
- bool bswitch_fsync;
- u8 framesync;
-
- u16 tx_counter;
- u16 rx_ctr;
-};
-
-extern const struct ethtool_ops rtl819x_ethtool_ops;
-
-u8 rtl92e_readb(struct net_device *dev, int x);
-u32 rtl92e_readl(struct net_device *dev, int x);
-u16 rtl92e_readw(struct net_device *dev, int x);
-void rtl92e_writeb(struct net_device *dev, int x, u8 y);
-void rtl92e_writew(struct net_device *dev, int x, u16 y);
-void rtl92e_writel(struct net_device *dev, int x, u32 y);
-
-void force_pci_posting(struct net_device *dev);
-
-void rtl92e_rx_enable(struct net_device *dev);
-void rtl92e_tx_enable(struct net_device *dev);
-
-void rtl92e_hw_sleep_wq(void *data);
-void rtl92e_commit(struct net_device *dev);
-
-void rtl92e_check_rfctrl_gpio_timer(struct timer_list *t);
-
-void rtl92e_hw_wakeup_wq(void *data);
-
-void rtl92e_reset_desc_ring(struct net_device *dev);
-void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode);
-void rtl92e_irq_enable(struct net_device *dev);
-void rtl92e_config_rate(struct net_device *dev, u16 *rate_config);
-void rtl92e_irq_disable(struct net_device *dev);
-
-long rtl92e_translate_to_dbm(struct r8192_priv *priv, u8 signal_strength_index);
-void rtl92e_update_rx_statistics(struct r8192_priv *priv,
- struct rtllib_rx_stats *pprevious_stats);
-u8 rtl92e_evm_db_to_percent(s8 value);
-u8 rtl92e_rx_db_to_percent(s8 antpower);
-void rtl92e_copy_mpdu_stats(struct rtllib_rx_stats *psrc_stats,
- struct rtllib_rx_stats *ptarget_stats);
-bool rtl92e_enable_nic(struct net_device *dev);
-
-bool rtl92e_set_rf_state(struct net_device *dev,
- enum rt_rf_power_state state_to_set,
- RT_RF_CHANGE_SOURCE change_source);
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
deleted file mode 100644
index e9ca5a8768ad..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
+++ /dev/null
@@ -1,1856 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtl_core.h"
-#include "rtl_dm.h"
-#include "r8192E_hw.h"
-#include "r8192E_phy.h"
-#include "r8192E_phyreg.h"
-#include "r8190P_rtl8256.h"
-#include "r8192E_cmdpkt.h"
-
-/*---------------------------Define Local Constant---------------------------*/
-static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
- 0x5e4322,
- 0x5e4322,
- 0x5ea44f,
- 0x5e4322,
- 0x604322,
- 0xa44f,
- 0x5e4322,
- 0x5e4332
-};
-
-static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = {
- 0x5e4322,
- 0x5e4322,
- 0x5e4322,
- 0x5e4322,
- 0x604322,
- 0xa44f,
- 0x5e4322,
- 0x5e4322
-};
-
-static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
- 0x5e4322,
- 0xa44f,
- 0x5ea44f,
- 0x5e4322,
- 0x604322,
- 0x5e4322,
- 0x5e4322,
- 0x5e4332
-};
-
-const u32 dm_tx_bb_gain[TX_BB_GAIN_TABLE_LEN] = {
- 0x7f8001fe, /* 12 dB */
- 0x788001e2, /* 11 dB */
- 0x71c001c7,
- 0x6b8001ae,
- 0x65400195,
- 0x5fc0017f,
- 0x5a400169,
- 0x55400155,
- 0x50800142,
- 0x4c000130,
- 0x47c0011f,
- 0x43c0010f,
- 0x40000100,
- 0x3c8000f2,
- 0x390000e4,
- 0x35c000d7,
- 0x32c000cb,
- 0x300000c0,
- 0x2d4000b5,
- 0x2ac000ab,
- 0x288000a2,
- 0x26000098,
- 0x24000090,
- 0x22000088,
- 0x20000080,
- 0x1a00006c,
- 0x1c800072,
- 0x18000060,
- 0x19800066,
- 0x15800056,
- 0x26c0005b,
- 0x14400051,
- 0x24400051,
- 0x1300004c,
- 0x12000048,
- 0x11000044,
- 0x10000040, /* -24 dB */
-};
-
-const u8 dm_cck_tx_bb_gain[CCK_TX_BB_GAIN_TABLE_LEN][8] = {
- {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
- {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
- {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
- {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
- {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
- {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
- {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
- {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
- {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
- {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
- {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
- {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
- {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
- {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
- {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
- {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
- {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
- {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
- {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
- {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
- {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
- {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
- {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}
-};
-
-const u8 dm_cck_tx_bb_gain_ch14[CCK_TX_BB_GAIN_TABLE_LEN][8] = {
- {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
- {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
- {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
- {0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00},
- {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
- {0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00},
- {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
- {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
- {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
- {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
- {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
- {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
- {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
- {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
- {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
- {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
- {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
- {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
- {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
- {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
- {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
- {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
- {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}
-};
-
-/*---------------------------Define Local Constant---------------------------*/
-
-
-/*------------------------Define global variable-----------------------------*/
-struct dig_t dm_digtable;
-
-static struct drx_path_sel dm_rx_path_sel_table;
-/*------------------------Define global variable-----------------------------*/
-
-
-/*------------------------Define local variable------------------------------*/
-/*------------------------Define local variable------------------------------*/
-
-
-
-/*---------------------Define local function prototype-----------------------*/
-static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev);
-
-static void _rtl92e_dm_init_bandwidth_autoswitch(struct net_device *dev);
-static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev);
-
-static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev);
-
-static void _rtl92e_dm_dig_init(struct net_device *dev);
-static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev);
-static void _rtl92e_dm_initial_gain(struct net_device *dev);
-static void _rtl92e_dm_pd_th(struct net_device *dev);
-static void _rtl92e_dm_cs_ratio(struct net_device *dev);
-
-static void _rtl92e_dm_init_cts_to_self(struct net_device *dev);
-
-static void _rtl92e_dm_check_edca_turbo(struct net_device *dev);
-static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev);
-static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev);
-static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev);
-
-static void _rtl92e_dm_init_fsync(struct net_device *dev);
-static void _rtl92e_dm_deinit_fsync(struct net_device *dev);
-
-static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev);
-static void _rtl92e_dm_check_fsync(struct net_device *dev);
-static void _rtl92e_dm_check_rf_ctrl_gpio(void *data);
-static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t);
-
-/*---------------------Define local function prototype-----------------------*/
-
-static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev);
-static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev);
-
-static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev);
-static void _rtl92e_dm_cts_to_self(struct net_device *dev);
-/*---------------------------Define function prototype------------------------*/
-
-void rtl92e_dm_init(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- priv->undecorated_smoothed_pwdb = -1;
-
- _rtl92e_dm_init_dynamic_tx_power(dev);
-
- rtl92e_init_adaptive_rate(dev);
-
- _rtl92e_dm_dig_init(dev);
- rtl92e_dm_init_edca_turbo(dev);
- _rtl92e_dm_init_bandwidth_autoswitch(dev);
- _rtl92e_dm_init_fsync(dev);
- _rtl92e_dm_init_rx_path_selection(dev);
- _rtl92e_dm_init_cts_to_self(dev);
-
- INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, (void *)_rtl92e_dm_check_rf_ctrl_gpio);
-}
-
-void rtl92e_dm_deinit(struct net_device *dev)
-{
- _rtl92e_dm_deinit_fsync(dev);
-}
-
-void rtl92e_dm_watchdog(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->being_init_adapter)
- return;
-
- _rtl92e_dm_check_txrateandretrycount(dev);
- _rtl92e_dm_check_edca_turbo(dev);
-
- _rtl92e_dm_check_rate_adaptive(dev);
- _rtl92e_dm_dynamic_tx_power(dev);
- _rtl92e_dm_check_tx_power_tracking(dev);
-
- _rtl92e_dm_ctrl_initgain_byrssi(dev);
- _rtl92e_dm_bandwidth_autoswitch(dev);
-
- _rtl92e_dm_check_rx_path_selection(dev);
- _rtl92e_dm_check_fsync(dev);
-
- _rtl92e_dm_send_rssi_to_fw(dev);
- _rtl92e_dm_cts_to_self(dev);
-}
-
-void rtl92e_init_adaptive_rate(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rate_adaptive *pra = &priv->rate_adaptive;
-
- pra->ratr_state = DM_RATR_STA_MAX;
- pra->high2low_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH;
- pra->low2high_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M + 5;
- pra->low2high_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M + 5;
-
- pra->high_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH + 5;
- pra->low_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M;
- pra->low_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M;
-
- if (priv->customer_id == RT_CID_819X_NETCORE)
- pra->ping_rssi_enable = 1;
- else
- pra->ping_rssi_enable = 0;
- pra->ping_rssi_thresh_for_ra = 15;
-
- pra->upper_rssi_threshold_ratr = 0x000fc000;
- pra->middle_rssi_threshold_ratr = 0x000ff000;
- pra->low_rssi_threshold_ratr = 0x000ff001;
- pra->low_rssi_threshold_ratr_40M = 0x000ff005;
- pra->low_rssi_threshold_ratr_20M = 0x000ff001;
- pra->ping_rssi_ratr = 0x0000000d;
-}
-
-static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_hi_throughput *ht_info = priv->rtllib->ht_info;
- struct rate_adaptive *pra = &priv->rate_adaptive;
- u32 current_ratr, target_ratr = 0;
- u32 low_rssi_thresh_for_ra = 0, high_rssi_thresh_for_ra = 0;
- bool bshort_gi_enabled = false;
- static u8 ping_rssi_state;
-
- if (!priv->up)
- return;
-
- if (priv->rtllib->mode != WIRELESS_MODE_N_24G)
- return;
-
- if (priv->rtllib->link_state == MAC80211_LINKED) {
- bshort_gi_enabled = (ht_info->cur_tx_bw40mhz &&
- ht_info->cur_short_gi_40mhz) ||
- (!ht_info->cur_tx_bw40mhz &&
- ht_info->cur_short_gi_20mhz);
-
- pra->upper_rssi_threshold_ratr =
- (pra->upper_rssi_threshold_ratr & (~BIT(31))) |
- ((bshort_gi_enabled) ? BIT(31) : 0);
-
- pra->middle_rssi_threshold_ratr =
- (pra->middle_rssi_threshold_ratr & (~BIT(31))) |
- ((bshort_gi_enabled) ? BIT(31) : 0);
-
- if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) {
- pra->low_rssi_threshold_ratr =
- (pra->low_rssi_threshold_ratr_40M & (~BIT(31))) |
- ((bshort_gi_enabled) ? BIT(31) : 0);
- } else {
- pra->low_rssi_threshold_ratr =
- (pra->low_rssi_threshold_ratr_20M & (~BIT(31))) |
- ((bshort_gi_enabled) ? BIT(31) : 0);
- }
- pra->ping_rssi_ratr =
- (pra->ping_rssi_ratr & (~BIT(31))) |
- ((bshort_gi_enabled) ? BIT(31) : 0);
-
- if (pra->ratr_state == DM_RATR_STA_HIGH) {
- high_rssi_thresh_for_ra = pra->high2low_rssi_thresh_for_ra;
- low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ?
- (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
- } else if (pra->ratr_state == DM_RATR_STA_LOW) {
- high_rssi_thresh_for_ra = pra->high_rssi_thresh_for_ra;
- low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ?
- (pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M);
- } else {
- high_rssi_thresh_for_ra = pra->high_rssi_thresh_for_ra;
- low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ?
- (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
- }
-
- if (priv->undecorated_smoothed_pwdb >=
- (long)high_rssi_thresh_for_ra) {
- pra->ratr_state = DM_RATR_STA_HIGH;
- target_ratr = pra->upper_rssi_threshold_ratr;
- } else if (priv->undecorated_smoothed_pwdb >=
- (long)low_rssi_thresh_for_ra) {
- pra->ratr_state = DM_RATR_STA_MIDDLE;
- target_ratr = pra->middle_rssi_threshold_ratr;
- } else {
- pra->ratr_state = DM_RATR_STA_LOW;
- target_ratr = pra->low_rssi_threshold_ratr;
- }
-
- if (pra->ping_rssi_enable) {
- if (priv->undecorated_smoothed_pwdb <
- (long)(pra->ping_rssi_thresh_for_ra + 5)) {
- if ((priv->undecorated_smoothed_pwdb <
- (long)pra->ping_rssi_thresh_for_ra) ||
- ping_rssi_state) {
- pra->ratr_state = DM_RATR_STA_LOW;
- target_ratr = pra->ping_rssi_ratr;
- ping_rssi_state = 1;
- }
- } else {
- ping_rssi_state = 0;
- }
- }
-
- if (priv->rtllib->get_half_nmode_support_by_aps_handler(dev))
- target_ratr &= 0xf00fffff;
-
- current_ratr = rtl92e_readl(dev, RATR0);
- if (target_ratr != current_ratr) {
- u32 ratr_value;
-
- ratr_value = target_ratr;
- ratr_value &= ~(RATE_ALL_OFDM_2SS);
- rtl92e_writel(dev, RATR0, ratr_value);
- rtl92e_writeb(dev, UFWP, 1);
- }
-
- } else {
- pra->ratr_state = DM_RATR_STA_MAX;
- }
-}
-
-static void _rtl92e_dm_init_bandwidth_autoswitch(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
- priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
- priv->rtllib->bandwidth_auto_switch.forced_tx_20MHz = false;
- priv->rtllib->bandwidth_auto_switch.bautoswitch_enable = false;
-}
-
-static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20 ||
- !priv->rtllib->bandwidth_auto_switch.bautoswitch_enable)
- return;
- if (!priv->rtllib->bandwidth_auto_switch.forced_tx_20MHz) {
- if (priv->undecorated_smoothed_pwdb <=
- priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
- priv->rtllib->bandwidth_auto_switch.forced_tx_20MHz = true;
- } else {
- if (priv->undecorated_smoothed_pwdb >=
- priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
- priv->rtllib->bandwidth_auto_switch.forced_tx_20MHz = false;
- }
-}
-
-static u32 OFDMSwingTable[OFDM_TABLE_LEN] = {
- 0x7f8001fe,
- 0x71c001c7,
- 0x65400195,
- 0x5a400169,
- 0x50800142,
- 0x47c0011f,
- 0x40000100,
- 0x390000e4,
- 0x32c000cb,
- 0x2d4000b5,
- 0x288000a2,
- 0x24000090,
- 0x20000080,
- 0x1c800072,
- 0x19800066,
- 0x26c0005b,
- 0x24400051,
- 0x12000048,
- 0x10000040
-};
-
-static u8 CCKSwingTable_Ch1_Ch13[CCK_TABLE_LEN][8] = {
- {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
- {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
- {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
- {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
- {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
- {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
- {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
- {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
- {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
- {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
- {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
- {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}
-};
-
-static u8 CCKSwingTable_Ch14[CCK_TABLE_LEN][8] = {
- {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
- {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
- {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
- {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
- {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
- {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
- {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
- {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
- {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
- {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
- {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
- {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}
-};
-
-#define Pw_Track_Flag 0x11d
-#define Tssi_Mea_Value 0x13c
-#define Tssi_Report_Value1 0x134
-#define Tssi_Report_Value2 0x13e
-#define FW_Busy_Flag 0x13f
-
-static void _rtl92e_dm_tx_update_tssi_weak_signal(struct net_device *dev)
-{
- struct r8192_priv *p = rtllib_priv(dev);
-
- if (p->rfa_txpowertrackingindex > 0) {
- p->rfa_txpowertrackingindex--;
- if (p->rfa_txpowertrackingindex_real > 4) {
- p->rfa_txpowertrackingindex_real--;
- rtl92e_set_bb_reg(dev,
- rOFDM0_XATxIQImbalance,
- bMaskDWord,
- dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]);
- }
- } else {
- rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
- bMaskDWord, dm_tx_bb_gain[4]);
- }
-}
-
-static void _rtl92e_dm_tx_update_tssi_strong_signal(struct net_device *dev)
-{
- struct r8192_priv *p = rtllib_priv(dev);
-
- if (p->rfa_txpowertrackingindex < (TX_BB_GAIN_TABLE_LEN - 1)) {
- p->rfa_txpowertrackingindex++;
- p->rfa_txpowertrackingindex_real++;
- rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
- bMaskDWord,
- dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]);
- } else {
- rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
- bMaskDWord,
- dm_tx_bb_gain[TX_BB_GAIN_TABLE_LEN - 1]);
- }
-}
-
-static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- bool viviflag = false;
- struct dcmd_txcmd tx_cmd;
- int i = 0, j = 0, k = 0;
- u8 tmp_report[5] = {0, 0, 0, 0, 0};
- u8 Pwr_Flag;
- u16 Avg_TSSI_Meas, tssi_13dBm, Avg_TSSI_Meas_from_driver = 0;
- u32 delta = 0;
-
- rtl92e_writeb(dev, Pw_Track_Flag, 0);
- rtl92e_writeb(dev, FW_Busy_Flag, 0);
- priv->rtllib->bdynamic_txpower_enable = false;
-
- for (j = 0; j <= 30; j++) {
- tx_cmd.op = TXCMD_SET_TX_PWR_TRACKING;
- tx_cmd.length = 4;
- tx_cmd.value = priv->pwr_track >> 24;
- rtl92e_send_cmd_pkt(dev, DESC_PACKET_TYPE_NORMAL, (u8 *)&tx_cmd,
- sizeof(struct dcmd_txcmd));
- mdelay(1);
- for (i = 0; i <= 30; i++) {
- Pwr_Flag = rtl92e_readb(dev, Pw_Track_Flag);
-
- if (Pwr_Flag == 0) {
- mdelay(1);
-
- if (priv->rtllib->rf_power_state != rf_on) {
- rtl92e_writeb(dev, Pw_Track_Flag, 0);
- rtl92e_writeb(dev, FW_Busy_Flag, 0);
- return;
- }
-
- continue;
- }
-
- Avg_TSSI_Meas = rtl92e_readw(dev, Tssi_Mea_Value);
-
- if (Avg_TSSI_Meas == 0) {
- rtl92e_writeb(dev, Pw_Track_Flag, 0);
- rtl92e_writeb(dev, FW_Busy_Flag, 0);
- return;
- }
-
- for (k = 0; k < 5; k++) {
- if (k != 4)
- tmp_report[k] = rtl92e_readb(dev,
- Tssi_Report_Value1 + k);
- else
- tmp_report[k] = rtl92e_readb(dev,
- Tssi_Report_Value2);
-
- if (tmp_report[k] <= 20) {
- viviflag = true;
- break;
- }
- }
-
- if (viviflag) {
- rtl92e_writeb(dev, Pw_Track_Flag, 0);
- viviflag = false;
- for (k = 0; k < 5; k++)
- tmp_report[k] = 0;
- break;
- }
-
- for (k = 0; k < 5; k++)
- Avg_TSSI_Meas_from_driver += tmp_report[k];
-
- Avg_TSSI_Meas_from_driver *= 100 / 5;
- tssi_13dBm = priv->tssi_13dBm;
-
- if (Avg_TSSI_Meas_from_driver > tssi_13dBm)
- delta = Avg_TSSI_Meas_from_driver - tssi_13dBm;
- else
- delta = tssi_13dBm - Avg_TSSI_Meas_from_driver;
-
- if (delta <= E_FOR_TX_POWER_TRACK) {
- priv->rtllib->bdynamic_txpower_enable = true;
- rtl92e_writeb(dev, Pw_Track_Flag, 0);
- rtl92e_writeb(dev, FW_Busy_Flag, 0);
- return;
- }
- if (Avg_TSSI_Meas_from_driver < tssi_13dBm - E_FOR_TX_POWER_TRACK)
- _rtl92e_dm_tx_update_tssi_weak_signal(dev);
- else
- _rtl92e_dm_tx_update_tssi_strong_signal(dev);
-
- priv->cck_present_attn_diff
- = priv->rfa_txpowertrackingindex_real - priv->rfa_txpowertracking_default;
-
- if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20)
- priv->cck_present_attn =
- priv->cck_present_attn_20m_def +
- priv->cck_present_attn_diff;
- else
- priv->cck_present_attn =
- priv->cck_present_attn_40m_def +
- priv->cck_present_attn_diff;
-
- if (priv->cck_present_attn > (CCK_TX_BB_GAIN_TABLE_LEN - 1))
- priv->cck_present_attn = CCK_TX_BB_GAIN_TABLE_LEN - 1;
- if (priv->cck_present_attn < 0)
- priv->cck_present_attn = 0;
-
- if (priv->cck_present_attn > -1 &&
- priv->cck_present_attn < CCK_TX_BB_GAIN_TABLE_LEN) {
- if (priv->rtllib->current_network.channel == 14 &&
- !priv->bcck_in_ch14) {
- priv->bcck_in_ch14 = true;
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- } else if (priv->rtllib->current_network.channel != 14 && priv->bcck_in_ch14) {
- priv->bcck_in_ch14 = false;
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- } else {
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- }
- }
-
- if (priv->cck_present_attn_diff <= -12 ||
- priv->cck_present_attn_diff >= 24) {
- priv->rtllib->bdynamic_txpower_enable = true;
- rtl92e_writeb(dev, Pw_Track_Flag, 0);
- rtl92e_writeb(dev, FW_Busy_Flag, 0);
- return;
- }
-
- rtl92e_writeb(dev, Pw_Track_Flag, 0);
- Avg_TSSI_Meas_from_driver = 0;
- for (k = 0; k < 5; k++)
- tmp_report[k] = 0;
- break;
- }
- rtl92e_writeb(dev, FW_Busy_Flag, 0);
- }
- priv->rtllib->bdynamic_txpower_enable = true;
- rtl92e_writeb(dev, Pw_Track_Flag, 0);
-}
-
-static void _rtl92e_dm_tx_power_tracking_cb_thermal(struct net_device *dev)
-{
-#define ThermalMeterVal 9
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 tmp_reg, tmp_cck;
- u8 tmp_ofdm_index, tmp_cck_index, tmp_cck_20m_index, tmp_cck_40m_index, tmpval;
- int i = 0, CCKSwingNeedUpdate = 0;
-
- if (!priv->tx_pwr_tracking_init) {
- tmp_reg = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance,
- bMaskDWord);
- for (i = 0; i < OFDM_TABLE_LEN; i++) {
- if (tmp_reg == OFDMSwingTable[i])
- priv->ofdm_index[0] = i;
- }
-
- tmp_cck = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, bMaskByte2);
- for (i = 0; i < CCK_TABLE_LEN; i++) {
- if (tmp_cck == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
- priv->cck_index = i;
- break;
- }
- }
- priv->tx_pwr_tracking_init = true;
- return;
- }
-
- tmp_reg = rtl92e_get_rf_reg(dev, RF90_PATH_A, 0x12, 0x078);
- if (tmp_reg < 3 || tmp_reg > 13)
- return;
- if (tmp_reg >= 12)
- tmp_reg = 12;
- priv->thermal_meter[0] = ThermalMeterVal;
- priv->thermal_meter[1] = ThermalMeterVal;
-
- if (priv->thermal_meter[0] >= (u8)tmp_reg) {
- tmp_ofdm_index = 6 + (priv->thermal_meter[0] - (u8)tmp_reg);
- tmp_cck_20m_index = tmp_ofdm_index;
- tmp_cck_40m_index = tmp_cck_20m_index - 6;
- if (tmp_ofdm_index >= OFDM_TABLE_LEN)
- tmp_ofdm_index = OFDM_TABLE_LEN - 1;
- if (tmp_cck_20m_index >= CCK_TABLE_LEN)
- tmp_cck_20m_index = CCK_TABLE_LEN - 1;
- if (tmp_cck_40m_index >= CCK_TABLE_LEN)
- tmp_cck_40m_index = CCK_TABLE_LEN - 1;
- } else {
- tmpval = (u8)tmp_reg - priv->thermal_meter[0];
- if (tmpval >= 6) {
- tmp_ofdm_index = 0;
- tmp_cck_20m_index = 0;
- } else {
- tmp_ofdm_index = 6 - tmpval;
- tmp_cck_20m_index = 6 - tmpval;
- }
- tmp_cck_40m_index = 0;
- }
- if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
- tmp_cck_index = tmp_cck_40m_index;
- else
- tmp_cck_index = tmp_cck_20m_index;
-
- priv->rec_cck_20m_idx = tmp_cck_20m_index;
- priv->rec_cck_40m_idx = tmp_cck_40m_index;
-
- if (priv->rtllib->current_network.channel == 14 &&
- !priv->bcck_in_ch14) {
- priv->bcck_in_ch14 = true;
- CCKSwingNeedUpdate = 1;
- } else if (priv->rtllib->current_network.channel != 14 &&
- priv->bcck_in_ch14) {
- priv->bcck_in_ch14 = false;
- CCKSwingNeedUpdate = 1;
- }
-
- if (priv->cck_index != tmp_cck_index) {
- priv->cck_index = tmp_cck_index;
- CCKSwingNeedUpdate = 1;
- }
-
- if (CCKSwingNeedUpdate)
- rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- if (priv->ofdm_index[0] != tmp_ofdm_index) {
- priv->ofdm_index[0] = tmp_ofdm_index;
- rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
- OFDMSwingTable[priv->ofdm_index[0]]);
- }
- priv->txpower_count = 0;
-}
-
-void rtl92e_dm_txpower_tracking_wq(void *data)
-{
- struct r8192_priv *priv = container_of_dwork_rsl(data,
- struct r8192_priv, txpower_tracking_wq);
- struct net_device *dev = priv->rtllib->dev;
-
- if (priv->ic_cut >= IC_VersionCut_D)
- _rtl92e_dm_tx_power_tracking_callback_tssi(dev);
- else
- _rtl92e_dm_tx_power_tracking_cb_thermal(dev);
-}
-
-static void _rtl92e_dm_initialize_tx_power_tracking_tssi(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- priv->btxpower_tracking = true;
- priv->txpower_count = 0;
- priv->tx_pwr_tracking_init = false;
-}
-
-static void _rtl92e_dm_init_tx_power_tracking_thermal(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->rtllib->FwRWRF)
- priv->btxpower_tracking = true;
- else
- priv->btxpower_tracking = false;
- priv->txpower_count = 0;
- priv->tx_pwr_tracking_init = false;
-}
-
-void rtl92e_dm_init_txpower_tracking(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->ic_cut >= IC_VersionCut_D)
- _rtl92e_dm_initialize_tx_power_tracking_tssi(dev);
- else
- _rtl92e_dm_init_tx_power_tracking_thermal(dev);
-}
-
-static void _rtl92e_dm_check_tx_power_tracking_tssi(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- static u32 tx_power_track_counter;
-
- if (rtl92e_readb(dev, 0x11e) == 1)
- return;
- if (!priv->btxpower_tracking)
- return;
- tx_power_track_counter++;
-
- if (tx_power_track_counter >= 180) {
- schedule_delayed_work(&priv->txpower_tracking_wq, 0);
- tx_power_track_counter = 0;
- }
-}
-
-static void _rtl92e_dm_check_tx_power_tracking_thermal(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- static u8 TM_Trigger;
- u8 TxPowerCheckCnt = 0;
-
- TxPowerCheckCnt = 2;
- if (!priv->btxpower_tracking)
- return;
-
- if (priv->txpower_count <= TxPowerCheckCnt) {
- priv->txpower_count++;
- return;
- }
-
- if (!TM_Trigger) {
- rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
- rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
- rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
- rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
- TM_Trigger = 1;
- return;
- }
- netdev_info(dev, "===============>Schedule TxPowerTrackingWorkItem\n");
- schedule_delayed_work(&priv->txpower_tracking_wq, 0);
- TM_Trigger = 0;
-}
-
-static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->ic_cut >= IC_VersionCut_D)
- _rtl92e_dm_check_tx_power_tracking_tssi(dev);
- else
- _rtl92e_dm_check_tx_power_tracking_thermal(dev);
-}
-
-static void _rtl92e_dm_cck_tx_power_adjust_tssi(struct net_device *dev,
- bool bInCH14)
-{
- u32 TempVal;
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 attenuation = priv->cck_present_attn;
-
- TempVal = 0;
- if (!bInCH14) {
- TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][0] +
- (dm_cck_tx_bb_gain[attenuation][1] << 8));
-
- rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
- TempVal = (u32)((dm_cck_tx_bb_gain[attenuation][2]) +
- (dm_cck_tx_bb_gain[attenuation][3] << 8) +
- (dm_cck_tx_bb_gain[attenuation][4] << 16) +
- (dm_cck_tx_bb_gain[attenuation][5] << 24));
- rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
- TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][6] +
- (dm_cck_tx_bb_gain[attenuation][7] << 8));
-
- rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
- } else {
- TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][0]) +
- (dm_cck_tx_bb_gain_ch14[attenuation][1] << 8));
-
- rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
- TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][2]) +
- (dm_cck_tx_bb_gain_ch14[attenuation][3] << 8) +
- (dm_cck_tx_bb_gain_ch14[attenuation][4] << 16) +
- (dm_cck_tx_bb_gain_ch14[attenuation][5] << 24));
- rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
- TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][6]) +
- (dm_cck_tx_bb_gain_ch14[attenuation][7] << 8));
-
- rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
- }
-}
-
-static void _rtl92e_dm_cck_tx_power_adjust_thermal_meter(struct net_device *dev,
- bool bInCH14)
-{
- u32 TempVal;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- TempVal = 0;
- if (!bInCH14) {
- TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][0] +
- (CCKSwingTable_Ch1_Ch13[priv->cck_index][1] << 8);
- rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
- TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][2] +
- (CCKSwingTable_Ch1_Ch13[priv->cck_index][3] << 8) +
- (CCKSwingTable_Ch1_Ch13[priv->cck_index][4] << 16) +
- (CCKSwingTable_Ch1_Ch13[priv->cck_index][5] << 24);
- rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
- TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][6] +
- (CCKSwingTable_Ch1_Ch13[priv->cck_index][7] << 8);
-
- rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
- } else {
- TempVal = CCKSwingTable_Ch14[priv->cck_index][0] +
- (CCKSwingTable_Ch14[priv->cck_index][1] << 8);
-
- rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
- TempVal = CCKSwingTable_Ch14[priv->cck_index][2] +
- (CCKSwingTable_Ch14[priv->cck_index][3] << 8) +
- (CCKSwingTable_Ch14[priv->cck_index][4] << 16) +
- (CCKSwingTable_Ch14[priv->cck_index][5] << 24);
- rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
- TempVal = CCKSwingTable_Ch14[priv->cck_index][6] +
- (CCKSwingTable_Ch14[priv->cck_index][7] << 8);
-
- rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
- }
-}
-
-void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->ic_cut >= IC_VersionCut_D)
- _rtl92e_dm_cck_tx_power_adjust_tssi(dev, binch14);
- else
- _rtl92e_dm_cck_tx_power_adjust_thermal_meter(dev, binch14);
-}
-
-static void _rtl92e_dm_dig_init(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT;
- dm_digtable.pre_sta_connect_state = DIG_STA_DISCONNECT;
-
- dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW;
- dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH;
-
- dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
- dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
-
- dm_digtable.rssi_val = 50;
- dm_digtable.backoff_val = DM_DIG_BACKOFF;
- dm_digtable.rx_gain_range_max = DM_DIG_MAX;
- if (priv->customer_id == RT_CID_819X_NETCORE)
- dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
- else
- dm_digtable.rx_gain_range_min = DM_DIG_MIN;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm()
- *
- * Overview: Driver monitor RSSI and False Alarm to change initial gain.
- Only change initial gain during link in progress.
- *
- * Input: IN PADAPTER pAdapter
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 03/04/2009 hpfan Create Version 0.
- *
- ******************************************************************************/
-
-static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 i;
- static u8 fw_dig;
-
- if (fw_dig <= 3) {
- for (i = 0; i < 3; i++)
- rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
- fw_dig++;
- }
-
- if (priv->rtllib->link_state == MAC80211_LINKED)
- dm_digtable.cur_sta_connect_state = DIG_STA_CONNECT;
- else
- dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT;
-
- dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
- _rtl92e_dm_initial_gain(dev);
- _rtl92e_dm_pd_th(dev);
- _rtl92e_dm_cs_ratio(dev);
- dm_digtable.pre_sta_connect_state = dm_digtable.cur_sta_connect_state;
-}
-
-static void _rtl92e_dm_initial_gain(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 initial_gain = 0;
- static u8 initialized, force_write;
-
- if (rtllib_act_scanning(priv->rtllib, true)) {
- force_write = 1;
- return;
- }
-
- if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
- if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
- long gain_range = dm_digtable.rssi_val + 10 -
- dm_digtable.backoff_val;
- gain_range = clamp_t(long, gain_range,
- dm_digtable.rx_gain_range_min,
- dm_digtable.rx_gain_range_max);
- dm_digtable.cur_ig_value = gain_range;
- } else {
- if (dm_digtable.cur_ig_value == 0)
- dm_digtable.cur_ig_value = priv->def_initial_gain[0];
- else
- dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
- }
- } else {
- dm_digtable.cur_ig_value = priv->def_initial_gain[0];
- dm_digtable.pre_ig_value = 0;
- }
-
- if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1))
- force_write = 1;
-
- if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
- || !initialized || force_write) {
- initial_gain = dm_digtable.cur_ig_value;
- rtl92e_writeb(dev, rOFDM0_XAAGCCore1, initial_gain);
- rtl92e_writeb(dev, rOFDM0_XBAGCCore1, initial_gain);
- rtl92e_writeb(dev, rOFDM0_XCAGCCore1, initial_gain);
- rtl92e_writeb(dev, rOFDM0_XDAGCCore1, initial_gain);
- dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
- initialized = 1;
- force_write = 0;
- }
-}
-
-static void _rtl92e_dm_pd_th(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- static u8 initialized, force_write;
-
- if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
- if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
- if (dm_digtable.rssi_val >=
- dm_digtable.rssi_high_power_highthresh)
- dm_digtable.curpd_thstate =
- DIG_PD_AT_HIGH_POWER;
- else if (dm_digtable.rssi_val <=
- dm_digtable.rssi_low_thresh)
- dm_digtable.curpd_thstate =
- DIG_PD_AT_LOW_POWER;
- else if ((dm_digtable.rssi_val >=
- dm_digtable.rssi_high_thresh) &&
- (dm_digtable.rssi_val <
- dm_digtable.rssi_high_power_lowthresh))
- dm_digtable.curpd_thstate =
- DIG_PD_AT_NORMAL_POWER;
- else
- dm_digtable.curpd_thstate =
- dm_digtable.prepd_thstate;
- } else {
- dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
- }
- } else {
- dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
- }
-
- if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
- (initialized <= 3) || force_write) {
- if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
- if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
- rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x00);
- else
- rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42);
- } else if (dm_digtable.curpd_thstate ==
- DIG_PD_AT_NORMAL_POWER) {
- if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
- rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x20);
- else
- rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
- } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
- if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
- rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x10);
- else
- rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43);
- }
- dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
- if (initialized <= 3)
- initialized++;
- force_write = 0;
- }
-}
-
-static void _rtl92e_dm_cs_ratio(struct net_device *dev)
-{
- static u8 initialized, force_write;
-
- if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
- if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
- if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
- dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
- else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
- dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
- else
- dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
- } else {
- dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
- }
- } else {
- dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
- }
-
- if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
- !initialized || force_write) {
- if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
- rtl92e_writeb(dev, 0xa0a, 0x08);
- else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
- rtl92e_writeb(dev, 0xa0a, 0xcd);
- dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
- initialized = 1;
- force_write = 0;
- }
-}
-
-void rtl92e_dm_init_edca_turbo(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- priv->bcurrent_turbo_EDCA = false;
- priv->rtllib->bis_any_nonbepkts = false;
- priv->bis_cur_rdlstate = false;
-}
-
-static void _rtl92e_dm_check_edca_turbo(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_hi_throughput *ht_info = priv->rtllib->ht_info;
-
- static unsigned long lastTxOkCnt;
- static unsigned long lastRxOkCnt;
- unsigned long curTxOkCnt = 0;
- unsigned long curRxOkCnt = 0;
-
- if (priv->rtllib->link_state != MAC80211_LINKED)
- goto dm_CheckEdcaTurbo_EXIT;
- if (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_DISABLE_EDCA_TURBO)
- goto dm_CheckEdcaTurbo_EXIT;
-
- if (!priv->rtllib->bis_any_nonbepkts) {
- curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
- curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
- if (ht_info->iot_action & HT_IOT_ACT_EDCA_BIAS_ON_RX) {
- if (curTxOkCnt > 4 * curRxOkCnt) {
- if (priv->bis_cur_rdlstate ||
- !priv->bcurrent_turbo_EDCA) {
- rtl92e_writel(dev, EDCAPARA_BE,
- edca_setting_UL[ht_info->iot_peer]);
- priv->bis_cur_rdlstate = false;
- }
- } else {
- if (!priv->bis_cur_rdlstate ||
- !priv->bcurrent_turbo_EDCA) {
- if (priv->rtllib->mode == WIRELESS_MODE_G)
- rtl92e_writel(dev, EDCAPARA_BE,
- edca_setting_DL_GMode[ht_info->iot_peer]);
- else
- rtl92e_writel(dev, EDCAPARA_BE,
- edca_setting_DL[ht_info->iot_peer]);
- priv->bis_cur_rdlstate = true;
- }
- }
- priv->bcurrent_turbo_EDCA = true;
- } else {
- if (curRxOkCnt > 4 * curTxOkCnt) {
- if (!priv->bis_cur_rdlstate ||
- !priv->bcurrent_turbo_EDCA) {
- if (priv->rtllib->mode == WIRELESS_MODE_G)
- rtl92e_writel(dev, EDCAPARA_BE,
- edca_setting_DL_GMode[ht_info->iot_peer]);
- else
- rtl92e_writel(dev, EDCAPARA_BE,
- edca_setting_DL[ht_info->iot_peer]);
- priv->bis_cur_rdlstate = true;
- }
- } else {
- if (priv->bis_cur_rdlstate ||
- !priv->bcurrent_turbo_EDCA) {
- rtl92e_writel(dev, EDCAPARA_BE,
- edca_setting_UL[ht_info->iot_peer]);
- priv->bis_cur_rdlstate = false;
- }
- }
-
- priv->bcurrent_turbo_EDCA = true;
- }
- } else {
- if (priv->bcurrent_turbo_EDCA) {
- u8 tmp = AC0_BE;
-
- priv->rtllib->set_hw_reg_handler(dev, HW_VAR_AC_PARAM,
- (u8 *)(&tmp));
- priv->bcurrent_turbo_EDCA = false;
- }
- }
-
-dm_CheckEdcaTurbo_EXIT:
- priv->rtllib->bis_any_nonbepkts = false;
- lastTxOkCnt = priv->stats.txbytesunicast;
- lastRxOkCnt = priv->stats.rxbytesunicast;
-}
-
-static void _rtl92e_dm_init_cts_to_self(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
-
- priv->rtllib->bCTSToSelfEnable = true;
-}
-
-static void _rtl92e_dm_cts_to_self(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
- struct rt_hi_throughput *ht_info = priv->rtllib->ht_info;
- static unsigned long lastTxOkCnt;
- static unsigned long lastRxOkCnt;
- unsigned long curTxOkCnt = 0;
- unsigned long curRxOkCnt = 0;
-
- if (!priv->rtllib->bCTSToSelfEnable) {
- ht_info->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF;
- return;
- }
- if (ht_info->iot_peer == HT_IOT_PEER_BROADCOM) {
- curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
- curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
- if (curRxOkCnt > 4 * curTxOkCnt)
- ht_info->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF;
- else
- ht_info->iot_action |= HT_IOT_ACT_FORCED_CTS2SELF;
-
- lastTxOkCnt = priv->stats.txbytesunicast;
- lastRxOkCnt = priv->stats.rxbytesunicast;
- }
-}
-
-static void _rtl92e_dm_check_rf_ctrl_gpio(void *data)
-{
- struct r8192_priv *priv = container_of_dwork_rsl(data,
- struct r8192_priv, gpio_change_rf_wq);
- struct net_device *dev = priv->rtllib->dev;
- u8 tmp1byte;
- enum rt_rf_power_state rf_power_state_to_set;
- bool bActuallySet = false;
-
- if ((priv->up_first_time == 1) || (priv->being_init_adapter))
- return;
-
- if (priv->bfirst_after_down)
- return;
-
- tmp1byte = rtl92e_readb(dev, GPI);
-
- rf_power_state_to_set = (tmp1byte & BIT(1)) ? rf_on : rf_off;
-
- if (priv->hw_radio_off && (rf_power_state_to_set == rf_on)) {
- netdev_info(dev, "gpiochangeRF - HW Radio ON\n");
- priv->hw_radio_off = false;
- bActuallySet = true;
- } else if (!priv->hw_radio_off && (rf_power_state_to_set == rf_off)) {
- netdev_info(dev, "gpiochangeRF - HW Radio OFF\n");
- priv->hw_radio_off = true;
- bActuallySet = true;
- }
-
- if (bActuallySet) {
- mdelay(1000);
- priv->hw_rf_off_action = 1;
- rtl92e_set_rf_state(dev, rf_power_state_to_set, RF_CHANGE_BY_HW);
- }
-}
-
-void rtl92e_dm_rf_pathcheck_wq(void *data)
-{
- struct r8192_priv *priv = container_of_dwork_rsl(data,
- struct r8192_priv,
- rfpath_check_wq);
- struct net_device *dev = priv->rtllib->dev;
- u8 rfpath, i;
-
- rfpath = rtl92e_readb(dev, 0xc04);
-
- for (i = 0; i < RF90_PATH_MAX; i++) {
- if (rfpath & (0x01 << i))
- priv->brfpath_rxenable[i] = true;
- else
- priv->brfpath_rxenable[i] = false;
- }
- if (!dm_rx_path_sel_table.enable)
- return;
-
- _rtl92e_dm_rx_path_sel_byrssi(dev);
-}
-
-static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev)
-{
- u8 i;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- dm_rx_path_sel_table.enable = 1;
- dm_rx_path_sel_table.ss_th_low = RX_PATH_SEL_SS_TH_LOW;
- dm_rx_path_sel_table.diff_th = RX_PATH_SEL_DIFF_TH;
- if (priv->customer_id == RT_CID_819X_NETCORE)
- dm_rx_path_sel_table.cck_method = CCK_Rx_Version_2;
- else
- dm_rx_path_sel_table.cck_method = CCK_Rx_Version_1;
- dm_rx_path_sel_table.disabled_rf = 0;
- for (i = 0; i < 4; i++) {
- dm_rx_path_sel_table.rf_rssi[i] = 50;
- dm_rx_path_sel_table.cck_pwdb_sta[i] = -64;
- dm_rx_path_sel_table.rf_enable_rssi_th[i] = 100;
- }
-}
-
-#define PWDB_IN_RANGE ((cur_cck_pwdb < tmp_cck_max_pwdb) && \
- (cur_cck_pwdb > tmp_cck_sec_pwdb))
-
-static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u8 i, max_rssi_index = 0, min_rssi_index = 0;
- u8 sec_rssi_index = 0, rf_num = 0;
- u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
- u8 cck_default_Rx = 0x2;
- u8 cck_optional_Rx = 0x3;
- long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
- u8 cck_rx_ver2_max_index = 0;
- u8 cck_rx_ver2_sec_index = 0;
- u8 cur_rf_rssi;
- long cur_cck_pwdb;
- static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
- u8 update_cck_rx_path;
-
- if (!cck_Rx_Path_initialized) {
- dm_rx_path_sel_table.cck_rx_path = (rtl92e_readb(dev, 0xa07) & 0xf);
- cck_Rx_Path_initialized = 1;
- }
-
- dm_rx_path_sel_table.disabled_rf = 0xf;
- dm_rx_path_sel_table.disabled_rf &= ~(rtl92e_readb(dev, 0xc04));
-
- if (priv->rtllib->mode == WIRELESS_MODE_B)
- dm_rx_path_sel_table.cck_method = CCK_Rx_Version_2;
-
- for (i = 0; i < RF90_PATH_MAX; i++) {
- dm_rx_path_sel_table.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
-
- if (!priv->brfpath_rxenable[i])
- continue;
-
- rf_num++;
- cur_rf_rssi = dm_rx_path_sel_table.rf_rssi[i];
-
- if (rf_num == 1) {
- max_rssi_index = min_rssi_index = sec_rssi_index = i;
- tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
- } else if (rf_num == 2) {
- if (cur_rf_rssi >= tmp_max_rssi) {
- tmp_max_rssi = cur_rf_rssi;
- max_rssi_index = i;
- } else {
- tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
- sec_rssi_index = min_rssi_index = i;
- }
- } else {
- if (cur_rf_rssi > tmp_max_rssi) {
- tmp_sec_rssi = tmp_max_rssi;
- sec_rssi_index = max_rssi_index;
- tmp_max_rssi = cur_rf_rssi;
- max_rssi_index = i;
- } else if (cur_rf_rssi == tmp_max_rssi) {
- tmp_sec_rssi = cur_rf_rssi;
- sec_rssi_index = i;
- } else if ((cur_rf_rssi < tmp_max_rssi) &&
- (cur_rf_rssi > tmp_sec_rssi)) {
- tmp_sec_rssi = cur_rf_rssi;
- sec_rssi_index = i;
- } else if (cur_rf_rssi == tmp_sec_rssi) {
- if (tmp_sec_rssi == tmp_min_rssi) {
- tmp_sec_rssi = cur_rf_rssi;
- sec_rssi_index = i;
- }
- } else if ((cur_rf_rssi < tmp_sec_rssi) &&
- (cur_rf_rssi > tmp_min_rssi)) {
- ;
- } else if (cur_rf_rssi == tmp_min_rssi) {
- if (tmp_sec_rssi == tmp_min_rssi) {
- tmp_min_rssi = cur_rf_rssi;
- min_rssi_index = i;
- }
- } else if (cur_rf_rssi < tmp_min_rssi) {
- tmp_min_rssi = cur_rf_rssi;
- min_rssi_index = i;
- }
- }
- }
-
- rf_num = 0;
- if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_2) {
- for (i = 0; i < RF90_PATH_MAX; i++) {
- if (!priv->brfpath_rxenable[i])
- continue;
-
- rf_num++;
- cur_cck_pwdb = dm_rx_path_sel_table.cck_pwdb_sta[i];
-
- if (rf_num == 1) {
- cck_rx_ver2_max_index = i;
- cck_rx_ver2_sec_index = i;
- tmp_cck_max_pwdb = cur_cck_pwdb;
- tmp_cck_min_pwdb = cur_cck_pwdb;
- tmp_cck_sec_pwdb = cur_cck_pwdb;
- } else if (rf_num == 2) {
- if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
- tmp_cck_max_pwdb = cur_cck_pwdb;
- cck_rx_ver2_max_index = i;
- } else {
- tmp_cck_sec_pwdb = cur_cck_pwdb;
- tmp_cck_min_pwdb = cur_cck_pwdb;
- cck_rx_ver2_sec_index = i;
- }
- } else {
- if (cur_cck_pwdb > tmp_cck_max_pwdb) {
- tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
- cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
- tmp_cck_max_pwdb = cur_cck_pwdb;
- cck_rx_ver2_max_index = i;
- } else if (cur_cck_pwdb == tmp_cck_max_pwdb) {
- tmp_cck_sec_pwdb = cur_cck_pwdb;
- cck_rx_ver2_sec_index = i;
- } else if (PWDB_IN_RANGE) {
- tmp_cck_sec_pwdb = cur_cck_pwdb;
- cck_rx_ver2_sec_index = i;
- } else if (cur_cck_pwdb == tmp_cck_sec_pwdb) {
- if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
- tmp_cck_sec_pwdb = cur_cck_pwdb;
- cck_rx_ver2_sec_index = i;
- }
- } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) &&
- (cur_cck_pwdb > tmp_cck_min_pwdb)) {
- ;
- } else if (cur_cck_pwdb == tmp_cck_min_pwdb) {
- if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
- tmp_cck_min_pwdb = cur_cck_pwdb;
- } else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
- tmp_cck_min_pwdb = cur_cck_pwdb;
- }
- }
- }
- }
-
- update_cck_rx_path = 0;
- if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_2) {
- cck_default_Rx = cck_rx_ver2_max_index;
- cck_optional_Rx = cck_rx_ver2_sec_index;
- if (tmp_cck_max_pwdb != -64)
- update_cck_rx_path = 1;
- }
-
- if (tmp_min_rssi < dm_rx_path_sel_table.ss_th_low && disabled_rf_cnt < 2) {
- if ((tmp_max_rssi - tmp_min_rssi) >=
- dm_rx_path_sel_table.diff_th) {
- dm_rx_path_sel_table.rf_enable_rssi_th[min_rssi_index] =
- tmp_max_rssi + 5;
- rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable,
- 0x1 << min_rssi_index, 0x0);
- rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable,
- 0x1 << min_rssi_index, 0x0);
- disabled_rf_cnt++;
- }
- if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_1) {
- cck_default_Rx = max_rssi_index;
- cck_optional_Rx = sec_rssi_index;
- if (tmp_max_rssi)
- update_cck_rx_path = 1;
- }
- }
-
- if (update_cck_rx_path) {
- dm_rx_path_sel_table.cck_rx_path = (cck_default_Rx << 2) |
- (cck_optional_Rx);
- rtl92e_set_bb_reg(dev, rCCK0_AFESetting, 0x0f000000,
- dm_rx_path_sel_table.cck_rx_path);
- }
-
- if (dm_rx_path_sel_table.disabled_rf) {
- for (i = 0; i < 4; i++) {
- if ((dm_rx_path_sel_table.disabled_rf >> i) & 0x1) {
- if (tmp_max_rssi >=
- dm_rx_path_sel_table.rf_enable_rssi_th[i]) {
- rtl92e_set_bb_reg(dev,
- rOFDM0_TRxPathEnable,
- 0x1 << i, 0x1);
- rtl92e_set_bb_reg(dev,
- rOFDM1_TRxPathEnable,
- 0x1 << i, 0x1);
- dm_rx_path_sel_table.rf_enable_rssi_th[i] = 100;
- disabled_rf_cnt--;
- }
- }
- }
- }
-}
-
-static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- schedule_delayed_work(&priv->rfpath_check_wq, 0);
-}
-
-static void _rtl92e_dm_init_fsync(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- priv->rtllib->fsync_time_interval = 500;
- priv->rtllib->fsync_rate_bitmap = 0x0f000800;
- priv->rtllib->fsync_rssi_threshold = 30;
- priv->rtllib->bfsync_enable = false;
- priv->rtllib->fsync_multiple_timeinterval = 3;
- priv->rtllib->fsync_firstdiff_ratethreshold = 100;
- priv->rtllib->fsync_seconddiff_ratethreshold = 200;
- priv->rtllib->fsync_state = DEFAULT_FSYNC;
-
- timer_setup(&priv->fsync_timer, _rtl92e_dm_fsync_timer_callback, 0);
-}
-
-static void _rtl92e_dm_deinit_fsync(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- del_timer_sync(&priv->fsync_timer);
-}
-
-static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t)
-{
- struct r8192_priv *priv = from_timer(priv, t, fsync_timer);
- struct net_device *dev = priv->rtllib->dev;
- u32 rate_index, rate_count = 0, rate_count_diff = 0;
- bool bSwitchFromCountDiff = false;
- bool bDoubleTimeInterval = false;
-
- if (priv->rtllib->link_state == MAC80211_LINKED &&
- priv->rtllib->bfsync_enable &&
- (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_CDD_FSYNC)) {
- u32 rate_bitmap;
-
- for (rate_index = 0; rate_index <= 27; rate_index++) {
- rate_bitmap = 1 << rate_index;
- if (priv->rtllib->fsync_rate_bitmap & rate_bitmap)
- rate_count +=
- priv->stats.received_rate_histogram[1]
- [rate_index];
- }
-
- if (rate_count < priv->rate_record)
- rate_count_diff = 0xffffffff - rate_count +
- priv->rate_record;
- else
- rate_count_diff = rate_count - priv->rate_record;
- if (rate_count_diff < priv->rate_count_diff_rec) {
- u32 DiffNum = priv->rate_count_diff_rec -
- rate_count_diff;
- if (DiffNum >=
- priv->rtllib->fsync_seconddiff_ratethreshold)
- priv->continue_diff_count++;
- else
- priv->continue_diff_count = 0;
-
- if (priv->continue_diff_count >= 2) {
- bSwitchFromCountDiff = true;
- priv->continue_diff_count = 0;
- }
- } else {
- priv->continue_diff_count = 0;
- }
-
- if (rate_count_diff <=
- priv->rtllib->fsync_firstdiff_ratethreshold) {
- bSwitchFromCountDiff = true;
- priv->continue_diff_count = 0;
- }
- priv->rate_record = rate_count;
- priv->rate_count_diff_rec = rate_count_diff;
- if (priv->undecorated_smoothed_pwdb >
- priv->rtllib->fsync_rssi_threshold &&
- bSwitchFromCountDiff) {
- bDoubleTimeInterval = true;
- priv->bswitch_fsync = !priv->bswitch_fsync;
- if (priv->bswitch_fsync) {
- rtl92e_writeb(dev, 0xC36, 0x1c);
- rtl92e_writeb(dev, 0xC3e, 0x90);
- } else {
- rtl92e_writeb(dev, 0xC36, 0x5c);
- rtl92e_writeb(dev, 0xC3e, 0x96);
- }
- } else if (priv->undecorated_smoothed_pwdb <=
- priv->rtllib->fsync_rssi_threshold) {
- if (priv->bswitch_fsync) {
- priv->bswitch_fsync = false;
- rtl92e_writeb(dev, 0xC36, 0x5c);
- rtl92e_writeb(dev, 0xC3e, 0x96);
- }
- }
- if (bDoubleTimeInterval) {
- if (timer_pending(&priv->fsync_timer))
- del_timer_sync(&priv->fsync_timer);
- priv->fsync_timer.expires = jiffies +
- msecs_to_jiffies(priv->rtllib->fsync_time_interval *
- priv->rtllib->fsync_multiple_timeinterval);
- add_timer(&priv->fsync_timer);
- } else {
- if (timer_pending(&priv->fsync_timer))
- del_timer_sync(&priv->fsync_timer);
- priv->fsync_timer.expires = jiffies +
- msecs_to_jiffies(priv->rtllib->fsync_time_interval);
- add_timer(&priv->fsync_timer);
- }
- } else {
- if (priv->bswitch_fsync) {
- priv->bswitch_fsync = false;
- rtl92e_writeb(dev, 0xC36, 0x5c);
- rtl92e_writeb(dev, 0xC3e, 0x96);
- }
- priv->continue_diff_count = 0;
- rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
- }
-}
-
-static void _rtl92e_dm_start_hw_fsync(struct net_device *dev)
-{
- u8 rf_timing = 0x77;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cf);
- priv->rtllib->set_hw_reg_handler(dev, HW_VAR_RF_TIMING,
- (u8 *)(&rf_timing));
- rtl92e_writeb(dev, 0xc3b, 0x41);
-}
-
-static void _rtl92e_dm_end_hw_fsync(struct net_device *dev)
-{
- u8 rf_timing = 0xaa;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
- priv->rtllib->set_hw_reg_handler(dev, HW_VAR_RF_TIMING, (u8 *)
- (&rf_timing));
- rtl92e_writeb(dev, 0xc3b, 0x49);
-}
-
-static void _rtl92e_dm_end_sw_fsync(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- del_timer_sync(&(priv->fsync_timer));
-
- if (priv->bswitch_fsync) {
- priv->bswitch_fsync = false;
-
- rtl92e_writeb(dev, 0xC36, 0x5c);
-
- rtl92e_writeb(dev, 0xC3e, 0x96);
- }
-
- priv->continue_diff_count = 0;
- rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
-}
-
-static void _rtl92e_dm_start_sw_fsync(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 rate_index;
- u32 rate_bitmap;
-
- priv->rate_record = 0;
- priv->continue_diff_count = 0;
- priv->rate_count_diff_rec = 0;
- priv->bswitch_fsync = false;
-
- if (priv->rtllib->mode == WIRELESS_MODE_N_24G) {
- priv->rtllib->fsync_firstdiff_ratethreshold = 600;
- priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff;
- } else {
- priv->rtllib->fsync_firstdiff_ratethreshold = 200;
- priv->rtllib->fsync_seconddiff_ratethreshold = 200;
- }
- for (rate_index = 0; rate_index <= 27; rate_index++) {
- rate_bitmap = 1 << rate_index;
- if (priv->rtllib->fsync_rate_bitmap & rate_bitmap)
- priv->rate_record +=
- priv->stats.received_rate_histogram[1]
- [rate_index];
- }
- if (timer_pending(&priv->fsync_timer))
- del_timer_sync(&priv->fsync_timer);
- priv->fsync_timer.expires = jiffies +
- msecs_to_jiffies(priv->rtllib->fsync_time_interval);
- add_timer(&priv->fsync_timer);
-
- rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cd);
-}
-
-static void _rtl92e_dm_check_fsync(struct net_device *dev)
-{
-#define RegC38_Default 0
-#define RegC38_NonFsync_Other_AP 1
-#define RegC38_Fsync_AP_BCM 2
- struct r8192_priv *priv = rtllib_priv(dev);
- static u8 reg_c38_State = RegC38_Default;
-
- if (priv->rtllib->link_state == MAC80211_LINKED &&
- priv->rtllib->ht_info->iot_peer == HT_IOT_PEER_BROADCOM) {
- if (priv->rtllib->bfsync_enable == 0) {
- switch (priv->rtllib->fsync_state) {
- case DEFAULT_FSYNC:
- _rtl92e_dm_start_hw_fsync(dev);
- priv->rtllib->fsync_state = HW_FSYNC;
- break;
- case SW_FSYNC:
- _rtl92e_dm_end_sw_fsync(dev);
- _rtl92e_dm_start_hw_fsync(dev);
- priv->rtllib->fsync_state = HW_FSYNC;
- break;
- default:
- break;
- }
- } else {
- switch (priv->rtllib->fsync_state) {
- case DEFAULT_FSYNC:
- _rtl92e_dm_start_sw_fsync(dev);
- priv->rtllib->fsync_state = SW_FSYNC;
- break;
- case HW_FSYNC:
- _rtl92e_dm_end_hw_fsync(dev);
- _rtl92e_dm_start_sw_fsync(dev);
- priv->rtllib->fsync_state = SW_FSYNC;
- break;
- default:
- break;
- }
- }
- if (reg_c38_State != RegC38_Fsync_AP_BCM) {
- rtl92e_writeb(dev, rOFDM0_RxDetector3, 0x95);
-
- reg_c38_State = RegC38_Fsync_AP_BCM;
- }
- } else {
- switch (priv->rtllib->fsync_state) {
- case HW_FSYNC:
- _rtl92e_dm_end_hw_fsync(dev);
- priv->rtllib->fsync_state = DEFAULT_FSYNC;
- break;
- case SW_FSYNC:
- _rtl92e_dm_end_sw_fsync(dev);
- priv->rtllib->fsync_state = DEFAULT_FSYNC;
- break;
- default:
- break;
- }
-
- if (priv->rtllib->link_state == MAC80211_LINKED) {
- if (priv->undecorated_smoothed_pwdb <=
- REG_C38_TH) {
- if (reg_c38_State !=
- RegC38_NonFsync_Other_AP) {
- rtl92e_writeb(dev,
- rOFDM0_RxDetector3,
- 0x90);
-
- reg_c38_State =
- RegC38_NonFsync_Other_AP;
- }
- } else if (priv->undecorated_smoothed_pwdb >=
- (REG_C38_TH + 5)) {
- if (reg_c38_State) {
- rtl92e_writeb(dev,
- rOFDM0_RxDetector3,
- priv->framesync);
- reg_c38_State = RegC38_Default;
- }
- }
- } else {
- if (reg_c38_State) {
- rtl92e_writeb(dev, rOFDM0_RxDetector3,
- priv->framesync);
- reg_c38_State = RegC38_Default;
- }
- }
- }
-}
-
-/*---------------------------Define function prototype------------------------*/
-static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- priv->rtllib->bdynamic_txpower_enable = true;
- priv->last_dtp_flag_high = false;
- priv->last_dtp_flag_low = false;
- priv->dynamic_tx_high_pwr = false;
- priv->dynamic_tx_low_pwr = false;
-}
-
-static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- unsigned int txhipower_threshold = 0;
- unsigned int txlowpower_threshold = 0;
-
- if (!priv->rtllib->bdynamic_txpower_enable) {
- priv->dynamic_tx_high_pwr = false;
- priv->dynamic_tx_low_pwr = false;
- return;
- }
- if ((priv->rtllib->ht_info->iot_peer == HT_IOT_PEER_ATHEROS) &&
- (priv->rtllib->mode == WIRELESS_MODE_G)) {
- txhipower_threshold = TX_POWER_ATHEROAP_THRESH_HIGH;
- txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
- } else {
- txhipower_threshold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
- txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
- }
-
- if (priv->rtllib->link_state == MAC80211_LINKED) {
- if (priv->undecorated_smoothed_pwdb >= txhipower_threshold) {
- priv->dynamic_tx_high_pwr = true;
- priv->dynamic_tx_low_pwr = false;
- } else {
- if (priv->undecorated_smoothed_pwdb <
- txlowpower_threshold && priv->dynamic_tx_high_pwr)
- priv->dynamic_tx_high_pwr = false;
- if (priv->undecorated_smoothed_pwdb < 35)
- priv->dynamic_tx_low_pwr = true;
- else if (priv->undecorated_smoothed_pwdb >= 40)
- priv->dynamic_tx_low_pwr = false;
- }
- } else {
- priv->dynamic_tx_high_pwr = false;
- priv->dynamic_tx_low_pwr = false;
- }
-
- if ((priv->dynamic_tx_high_pwr != priv->last_dtp_flag_high) ||
- (priv->dynamic_tx_low_pwr != priv->last_dtp_flag_low)) {
- rtl92e_set_tx_power(dev, priv->rtllib->current_network.channel);
- }
- priv->last_dtp_flag_high = priv->dynamic_tx_high_pwr;
- priv->last_dtp_flag_low = priv->dynamic_tx_low_pwr;
-}
-
-static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
-
- ieee->softmac_stats.CurrentShowTxate = rtl92e_readb(dev, CURRENT_TX_RATE_REG);
- ieee->softmac_stats.last_packet_rate = rtl92e_readb(dev, INITIAL_TX_RATE_REG);
- ieee->softmac_stats.txretrycount = rtl92e_readl(dev, TX_RETRY_COUNT_REG);
-}
-
-static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- rtl92e_writeb(dev, DRIVER_RSSI, priv->undecorated_smoothed_pwdb);
-}
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h
deleted file mode 100644
index 55641f17412b..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef __R8192UDM_H__
-#define __R8192UDM_H__
-
-/*--------------------------Define Parameters-------------------------------*/
-#define OFDM_TABLE_LEN 19
-#define CCK_TABLE_LEN 12
-
-#define DM_DIG_THRESH_HIGH 40
-#define DM_DIG_THRESH_LOW 35
-
-#define DM_DIG_HIGH_PWR_THRESH_HIGH 75
-#define DM_DIG_HIGH_PWR_THRESH_LOW 70
-
-#define BW_AUTO_SWITCH_HIGH_LOW 25
-#define BW_AUTO_SWITCH_LOW_HIGH 30
-
-#define DM_DIG_BACKOFF 12
-#define DM_DIG_MAX 0x36
-#define DM_DIG_MIN 0x1c
-#define DM_DIG_MIN_Netcore 0x12
-
-#define RX_PATH_SEL_SS_TH_LOW 30
-#define RX_PATH_SEL_DIFF_TH 18
-
-#define RATE_ADAPTIVE_TH_HIGH 50
-#define RATE_ADAPTIVE_TH_LOW_20M 30
-#define RATE_ADAPTIVE_TH_LOW_40M 10
-#define VERY_LOW_RSSI 15
-
-#define E_FOR_TX_POWER_TRACK 300
-#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68
-#define TX_POWER_NEAR_FIELD_THRESH_LOW 62
-#define TX_POWER_ATHEROAP_THRESH_HIGH 78
-#define TX_POWER_ATHEROAP_THRESH_LOW 72
-
-#define CURRENT_TX_RATE_REG 0x1e0
-#define INITIAL_TX_RATE_REG 0x1e1
-#define TX_RETRY_COUNT_REG 0x1ac
-#define REG_C38_TH 20
-
-/*--------------------------Define Parameters-------------------------------*/
-
-/*------------------------------Define structure----------------------------*/
-struct dig_t {
- long rssi_low_thresh;
- long rssi_high_thresh;
-
- long rssi_high_power_lowthresh;
- long rssi_high_power_highthresh;
-
- u8 cur_sta_connect_state;
- u8 pre_sta_connect_state;
-
- u8 curpd_thstate;
- u8 prepd_thstate;
- u8 curcs_ratio_state;
- u8 precs_ratio_state;
-
- u32 pre_ig_value;
- u32 cur_ig_value;
-
- u8 backoff_val;
- u8 rx_gain_range_max;
- u8 rx_gain_range_min;
-
- long rssi_val;
-};
-
-enum dm_ratr_sta {
- DM_RATR_STA_HIGH = 0,
- DM_RATR_STA_MIDDLE = 1,
- DM_RATR_STA_LOW = 2,
- DM_RATR_STA_MAX
-};
-
-enum dm_dig_connect {
- DIG_STA_DISCONNECT = 0,
- DIG_STA_CONNECT = 1,
-};
-
-enum dm_dig_pd_th {
- DIG_PD_AT_LOW_POWER = 0,
- DIG_PD_AT_NORMAL_POWER = 1,
- DIG_PD_AT_HIGH_POWER = 2,
- DIG_PD_MAX
-};
-
-enum dm_dig_cs_ratio {
- DIG_CS_RATIO_LOWER = 0,
- DIG_CS_RATIO_HIGHER = 1,
- DIG_CS_MAX
-};
-
-struct drx_path_sel {
- u8 enable;
- u8 cck_method;
- u8 cck_rx_path;
-
- u8 ss_th_low;
- u8 diff_th;
- u8 disabled_rf;
- u8 reserved;
-
- u8 rf_rssi[4];
- u8 rf_enable_rssi_th[4];
- long cck_pwdb_sta[4];
-};
-
-enum dm_cck_rx_path_method {
- CCK_Rx_Version_1 = 0,
- CCK_Rx_Version_2 = 1,
- CCK_Rx_Version_MAX
-};
-
-struct dcmd_txcmd {
- u32 op;
- u32 length;
- u32 value;
-};
-
-/*------------------------------Define structure----------------------------*/
-
-/*------------------------Export global variable----------------------------*/
-extern struct dig_t dm_digtable;
-
-/* Pre-calculated gain tables */
-extern const u32 dm_tx_bb_gain[TX_BB_GAIN_TABLE_LEN];
-extern const u8 dm_cck_tx_bb_gain[CCK_TX_BB_GAIN_TABLE_LEN][8];
-extern const u8 dm_cck_tx_bb_gain_ch14[CCK_TX_BB_GAIN_TABLE_LEN][8];
-
-/*------------------------Export global variable----------------------------*/
-
-/*--------------------------Exported Function prototype---------------------*/
-/*--------------------------Exported Function prototype---------------------*/
-
-void rtl92e_dm_init(struct net_device *dev);
-void rtl92e_dm_deinit(struct net_device *dev);
-
-void rtl92e_dm_watchdog(struct net_device *dev);
-
-void rtl92e_init_adaptive_rate(struct net_device *dev);
-void rtl92e_dm_txpower_tracking_wq(void *data);
-
-void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14);
-
-void rtl92e_dm_init_edca_turbo(struct net_device *dev);
-void rtl92e_dm_rf_pathcheck_wq(void *data);
-void rtl92e_dm_init_txpower_tracking(struct net_device *dev);
-#endif /*__R8192UDM_H__ */
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c b/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c
deleted file mode 100644
index db57c655c695..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtl_core.h"
-#include "rtl_eeprom.h"
-
-static void _rtl92e_gpio_write_bit(struct net_device *dev, int no, bool val)
-{
- u8 reg = rtl92e_readb(dev, EPROM_CMD);
-
- if (val)
- reg |= 1 << no;
- else
- reg &= ~(1 << no);
-
- rtl92e_writeb(dev, EPROM_CMD, reg);
- udelay(EPROM_DELAY);
-}
-
-static bool _rtl92e_gpio_get_bit(struct net_device *dev, int no)
-{
- u8 reg = rtl92e_readb(dev, EPROM_CMD);
-
- return (reg >> no) & 0x1;
-}
-
-static void _rtl92e_eeprom_ck_cycle(struct net_device *dev)
-{
- _rtl92e_gpio_write_bit(dev, EPROM_CK_BIT, 1);
- _rtl92e_gpio_write_bit(dev, EPROM_CK_BIT, 0);
-}
-
-static u16 _rtl92e_eeprom_xfer(struct net_device *dev, u16 data, int tx_len)
-{
- u16 ret = 0;
- int rx_len = 16;
-
- _rtl92e_gpio_write_bit(dev, EPROM_CS_BIT, 1);
- _rtl92e_eeprom_ck_cycle(dev);
-
- while (tx_len--) {
- _rtl92e_gpio_write_bit(dev, EPROM_W_BIT,
- (data >> tx_len) & 0x1);
- _rtl92e_eeprom_ck_cycle(dev);
- }
-
- _rtl92e_gpio_write_bit(dev, EPROM_W_BIT, 0);
-
- while (rx_len--) {
- _rtl92e_eeprom_ck_cycle(dev);
- ret |= _rtl92e_gpio_get_bit(dev, EPROM_R_BIT) << rx_len;
- }
-
- _rtl92e_gpio_write_bit(dev, EPROM_CS_BIT, 0);
- _rtl92e_eeprom_ck_cycle(dev);
-
- return ret;
-}
-
-u32 rtl92e_eeprom_read(struct net_device *dev, u32 addr)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 ret = 0;
-
- rtl92e_writeb(dev, EPROM_CMD,
- (EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT));
- udelay(EPROM_DELAY);
-
- /* EEPROM is configured as x16 */
- if (priv->epromtype == EEPROM_93C56)
- ret = _rtl92e_eeprom_xfer(dev, (addr & 0xFF) | (0x6 << 8), 11);
- else
- ret = _rtl92e_eeprom_xfer(dev, (addr & 0x3F) | (0x6 << 6), 9);
-
- rtl92e_writeb(dev, EPROM_CMD,
- (EPROM_CMD_NORMAL << EPROM_CMD_OPERATING_MODE_SHIFT));
- return ret;
-}
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.h b/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.h
deleted file mode 100644
index 66f1979bb1d5..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#define EPROM_DELAY 10
-
-u32 rtl92e_eeprom_read(struct net_device *dev, u32 addr);
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ethtool.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ethtool.c
deleted file mode 100644
index fab8932e67da..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_ethtool.c
+++ /dev/null
@@ -1,37 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-
-#include "rtl_core.h"
-
-static void _rtl92e_ethtool_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- strscpy(info->driver, DRV_NAME, sizeof(info->driver));
- strscpy(info->version, DRV_VERSION, sizeof(info->version));
- strscpy(info->bus_info, pci_name(priv->pdev), sizeof(info->bus_info));
-}
-
-static u32 _rtl92e_ethtool_get_link(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- return ((priv->rtllib->link_state == MAC80211_LINKED) ||
- (priv->rtllib->link_state == MAC80211_LINKED_SCANNING));
-}
-
-const struct ethtool_ops rtl819x_ethtool_ops = {
- .get_drvinfo = _rtl92e_ethtool_get_drvinfo,
- .get_link = _rtl92e_ethtool_get_link,
-};
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c
deleted file mode 100644
index 1aa73561581b..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c
+++ /dev/null
@@ -1,79 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtl_pci.h"
-#include "rtl_core.h"
-
-static void _rtl92e_parse_pci_configuration(struct pci_dev *pdev,
- struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-
- u8 tmp;
- u16 link_ctrl_reg;
-
- pcie_capability_read_word(priv->pdev, PCI_EXP_LNKCTL, &link_ctrl_reg);
-
- pci_read_config_byte(pdev, 0x98, &tmp);
- tmp |= BIT(4);
- pci_write_config_byte(pdev, 0x98, tmp);
-
- tmp = 0x17;
- pci_write_config_byte(pdev, 0x70f, tmp);
-}
-
-bool rtl92e_check_adapter(struct pci_dev *pdev, struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
- u16 device_id;
- u8 revision_id;
- u16 irq_line;
-
- device_id = pdev->device;
- revision_id = pdev->revision;
- pci_read_config_word(pdev, 0x3C, &irq_line);
-
- priv->card_8192 = NIC_8192E;
-
- if (device_id == 0x8192) {
- switch (revision_id) {
- case HAL_HW_PCI_REVISION_ID_8192PCIE:
- dev_info(&pdev->dev,
- "Adapter(8192 PCI-E) is found - DeviceID=%x\n",
- device_id);
- priv->card_8192 = NIC_8192E;
- break;
- case HAL_HW_PCI_REVISION_ID_8192SE:
- dev_info(&pdev->dev,
- "Adapter(8192SE) is found - DeviceID=%x\n",
- device_id);
- priv->card_8192 = NIC_8192SE;
- break;
- default:
- dev_info(&pdev->dev,
- "UNKNOWN nic type(%4x:%4x)\n",
- pdev->vendor, pdev->device);
- priv->card_8192 = NIC_UNKNOWN;
- return false;
- }
- }
-
- if (priv->card_8192 != NIC_8192E) {
- dev_info(&pdev->dev,
- "Detect info(%x) and hardware info(%x) not match!\n",
- NIC_8192E, priv->card_8192);
- dev_info(&pdev->dev,
- "Please select proper driver before install!!!!\n");
- return false;
- }
-
- _rtl92e_parse_pci_configuration(pdev, dev);
-
- return true;
-}
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h
deleted file mode 100644
index 3e39c4835ac8..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef _RTL_PCI_H
-#define _RTL_PCI_H
-
-#include <linux/types.h>
-#include <linux/pci.h>
-
-struct net_device;
-
-bool rtl92e_check_adapter(struct pci_dev *pdev, struct net_device *dev);
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
deleted file mode 100644
index d124b5eee0cc..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtl_core.h"
-#include "r8192E_hw.h"
-#include "r8190P_rtl8256.h"
-#include "rtl_pm.h"
-
-int rtl92e_suspend(struct device *dev_d)
-{
- struct net_device *dev = dev_get_drvdata(dev_d);
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 ulRegRead;
-
- netdev_info(dev, "============> r8192E suspend call.\n");
- del_timer_sync(&priv->gpio_polling_timer);
- cancel_delayed_work_sync(&priv->gpio_change_rf_wq);
- priv->polling_timer_on = 0;
-
- if (!netif_running(dev)) {
- netdev_info(dev,
- "RTL819XE:UI is open out of suspend function\n");
- goto out_pci_suspend;
- }
-
- if (dev->netdev_ops->ndo_stop)
- dev->netdev_ops->ndo_stop(dev);
- netif_device_detach(dev);
-
- if (!priv->rtllib->bSupportRemoteWakeUp) {
- rtl92e_set_rf_state(dev, rf_off, RF_CHANGE_BY_INIT);
- ulRegRead = rtl92e_readl(dev, CPU_GEN);
- ulRegRead |= CPU_GEN_SYSTEM_RESET;
- rtl92e_writel(dev, CPU_GEN, ulRegRead);
- } else {
- rtl92e_writel(dev, WFCRC0, 0xffffffff);
- rtl92e_writel(dev, WFCRC1, 0xffffffff);
- rtl92e_writel(dev, WFCRC2, 0xffffffff);
- rtl92e_writeb(dev, PMR, 0x5);
- rtl92e_writeb(dev, MAC_BLK_CTRL, 0xa);
- }
-out_pci_suspend:
- netdev_info(dev, "WOL is %s\n", priv->rtllib->bSupportRemoteWakeUp ?
- "Supported" : "Not supported");
- device_set_wakeup_enable(dev_d, priv->rtllib->bSupportRemoteWakeUp);
-
- mdelay(20);
-
- return 0;
-}
-
-int rtl92e_resume(struct device *dev_d)
-{
- struct pci_dev *pdev = to_pci_dev(dev_d);
- struct net_device *dev = dev_get_drvdata(dev_d);
- struct r8192_priv *priv = rtllib_priv(dev);
- u32 val;
-
- netdev_info(dev, "================>r8192E resume call.\n");
-
- pci_read_config_dword(pdev, 0x40, &val);
- if ((val & 0x0000ff00) != 0)
- pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
- device_wakeup_disable(dev_d);
-
- if (priv->polling_timer_on == 0)
- rtl92e_check_rfctrl_gpio_timer(&priv->gpio_polling_timer);
-
- if (!netif_running(dev)) {
- netdev_info(dev,
- "RTL819XE:UI is open out of resume function\n");
- goto out;
- }
-
- netif_device_attach(dev);
- if (dev->netdev_ops->ndo_open)
- dev->netdev_ops->ndo_open(dev);
-
- if (!priv->rtllib->bSupportRemoteWakeUp)
- rtl92e_set_rf_state(dev, rf_on, RF_CHANGE_BY_INIT);
-
-out:
- return 0;
-}
-
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
deleted file mode 100644
index fd8611495975..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef R8192E_PM_H
-#define R8192E_PM_H
-
-#include <linux/types.h>
-#include <linux/pci.h>
-
-int rtl92e_suspend(struct device *dev_d);
-int rtl92e_resume(struct device *dev_d);
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c
deleted file mode 100644
index 7b6247acf6f4..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c
+++ /dev/null
@@ -1,230 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtl_ps.h"
-#include "rtl_core.h"
-#include "r8192E_phy.h"
-#include "r8192E_phyreg.h"
-#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
-#include "r8192E_cmdpkt.h"
-#include <linux/jiffies.h>
-
-static void _rtl92e_hw_sleep(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- unsigned long flags = 0;
-
- spin_lock_irqsave(&priv->rf_ps_lock, flags);
- if (priv->rf_change_in_progress) {
- spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
- return;
- }
- spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
- rtl92e_set_rf_state(dev, rf_sleep, RF_CHANGE_BY_PS);
-}
-
-void rtl92e_hw_sleep_wq(void *data)
-{
- struct rtllib_device *ieee = container_of_dwork_rsl(data,
- struct rtllib_device, hw_sleep_wq);
- struct net_device *dev = ieee->dev;
-
- _rtl92e_hw_sleep(dev);
-}
-
-void rtl92e_hw_wakeup(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- unsigned long flags = 0;
-
- spin_lock_irqsave(&priv->rf_ps_lock, flags);
- if (priv->rf_change_in_progress) {
- spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
- schedule_delayed_work(&priv->rtllib->hw_wakeup_wq,
- msecs_to_jiffies(10));
- return;
- }
- spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
- rtl92e_set_rf_state(dev, rf_on, RF_CHANGE_BY_PS);
-}
-
-void rtl92e_hw_wakeup_wq(void *data)
-{
- struct rtllib_device *ieee = container_of_dwork_rsl(data,
- struct rtllib_device, hw_wakeup_wq);
- struct net_device *dev = ieee->dev;
-
- rtl92e_hw_wakeup(dev);
-}
-
-#define MIN_SLEEP_TIME 50
-#define MAX_SLEEP_TIME 10000
-void rtl92e_enter_sleep(struct net_device *dev, u64 time)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- u32 tmp;
- unsigned long flags;
- unsigned long timeout;
-
- spin_lock_irqsave(&priv->ps_lock, flags);
-
- time -= msecs_to_jiffies(8 + 16 + 7);
-
- timeout = jiffies + msecs_to_jiffies(MIN_SLEEP_TIME);
- if (time_before((unsigned long)time, timeout)) {
- spin_unlock_irqrestore(&priv->ps_lock, flags);
- netdev_info(dev, "too short to sleep::%lld < %ld\n",
- time - jiffies, msecs_to_jiffies(MIN_SLEEP_TIME));
- return;
- }
- timeout = jiffies + msecs_to_jiffies(MAX_SLEEP_TIME);
- if (time_after((unsigned long)time, timeout)) {
- netdev_info(dev, "========>too long to sleep:%lld > %ld\n",
- time - jiffies, msecs_to_jiffies(MAX_SLEEP_TIME));
- spin_unlock_irqrestore(&priv->ps_lock, flags);
- return;
- }
- tmp = time - jiffies;
- schedule_delayed_work(&priv->rtllib->hw_wakeup_wq, tmp);
- schedule_delayed_work(&priv->rtllib->hw_sleep_wq, 0);
- spin_unlock_irqrestore(&priv->ps_lock, flags);
-}
-
-static void _rtl92e_ps_update_rf_state(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
- &priv->rtllib->pwr_save_ctrl;
-
- psc->bSwRfProcessing = true;
- rtl92e_set_rf_state(dev, psc->eInactivePowerState, RF_CHANGE_BY_IPS);
-
- psc->bSwRfProcessing = false;
-}
-
-void rtl92e_ips_enter(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
- &priv->rtllib->pwr_save_ctrl;
- enum rt_rf_power_state rt_state;
-
- rt_state = priv->rtllib->rf_power_state;
- if (rt_state == rf_on && !psc->bSwRfProcessing &&
- (priv->rtllib->link_state != MAC80211_LINKED)) {
- psc->eInactivePowerState = rf_off;
- _rtl92e_ps_update_rf_state(dev);
- }
-}
-
-void rtl92e_ips_leave(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
- &priv->rtllib->pwr_save_ctrl;
- enum rt_rf_power_state rt_state;
-
- rt_state = priv->rtllib->rf_power_state;
- if (rt_state != rf_on && !psc->bSwRfProcessing &&
- priv->rtllib->rf_off_reason <= RF_CHANGE_BY_IPS) {
- psc->eInactivePowerState = rf_on;
- _rtl92e_ps_update_rf_state(dev);
- }
-}
-
-void rtl92e_ips_leave_wq(void *data)
-{
- struct rtllib_device *ieee = container_of(data, struct rtllib_device, ips_leave_wq);
- struct net_device *dev = ieee->dev;
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-
- mutex_lock(&priv->rtllib->ips_mutex);
- rtl92e_ips_leave(dev);
- mutex_unlock(&priv->rtllib->ips_mutex);
-}
-
-void rtl92e_rtllib_ips_leave_wq(struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
- enum rt_rf_power_state rt_state;
-
- rt_state = priv->rtllib->rf_power_state;
- if (rt_state == rf_off) {
- if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) {
- netdev_warn(dev, "%s(): RF is OFF.\n",
- __func__);
- return;
- }
- netdev_info(dev, "=========>%s(): rtl92e_ips_leave\n",
- __func__);
- schedule_work(&priv->rtllib->ips_leave_wq);
- }
-}
-
-void rtl92e_rtllib_ips_leave(struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-
- mutex_lock(&priv->rtllib->ips_mutex);
- rtl92e_ips_leave(dev);
- mutex_unlock(&priv->rtllib->ips_mutex);
-}
-
-static bool _rtl92e_ps_set_mode(struct net_device *dev, u8 rtPsMode)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- priv->rtllib->ps = rtPsMode;
- if (priv->rtllib->sta_sleep != LPS_IS_WAKE &&
- rtPsMode == RTLLIB_PS_DISABLED) {
- unsigned long flags;
-
- rtl92e_hw_wakeup(dev);
- priv->rtllib->sta_sleep = LPS_IS_WAKE;
-
- spin_lock_irqsave(&(priv->rtllib->mgmt_tx_lock), flags);
- rtllib_sta_ps_send_null_frame(priv->rtllib, 0);
- spin_unlock_irqrestore(&(priv->rtllib->mgmt_tx_lock), flags);
- }
-
- return true;
-}
-
-void rtl92e_leisure_ps_enter(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
- &priv->rtllib->pwr_save_ctrl;
-
- if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) &&
- (priv->rtllib->link_state == MAC80211_LINKED)))
- return;
-
- if (psc->bLeisurePs) {
- if (psc->lps_idle_count >= RT_CHECK_FOR_HANG_PERIOD) {
- if (priv->rtllib->ps == RTLLIB_PS_DISABLED)
- _rtl92e_ps_set_mode(dev, RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST);
- } else {
- psc->lps_idle_count++;
- }
- }
-}
-
-void rtl92e_leisure_ps_leave(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
- &priv->rtllib->pwr_save_ctrl;
-
- if (psc->bLeisurePs) {
- if (priv->rtllib->ps != RTLLIB_PS_DISABLED)
- _rtl92e_ps_set_mode(dev, RTLLIB_PS_DISABLED);
- }
-}
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.h b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.h
deleted file mode 100644
index 70fe5d39be9a..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef _RTL_PS_H
-#define _RTL_PS_H
-
-#include <linux/types.h>
-
-struct net_device;
-
-#define RT_CHECK_FOR_HANG_PERIOD 2
-
-void rtl92e_hw_wakeup(struct net_device *dev);
-void rtl92e_enter_sleep(struct net_device *dev, u64 time);
-void rtl92e_rtllib_ips_leave_wq(struct net_device *dev);
-void rtl92e_rtllib_ips_leave(struct net_device *dev);
-void rtl92e_ips_leave_wq(void *data);
-
-void rtl92e_ips_enter(struct net_device *dev);
-void rtl92e_ips_leave(struct net_device *dev);
-
-void rtl92e_leisure_ps_enter(struct net_device *dev);
-void rtl92e_leisure_ps_leave(struct net_device *dev);
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
deleted file mode 100644
index fe3a42a4fcd5..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
+++ /dev/null
@@ -1,867 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include <linux/string.h>
-#include "rtl_core.h"
-#include "rtl_wx.h"
-
-#define RATE_COUNT 12
-static u32 rtl8192_rates[] = {
- 1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000,
- 18000000, 24000000, 36000000, 48000000, 54000000
-};
-
-#ifndef ENETDOWN
-#define ENETDOWN 1
-#endif
-
-static int _rtl92e_wx_get_freq(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- return rtllib_wx_get_freq(priv->rtllib, a, wrqu, b);
-}
-
-static int _rtl92e_wx_get_mode(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- return rtllib_wx_get_mode(priv->rtllib, a, wrqu, b);
-}
-
-static int _rtl92e_wx_get_rate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- return rtllib_wx_get_rate(priv->rtllib, info, wrqu, extra);
-}
-
-static int _rtl92e_wx_set_rate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->hw_radio_off)
- return 0;
-
- mutex_lock(&priv->wx_mutex);
-
- ret = rtllib_wx_set_rate(priv->rtllib, info, wrqu, extra);
-
- mutex_unlock(&priv->wx_mutex);
-
- return ret;
-}
-
-static int _rtl92e_wx_set_rts(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->hw_radio_off)
- return 0;
-
- mutex_lock(&priv->wx_mutex);
-
- ret = rtllib_wx_set_rts(priv->rtllib, info, wrqu, extra);
-
- mutex_unlock(&priv->wx_mutex);
-
- return ret;
-}
-
-static int _rtl92e_wx_get_rts(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- return rtllib_wx_get_rts(priv->rtllib, info, wrqu, extra);
-}
-
-static int _rtl92e_wx_set_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->hw_radio_off) {
- netdev_warn(dev, "%s(): Can't set Power: Radio is Off.\n",
- __func__);
- return 0;
- }
- mutex_lock(&priv->wx_mutex);
-
- ret = rtllib_wx_set_power(priv->rtllib, info, wrqu, extra);
-
- mutex_unlock(&priv->wx_mutex);
-
- return ret;
-}
-
-static int _rtl92e_wx_get_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra);
-}
-
-static int _rtl92e_wx_set_mode(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- enum rt_rf_power_state rt_state;
- int ret;
-
- if (priv->hw_radio_off)
- return 0;
- rt_state = priv->rtllib->rf_power_state;
- mutex_lock(&priv->wx_mutex);
- if (wrqu->mode == IW_MODE_MONITOR) {
- if (rt_state == rf_off) {
- if (priv->rtllib->rf_off_reason >
- RF_CHANGE_BY_IPS) {
- netdev_warn(dev, "%s(): RF is OFF.\n",
- __func__);
- mutex_unlock(&priv->wx_mutex);
- return -1;
- }
- netdev_info(dev,
- "=========>%s(): rtl92e_ips_leave\n",
- __func__);
- mutex_lock(&priv->rtllib->ips_mutex);
- rtl92e_ips_leave(dev);
- mutex_unlock(&priv->rtllib->ips_mutex);
- }
- }
- ret = rtllib_wx_set_mode(priv->rtllib, a, wrqu, b);
-
- mutex_unlock(&priv->wx_mutex);
- return ret;
-}
-
-static int _rtl92e_wx_get_range(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_range *range = (struct iw_range *)extra;
- struct r8192_priv *priv = rtllib_priv(dev);
- u16 val;
- int i;
-
- wrqu->data.length = sizeof(*range);
- memset(range, 0, sizeof(*range));
-
- /* ~130 Mb/s real (802.11n) */
- range->throughput = 130 * 1000 * 1000;
-
- range->max_qual.qual = 100;
- range->max_qual.level = 0;
- range->max_qual.noise = 0;
- range->max_qual.updated = 7; /* Updated all three */
-
- range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
- range->avg_qual.level = 0;
- range->avg_qual.noise = 0;
- range->avg_qual.updated = 7; /* Updated all three */
-
- range->num_bitrates = min(RATE_COUNT, IW_MAX_BITRATES);
-
- for (i = 0; i < range->num_bitrates; i++)
- range->bitrate[i] = rtl8192_rates[i];
-
- range->max_rts = DEFAULT_RTS_THRESHOLD;
- range->min_frag = MIN_FRAG_THRESHOLD;
- range->max_frag = MAX_FRAG_THRESHOLD;
-
- range->min_pmp = 0;
- range->max_pmp = 5000000;
- range->min_pmt = 0;
- range->max_pmt = 65535 * 1000;
- range->pmp_flags = IW_POWER_PERIOD;
- range->pmt_flags = IW_POWER_TIMEOUT;
- range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 18;
-
- for (i = 0, val = 0; i < 14; i++) {
- if ((priv->rtllib->active_channel_map)[i + 1]) {
- s32 freq_khz;
-
- range->freq[val].i = i + 1;
- freq_khz = ieee80211_channel_to_freq_khz(i + 1, NL80211_BAND_2GHZ);
- range->freq[val].m = freq_khz * 100;
- range->freq[val].e = 1;
- val++;
- }
-
- if (val == IW_MAX_FREQUENCIES)
- break;
- }
- range->num_frequency = val;
- range->num_channels = val;
- range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
- IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
- range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE;
-
- /* Event capability (kernel + driver) */
-
- return 0;
-}
-
-static int _rtl92e_wx_set_scan(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
- enum rt_rf_power_state rt_state;
- int ret;
-
- if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) {
- if ((ieee->link_state >= RTLLIB_ASSOCIATING) &&
- (ieee->link_state <= RTLLIB_ASSOCIATING_AUTHENTICATED))
- return 0;
- if ((priv->rtllib->link_state == MAC80211_LINKED) &&
- (priv->rtllib->cnt_after_link < 2))
- return 0;
- }
-
- if (priv->hw_radio_off) {
- netdev_info(dev, "================>%s(): hwradio off\n",
- __func__);
- return 0;
- }
- rt_state = priv->rtllib->rf_power_state;
- if (!priv->up)
- return -ENETDOWN;
- if (priv->rtllib->link_detect_info.busy_traffic)
- return -EAGAIN;
-
- if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
- struct iw_scan_req *req = (struct iw_scan_req *)b;
-
- if (req->essid_len) {
- int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE);
-
- ieee->current_network.ssid_len = len;
- memcpy(ieee->current_network.ssid, req->essid, len);
- }
- }
-
- mutex_lock(&priv->wx_mutex);
-
- priv->rtllib->first_ie_in_scan = true;
-
- if (priv->rtllib->link_state != MAC80211_LINKED) {
- if (rt_state == rf_off) {
- if (priv->rtllib->rf_off_reason >
- RF_CHANGE_BY_IPS) {
- netdev_warn(dev, "%s(): RF is OFF.\n",
- __func__);
- mutex_unlock(&priv->wx_mutex);
- return -1;
- }
- mutex_lock(&priv->rtllib->ips_mutex);
- rtl92e_ips_leave(dev);
- mutex_unlock(&priv->rtllib->ips_mutex);
- }
- rtllib_stop_scan(priv->rtllib);
- if (priv->rtllib->rf_power_state != rf_off) {
- priv->rtllib->actscanning = true;
-
- ieee->scan_operation_backup_handler(ieee->dev, SCAN_OPT_BACKUP);
-
- rtllib_start_scan_syncro(priv->rtllib);
-
- ieee->scan_operation_backup_handler(ieee->dev, SCAN_OPT_RESTORE);
- }
- ret = 0;
- } else {
- priv->rtllib->actscanning = true;
- ret = rtllib_wx_set_scan(priv->rtllib, a, wrqu, b);
- }
-
- mutex_unlock(&priv->wx_mutex);
- return ret;
-}
-
-static int _rtl92e_wx_get_scan(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (!priv->up)
- return -ENETDOWN;
-
- if (priv->hw_radio_off)
- return 0;
-
- mutex_lock(&priv->wx_mutex);
-
- ret = rtllib_wx_get_scan(priv->rtllib, a, wrqu, b);
-
- mutex_unlock(&priv->wx_mutex);
-
- return ret;
-}
-
-static int _rtl92e_wx_set_essid(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- int ret;
-
- if (priv->hw_radio_off) {
- netdev_info(dev,
- "=========>%s():hw radio off,or Rf state is rf_off, return\n",
- __func__);
- return 0;
- }
- mutex_lock(&priv->wx_mutex);
- ret = rtllib_wx_set_essid(priv->rtllib, a, wrqu, b);
-
- mutex_unlock(&priv->wx_mutex);
-
- return ret;
-}
-
-static int _rtl92e_wx_get_essid(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- mutex_lock(&priv->wx_mutex);
-
- ret = rtllib_wx_get_essid(priv->rtllib, a, wrqu, b);
-
- mutex_unlock(&priv->wx_mutex);
-
- return ret;
-}
-
-static int _rtl92e_wx_set_nick(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (wrqu->data.length > IW_ESSID_MAX_SIZE)
- return -E2BIG;
- mutex_lock(&priv->wx_mutex);
- wrqu->data.length = min_t(size_t, wrqu->data.length,
- sizeof(priv->nick));
- memset(priv->nick, 0, sizeof(priv->nick));
- memcpy(priv->nick, extra, wrqu->data.length);
- mutex_unlock(&priv->wx_mutex);
- return 0;
-}
-
-static int _rtl92e_wx_get_nick(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- mutex_lock(&priv->wx_mutex);
- wrqu->data.length = strlen(priv->nick);
- memcpy(extra, priv->nick, wrqu->data.length);
- wrqu->data.flags = 1; /* active */
- mutex_unlock(&priv->wx_mutex);
- return 0;
-}
-
-static int _rtl92e_wx_set_freq(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->hw_radio_off)
- return 0;
-
- mutex_lock(&priv->wx_mutex);
-
- ret = rtllib_wx_set_freq(priv->rtllib, a, wrqu, b);
-
- mutex_unlock(&priv->wx_mutex);
- return ret;
-}
-
-static int _rtl92e_wx_get_name(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- return rtllib_wx_get_name(priv->rtllib, info, wrqu, extra);
-}
-
-static int _rtl92e_wx_set_frag(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->hw_radio_off)
- return 0;
-
- if (wrqu->frag.disabled) {
- priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD;
- } else {
- if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
- wrqu->frag.value > MAX_FRAG_THRESHOLD)
- return -EINVAL;
-
- priv->rtllib->fts = wrqu->frag.value & ~0x1;
- }
-
- return 0;
-}
-
-static int _rtl92e_wx_get_frag(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- wrqu->frag.value = priv->rtllib->fts;
- wrqu->frag.fixed = 0; /* no auto select */
- wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
-
- return 0;
-}
-
-static int _rtl92e_wx_set_wap(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *awrq, char *extra)
-{
- int ret;
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->hw_radio_off)
- return 0;
-
- mutex_lock(&priv->wx_mutex);
-
- ret = rtllib_wx_set_wap(priv->rtllib, info, awrq, extra);
-
- mutex_unlock(&priv->wx_mutex);
-
- return ret;
-}
-
-static int _rtl92e_wx_get_wap(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- return rtllib_wx_get_wap(priv->rtllib, info, wrqu, extra);
-}
-
-static int _rtl92e_wx_get_enc(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- return rtllib_wx_get_encode(priv->rtllib, info, wrqu, key);
-}
-
-static int _rtl92e_wx_set_enc(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- int ret;
-
- struct rtllib_device *ieee = priv->rtllib;
- u32 hwkey[4] = {0, 0, 0, 0};
- u8 mask = 0xff;
- u32 key_idx = 0;
- u8 zero_addr[4][6] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
- int i;
-
- if (priv->hw_radio_off)
- return 0;
-
- if (!priv->up)
- return -ENETDOWN;
-
- priv->rtllib->wx_set_enc = 1;
- mutex_lock(&priv->rtllib->ips_mutex);
- rtl92e_ips_leave(dev);
- mutex_unlock(&priv->rtllib->ips_mutex);
- mutex_lock(&priv->wx_mutex);
-
- ret = rtllib_wx_set_encode(priv->rtllib, info, wrqu, key);
- mutex_unlock(&priv->wx_mutex);
-
- if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
- ieee->pairwise_key_type = KEY_TYPE_NA;
- ieee->group_key_type = KEY_TYPE_NA;
- rtl92e_cam_reset(dev);
- memset(priv->rtllib->swcamtable, 0,
- sizeof(struct sw_cam_table) * 32);
- goto end_hw_sec;
- }
- if (wrqu->encoding.length != 0) {
- for (i = 0; i < 4; i++) {
- hwkey[i] |= key[4 * i + 0] & mask;
- if (i == 1 && (4 * i + 1) == wrqu->encoding.length)
- mask = 0x00;
- if (i == 3 && (4 * i + 1) == wrqu->encoding.length)
- mask = 0x00;
- hwkey[i] |= (key[4 * i + 1] & mask) << 8;
- hwkey[i] |= (key[4 * i + 2] & mask) << 16;
- hwkey[i] |= (key[4 * i + 3] & mask) << 24;
- }
-
- switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
- case 0:
- key_idx = ieee->crypt_info.tx_keyidx;
- break;
- case 1:
- key_idx = 0;
- break;
- case 2:
- key_idx = 1;
- break;
- case 3:
- key_idx = 2;
- break;
- case 4:
- key_idx = 3;
- break;
- default:
- break;
- }
- if (wrqu->encoding.length == 0x5) {
- ieee->pairwise_key_type = KEY_TYPE_WEP40;
- rtl92e_enable_hw_security_config(dev);
- }
-
- else if (wrqu->encoding.length == 0xd) {
- ieee->pairwise_key_type = KEY_TYPE_WEP104;
- rtl92e_enable_hw_security_config(dev);
- rtl92e_set_key(dev, key_idx, key_idx, KEY_TYPE_WEP104,
- zero_addr[key_idx], 0, hwkey);
- rtl92e_set_swcam(dev, key_idx, key_idx, KEY_TYPE_WEP104,
- zero_addr[key_idx], hwkey);
- } else {
- netdev_info(dev,
- "wrong type in WEP, not WEP40 and WEP104\n");
- }
- }
-
-end_hw_sec:
- priv->rtllib->wx_set_enc = 0;
- return ret;
-}
-
-#define R8192_MAX_RETRY 255
-static int _rtl92e_wx_set_retry(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- int err = 0;
-
- if (priv->hw_radio_off)
- return 0;
-
- mutex_lock(&priv->wx_mutex);
-
- if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
- wrqu->retry.disabled) {
- err = -EINVAL;
- goto exit;
- }
- if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
- err = -EINVAL;
- goto exit;
- }
-
- if (wrqu->retry.value > R8192_MAX_RETRY) {
- err = -EINVAL;
- goto exit;
- }
- if (wrqu->retry.flags & IW_RETRY_MAX)
- priv->retry_rts = wrqu->retry.value;
- else
- priv->retry_data = wrqu->retry.value;
-
- rtl92e_commit(dev);
-exit:
- mutex_unlock(&priv->wx_mutex);
-
- return err;
-}
-
-static int _rtl92e_wx_get_retry(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
-
- wrqu->retry.disabled = 0; /* can't be disabled */
-
- if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
- IW_RETRY_LIFETIME)
- return -EINVAL;
-
- if (wrqu->retry.flags & IW_RETRY_MAX) {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
- wrqu->retry.value = priv->retry_rts;
- } else {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
- wrqu->retry.value = priv->retry_data;
- }
- return 0;
-}
-
-static int _rtl92e_wx_set_encode_ext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
-
- if (priv->hw_radio_off)
- return 0;
-
- mutex_lock(&priv->wx_mutex);
-
- priv->rtllib->wx_set_enc = 1;
- mutex_lock(&priv->rtllib->ips_mutex);
- rtl92e_ips_leave(dev);
- mutex_unlock(&priv->rtllib->ips_mutex);
-
- ret = rtllib_wx_set_encode_ext(ieee, info, wrqu, extra);
- {
- const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- const u8 zero[ETH_ALEN] = {0};
- u32 key[4] = {0};
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- struct iw_point *encoding = &wrqu->encoding;
- u8 idx = 0, alg = 0, group = 0;
-
- if ((encoding->flags & IW_ENCODE_DISABLED) ||
- ext->alg == IW_ENCODE_ALG_NONE) {
- ieee->pairwise_key_type = KEY_TYPE_NA;
- ieee->group_key_type = KEY_TYPE_NA;
- rtl92e_cam_reset(dev);
- memset(priv->rtllib->swcamtable, 0,
- sizeof(struct sw_cam_table) * 32);
- goto end_hw_sec;
- }
- alg = (ext->alg == IW_ENCODE_ALG_CCMP) ? KEY_TYPE_CCMP :
- ext->alg;
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx)
- idx--;
- group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
-
- if ((!group) || (alg == KEY_TYPE_WEP40)) {
- if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
- alg = KEY_TYPE_WEP104;
- ieee->pairwise_key_type = alg;
- rtl92e_enable_hw_security_config(dev);
- }
- memcpy((u8 *)key, ext->key, 16);
-
- if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
- if (ext->key_len == 13)
- ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
- rtl92e_set_key(dev, idx, idx, alg, zero, 0, key);
- rtl92e_set_swcam(dev, idx, idx, alg, zero, key);
- } else if (group) {
- ieee->group_key_type = alg;
- rtl92e_set_key(dev, idx, idx, alg, broadcast_addr, 0,
- key);
- rtl92e_set_swcam(dev, idx, idx, alg, broadcast_addr, key);
- } else {
- if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) &&
- ieee->ht_info->current_ht_support)
- rtl92e_writeb(dev, 0x173, 1);
- rtl92e_set_key(dev, 4, idx, alg,
- (u8 *)ieee->ap_mac_addr, 0, key);
- rtl92e_set_swcam(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr, key);
- }
- }
-
-end_hw_sec:
- priv->rtllib->wx_set_enc = 0;
- mutex_unlock(&priv->wx_mutex);
- return ret;
-}
-
-static int _rtl92e_wx_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *data, char *extra)
-{
- int ret = 0;
-
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->hw_radio_off)
- return 0;
-
- mutex_lock(&priv->wx_mutex);
- ret = rtllib_wx_set_auth(priv->rtllib, info, &data->param, extra);
- mutex_unlock(&priv->wx_mutex);
- return ret;
-}
-
-static int _rtl92e_wx_set_mlme(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
-
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->hw_radio_off)
- return 0;
-
- mutex_lock(&priv->wx_mutex);
- ret = rtllib_wx_set_mlme(priv->rtllib, info, wrqu, extra);
- mutex_unlock(&priv->wx_mutex);
- return ret;
-}
-
-static int _rtl92e_wx_set_gen_ie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *data, char *extra)
-{
- int ret = 0;
-
- struct r8192_priv *priv = rtllib_priv(dev);
-
- if (priv->hw_radio_off)
- return 0;
-
- mutex_lock(&priv->wx_mutex);
- ret = rtllib_wx_set_gen_ie(priv->rtllib, extra, data->data.length);
- mutex_unlock(&priv->wx_mutex);
- return ret;
-}
-
-static int _rtl92e_wx_get_gen_ie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *data, char *extra)
-{
- int ret = 0;
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
-
- if (ieee->wpa_ie_len == 0 || !ieee->wpa_ie) {
- data->data.length = 0;
- return 0;
- }
-
- if (data->data.length < ieee->wpa_ie_len)
- return -E2BIG;
-
- data->data.length = ieee->wpa_ie_len;
- memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
- return ret;
-}
-
-#define IW_IOCTL(x) ((x) - SIOCSIWCOMMIT)
-static iw_handler r8192_wx_handlers[] = {
- [IW_IOCTL(SIOCGIWNAME)] = _rtl92e_wx_get_name,
- [IW_IOCTL(SIOCSIWFREQ)] = _rtl92e_wx_set_freq,
- [IW_IOCTL(SIOCGIWFREQ)] = _rtl92e_wx_get_freq,
- [IW_IOCTL(SIOCSIWMODE)] = _rtl92e_wx_set_mode,
- [IW_IOCTL(SIOCGIWMODE)] = _rtl92e_wx_get_mode,
- [IW_IOCTL(SIOCGIWRANGE)] = _rtl92e_wx_get_range,
- [IW_IOCTL(SIOCSIWAP)] = _rtl92e_wx_set_wap,
- [IW_IOCTL(SIOCGIWAP)] = _rtl92e_wx_get_wap,
- [IW_IOCTL(SIOCSIWSCAN)] = _rtl92e_wx_set_scan,
- [IW_IOCTL(SIOCGIWSCAN)] = _rtl92e_wx_get_scan,
- [IW_IOCTL(SIOCSIWESSID)] = _rtl92e_wx_set_essid,
- [IW_IOCTL(SIOCGIWESSID)] = _rtl92e_wx_get_essid,
- [IW_IOCTL(SIOCSIWNICKN)] = _rtl92e_wx_set_nick,
- [IW_IOCTL(SIOCGIWNICKN)] = _rtl92e_wx_get_nick,
- [IW_IOCTL(SIOCSIWRATE)] = _rtl92e_wx_set_rate,
- [IW_IOCTL(SIOCGIWRATE)] = _rtl92e_wx_get_rate,
- [IW_IOCTL(SIOCSIWRTS)] = _rtl92e_wx_set_rts,
- [IW_IOCTL(SIOCGIWRTS)] = _rtl92e_wx_get_rts,
- [IW_IOCTL(SIOCSIWFRAG)] = _rtl92e_wx_set_frag,
- [IW_IOCTL(SIOCGIWFRAG)] = _rtl92e_wx_get_frag,
- [IW_IOCTL(SIOCSIWRETRY)] = _rtl92e_wx_set_retry,
- [IW_IOCTL(SIOCGIWRETRY)] = _rtl92e_wx_get_retry,
- [IW_IOCTL(SIOCSIWENCODE)] = _rtl92e_wx_set_enc,
- [IW_IOCTL(SIOCGIWENCODE)] = _rtl92e_wx_get_enc,
- [IW_IOCTL(SIOCSIWPOWER)] = _rtl92e_wx_set_power,
- [IW_IOCTL(SIOCGIWPOWER)] = _rtl92e_wx_get_power,
- [IW_IOCTL(SIOCSIWGENIE)] = _rtl92e_wx_set_gen_ie,
- [IW_IOCTL(SIOCGIWGENIE)] = _rtl92e_wx_get_gen_ie,
- [IW_IOCTL(SIOCSIWMLME)] = _rtl92e_wx_set_mlme,
- [IW_IOCTL(SIOCSIWAUTH)] = _rtl92e_wx_set_auth,
- [IW_IOCTL(SIOCSIWENCODEEXT)] = _rtl92e_wx_set_encode_ext,
-};
-
-static struct iw_statistics *_rtl92e_get_wireless_stats(struct net_device *dev)
-{
- struct r8192_priv *priv = rtllib_priv(dev);
- struct rtllib_device *ieee = priv->rtllib;
- struct iw_statistics *wstats = &priv->wstats;
- int tmp_level = 0;
- int tmp_qual = 0;
- int tmp_noise = 0;
-
- if (ieee->link_state < MAC80211_LINKED) {
- wstats->qual.qual = 10;
- wstats->qual.level = 0;
- wstats->qual.noise = 0x100 - 100; /* -100 dBm */
- wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- return wstats;
- }
-
- tmp_level = (&ieee->current_network)->stats.rssi;
- tmp_qual = (&ieee->current_network)->stats.signal;
- tmp_noise = (&ieee->current_network)->stats.noise;
-
- wstats->qual.level = tmp_level;
- wstats->qual.qual = tmp_qual;
- wstats->qual.noise = tmp_noise;
- wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- return wstats;
-}
-
-const struct iw_handler_def r8192_wx_handlers_def = {
- .standard = r8192_wx_handlers,
- .num_standard = ARRAY_SIZE(r8192_wx_handlers),
- .get_wireless_stats = _rtl92e_get_wireless_stats,
-};
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h
deleted file mode 100644
index d70a747ac1dd..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef R819x_WX_H
-#define R819x_WX_H
-
-struct iw_handler_def;
-
-extern const struct iw_handler_def r8192_wx_handlers_def;
-#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/table.c b/drivers/staging/rtl8192e/rtl8192e/table.c
deleted file mode 100644
index 0b5cc6049232..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/table.c
+++ /dev/null
@@ -1,543 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "table.h"
-
-u32 RTL8192E_PHY_REG_1T2R_ARR[RTL8192E_PHY_REG_1T2R_ARR_LEN] = {
- 0x800, 0x00000000,
- 0x804, 0x00000001,
- 0x808, 0x0000fc00,
- 0x80c, 0x0000001c,
- 0x810, 0x801010aa,
- 0x814, 0x008514d0,
- 0x818, 0x00000040,
- 0x81c, 0x00000000,
- 0x820, 0x00000004,
- 0x824, 0x00690000,
- 0x828, 0x00000004,
- 0x82c, 0x00e90000,
- 0x830, 0x00000004,
- 0x834, 0x00690000,
- 0x838, 0x00000004,
- 0x83c, 0x00e90000,
- 0x840, 0x00000000,
- 0x844, 0x00000000,
- 0x848, 0x00000000,
- 0x84c, 0x00000000,
- 0x850, 0x00000000,
- 0x854, 0x00000000,
- 0x858, 0x65a965a9,
- 0x85c, 0x65a965a9,
- 0x860, 0x001f0010,
- 0x864, 0x007f0010,
- 0x868, 0x001f0010,
- 0x86c, 0x007f0010,
- 0x870, 0x0f100f70,
- 0x874, 0x0f100f70,
- 0x878, 0x00000000,
- 0x87c, 0x00000000,
- 0x880, 0x6870e36c,
- 0x884, 0xe3573600,
- 0x888, 0x4260c340,
- 0x88c, 0x0000ff00,
- 0x890, 0x00000000,
- 0x894, 0xfffffffe,
- 0x898, 0x4c42382f,
- 0x89c, 0x00656056,
- 0x8b0, 0x00000000,
- 0x8e0, 0x00000000,
- 0x8e4, 0x00000000,
- 0x900, 0x00000000,
- 0x904, 0x00000023,
- 0x908, 0x00000000,
- 0x90c, 0x31121311,
- 0xa00, 0x00d0c7d8,
- 0xa04, 0x811f0008,
- 0xa08, 0x80cd8300,
- 0xa0c, 0x2e62740f,
- 0xa10, 0x95009b78,
- 0xa14, 0x11145008,
- 0xa18, 0x00881117,
- 0xa1c, 0x89140fa0,
- 0xa20, 0x1a1b0000,
- 0xa24, 0x090e1317,
- 0xa28, 0x00000204,
- 0xa2c, 0x00000000,
- 0xc00, 0x00000040,
- 0xc04, 0x00005433,
- 0xc08, 0x000000e4,
- 0xc0c, 0x6c6c6c6c,
- 0xc10, 0x08800000,
- 0xc14, 0x40000100,
- 0xc18, 0x08000000,
- 0xc1c, 0x40000100,
- 0xc20, 0x08000000,
- 0xc24, 0x40000100,
- 0xc28, 0x08000000,
- 0xc2c, 0x40000100,
- 0xc30, 0x6de9ac44,
- 0xc34, 0x465c52cd,
- 0xc38, 0x497f5994,
- 0xc3c, 0x0a969764,
- 0xc40, 0x1f7c403f,
- 0xc44, 0x000100b7,
- 0xc48, 0xec020000,
- 0xc4c, 0x00000300,
- 0xc50, 0x69543420,
- 0xc54, 0x433c0094,
- 0xc58, 0x69543420,
- 0xc5c, 0x433c0094,
- 0xc60, 0x69543420,
- 0xc64, 0x433c0094,
- 0xc68, 0x69543420,
- 0xc6c, 0x433c0094,
- 0xc70, 0x2c7f000d,
- 0xc74, 0x0186175b,
- 0xc78, 0x0000001f,
- 0xc7c, 0x00b91612,
- 0xc80, 0x40000100,
- 0xc84, 0x20000000,
- 0xc88, 0x40000100,
- 0xc8c, 0x20200000,
- 0xc90, 0x40000100,
- 0xc94, 0x00000000,
- 0xc98, 0x40000100,
- 0xc9c, 0x00000000,
- 0xca0, 0x00492492,
- 0xca4, 0x00000000,
- 0xca8, 0x00000000,
- 0xcac, 0x00000000,
- 0xcb0, 0x00000000,
- 0xcb4, 0x00000000,
- 0xcb8, 0x00000000,
- 0xcbc, 0x00492492,
- 0xcc0, 0x00000000,
- 0xcc4, 0x00000000,
- 0xcc8, 0x00000000,
- 0xccc, 0x00000000,
- 0xcd0, 0x00000000,
- 0xcd4, 0x00000000,
- 0xcd8, 0x64b22427,
- 0xcdc, 0x00766932,
- 0xce0, 0x00222222,
- 0xd00, 0x00000750,
- 0xd04, 0x00000403,
- 0xd08, 0x0000907f,
- 0xd0c, 0x00000001,
- 0xd10, 0xa0633333,
- 0xd14, 0x33333c63,
- 0xd18, 0x6a8f5b6b,
- 0xd1c, 0x00000000,
- 0xd20, 0x00000000,
- 0xd24, 0x00000000,
- 0xd28, 0x00000000,
- 0xd2c, 0xcc979975,
- 0xd30, 0x00000000,
- 0xd34, 0x00000000,
- 0xd38, 0x00000000,
- 0xd3c, 0x00027293,
- 0xd40, 0x00000000,
- 0xd44, 0x00000000,
- 0xd48, 0x00000000,
- 0xd4c, 0x00000000,
- 0xd50, 0x6437140a,
- 0xd54, 0x024dbd02,
- 0xd58, 0x00000000,
- 0xd5c, 0x04032064,
- 0xe00, 0x161a1a1a,
- 0xe04, 0x12121416,
- 0xe08, 0x00001800,
- 0xe0c, 0x00000000,
- 0xe10, 0x161a1a1a,
- 0xe14, 0x12121416,
- 0xe18, 0x161a1a1a,
- 0xe1c, 0x12121416,
-};
-
-u32 RTL8192E_RADIO_A_ARR[RTL8192E_RADIO_A_ARR_LEN] = {
- 0x019, 0x00000003,
- 0x000, 0x000000bf,
- 0x001, 0x00000ee0,
- 0x002, 0x0000004c,
- 0x003, 0x000007f1,
- 0x004, 0x00000975,
- 0x005, 0x00000c58,
- 0x006, 0x00000ae6,
- 0x007, 0x000000ca,
- 0x008, 0x00000e1c,
- 0x009, 0x000007f0,
- 0x00a, 0x000009d0,
- 0x00b, 0x000001ba,
- 0x00c, 0x00000240,
- 0x00e, 0x00000020,
- 0x00f, 0x00000990,
- 0x012, 0x00000806,
- 0x014, 0x000005ab,
- 0x015, 0x00000f80,
- 0x016, 0x00000020,
- 0x017, 0x00000597,
- 0x018, 0x0000050a,
- 0x01a, 0x00000f80,
- 0x01b, 0x00000f5e,
- 0x01c, 0x00000008,
- 0x01d, 0x00000607,
- 0x01e, 0x000006cc,
- 0x01f, 0x00000000,
- 0x020, 0x000001a5,
- 0x01f, 0x00000001,
- 0x020, 0x00000165,
- 0x01f, 0x00000002,
- 0x020, 0x000000c6,
- 0x01f, 0x00000003,
- 0x020, 0x00000086,
- 0x01f, 0x00000004,
- 0x020, 0x00000046,
- 0x01f, 0x00000005,
- 0x020, 0x000001e6,
- 0x01f, 0x00000006,
- 0x020, 0x000001a6,
- 0x01f, 0x00000007,
- 0x020, 0x00000166,
- 0x01f, 0x00000008,
- 0x020, 0x000000c7,
- 0x01f, 0x00000009,
- 0x020, 0x00000087,
- 0x01f, 0x0000000a,
- 0x020, 0x000000f7,
- 0x01f, 0x0000000b,
- 0x020, 0x000000d7,
- 0x01f, 0x0000000c,
- 0x020, 0x000000b7,
- 0x01f, 0x0000000d,
- 0x020, 0x00000097,
- 0x01f, 0x0000000e,
- 0x020, 0x00000077,
- 0x01f, 0x0000000f,
- 0x020, 0x00000057,
- 0x01f, 0x00000010,
- 0x020, 0x00000037,
- 0x01f, 0x00000011,
- 0x020, 0x000000fb,
- 0x01f, 0x00000012,
- 0x020, 0x000000db,
- 0x01f, 0x00000013,
- 0x020, 0x000000bb,
- 0x01f, 0x00000014,
- 0x020, 0x000000ff,
- 0x01f, 0x00000015,
- 0x020, 0x000000e3,
- 0x01f, 0x00000016,
- 0x020, 0x000000c3,
- 0x01f, 0x00000017,
- 0x020, 0x000000a3,
- 0x01f, 0x00000018,
- 0x020, 0x00000083,
- 0x01f, 0x00000019,
- 0x020, 0x00000063,
- 0x01f, 0x0000001a,
- 0x020, 0x00000043,
- 0x01f, 0x0000001b,
- 0x020, 0x00000023,
- 0x01f, 0x0000001c,
- 0x020, 0x00000003,
- 0x01f, 0x0000001d,
- 0x020, 0x000001e3,
- 0x01f, 0x0000001e,
- 0x020, 0x000001c3,
- 0x01f, 0x0000001f,
- 0x020, 0x000001a3,
- 0x01f, 0x00000020,
- 0x020, 0x00000183,
- 0x01f, 0x00000021,
- 0x020, 0x00000163,
- 0x01f, 0x00000022,
- 0x020, 0x00000143,
- 0x01f, 0x00000023,
- 0x020, 0x00000123,
- 0x01f, 0x00000024,
- 0x020, 0x00000103,
- 0x023, 0x00000203,
- 0x024, 0x00000100,
- 0x00b, 0x000001ba,
- 0x02c, 0x000003d7,
- 0x02d, 0x00000ff0,
- 0x000, 0x00000037,
- 0x004, 0x00000160,
- 0x007, 0x00000080,
- 0x002, 0x0000088d,
- 0x0fe, 0x00000000,
- 0x0fe, 0x00000000,
- 0x016, 0x00000200,
- 0x016, 0x00000380,
- 0x016, 0x00000020,
- 0x016, 0x000001a0,
- 0x000, 0x000000bf,
- 0x00d, 0x0000001f,
- 0x00d, 0x00000c9f,
- 0x002, 0x0000004d,
- 0x000, 0x00000cbf,
- 0x004, 0x00000975,
- 0x007, 0x00000700,
-};
-
-u32 RTL8192E_RADIO_B_ARR[RTL8192E_RADIO_B_ARR_LEN] = {
- 0x019, 0x00000003,
- 0x000, 0x000000bf,
- 0x001, 0x000006e0,
- 0x002, 0x0000004c,
- 0x003, 0x000007f1,
- 0x004, 0x00000975,
- 0x005, 0x00000c58,
- 0x006, 0x00000ae6,
- 0x007, 0x000000ca,
- 0x008, 0x00000e1c,
- 0x000, 0x000000b7,
- 0x00a, 0x00000850,
- 0x000, 0x000000bf,
- 0x00b, 0x000001ba,
- 0x00c, 0x00000240,
- 0x00e, 0x00000020,
- 0x015, 0x00000f80,
- 0x016, 0x00000020,
- 0x017, 0x00000597,
- 0x018, 0x0000050a,
- 0x01a, 0x00000e00,
- 0x01b, 0x00000f5e,
- 0x01d, 0x00000607,
- 0x01e, 0x000006cc,
- 0x00b, 0x000001ba,
- 0x023, 0x00000203,
- 0x024, 0x00000100,
- 0x000, 0x00000037,
- 0x004, 0x00000160,
- 0x016, 0x00000200,
- 0x016, 0x00000380,
- 0x016, 0x00000020,
- 0x016, 0x000001a0,
- 0x00d, 0x00000ccc,
- 0x000, 0x000000bf,
- 0x002, 0x0000004d,
- 0x000, 0x00000cbf,
- 0x004, 0x00000975,
- 0x007, 0x00000700,
-};
-
-u32 RTL8192E_MACPHY_ARR[] = {
- 0x03c, 0xffff0000, 0x00000f0f,
- 0x340, 0xffffffff, 0x161a1a1a,
- 0x344, 0xffffffff, 0x12121416,
- 0x348, 0x0000ffff, 0x00001818,
- 0x12c, 0xffffffff, 0x04000802,
- 0x318, 0x00000fff, 0x00000100,
-};
-
-u32 RTL8192E_MACPHY_ARR_PG[] = {
- 0x03c, 0xffff0000, 0x00000f0f,
- 0xe00, 0xffffffff, 0x06090909,
- 0xe04, 0xffffffff, 0x00030306,
- 0xe08, 0x0000ff00, 0x00000000,
- 0xe10, 0xffffffff, 0x0a0c0d0f,
- 0xe14, 0xffffffff, 0x06070809,
- 0xe18, 0xffffffff, 0x0a0c0d0f,
- 0xe1c, 0xffffffff, 0x06070809,
- 0x12c, 0xffffffff, 0x04000802,
- 0x318, 0x00000fff, 0x00000800,
-};
-
-u32 RTL8192E_AGCTAB_ARR[RTL8192E_AGCTAB_ARR_LEN] = {
- 0xc78, 0x7d000001,
- 0xc78, 0x7d010001,
- 0xc78, 0x7d020001,
- 0xc78, 0x7d030001,
- 0xc78, 0x7d040001,
- 0xc78, 0x7d050001,
- 0xc78, 0x7c060001,
- 0xc78, 0x7b070001,
- 0xc78, 0x7a080001,
- 0xc78, 0x79090001,
- 0xc78, 0x780a0001,
- 0xc78, 0x770b0001,
- 0xc78, 0x760c0001,
- 0xc78, 0x750d0001,
- 0xc78, 0x740e0001,
- 0xc78, 0x730f0001,
- 0xc78, 0x72100001,
- 0xc78, 0x71110001,
- 0xc78, 0x70120001,
- 0xc78, 0x6f130001,
- 0xc78, 0x6e140001,
- 0xc78, 0x6d150001,
- 0xc78, 0x6c160001,
- 0xc78, 0x6b170001,
- 0xc78, 0x6a180001,
- 0xc78, 0x69190001,
- 0xc78, 0x681a0001,
- 0xc78, 0x671b0001,
- 0xc78, 0x661c0001,
- 0xc78, 0x651d0001,
- 0xc78, 0x641e0001,
- 0xc78, 0x491f0001,
- 0xc78, 0x48200001,
- 0xc78, 0x47210001,
- 0xc78, 0x46220001,
- 0xc78, 0x45230001,
- 0xc78, 0x44240001,
- 0xc78, 0x43250001,
- 0xc78, 0x28260001,
- 0xc78, 0x27270001,
- 0xc78, 0x26280001,
- 0xc78, 0x25290001,
- 0xc78, 0x242a0001,
- 0xc78, 0x232b0001,
- 0xc78, 0x222c0001,
- 0xc78, 0x212d0001,
- 0xc78, 0x202e0001,
- 0xc78, 0x0a2f0001,
- 0xc78, 0x08300001,
- 0xc78, 0x06310001,
- 0xc78, 0x05320001,
- 0xc78, 0x04330001,
- 0xc78, 0x03340001,
- 0xc78, 0x02350001,
- 0xc78, 0x01360001,
- 0xc78, 0x00370001,
- 0xc78, 0x00380001,
- 0xc78, 0x00390001,
- 0xc78, 0x003a0001,
- 0xc78, 0x003b0001,
- 0xc78, 0x003c0001,
- 0xc78, 0x003d0001,
- 0xc78, 0x003e0001,
- 0xc78, 0x003f0001,
- 0xc78, 0x7d400001,
- 0xc78, 0x7d410001,
- 0xc78, 0x7d420001,
- 0xc78, 0x7d430001,
- 0xc78, 0x7d440001,
- 0xc78, 0x7d450001,
- 0xc78, 0x7c460001,
- 0xc78, 0x7b470001,
- 0xc78, 0x7a480001,
- 0xc78, 0x79490001,
- 0xc78, 0x784a0001,
- 0xc78, 0x774b0001,
- 0xc78, 0x764c0001,
- 0xc78, 0x754d0001,
- 0xc78, 0x744e0001,
- 0xc78, 0x734f0001,
- 0xc78, 0x72500001,
- 0xc78, 0x71510001,
- 0xc78, 0x70520001,
- 0xc78, 0x6f530001,
- 0xc78, 0x6e540001,
- 0xc78, 0x6d550001,
- 0xc78, 0x6c560001,
- 0xc78, 0x6b570001,
- 0xc78, 0x6a580001,
- 0xc78, 0x69590001,
- 0xc78, 0x685a0001,
- 0xc78, 0x675b0001,
- 0xc78, 0x665c0001,
- 0xc78, 0x655d0001,
- 0xc78, 0x645e0001,
- 0xc78, 0x495f0001,
- 0xc78, 0x48600001,
- 0xc78, 0x47610001,
- 0xc78, 0x46620001,
- 0xc78, 0x45630001,
- 0xc78, 0x44640001,
- 0xc78, 0x43650001,
- 0xc78, 0x28660001,
- 0xc78, 0x27670001,
- 0xc78, 0x26680001,
- 0xc78, 0x25690001,
- 0xc78, 0x246a0001,
- 0xc78, 0x236b0001,
- 0xc78, 0x226c0001,
- 0xc78, 0x216d0001,
- 0xc78, 0x206e0001,
- 0xc78, 0x0a6f0001,
- 0xc78, 0x08700001,
- 0xc78, 0x06710001,
- 0xc78, 0x05720001,
- 0xc78, 0x04730001,
- 0xc78, 0x03740001,
- 0xc78, 0x02750001,
- 0xc78, 0x01760001,
- 0xc78, 0x00770001,
- 0xc78, 0x00780001,
- 0xc78, 0x00790001,
- 0xc78, 0x007a0001,
- 0xc78, 0x007b0001,
- 0xc78, 0x007c0001,
- 0xc78, 0x007d0001,
- 0xc78, 0x007e0001,
- 0xc78, 0x007f0001,
- 0xc78, 0x2e00001e,
- 0xc78, 0x2e01001e,
- 0xc78, 0x2e02001e,
- 0xc78, 0x2e03001e,
- 0xc78, 0x2e04001e,
- 0xc78, 0x2e05001e,
- 0xc78, 0x3006001e,
- 0xc78, 0x3407001e,
- 0xc78, 0x3908001e,
- 0xc78, 0x3c09001e,
- 0xc78, 0x3f0a001e,
- 0xc78, 0x420b001e,
- 0xc78, 0x440c001e,
- 0xc78, 0x450d001e,
- 0xc78, 0x460e001e,
- 0xc78, 0x460f001e,
- 0xc78, 0x4710001e,
- 0xc78, 0x4811001e,
- 0xc78, 0x4912001e,
- 0xc78, 0x4a13001e,
- 0xc78, 0x4b14001e,
- 0xc78, 0x4b15001e,
- 0xc78, 0x4c16001e,
- 0xc78, 0x4d17001e,
- 0xc78, 0x4e18001e,
- 0xc78, 0x4f19001e,
- 0xc78, 0x4f1a001e,
- 0xc78, 0x501b001e,
- 0xc78, 0x511c001e,
- 0xc78, 0x521d001e,
- 0xc78, 0x521e001e,
- 0xc78, 0x531f001e,
- 0xc78, 0x5320001e,
- 0xc78, 0x5421001e,
- 0xc78, 0x5522001e,
- 0xc78, 0x5523001e,
- 0xc78, 0x5624001e,
- 0xc78, 0x5725001e,
- 0xc78, 0x5726001e,
- 0xc78, 0x5827001e,
- 0xc78, 0x5828001e,
- 0xc78, 0x5929001e,
- 0xc78, 0x592a001e,
- 0xc78, 0x5a2b001e,
- 0xc78, 0x5b2c001e,
- 0xc78, 0x5c2d001e,
- 0xc78, 0x5c2e001e,
- 0xc78, 0x5d2f001e,
- 0xc78, 0x5e30001e,
- 0xc78, 0x5f31001e,
- 0xc78, 0x6032001e,
- 0xc78, 0x6033001e,
- 0xc78, 0x6134001e,
- 0xc78, 0x6235001e,
- 0xc78, 0x6336001e,
- 0xc78, 0x6437001e,
- 0xc78, 0x6438001e,
- 0xc78, 0x6539001e,
- 0xc78, 0x663a001e,
- 0xc78, 0x673b001e,
- 0xc78, 0x673c001e,
- 0xc78, 0x683d001e,
- 0xc78, 0x693e001e,
- 0xc78, 0x6a3f001e,
-};
diff --git a/drivers/staging/rtl8192e/rtl8192e/table.h b/drivers/staging/rtl8192e/rtl8192e/table.h
deleted file mode 100644
index 82be44a9d4e8..000000000000
--- a/drivers/staging/rtl8192e/rtl8192e/table.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef __INC_HAL8192PciE_FW_IMG_H
-#define __INC_HAL8192PciE_FW_IMG_H
-
-/*Created on 2008/11/18, 3: 7*/
-
-#include <linux/types.h>
-
-#define RTL8192E_PHY_REG_1T2R_ARR_LEN 296
-extern u32 RTL8192E_PHY_REG_1T2R_ARR[RTL8192E_PHY_REG_1T2R_ARR_LEN];
-#define RTL8192E_RADIO_A_ARR_LEN 246
-extern u32 RTL8192E_RADIO_A_ARR[RTL8192E_RADIO_A_ARR_LEN];
-#define RTL8192E_RADIO_B_ARR_LEN 78
-extern u32 RTL8192E_RADIO_B_ARR[RTL8192E_RADIO_B_ARR_LEN];
-#define RTL8192E_MACPHY_ARR_LEN 18
-extern u32 RTL8192E_MACPHY_ARR[RTL8192E_MACPHY_ARR_LEN];
-#define RTL8192E_MACPHY_ARR_PG_LEN 30
-extern u32 RTL8192E_MACPHY_ARR_PG[RTL8192E_MACPHY_ARR_PG_LEN];
-#define RTL8192E_AGCTAB_ARR_LEN 384
-extern u32 RTL8192E_AGCTAB_ARR[RTL8192E_AGCTAB_ARR_LEN];
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl819x_BA.h b/drivers/staging/rtl8192e/rtl819x_BA.h
deleted file mode 100644
index 8a35d7a3eee1..000000000000
--- a/drivers/staging/rtl8192e/rtl819x_BA.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef _BATYPE_H_
-#define _BATYPE_H_
-
-#define BA_SETUP_TIMEOUT 200
-
-#define BA_POLICY_DELAYED 0
-#define BA_POLICY_IMMEDIATE 1
-
-#define ADDBA_STATUS_SUCCESS 0
-#define ADDBA_STATUS_REFUSED 37
-#define ADDBA_STATUS_INVALID_PARAM 38
-
-#define DELBA_REASON_END_BA 37
-#define DELBA_REASON_UNKNOWN_BA 38
-#define DELBA_REASON_TIMEOUT 39
-union sequence_control {
- u16 short_data;
- struct {
- u16 frag_num:4;
- u16 seq_num:12;
- } field;
-};
-
-union ba_param_set {
- u8 char_data[2];
- u16 short_data;
- struct {
- u16 amsdu_support:1;
- u16 ba_policy:1;
- u16 tid:4;
- u16 buffer_size:10;
- } field;
-};
-
-union delba_param_set {
- u8 char_data[2];
- u16 short_data;
- struct {
- u16 reserved:11;
- u16 initiator:1;
- u16 tid:4;
- } field;
-};
-
-struct ba_record {
- struct timer_list timer;
- u8 b_valid;
- u8 dialog_token;
- union ba_param_set ba_param_set;
- u16 ba_timeout_value;
- union sequence_control ba_start_seq_ctrl;
-};
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c
deleted file mode 100644
index c400d4f8ff9a..000000000000
--- a/drivers/staging/rtl8192e/rtl819x_BAProc.c
+++ /dev/null
@@ -1,544 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include <asm/byteorder.h>
-#include <linux/unaligned.h>
-#include <linux/etherdevice.h>
-#include "rtllib.h"
-#include "rtl819x_BA.h"
-
-static void activate_ba_entry(struct ba_record *ba, u16 time)
-{
- ba->b_valid = true;
- if (time != 0)
- mod_timer(&ba->timer, jiffies + msecs_to_jiffies(time));
-}
-
-static void deactivate_ba_entry(struct rtllib_device *ieee, struct ba_record *ba)
-{
- ba->b_valid = false;
- del_timer_sync(&ba->timer);
-}
-
-static u8 tx_ts_delete_ba(struct rtllib_device *ieee, struct tx_ts_record *ts)
-{
- struct ba_record *admitted_ba = &ts->tx_admitted_ba_record;
- struct ba_record *pending_ba = &ts->tx_pending_ba_record;
- u8 send_del_ba = false;
-
- if (pending_ba->b_valid) {
- deactivate_ba_entry(ieee, pending_ba);
- send_del_ba = true;
- }
-
- if (admitted_ba->b_valid) {
- deactivate_ba_entry(ieee, admitted_ba);
- send_del_ba = true;
- }
- return send_del_ba;
-}
-
-static u8 rx_ts_delete_ba(struct rtllib_device *ieee, struct rx_ts_record *ts)
-{
- struct ba_record *ba = &ts->rx_admitted_ba_record;
- u8 send_del_ba = false;
-
- if (ba->b_valid) {
- deactivate_ba_entry(ieee, ba);
- send_del_ba = true;
- }
-
- return send_del_ba;
-}
-
-void rtllib_reset_ba_entry(struct ba_record *ba)
-{
- ba->b_valid = false;
- ba->ba_param_set.short_data = 0;
- ba->ba_timeout_value = 0;
- ba->dialog_token = 0;
- ba->ba_start_seq_ctrl.short_data = 0;
-}
-
-static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *dst,
- struct ba_record *ba,
- u16 status_code, u8 type)
-{
- struct sk_buff *skb = NULL;
- struct ieee80211_hdr_3addr *ba_req = NULL;
- u8 *tag = NULL;
- u16 len = ieee->tx_headroom + 9;
-
- netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n",
- __func__, type, dst, ieee->dev);
-
- if (!ba) {
- netdev_warn(ieee->dev, "ba is NULL\n");
- return NULL;
- }
- skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr));
- if (!skb)
- return NULL;
-
- memset(skb->data, 0, sizeof(struct ieee80211_hdr_3addr));
-
- skb_reserve(skb, ieee->tx_headroom);
-
- ba_req = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
-
- ether_addr_copy(ba_req->addr1, dst);
- ether_addr_copy(ba_req->addr2, ieee->dev->dev_addr);
-
- ether_addr_copy(ba_req->addr3, ieee->current_network.bssid);
- ba_req->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);
-
- tag = skb_put(skb, 9);
- *tag++ = ACT_CAT_BA;
- *tag++ = type;
- *tag++ = ba->dialog_token;
-
- if (type == ACT_ADDBARSP) {
- put_unaligned_le16(status_code, tag);
- tag += 2;
- }
-
- put_unaligned_le16(ba->ba_param_set.short_data, tag);
- tag += 2;
-
- put_unaligned_le16(ba->ba_timeout_value, tag);
- tag += 2;
-
- if (type == ACT_ADDBAREQ) {
- memcpy(tag, (u8 *)&ba->ba_start_seq_ctrl, 2);
- tag += 2;
- }
-
-#ifdef VERBOSE_DEBUG
- print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
- __func__, skb->len);
-#endif
- return skb;
-}
-
-static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst,
- struct ba_record *ba,
- enum tr_select tx_rx_select, u16 reason_code)
-{
- union delba_param_set del_ba_param_set;
- struct sk_buff *skb = NULL;
- struct ieee80211_hdr_3addr *del_ba = NULL;
- u8 *tag = NULL;
- u16 len = 6 + ieee->tx_headroom;
-
- if (net_ratelimit())
- netdev_dbg(ieee->dev, "%s(): reason_code(%d) sentd to: %pM\n",
- __func__, reason_code, dst);
-
- memset(&del_ba_param_set, 0, 2);
-
- del_ba_param_set.field.initiator = (tx_rx_select == TX_DIR) ? 1 : 0;
- del_ba_param_set.field.tid = ba->ba_param_set.field.tid;
-
- skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr));
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- del_ba = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
-
- ether_addr_copy(del_ba->addr1, dst);
- ether_addr_copy(del_ba->addr2, ieee->dev->dev_addr);
- ether_addr_copy(del_ba->addr3, ieee->current_network.bssid);
- del_ba->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);
-
- tag = skb_put(skb, 6);
-
- *tag++ = ACT_CAT_BA;
- *tag++ = ACT_DELBA;
-
- put_unaligned_le16(del_ba_param_set.short_data, tag);
- tag += 2;
-
- put_unaligned_le16(reason_code, tag);
- tag += 2;
-
-#ifdef VERBOSE_DEBUG
- print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
- __func__, skb->len);
-#endif
- return skb;
-}
-
-static void rtllib_send_add_ba_req(struct rtllib_device *ieee, u8 *dst,
- struct ba_record *ba)
-{
- struct sk_buff *skb;
-
- skb = rtllib_ADDBA(ieee, dst, ba, 0, ACT_ADDBAREQ);
-
- if (skb)
- softmac_mgmt_xmit(skb, ieee);
- else
- netdev_dbg(ieee->dev, "Failed to generate ADDBAReq packet.\n");
-}
-
-static void rtllib_send_add_ba_rsp(struct rtllib_device *ieee, u8 *dst,
- struct ba_record *ba, u16 status_code)
-{
- struct sk_buff *skb;
-
- skb = rtllib_ADDBA(ieee, dst, ba, status_code, ACT_ADDBARSP);
- if (skb)
- softmac_mgmt_xmit(skb, ieee);
- else
- netdev_dbg(ieee->dev, "Failed to generate ADDBARsp packet.\n");
-}
-
-static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst,
- struct ba_record *ba, enum tr_select tx_rx_select,
- u16 reason_code)
-{
- struct sk_buff *skb;
-
- skb = rtllib_DELBA(ieee, dst, ba, tx_rx_select, reason_code);
- if (skb)
- softmac_mgmt_xmit(skb, ieee);
- else
- netdev_dbg(ieee->dev, "Failed to generate DELBA packet.\n");
-}
-
-int rtllib_rx_add_ba_req(struct rtllib_device *ieee, struct sk_buff *skb)
-{
- struct ieee80211_hdr_3addr *req = NULL;
- u16 rc = 0;
- u8 *dst = NULL, *dialog_token = NULL, *tag = NULL;
- struct ba_record *ba = NULL;
- union ba_param_set *ba_param_set = NULL;
- u16 *ba_timeout_value = NULL;
- union sequence_control *ba_start_seq_ctrl = NULL;
- struct rx_ts_record *ts = NULL;
-
- if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) {
- netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n",
- (int)skb->len,
- (int)(sizeof(struct ieee80211_hdr_3addr) + 9));
- return -1;
- }
-
-#ifdef VERBOSE_DEBUG
- print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, __func__,
- skb->data, skb->len);
-#endif
-
- req = (struct ieee80211_hdr_3addr *)skb->data;
- tag = (u8 *)req;
- dst = (u8 *)(&req->addr2[0]);
- tag += sizeof(struct ieee80211_hdr_3addr);
- dialog_token = tag + 2;
- ba_param_set = (union ba_param_set *)(tag + 3);
- ba_timeout_value = (u16 *)(tag + 5);
- ba_start_seq_ctrl = (union sequence_control *)(req + 7);
-
- if (!ieee->current_network.qos_data.active ||
- !ieee->ht_info->current_ht_support ||
- (ieee->ht_info->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) {
- rc = ADDBA_STATUS_REFUSED;
- netdev_warn(ieee->dev,
- "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n",
- ieee->current_network.qos_data.active,
- ieee->ht_info->current_ht_support);
- goto on_add_ba_req_fail;
- }
- if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
- (u8)(ba_param_set->field.tid), RX_DIR, true)) {
- rc = ADDBA_STATUS_REFUSED;
- netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
- goto on_add_ba_req_fail;
- }
- ba = &ts->rx_admitted_ba_record;
-
- if (ba_param_set->field.ba_policy == BA_POLICY_DELAYED) {
- rc = ADDBA_STATUS_INVALID_PARAM;
- netdev_warn(ieee->dev, "%s(): BA Policy is not correct\n",
- __func__);
- goto on_add_ba_req_fail;
- }
-
- rtllib_flush_rx_ts_pending_pkts(ieee, ts);
-
- deactivate_ba_entry(ieee, ba);
- ba->dialog_token = *dialog_token;
- ba->ba_param_set = *ba_param_set;
- ba->ba_timeout_value = *ba_timeout_value;
- ba->ba_start_seq_ctrl = *ba_start_seq_ctrl;
-
- if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev) ||
- (ieee->ht_info->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT))
- ba->ba_param_set.field.buffer_size = 1;
- else
- ba->ba_param_set.field.buffer_size = 32;
-
- activate_ba_entry(ba, 0);
- rtllib_send_add_ba_rsp(ieee, dst, ba, ADDBA_STATUS_SUCCESS);
-
- return 0;
-
-on_add_ba_req_fail:
- {
- struct ba_record BA;
-
- BA.ba_param_set = *ba_param_set;
- BA.ba_timeout_value = *ba_timeout_value;
- BA.dialog_token = *dialog_token;
- BA.ba_param_set.field.ba_policy = BA_POLICY_IMMEDIATE;
- rtllib_send_add_ba_rsp(ieee, dst, &BA, rc);
- return 0;
- }
-}
-
-int rtllib_rx_add_ba_rsp(struct rtllib_device *ieee, struct sk_buff *skb)
-{
- struct ieee80211_hdr_3addr *rsp = NULL;
- struct ba_record *pending_ba, *admitted_ba;
- struct tx_ts_record *ts = NULL;
- u8 *dst = NULL, *dialog_token = NULL, *tag = NULL;
- u16 *status_code = NULL, *ba_timeout_value = NULL;
- union ba_param_set *ba_param_set = NULL;
- u16 reason_code;
-
- if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) {
- netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n",
- (int)skb->len,
- (int)(sizeof(struct ieee80211_hdr_3addr) + 9));
- return -1;
- }
- rsp = (struct ieee80211_hdr_3addr *)skb->data;
- tag = (u8 *)rsp;
- dst = (u8 *)(&rsp->addr2[0]);
- tag += sizeof(struct ieee80211_hdr_3addr);
- dialog_token = tag + 2;
- status_code = (u16 *)(tag + 3);
- ba_param_set = (union ba_param_set *)(tag + 5);
- ba_timeout_value = (u16 *)(tag + 7);
-
- if (!ieee->current_network.qos_data.active ||
- !ieee->ht_info->current_ht_support ||
- !ieee->ht_info->current_ampdu_enable) {
- netdev_warn(ieee->dev,
- "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",
- ieee->current_network.qos_data.active,
- ieee->ht_info->current_ht_support,
- ieee->ht_info->current_ampdu_enable);
- reason_code = DELBA_REASON_UNKNOWN_BA;
- goto on_add_ba_rsp_reject;
- }
-
- if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
- (u8)(ba_param_set->field.tid), TX_DIR, false)) {
- netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
- reason_code = DELBA_REASON_UNKNOWN_BA;
- goto on_add_ba_rsp_reject;
- }
-
- ts->add_ba_req_in_progress = false;
- pending_ba = &ts->tx_pending_ba_record;
- admitted_ba = &ts->tx_admitted_ba_record;
-
- if (admitted_ba->b_valid) {
- netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n",
- __func__);
- return -1;
- } else if (!pending_ba->b_valid ||
- (*dialog_token != pending_ba->dialog_token)) {
- netdev_warn(ieee->dev,
- "%s(): ADDBA Rsp. BA invalid, DELBA!\n",
- __func__);
- reason_code = DELBA_REASON_UNKNOWN_BA;
- goto on_add_ba_rsp_reject;
- } else {
- netdev_dbg(ieee->dev,
- "%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n",
- __func__, *status_code);
- deactivate_ba_entry(ieee, pending_ba);
- }
-
- if (*status_code == ADDBA_STATUS_SUCCESS) {
- if (ba_param_set->field.ba_policy == BA_POLICY_DELAYED) {
- ts->add_ba_req_delayed = true;
- deactivate_ba_entry(ieee, admitted_ba);
- reason_code = DELBA_REASON_END_BA;
- goto on_add_ba_rsp_reject;
- }
-
- admitted_ba->dialog_token = *dialog_token;
- admitted_ba->ba_timeout_value = *ba_timeout_value;
- admitted_ba->ba_start_seq_ctrl = pending_ba->ba_start_seq_ctrl;
- admitted_ba->ba_param_set = *ba_param_set;
- deactivate_ba_entry(ieee, admitted_ba);
- activate_ba_entry(admitted_ba, *ba_timeout_value);
- } else {
- ts->add_ba_req_delayed = true;
- ts->disable_add_ba = true;
- reason_code = DELBA_REASON_END_BA;
- goto on_add_ba_rsp_reject;
- }
-
- return 0;
-
-on_add_ba_rsp_reject:
- {
- struct ba_record BA;
-
- BA.ba_param_set = *ba_param_set;
- rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, reason_code);
- return 0;
- }
-}
-
-int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb)
-{
- struct ieee80211_hdr_3addr *delba = NULL;
- union delba_param_set *del_ba_param_set = NULL;
- u8 *dst = NULL;
-
- if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 6) {
- netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n",
- (int)skb->len,
- (int)(sizeof(struct ieee80211_hdr_3addr) + 6));
- return -1;
- }
-
- if (!ieee->current_network.qos_data.active ||
- !ieee->ht_info->current_ht_support) {
- netdev_warn(ieee->dev,
- "received DELBA while QOS or HT is not supported(%d, %d)\n",
- ieee->current_network. qos_data.active,
- ieee->ht_info->current_ht_support);
- return -1;
- }
-
-#ifdef VERBOSE_DEBUG
- print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
- __func__, skb->len);
-#endif
- delba = (struct ieee80211_hdr_3addr *)skb->data;
- dst = (u8 *)(&delba->addr2[0]);
- del_ba_param_set = (union delba_param_set *)&delba->seq_ctrl + 2;
-
- if (del_ba_param_set->field.initiator == 1) {
- struct rx_ts_record *ts;
-
- if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
- (u8)del_ba_param_set->field.tid, RX_DIR, false)) {
- netdev_warn(ieee->dev,
- "%s(): can't get TS for RXTS. dst:%pM TID:%d\n",
- __func__, dst,
- (u8)del_ba_param_set->field.tid);
- return -1;
- }
-
- rx_ts_delete_ba(ieee, ts);
- } else {
- struct tx_ts_record *ts;
-
- if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
- (u8)del_ba_param_set->field.tid, TX_DIR, false)) {
- netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n",
- __func__);
- return -1;
- }
-
- ts->using_ba = false;
- ts->add_ba_req_in_progress = false;
- ts->add_ba_req_delayed = false;
- del_timer_sync(&ts->ts_add_ba_timer);
- tx_ts_delete_ba(ieee, ts);
- }
- return 0;
-}
-
-void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts,
- u8 policy, u8 overwrite_pending)
-{
- struct ba_record *ba = &ts->tx_pending_ba_record;
-
- if (ba->b_valid && !overwrite_pending)
- return;
-
- deactivate_ba_entry(ieee, ba);
-
- ba->dialog_token++;
- ba->ba_param_set.field.amsdu_support = 0;
- ba->ba_param_set.field.ba_policy = policy;
- ba->ba_param_set.field.tid = ts->ts_common_info.tspec.ts_id;
- ba->ba_param_set.field.buffer_size = 32;
- ba->ba_timeout_value = 0;
- ba->ba_start_seq_ctrl.field.seq_num = (ts->tx_cur_seq + 3) % 4096;
-
- activate_ba_entry(ba, BA_SETUP_TIMEOUT);
-
- rtllib_send_add_ba_req(ieee, ts->ts_common_info.addr, ba);
-}
-
-void rtllib_ts_init_del_ba(struct rtllib_device *ieee,
- struct ts_common_info *ts_common_info,
- enum tr_select tx_rx_select)
-{
- if (tx_rx_select == TX_DIR) {
- struct tx_ts_record *ts =
- (struct tx_ts_record *)ts_common_info;
-
- if (tx_ts_delete_ba(ieee, ts))
- rtllib_send_DELBA(ieee, ts_common_info->addr,
- (ts->tx_admitted_ba_record.b_valid) ?
- (&ts->tx_admitted_ba_record) :
- (&ts->tx_pending_ba_record),
- tx_rx_select, DELBA_REASON_END_BA);
- } else if (tx_rx_select == RX_DIR) {
- struct rx_ts_record *ts =
- (struct rx_ts_record *)ts_common_info;
- if (rx_ts_delete_ba(ieee, ts))
- rtllib_send_DELBA(ieee, ts_common_info->addr,
- &ts->rx_admitted_ba_record,
- tx_rx_select, DELBA_REASON_END_BA);
- }
-}
-
-void rtllib_ba_setup_timeout(struct timer_list *t)
-{
- struct tx_ts_record *ts = from_timer(ts, t,
- tx_pending_ba_record.timer);
-
- ts->add_ba_req_in_progress = false;
- ts->add_ba_req_delayed = true;
- ts->tx_pending_ba_record.b_valid = false;
-}
-
-void rtllib_tx_ba_inact_timeout(struct timer_list *t)
-{
- struct tx_ts_record *ts = from_timer(ts, t,
- tx_admitted_ba_record.timer);
- struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
- tx_ts_records[ts->num]);
- tx_ts_delete_ba(ieee, ts);
- rtllib_send_DELBA(ieee, ts->ts_common_info.addr,
- &ts->tx_admitted_ba_record, TX_DIR,
- DELBA_REASON_TIMEOUT);
-}
-
-void rtllib_rx_ba_inact_timeout(struct timer_list *t)
-{
- struct rx_ts_record *ts = from_timer(ts, t,
- rx_admitted_ba_record.timer);
- struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
- rx_ts_records[ts->num]);
-
- rx_ts_delete_ba(ieee, ts);
- rtllib_send_DELBA(ieee, ts->ts_common_info.addr,
- &ts->rx_admitted_ba_record, RX_DIR,
- DELBA_REASON_TIMEOUT);
-}
diff --git a/drivers/staging/rtl8192e/rtl819x_HT.h b/drivers/staging/rtl8192e/rtl819x_HT.h
deleted file mode 100644
index a6e0077630c7..000000000000
--- a/drivers/staging/rtl8192e/rtl819x_HT.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef _RTL819XU_HTTYPE_H_
-#define _RTL819XU_HTTYPE_H_
-
-#define MIMO_PS_STATIC 0
-
-#define sHTCLng 4
-
-enum ht_channel_width {
- HT_CHANNEL_WIDTH_20 = 0,
- HT_CHANNEL_WIDTH_20_40 = 1,
-};
-
-enum ht_extchnl_offset {
- HT_EXTCHNL_OFFSET_NO_EXT = 0,
- HT_EXTCHNL_OFFSET_UPPER = 1,
- HT_EXTCHNL_OFFSET_NO_DEF = 2,
- HT_EXTCHNL_OFFSET_LOWER = 3,
-};
-
-struct ht_capab_ele {
- u8 adv_coding:1;
- u8 chl_width:1;
- u8 mimo_pwr_save:2;
- u8 green_field:1;
- u8 short_gi_20mhz:1;
- u8 short_gi_40mhz:1;
- u8 tx_stbc:1;
- u8 rx_stbc:2;
- u8 delay_ba:1;
- u8 max_amsdu_size:1;
- u8 dss_cck:1;
- u8 PSMP:1;
- u8 Rsvd1:1;
- u8 lsig_txop_protect:1;
-
- u8 max_rx_ampdu_factor:2;
- u8 mpdu_density:3;
- u8 Rsvd2:3;
-
- u8 MCS[16];
-
- u16 ext_ht_cap_info;
-
- u8 TxBFCap[4];
-
- u8 ASCap;
-
-} __packed;
-
-struct ht_info_ele {
- u8 ControlChl;
-
- u8 ExtChlOffset:2;
- u8 RecommemdedTxWidth:1;
- u8 RIFS:1;
- u8 PSMPAccessOnly:1;
- u8 SrvIntGranularity:3;
-
- u8 opt_mode:2;
- u8 NonGFDevPresent:1;
- u8 Revd1:5;
- u8 Revd2:8;
-
- u8 Rsvd3:6;
- u8 DualBeacon:1;
- u8 DualCTSProtect:1;
-
- u8 SecondaryBeacon:1;
- u8 LSigTxopProtectFull:1;
- u8 PcoActive:1;
- u8 PcoPhase:1;
- u8 Rsvd4:4;
-
- u8 BasicMSC[16];
-} __packed;
-
-enum ht_spec_ver {
- HT_SPEC_VER_IEEE = 0,
- HT_SPEC_VER_EWC = 1,
-};
-
-enum ht_aggre_mode {
- HT_AGG_AUTO = 0,
- HT_AGG_FORCE_ENABLE = 1,
- HT_AGG_FORCE_DISABLE = 2,
-};
-
-struct rt_hi_throughput {
- u8 enable_ht;
- u8 current_ht_support;
- u8 cur_bw_40mhz;
- u8 cur_short_gi_40mhz;
- u8 cur_short_gi_20mhz;
- enum ht_spec_ver peer_ht_spec_ver;
- struct ht_capab_ele self_ht_cap;
- u8 peer_ht_cap_buf[32];
- u8 peer_ht_info_buf[32];
- u8 ampdu_enable;
- u8 current_ampdu_enable;
- u8 ampdu_factor;
- u8 current_ampdu_factor;
- u8 current_mpdu_density;
- u8 forced_ampdu_factor;
- u8 forced_mpdu_density;
- u8 current_op_mode;
- enum ht_extchnl_offset cur_sta_ext_chnl_offset;
- u8 cur_tx_bw40mhz;
- u8 sw_bw_in_progress;
- u8 current_rt2rt_aggregation;
- u8 current_rt2rt_long_slot_time;
- u8 sz_rt2rt_agg_buf[10];
- u8 cur_rx_reorder_enable;
- u8 rx_reorder_win_size;
- u8 rx_reorder_pending_time;
- u16 rx_reorder_drop_counter;
- u8 iot_peer;
- u32 iot_action;
- u8 iot_ra_func;
-} __packed;
-
-struct bss_ht {
- u8 bd_support_ht;
-
- u8 bd_ht_cap_buf[32];
- u16 bd_ht_cap_len;
- u8 bd_ht_info_buf[32];
- u16 bd_ht_info_len;
-
- enum ht_spec_ver bd_ht_spec_ver;
- enum ht_channel_width bd_bandwidth;
-
- u8 bd_rt2rt_aggregation;
- u8 bd_rt2rt_long_slot_time;
- u8 rt2rt_ht_mode;
- u8 bd_ht_1r;
-};
-
-extern u8 MCS_FILTER_ALL[16];
-extern u8 MCS_FILTER_1SS[16];
-
-#define RATE_ADPT_1SS_MASK 0xFF
-#define RATE_ADPT_2SS_MASK 0xF0
-#define RATE_ADPT_MCS32_MASK 0x01
-
-enum ht_aggre_size {
- HT_AGG_SIZE_8K = 0,
- HT_AGG_SIZE_16K = 1,
- HT_AGG_SIZE_32K = 2,
- HT_AGG_SIZE_64K = 3,
-};
-
-enum ht_iot_peer {
- HT_IOT_PEER_UNKNOWN = 0,
- HT_IOT_PEER_REALTEK = 1,
- HT_IOT_PEER_REALTEK_92SE = 2,
- HT_IOT_PEER_BROADCOM = 3,
- HT_IOT_PEER_RALINK = 4,
- HT_IOT_PEER_ATHEROS = 5,
- HT_IOT_PEER_CISCO = 6,
- HT_IOT_PEER_MARVELL = 7,
- HT_IOT_PEER_92U_SOFTAP = 8,
- HT_IOT_PEER_SELF_SOFTAP = 9,
- HT_IOT_PEER_AIRGO = 10,
- HT_IOT_PEER_MAX = 11,
-};
-
-enum ht_iot_action {
- HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
- HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
- HT_IOT_ACT_DISABLE_MCS14 = 0x00000004,
- HT_IOT_ACT_DISABLE_MCS15 = 0x00000008,
- HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010,
- HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020,
- HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040,
- HT_IOT_ACT_CDD_FSYNC = 0x00000080,
- HT_IOT_ACT_PURE_N_MODE = 0x00000100,
- HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
- HT_IOT_ACT_FORCED_RTS = 0x00000400,
- HT_IOT_ACT_AMSDU_ENABLE = 0x00000800,
- HT_IOT_ACT_REJECT_ADDBA_REQ = 0x00001000,
- HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT = 0x00002000,
- HT_IOT_ACT_EDCA_BIAS_ON_RX = 0x00004000,
-
- HT_IOT_ACT_HYBRID_AGGREGATION = 0x00010000,
- HT_IOT_ACT_DISABLE_SHORT_GI = 0x00020000,
- HT_IOT_ACT_DISABLE_HIGH_POWER = 0x00040000,
- HT_IOT_ACT_DISABLE_TX_40_MHZ = 0x00080000,
- HT_IOT_ACT_TX_NO_AGGREGATION = 0x00100000,
- HT_IOT_ACT_DISABLE_TX_2SS = 0x00200000,
-
- HT_IOT_ACT_MID_HIGHPOWER = 0x00400000,
- HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000,
-
- HT_IOT_ACT_DISABLE_CCK_RATE = 0x01000000,
- HT_IOT_ACT_FORCED_ENABLE_BE_TXOP = 0x02000000,
- HT_IOT_ACT_WA_IOT_Broadcom = 0x04000000,
-
- HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI = 0x08000000,
-
-};
-
-enum ht_iot_rafunc {
- HT_IOT_RAFUNC_DISABLE_ALL = 0x00,
- HT_IOT_RAFUNC_PEER_1R = 0x01,
- HT_IOT_RAFUNC_TX_AMSDU = 0x02,
-};
-
-enum rt_ht_capability {
- RT_HT_CAP_USE_TURBO_AGGR = 0x01,
- RT_HT_CAP_USE_LONG_PREAMBLE = 0x02,
- RT_HT_CAP_USE_AMPDU = 0x04,
- RT_HT_CAP_USE_WOW = 0x8,
- RT_HT_CAP_USE_SOFTAP = 0x10,
- RT_HT_CAP_USE_92SE = 0x20,
-};
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c
deleted file mode 100644
index 9c9c0bc0cfde..000000000000
--- a/drivers/staging/rtl8192e/rtl819x_HTProc.c
+++ /dev/null
@@ -1,699 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtllib.h"
-#include "rtl819x_HT.h"
-u8 MCS_FILTER_ALL[16] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-u8 MCS_FILTER_1SS[16] = {
- 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-;
-
-u16 MCS_DATA_RATE[2][2][77] = {
- {{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234,
- 260, 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416,
- 468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182,
- 182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156,
- 181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273,
- 312, 351, 312, 351, 390, 390, 429},
- {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
- 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520,
- 578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231,
- 173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260,
- 231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390,
- 433, 433, 477} },
- {{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486,
- 540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648,
- 864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324,
- 378, 378, 432, 324, 405, 405, 486, 567, 567, 648, 270, 324, 378, 324,
- 378, 432, 486, 432, 486, 540, 540, 594, 405, 486, 567, 486, 567, 648,
- 729, 648, 729, 810, 810, 891},
- {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
- 600, 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720,
- 960, 1080, 1200, 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360,
- 420, 420, 480, 360, 450, 450, 540, 630, 630, 720, 300, 360, 420, 360,
- 420, 480, 540, 480, 540, 600, 600, 660, 450, 540, 630, 540, 630, 720,
- 810, 720, 810, 900, 900, 990} }
-};
-
-static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
-
-static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
-
-static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
-
-static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};
-
-static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
-
-static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
-
-static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
-
-static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
-
-static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0};
-
-static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
-
-static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
-
-static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
-
-void ht_update_default_setting(struct rtllib_device *ieee)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
-
- ht_info->ampdu_enable = 1;
- ht_info->ampdu_factor = 2;
-
- ieee->tx_dis_rate_fallback = 0;
- ieee->tx_use_drv_assinged_rate = 0;
-
- ieee->tx_enable_fw_calc_dur = 1;
-
- ht_info->rx_reorder_win_size = 64;
- ht_info->rx_reorder_pending_time = 30;
-}
-
-static u16 ht_mcs_to_data_rate(struct rtllib_device *ieee, u8 mcs_rate)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
-
- u8 is40MHz = (ht_info->cur_bw_40mhz) ? 1 : 0;
- u8 isShortGI = (ht_info->cur_bw_40mhz) ?
- ((ht_info->cur_short_gi_40mhz) ? 1 : 0) :
- ((ht_info->cur_short_gi_20mhz) ? 1 : 0);
- return MCS_DATA_RATE[is40MHz][isShortGI][(mcs_rate & 0x7f)];
-}
-
-u16 tx_count_to_data_rate(struct rtllib_device *ieee, u8 data_rate)
-{
- u16 cck_of_dm_rate[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18,
- 0x24, 0x30, 0x48, 0x60, 0x6c};
- u8 is40MHz = 0;
- u8 isShortGI = 0;
-
- if (data_rate < 12)
- return cck_of_dm_rate[data_rate];
- if (data_rate >= 0x10 && data_rate <= 0x1f) {
- is40MHz = 0;
- isShortGI = 0;
- } else if (data_rate >= 0x20 && data_rate <= 0x2f) {
- is40MHz = 1;
- isShortGI = 0;
- } else if (data_rate >= 0x30 && data_rate <= 0x3f) {
- is40MHz = 0;
- isShortGI = 1;
- } else if (data_rate >= 0x40 && data_rate <= 0x4f) {
- is40MHz = 1;
- isShortGI = 1;
- }
- return MCS_DATA_RATE[is40MHz][isShortGI][data_rate & 0xf];
-}
-
-bool is_ht_half_nmode_aps(struct rtllib_device *ieee)
-{
- bool retValue = false;
- struct rtllib_network *net = &ieee->current_network;
-
- if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) ||
- (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) ||
- (memcmp(net->bssid, PCI_RALINK, 3) == 0) ||
- (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) ||
- (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) ||
- (net->ralink_cap_exist))
- retValue = true;
- else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) ||
- !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) ||
- !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ||
- (net->broadcom_cap_exist))
- retValue = true;
- else if (net->bssht.bd_rt2rt_aggregation)
- retValue = true;
- else
- retValue = false;
-
- return retValue;
-}
-
-static void ht_iot_peer_determine(struct rtllib_device *ieee)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
- struct rtllib_network *net = &ieee->current_network;
-
- if (net->bssht.bd_rt2rt_aggregation) {
- ht_info->iot_peer = HT_IOT_PEER_REALTEK;
- if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_92SE)
- ht_info->iot_peer = HT_IOT_PEER_REALTEK_92SE;
- if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_SOFTAP)
- ht_info->iot_peer = HT_IOT_PEER_92U_SOFTAP;
- } else if (net->broadcom_cap_exist) {
- ht_info->iot_peer = HT_IOT_PEER_BROADCOM;
- } else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) ||
- !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) ||
- !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)) {
- ht_info->iot_peer = HT_IOT_PEER_BROADCOM;
- } else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) ||
- (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) ||
- (memcmp(net->bssid, PCI_RALINK, 3) == 0) ||
- (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) ||
- (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) ||
- net->ralink_cap_exist) {
- ht_info->iot_peer = HT_IOT_PEER_RALINK;
- } else if ((net->atheros_cap_exist) ||
- (memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0) ||
- (memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0)) {
- ht_info->iot_peer = HT_IOT_PEER_ATHEROS;
- } else if ((memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) ||
- net->cisco_cap_exist) {
- ht_info->iot_peer = HT_IOT_PEER_CISCO;
- } else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
- net->marvell_cap_exist) {
- ht_info->iot_peer = HT_IOT_PEER_MARVELL;
- } else if (net->airgo_cap_exist) {
- ht_info->iot_peer = HT_IOT_PEER_AIRGO;
- } else {
- ht_info->iot_peer = HT_IOT_PEER_UNKNOWN;
- }
-
- netdev_dbg(ieee->dev, "IOTPEER: %x\n", ht_info->iot_peer);
-}
-
-static u8 ht_iot_act_is_mgnt_use_cck_6m(struct rtllib_device *ieee,
- struct rtllib_network *network)
-{
- u8 retValue = 0;
-
- if (ieee->ht_info->iot_peer == HT_IOT_PEER_BROADCOM)
- retValue = 1;
-
- return retValue;
-}
-
-static u8 ht_iot_act_is_ccd_fsync(struct rtllib_device *ieee)
-{
- u8 retValue = 0;
-
- if (ieee->ht_info->iot_peer == HT_IOT_PEER_BROADCOM)
- retValue = 1;
- return retValue;
-}
-
-static void ht_iot_act_determine_ra_func(struct rtllib_device *ieee, bool bPeerRx2ss)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
-
- ht_info->iot_ra_func &= HT_IOT_RAFUNC_DISABLE_ALL;
-
- if (ht_info->iot_peer == HT_IOT_PEER_RALINK && !bPeerRx2ss)
- ht_info->iot_ra_func |= HT_IOT_RAFUNC_PEER_1R;
-
- if (ht_info->iot_action & HT_IOT_ACT_AMSDU_ENABLE)
- ht_info->iot_ra_func |= HT_IOT_RAFUNC_TX_AMSDU;
-}
-
-void ht_reset_iot_setting(struct rt_hi_throughput *ht_info)
-{
- ht_info->iot_action = 0;
- ht_info->iot_peer = HT_IOT_PEER_UNKNOWN;
- ht_info->iot_ra_func = 0;
-}
-
-void ht_construct_capability_element(struct rtllib_device *ieee, u8 *pos_ht_cap,
- u8 *len, u8 is_encrypt, bool assoc)
-{
- struct rt_hi_throughput *ht = ieee->ht_info;
- struct ht_capab_ele *cap_ele = NULL;
-
- if (!pos_ht_cap || !ht) {
- netdev_warn(ieee->dev,
- "%s(): pos_ht_cap and ht_info are null\n", __func__);
- return;
- }
- memset(pos_ht_cap, 0, *len);
-
- if ((assoc) && (ht->peer_ht_spec_ver == HT_SPEC_VER_EWC)) {
- static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 };
-
- memcpy(pos_ht_cap, EWC11NHTCap, sizeof(EWC11NHTCap));
- cap_ele = (struct ht_capab_ele *)&pos_ht_cap[4];
- *len = 30 + 2;
- } else {
- cap_ele = (struct ht_capab_ele *)pos_ht_cap;
- *len = 26 + 2;
- }
-
- cap_ele->adv_coding = 0;
- if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev))
- cap_ele->chl_width = 0;
- else
- cap_ele->chl_width = 1;
-
- cap_ele->mimo_pwr_save = 3;
- cap_ele->green_field = 0;
- cap_ele->short_gi_20mhz = 1;
- cap_ele->short_gi_40mhz = 1;
-
- cap_ele->tx_stbc = 1;
- cap_ele->rx_stbc = 0;
- cap_ele->delay_ba = 0;
- cap_ele->max_amsdu_size = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0;
- cap_ele->dss_cck = 1;
- cap_ele->PSMP = 0;
- cap_ele->lsig_txop_protect = 0;
-
- netdev_dbg(ieee->dev,
- "TX HT cap/info ele BW=%d max_amsdu_size:%d dss_cck:%d\n",
- cap_ele->chl_width, cap_ele->max_amsdu_size, cap_ele->dss_cck);
-
- if (is_encrypt) {
- cap_ele->mpdu_density = 7;
- cap_ele->max_rx_ampdu_factor = 2;
- } else {
- cap_ele->max_rx_ampdu_factor = 3;
- cap_ele->mpdu_density = 0;
- }
-
- memcpy(cap_ele->MCS, ieee->reg_dot11ht_oper_rate_set, 16);
- memset(&cap_ele->ext_ht_cap_info, 0, 2);
- memset(cap_ele->TxBFCap, 0, 4);
-
- cap_ele->ASCap = 0;
-
- if (assoc) {
- if (ht->iot_action & HT_IOT_ACT_DISABLE_MCS15)
- cap_ele->MCS[1] &= 0x7f;
-
- if (ht->iot_action & HT_IOT_ACT_DISABLE_MCS14)
- cap_ele->MCS[1] &= 0xbf;
-
- if (ht->iot_action & HT_IOT_ACT_DISABLE_ALL_2SS)
- cap_ele->MCS[1] &= 0x00;
-
- if (ht->iot_action & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI)
- cap_ele->short_gi_40mhz = 0;
-
- if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev)) {
- cap_ele->chl_width = 0;
- cap_ele->MCS[1] = 0;
- }
- }
-}
-
-void ht_construct_rt2rt_agg_element(struct rtllib_device *ieee, u8 *posRT2RTAgg,
- u8 *len)
-{
- if (!posRT2RTAgg) {
- netdev_warn(ieee->dev, "%s(): posRT2RTAgg is null\n", __func__);
- return;
- }
- memset(posRT2RTAgg, 0, *len);
- *posRT2RTAgg++ = 0x00;
- *posRT2RTAgg++ = 0xe0;
- *posRT2RTAgg++ = 0x4c;
- *posRT2RTAgg++ = 0x02;
- *posRT2RTAgg++ = 0x01;
-
- *posRT2RTAgg = 0x30;
-
- if (ieee->bSupportRemoteWakeUp)
- *posRT2RTAgg |= RT_HT_CAP_USE_WOW;
-
- *len = 6 + 2;
-}
-
-static u8 ht_pick_mcs_rate(struct rtllib_device *ieee, u8 *pOperateMCS)
-{
- u8 i;
-
- if (!pOperateMCS) {
- netdev_warn(ieee->dev, "%s(): pOperateMCS is null\n", __func__);
- return false;
- }
-
- switch (ieee->mode) {
- case WIRELESS_MODE_B:
- case WIRELESS_MODE_G:
- for (i = 0; i <= 15; i++)
- pOperateMCS[i] = 0;
- break;
- case WIRELESS_MODE_N_24G:
- pOperateMCS[0] &= RATE_ADPT_1SS_MASK;
- pOperateMCS[1] &= RATE_ADPT_2SS_MASK;
- pOperateMCS[3] &= RATE_ADPT_MCS32_MASK;
- break;
- default:
- break;
- }
-
- return true;
-}
-
-u8 ht_get_highest_mcs_rate(struct rtllib_device *ieee, u8 *pMCSRateSet,
- u8 *pMCSFilter)
-{
- u8 i, j;
- u8 bitMap;
- u8 mcsRate = 0;
- u8 availableMcsRate[16];
-
- if (!pMCSRateSet || !pMCSFilter) {
- netdev_warn(ieee->dev,
- "%s(): pMCSRateSet and pMCSFilter are null\n",
- __func__);
- return false;
- }
- for (i = 0; i < 16; i++)
- availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
-
- for (i = 0; i < 16; i++) {
- if (availableMcsRate[i] != 0)
- break;
- }
- if (i == 16)
- return false;
-
- for (i = 0; i < 16; i++) {
- if (availableMcsRate[i] != 0) {
- bitMap = availableMcsRate[i];
- for (j = 0; j < 8; j++) {
- if ((bitMap % 2) != 0) {
- if (ht_mcs_to_data_rate(ieee, (8 * i + j)) >
- ht_mcs_to_data_rate(ieee, mcsRate))
- mcsRate = 8 * i + j;
- }
- bitMap >>= 1;
- }
- }
- }
- return mcsRate | 0x80;
-}
-
-static u8 ht_filter_mcs_rate(struct rtllib_device *ieee, u8 *pSupportMCS,
- u8 *pOperateMCS)
-{
- u8 i;
-
- for (i = 0; i <= 15; i++)
- pOperateMCS[i] = ieee->reg_dot11tx_ht_oper_rate_set[i] &
- pSupportMCS[i];
-
- ht_pick_mcs_rate(ieee, pOperateMCS);
-
- if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev))
- pOperateMCS[1] = 0;
-
- for (i = 2; i <= 15; i++)
- pOperateMCS[i] = 0;
-
- return true;
-}
-
-void ht_set_connect_bw_mode(struct rtllib_device *ieee,
- enum ht_channel_width bandwidth,
- enum ht_extchnl_offset Offset);
-
-void ht_on_assoc_rsp(struct rtllib_device *ieee)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
- struct ht_capab_ele *pPeerHTCap = NULL;
- struct ht_info_ele *pPeerHTInfo = NULL;
- u8 *pMcsFilter = NULL;
-
- static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 };
- static const u8 EWC11NHTInfo[] = { 0x00, 0x90, 0x4c, 0x34 };
-
- if (!ht_info->current_ht_support) {
- netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__);
- return;
- }
- netdev_dbg(ieee->dev, "%s(): HT_ENABLE\n", __func__);
-
- if (!memcmp(ht_info->peer_ht_cap_buf, EWC11NHTCap, sizeof(EWC11NHTCap)))
- pPeerHTCap = (struct ht_capab_ele *)(&ht_info->peer_ht_cap_buf[4]);
- else
- pPeerHTCap = (struct ht_capab_ele *)(ht_info->peer_ht_cap_buf);
-
- if (!memcmp(ht_info->peer_ht_info_buf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
- pPeerHTInfo = (struct ht_info_ele *)
- (&ht_info->peer_ht_info_buf[4]);
- else
- pPeerHTInfo = (struct ht_info_ele *)(ht_info->peer_ht_info_buf);
-
-#ifdef VERBOSE_DEBUG
- print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE,
- pPeerHTCap, sizeof(struct ht_capab_ele));
-#endif
- ht_set_connect_bw_mode(ieee, (enum ht_channel_width)(pPeerHTCap->chl_width),
- (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset));
- ht_info->cur_tx_bw40mhz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ?
- true : false);
-
- ht_info->cur_short_gi_20mhz = ((pPeerHTCap->short_gi_20mhz == 1) ? true : false);
- ht_info->cur_short_gi_40mhz = ((pPeerHTCap->short_gi_40mhz == 1) ? true : false);
-
- ht_info->current_ampdu_enable = ht_info->ampdu_enable;
- if (ieee->rtllib_ap_sec_type &&
- (ieee->rtllib_ap_sec_type(ieee) & (SEC_ALG_WEP | SEC_ALG_TKIP))) {
- if ((ht_info->iot_peer == HT_IOT_PEER_ATHEROS) ||
- (ht_info->iot_peer == HT_IOT_PEER_UNKNOWN))
- ht_info->current_ampdu_enable = false;
- }
-
- if (ieee->current_network.bssht.bd_rt2rt_aggregation) {
- if (ieee->pairwise_key_type != KEY_TYPE_NA)
- ht_info->current_ampdu_factor =
- pPeerHTCap->max_rx_ampdu_factor;
- else
- ht_info->current_ampdu_factor = HT_AGG_SIZE_64K;
- } else {
- ht_info->current_ampdu_factor = min_t(u32, pPeerHTCap->max_rx_ampdu_factor,
- HT_AGG_SIZE_32K);
- }
-
- ht_info->current_mpdu_density = pPeerHTCap->mpdu_density;
- if (ht_info->iot_action & HT_IOT_ACT_TX_USE_AMSDU_8K)
- ht_info->current_ampdu_enable = false;
-
- ht_info->cur_rx_reorder_enable = 1;
-
- if (pPeerHTCap->MCS[0] == 0)
- pPeerHTCap->MCS[0] = 0xff;
-
- ht_iot_act_determine_ra_func(ieee, ((pPeerHTCap->MCS[1]) != 0));
-
- ht_filter_mcs_rate(ieee, pPeerHTCap->MCS, ieee->dot11ht_oper_rate_set);
-
- pMcsFilter = MCS_FILTER_ALL;
- ieee->HTHighestOperaRate = ht_get_highest_mcs_rate(ieee,
- ieee->dot11ht_oper_rate_set,
- pMcsFilter);
- ieee->ht_curr_op_rate = ieee->HTHighestOperaRate;
-
- ht_info->current_op_mode = pPeerHTInfo->opt_mode;
-}
-
-void ht_initialize_ht_info(struct rtllib_device *ieee)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
-
- ht_info->current_ht_support = false;
-
- ht_info->cur_bw_40mhz = false;
- ht_info->cur_tx_bw40mhz = false;
-
- ht_info->cur_short_gi_20mhz = false;
- ht_info->cur_short_gi_40mhz = false;
-
- ht_info->current_mpdu_density = 0;
- ht_info->current_ampdu_factor = ht_info->ampdu_factor;
-
- memset((void *)(&ht_info->self_ht_cap), 0,
- sizeof(ht_info->self_ht_cap));
- memset((void *)(&ht_info->peer_ht_cap_buf), 0,
- sizeof(ht_info->peer_ht_cap_buf));
- memset((void *)(&ht_info->peer_ht_info_buf), 0,
- sizeof(ht_info->peer_ht_info_buf));
-
- ht_info->sw_bw_in_progress = false;
-
- ht_info->peer_ht_spec_ver = HT_SPEC_VER_IEEE;
-
- ht_info->current_rt2rt_aggregation = false;
- ht_info->current_rt2rt_long_slot_time = false;
-
- ht_info->iot_peer = 0;
- ht_info->iot_action = 0;
- ht_info->iot_ra_func = 0;
-
- {
- u8 *RegHTSuppRateSets = &ieee->reg_ht_supp_rate_set[0];
-
- RegHTSuppRateSets[0] = 0xFF;
- RegHTSuppRateSets[1] = 0xFF;
- RegHTSuppRateSets[4] = 0x01;
- }
-}
-
-void ht_initialize_bss_desc(struct bss_ht *bss_ht)
-{
- bss_ht->bd_support_ht = false;
- memset(bss_ht->bd_ht_cap_buf, 0, sizeof(bss_ht->bd_ht_cap_buf));
- bss_ht->bd_ht_cap_len = 0;
- memset(bss_ht->bd_ht_info_buf, 0, sizeof(bss_ht->bd_ht_info_buf));
- bss_ht->bd_ht_info_len = 0;
-
- bss_ht->bd_ht_spec_ver = HT_SPEC_VER_IEEE;
-
- bss_ht->bd_rt2rt_aggregation = false;
- bss_ht->bd_rt2rt_long_slot_time = false;
- bss_ht->rt2rt_ht_mode = (enum rt_ht_capability)0;
-}
-
-void ht_reset_self_and_save_peer_setting(struct rtllib_device *ieee,
- struct rtllib_network *network)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
- u8 bIOTAction = 0;
-
- /* unmark enable_ht flag here is the same reason why unmarked in
- * function rtllib_softmac_new_net. WB 2008.09.10
- */
- if (network->bssht.bd_support_ht) {
- ht_info->current_ht_support = true;
- ht_info->peer_ht_spec_ver = network->bssht.bd_ht_spec_ver;
-
- if (network->bssht.bd_ht_cap_len > 0 &&
- network->bssht.bd_ht_cap_len <= sizeof(ht_info->peer_ht_cap_buf))
- memcpy(ht_info->peer_ht_cap_buf,
- network->bssht.bd_ht_cap_buf,
- network->bssht.bd_ht_cap_len);
-
- if (network->bssht.bd_ht_info_len > 0 &&
- network->bssht.bd_ht_info_len <=
- sizeof(ht_info->peer_ht_info_buf))
- memcpy(ht_info->peer_ht_info_buf,
- network->bssht.bd_ht_info_buf,
- network->bssht.bd_ht_info_len);
-
- ht_info->current_rt2rt_aggregation =
- network->bssht.bd_rt2rt_aggregation;
- ht_info->current_rt2rt_long_slot_time =
- network->bssht.bd_rt2rt_long_slot_time;
-
- ht_iot_peer_determine(ieee);
-
- ht_info->iot_action = 0;
- bIOTAction = ht_iot_act_is_mgnt_use_cck_6m(ieee, network);
- if (bIOTAction)
- ht_info->iot_action |= HT_IOT_ACT_MGNT_USE_CCK_6M;
- bIOTAction = ht_iot_act_is_ccd_fsync(ieee);
- if (bIOTAction)
- ht_info->iot_action |= HT_IOT_ACT_CDD_FSYNC;
- } else {
- ht_info->current_ht_support = false;
- ht_info->current_rt2rt_aggregation = false;
- ht_info->current_rt2rt_long_slot_time = false;
-
- ht_info->iot_action = 0;
- ht_info->iot_ra_func = 0;
- }
-}
-
-void HT_update_self_and_peer_setting(struct rtllib_device *ieee,
- struct rtllib_network *network)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
- struct ht_info_ele *pPeerHTInfo =
- (struct ht_info_ele *)network->bssht.bd_ht_info_buf;
-
- if (ht_info->current_ht_support) {
- if (network->bssht.bd_ht_info_len != 0)
- ht_info->current_op_mode = pPeerHTInfo->opt_mode;
- }
-}
-EXPORT_SYMBOL(HT_update_self_and_peer_setting);
-
-u8 ht_c_check(struct rtllib_device *ieee, u8 *frame)
-{
- if (ieee->ht_info->current_ht_support) {
- if ((is_qos_data_frame(frame) && frame_order(frame)) == 1) {
- netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n");
- return true;
- }
- }
- return false;
-}
-
-static void ht_set_connect_bw_mode_callback(struct rtllib_device *ieee)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
-
- if (ht_info->cur_bw_40mhz) {
- if (ht_info->cur_sta_ext_chnl_offset == HT_EXTCHNL_OFFSET_UPPER)
- ieee->set_chan(ieee->dev,
- ieee->current_network.channel + 2);
- else if (ht_info->cur_sta_ext_chnl_offset ==
- HT_EXTCHNL_OFFSET_LOWER)
- ieee->set_chan(ieee->dev,
- ieee->current_network.channel - 2);
- else
- ieee->set_chan(ieee->dev,
- ieee->current_network.channel);
-
- ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20_40,
- ht_info->cur_sta_ext_chnl_offset);
- } else {
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20,
- HT_EXTCHNL_OFFSET_NO_EXT);
- }
-
- ht_info->sw_bw_in_progress = false;
-}
-
-void ht_set_connect_bw_mode(struct rtllib_device *ieee,
- enum ht_channel_width bandwidth,
- enum ht_extchnl_offset Offset)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
-
- if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev))
- bandwidth = HT_CHANNEL_WIDTH_20;
-
- if (ht_info->sw_bw_in_progress) {
- pr_info("%s: sw_bw_in_progress!!\n", __func__);
- return;
- }
- if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
- if (ieee->current_network.channel < 2 &&
- Offset == HT_EXTCHNL_OFFSET_LOWER)
- Offset = HT_EXTCHNL_OFFSET_NO_EXT;
- if (Offset == HT_EXTCHNL_OFFSET_UPPER ||
- Offset == HT_EXTCHNL_OFFSET_LOWER) {
- ht_info->cur_bw_40mhz = true;
- ht_info->cur_sta_ext_chnl_offset = Offset;
- } else {
- ht_info->cur_bw_40mhz = false;
- ht_info->cur_sta_ext_chnl_offset = HT_EXTCHNL_OFFSET_NO_EXT;
- }
- } else {
- ht_info->cur_bw_40mhz = false;
- ht_info->cur_sta_ext_chnl_offset = HT_EXTCHNL_OFFSET_NO_EXT;
- }
-
- netdev_dbg(ieee->dev, "%s():ht_info->bCurBW40MHz:%x\n", __func__,
- ht_info->cur_bw_40mhz);
-
- ht_info->sw_bw_in_progress = true;
-
- ht_set_connect_bw_mode_callback(ieee);
-}
diff --git a/drivers/staging/rtl8192e/rtl819x_Qos.h b/drivers/staging/rtl8192e/rtl819x_Qos.h
deleted file mode 100644
index dc991100742f..000000000000
--- a/drivers/staging/rtl8192e/rtl819x_Qos.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef __INC_QOS_TYPE_H
-#define __INC_QOS_TYPE_H
-
-struct qos_tsinfo {
- u8 ts_id:4;
- u8 ucDirection:2;
-};
-
-struct octet_string {
- u8 *octet;
- u16 Length;
-};
-
-#define AC0_BE 0
-#define AC1_BK 1
-#define AC2_VI 2
-#define AC3_VO 3
-
-enum direction_value {
- DIR_UP = 0,
- DIR_DOWN = 1,
- DIR_DIRECT = 2,
- DIR_BI_DIR = 3,
-};
-
-union aci_aifsn {
- u8 charData;
-
- struct {
- u8 AIFSN:4;
- u8 acm:1;
- u8 ACI:2;
- u8 Reserved:1;
- } f;
-};
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl819x_TS.h b/drivers/staging/rtl8192e/rtl819x_TS.h
deleted file mode 100644
index 5b0e4cb572d2..000000000000
--- a/drivers/staging/rtl8192e/rtl819x_TS.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#ifndef _TSTYPE_H_
-#define _TSTYPE_H_
-#include "rtl819x_Qos.h"
-#define TS_ADDBA_DELAY 60
-
-#define TOTAL_TS_NUM 16
-
-enum tr_select {
- TX_DIR = 0,
- RX_DIR = 1,
-};
-
-struct ts_common_info {
- struct list_head list;
- u8 addr[ETH_ALEN];
- struct qos_tsinfo tspec;
-};
-
-struct tx_ts_record {
- struct ts_common_info ts_common_info;
- u16 tx_cur_seq;
- struct ba_record tx_pending_ba_record;
- struct ba_record tx_admitted_ba_record;
- u8 add_ba_req_in_progress;
- u8 add_ba_req_delayed;
- u8 using_ba;
- u8 disable_add_ba;
- struct timer_list ts_add_ba_timer;
- u8 num;
-};
-
-struct rx_ts_record {
- struct ts_common_info ts_common_info;
- u16 rx_indicate_seq;
- u16 rx_timeout_indicate_seq;
- struct list_head rx_pending_pkt_list;
- struct timer_list rx_pkt_pending_timer;
- struct ba_record rx_admitted_ba_record;
- u16 rx_last_seq_num;
- u8 rx_last_frag_num;
- u8 num;
-};
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl819x_TSProc.c b/drivers/staging/rtl8192e/rtl819x_TSProc.c
deleted file mode 100644
index 89092cd434de..000000000000
--- a/drivers/staging/rtl8192e/rtl819x_TSProc.c
+++ /dev/null
@@ -1,450 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Contact Information: wlanfae <wlanfae@realtek.com>
- */
-#include "rtllib.h"
-#include <linux/etherdevice.h>
-#include "rtl819x_TS.h"
-
-static void RxPktPendingTimeout(struct timer_list *t)
-{
- struct rx_ts_record *ts = from_timer(ts, t, rx_pkt_pending_timer);
- struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
- rx_ts_records[ts->num]);
-
- struct rx_reorder_entry *reorder_entry = NULL;
-
- unsigned long flags = 0;
- u8 index = 0;
- bool pkt_in_buf = false;
-
- spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
- if (ts->rx_timeout_indicate_seq != 0xffff) {
- while (!list_empty(&ts->rx_pending_pkt_list)) {
- reorder_entry = (struct rx_reorder_entry *)
- list_entry(ts->rx_pending_pkt_list.prev,
- struct rx_reorder_entry, list);
- if (index == 0)
- ts->rx_indicate_seq = reorder_entry->seq_num;
-
- if (SN_LESS(reorder_entry->seq_num,
- ts->rx_indicate_seq) ||
- SN_EQUAL(reorder_entry->seq_num,
- ts->rx_indicate_seq)) {
- list_del_init(&reorder_entry->list);
-
- if (SN_EQUAL(reorder_entry->seq_num,
- ts->rx_indicate_seq))
- ts->rx_indicate_seq =
- (ts->rx_indicate_seq + 1) % 4096;
-
- netdev_dbg(ieee->dev,
- "%s(): Indicate seq_num: %d\n",
- __func__, reorder_entry->seq_num);
- ieee->stats_IndicateArray[index] =
- reorder_entry->prxb;
- index++;
-
- list_add_tail(&reorder_entry->list,
- &ieee->RxReorder_Unused_List);
- } else {
- pkt_in_buf = true;
- break;
- }
- }
- }
-
- if (index > 0) {
- ts->rx_timeout_indicate_seq = 0xffff;
-
- if (index > REORDER_WIN_SIZE) {
- netdev_warn(ieee->dev,
- "%s(): Rx Reorder struct buffer full\n",
- __func__);
- spin_unlock_irqrestore(&(ieee->reorder_spinlock),
- flags);
- return;
- }
- rtllib_indicate_packets(ieee, ieee->stats_IndicateArray, index);
- pkt_in_buf = false;
- }
-
- if (pkt_in_buf && (ts->rx_timeout_indicate_seq == 0xffff)) {
- ts->rx_timeout_indicate_seq = ts->rx_indicate_seq;
- mod_timer(&ts->rx_pkt_pending_timer, jiffies +
- msecs_to_jiffies(ieee->ht_info->rx_reorder_pending_time)
- );
- }
- spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
-}
-
-static void TsAddBaProcess(struct timer_list *t)
-{
- struct tx_ts_record *ts = from_timer(ts, t, ts_add_ba_timer);
- u8 num = ts->num;
- struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
- tx_ts_records[num]);
-
- rtllib_ts_init_add_ba(ieee, ts, BA_POLICY_IMMEDIATE, false);
- netdev_dbg(ieee->dev, "%s(): ADDBA Req is started\n", __func__);
-}
-
-static void ResetTsCommonInfo(struct ts_common_info *ts_common_info)
-{
- eth_zero_addr(ts_common_info->addr);
- memset(&ts_common_info->tspec, 0, sizeof(struct qos_tsinfo));
-}
-
-static void ResetTxTsEntry(struct tx_ts_record *ts)
-{
- ResetTsCommonInfo(&ts->ts_common_info);
- ts->tx_cur_seq = 0;
- ts->add_ba_req_in_progress = false;
- ts->add_ba_req_delayed = false;
- ts->using_ba = false;
- ts->disable_add_ba = false;
- rtllib_reset_ba_entry(&ts->tx_admitted_ba_record);
- rtllib_reset_ba_entry(&ts->tx_pending_ba_record);
-}
-
-static void ResetRxTsEntry(struct rx_ts_record *ts)
-{
- ResetTsCommonInfo(&ts->ts_common_info);
- ts->rx_indicate_seq = 0xffff;
- ts->rx_timeout_indicate_seq = 0xffff;
- rtllib_reset_ba_entry(&ts->rx_admitted_ba_record);
-}
-
-void rtllib_ts_init(struct rtllib_device *ieee)
-{
- struct tx_ts_record *pTxTS = ieee->tx_ts_records;
- struct rx_ts_record *rxts = ieee->rx_ts_records;
- struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry;
- u8 count = 0;
-
- INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List);
- INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List);
- INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List);
-
- for (count = 0; count < TOTAL_TS_NUM; count++) {
- pTxTS->num = count;
- timer_setup(&pTxTS->ts_add_ba_timer, TsAddBaProcess, 0);
-
- timer_setup(&pTxTS->tx_pending_ba_record.timer, rtllib_ba_setup_timeout,
- 0);
- timer_setup(&pTxTS->tx_admitted_ba_record.timer,
- rtllib_tx_ba_inact_timeout, 0);
-
- ResetTxTsEntry(pTxTS);
- list_add_tail(&pTxTS->ts_common_info.list,
- &ieee->Tx_TS_Unused_List);
- pTxTS++;
- }
-
- INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
- INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
- INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
- for (count = 0; count < TOTAL_TS_NUM; count++) {
- rxts->num = count;
- INIT_LIST_HEAD(&rxts->rx_pending_pkt_list);
- timer_setup(&rxts->rx_admitted_ba_record.timer,
- rtllib_rx_ba_inact_timeout, 0);
-
- timer_setup(&rxts->rx_pkt_pending_timer, RxPktPendingTimeout, 0);
-
- ResetRxTsEntry(rxts);
- list_add_tail(&rxts->ts_common_info.list,
- &ieee->Rx_TS_Unused_List);
- rxts++;
- }
- INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
- for (count = 0; count < REORDER_ENTRY_NUM; count++) {
- list_add_tail(&pRxReorderEntry->list,
- &ieee->RxReorder_Unused_List);
- if (count == (REORDER_ENTRY_NUM - 1))
- break;
- pRxReorderEntry = &ieee->RxReorderEntry[count + 1];
- }
-}
-
-static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee,
- u8 *addr, u8 TID,
- enum tr_select tx_rx_select)
-{
- u8 dir;
- bool search_dir[4] = {0};
- struct list_head *psearch_list;
- struct ts_common_info *pRet = NULL;
-
- if (tx_rx_select == TX_DIR) {
- search_dir[DIR_UP] = true;
- search_dir[DIR_BI_DIR] = true;
- search_dir[DIR_DIRECT] = true;
- } else {
- search_dir[DIR_DOWN] = true;
- search_dir[DIR_BI_DIR] = true;
- search_dir[DIR_DIRECT] = true;
- }
-
- if (tx_rx_select == TX_DIR)
- psearch_list = &ieee->Tx_TS_Admit_List;
- else
- psearch_list = &ieee->Rx_TS_Admit_List;
-
- for (dir = 0; dir <= DIR_BI_DIR; dir++) {
- if (!search_dir[dir])
- continue;
- list_for_each_entry(pRet, psearch_list, list) {
- if (memcmp(pRet->addr, addr, 6) == 0 &&
- pRet->tspec.ts_id == TID &&
- pRet->tspec.ucDirection == dir)
- break;
- }
- if (&pRet->list != psearch_list)
- break;
- }
-
- if (pRet && &pRet->list != psearch_list)
- return pRet;
- return NULL;
-}
-
-static void MakeTSEntry(struct ts_common_info *ts_common_info, u8 *addr,
- struct qos_tsinfo *pTSPEC)
-{
- if (!ts_common_info)
- return;
-
- memcpy(ts_common_info->addr, addr, 6);
-
- if (pTSPEC)
- memcpy((u8 *)(&(ts_common_info->tspec)), (u8 *)pTSPEC,
- sizeof(struct qos_tsinfo));
-}
-
-bool rtllib_get_ts(struct rtllib_device *ieee, struct ts_common_info **ppTS,
- u8 *addr, u8 TID, enum tr_select tx_rx_select, bool add_new_ts)
-{
- u8 UP = 0;
- struct qos_tsinfo tspec;
- struct qos_tsinfo *ts_info = &tspec;
- struct list_head *pUnusedList;
- struct list_head *pAddmitList;
- enum direction_value Dir;
-
- if (is_multicast_ether_addr(addr)) {
- netdev_warn(ieee->dev, "Get TS for Broadcast or Multicast\n");
- return false;
- }
- if (ieee->current_network.qos_data.supported == 0) {
- UP = 0;
- } else {
- switch (TID) {
- case 0:
- case 3:
- UP = 0;
- break;
- case 1:
- case 2:
- UP = 2;
- break;
- case 4:
- case 5:
- UP = 5;
- break;
- case 6:
- case 7:
- UP = 7;
- break;
- default:
- netdev_warn(ieee->dev, "%s(): TID(%d) is not valid\n",
- __func__, TID);
- return false;
- }
- }
-
- *ppTS = SearchAdmitTRStream(ieee, addr, UP, tx_rx_select);
- if (*ppTS)
- return true;
-
- if (!add_new_ts) {
- netdev_dbg(ieee->dev, "add new TS failed(tid:%d)\n", UP);
- return false;
- }
-
- pUnusedList = (tx_rx_select == TX_DIR) ?
- (&ieee->Tx_TS_Unused_List) :
- (&ieee->Rx_TS_Unused_List);
-
- pAddmitList = (tx_rx_select == TX_DIR) ?
- (&ieee->Tx_TS_Admit_List) :
- (&ieee->Rx_TS_Admit_List);
-
- Dir = ((tx_rx_select == TX_DIR) ? DIR_UP : DIR_DOWN);
-
- if (!list_empty(pUnusedList)) {
- (*ppTS) = list_entry(pUnusedList->next,
- struct ts_common_info, list);
- list_del_init(&(*ppTS)->list);
- if (tx_rx_select == TX_DIR) {
- struct tx_ts_record *tmp =
- container_of(*ppTS,
- struct tx_ts_record,
- ts_common_info);
- ResetTxTsEntry(tmp);
- } else {
- struct rx_ts_record *ts =
- container_of(*ppTS,
- struct rx_ts_record,
- ts_common_info);
- ResetRxTsEntry(ts);
- }
-
- netdev_dbg(ieee->dev,
- "to init current TS, UP:%d, Dir:%d, addr: %pM ppTs=%p\n",
- UP, Dir, addr, *ppTS);
- ts_info->ts_id = UP;
- ts_info->ucDirection = Dir;
-
- MakeTSEntry(*ppTS, addr, &tspec);
- list_add_tail(&((*ppTS)->list), pAddmitList);
-
- return true;
- }
-
- netdev_warn(ieee->dev,
- "There is not enough dir=%d(0=up down=1) TS record to be used!",
- Dir);
- return false;
-}
-
-static void RemoveTsEntry(struct rtllib_device *ieee,
- struct ts_common_info *pTs, enum tr_select tx_rx_select)
-{
- rtllib_ts_init_del_ba(ieee, pTs, tx_rx_select);
-
- if (tx_rx_select == RX_DIR) {
- struct rx_reorder_entry *pRxReorderEntry;
- struct rx_ts_record *ts = (struct rx_ts_record *)pTs;
-
- if (timer_pending(&ts->rx_pkt_pending_timer))
- del_timer_sync(&ts->rx_pkt_pending_timer);
-
- while (!list_empty(&ts->rx_pending_pkt_list)) {
- pRxReorderEntry = (struct rx_reorder_entry *)
- list_entry(ts->rx_pending_pkt_list.prev,
- struct rx_reorder_entry, list);
- netdev_dbg(ieee->dev, "%s(): Delete seq_num %d!\n",
- __func__, pRxReorderEntry->seq_num);
- list_del_init(&pRxReorderEntry->list);
- {
- int i = 0;
- struct rtllib_rxb *prxb = pRxReorderEntry->prxb;
-
- if (unlikely(!prxb))
- return;
- for (i = 0; i < prxb->nr_subframes; i++)
- dev_kfree_skb(prxb->subframes[i]);
- kfree(prxb);
- prxb = NULL;
- }
- list_add_tail(&pRxReorderEntry->list,
- &ieee->RxReorder_Unused_List);
- }
- } else {
- struct tx_ts_record *pTxTS = (struct tx_ts_record *)pTs;
-
- del_timer_sync(&pTxTS->ts_add_ba_timer);
- }
-}
-
-void remove_peer_ts(struct rtllib_device *ieee, u8 *addr)
-{
- struct ts_common_info *ts, *pTmpTS;
-
- netdev_info(ieee->dev, "===========>%s, %pM\n", __func__, addr);
-
- list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Pending_List, list) {
- if (memcmp(ts->addr, addr, 6) == 0) {
- RemoveTsEntry(ieee, ts, TX_DIR);
- list_del_init(&ts->list);
- list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List);
- }
- }
-
- list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Admit_List, list) {
- if (memcmp(ts->addr, addr, 6) == 0) {
- netdev_info(ieee->dev,
- "====>remove Tx_TS_admin_list\n");
- RemoveTsEntry(ieee, ts, TX_DIR);
- list_del_init(&ts->list);
- list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List);
- }
- }
-
- list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Pending_List, list) {
- if (memcmp(ts->addr, addr, 6) == 0) {
- RemoveTsEntry(ieee, ts, RX_DIR);
- list_del_init(&ts->list);
- list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List);
- }
- }
-
- list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Admit_List, list) {
- if (memcmp(ts->addr, addr, 6) == 0) {
- RemoveTsEntry(ieee, ts, RX_DIR);
- list_del_init(&ts->list);
- list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List);
- }
- }
-}
-EXPORT_SYMBOL(remove_peer_ts);
-
-void remove_all_ts(struct rtllib_device *ieee)
-{
- struct ts_common_info *ts, *pTmpTS;
-
- list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Pending_List, list) {
- RemoveTsEntry(ieee, ts, TX_DIR);
- list_del_init(&ts->list);
- list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List);
- }
-
- list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Admit_List, list) {
- RemoveTsEntry(ieee, ts, TX_DIR);
- list_del_init(&ts->list);
- list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List);
- }
-
- list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Pending_List, list) {
- RemoveTsEntry(ieee, ts, RX_DIR);
- list_del_init(&ts->list);
- list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List);
- }
-
- list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Admit_List, list) {
- RemoveTsEntry(ieee, ts, RX_DIR);
- list_del_init(&ts->list);
- list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List);
- }
-}
-
-void rtllib_ts_start_add_ba_process(struct rtllib_device *ieee, struct tx_ts_record *pTxTS)
-{
- if (pTxTS->add_ba_req_in_progress == false) {
- pTxTS->add_ba_req_in_progress = true;
-
- if (pTxTS->add_ba_req_delayed) {
- netdev_dbg(ieee->dev, "Start ADDBA after 60 sec!!\n");
- mod_timer(&pTxTS->ts_add_ba_timer, jiffies +
- msecs_to_jiffies(TS_ADDBA_DELAY));
- } else {
- netdev_dbg(ieee->dev, "Immediately Start ADDBA\n");
- mod_timer(&pTxTS->ts_add_ba_timer, jiffies + 10);
- }
- } else {
- netdev_dbg(ieee->dev, "BA timer is already added\n");
- }
-}
diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h
deleted file mode 100644
index d6615f787d53..000000000000
--- a/drivers/staging/rtl8192e/rtllib.h
+++ /dev/null
@@ -1,1799 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Merged with mainline rtllib.h in Aug 2004. Original ieee802_11
- * remains copyright by the original authors
- *
- * Portions of the merged code are based on Host AP (software wireless
- * LAN access point) driver for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
- *
- * Modified for Realtek's wi-fi cards by Andrea Merello
- * <andrea.merello@gmail.com>
- */
-#ifndef RTLLIB_H
-#define RTLLIB_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h> /* ARRAY_SIZE */
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-#include <linux/mutex.h>
-
-#include <linux/delay.h>
-#include <linux/wireless.h>
-
-#include "rtl819x_HT.h"
-#include "rtl819x_BA.h"
-#include "rtl819x_TS.h"
-
-#include <linux/netdevice.h>
-#include <linux/if_arp.h> /* ARPHRD_ETHER */
-#include <net/cfg80211.h>
-#include <net/lib80211.h>
-
-#define MAX_PRECMD_CNT 16
-#define MAX_RFDEPENDCMD_CNT 16
-#define MAX_POSTCMD_CNT 16
-
-#ifndef WIRELESS_SPY
-#define WIRELESS_SPY
-#endif
-#include <net/iw_handler.h>
-
-#ifndef IW_MODE_MONITOR
-#define IW_MODE_MONITOR 6
-#endif
-
-#ifndef IWEVCUSTOM
-#define IWEVCUSTOM 0x8c02
-#endif
-
-#ifndef IW_CUSTOM_MAX
-/* Max number of char in custom event - use multiple of them if needed */
-#define IW_CUSTOM_MAX 256 /* In bytes */
-#endif
-
-#define container_of_dwork_rsl(x, y, z) \
- container_of(to_delayed_work(x), y, z)
-
-static inline void *netdev_priv_rsl(struct net_device *dev)
-{
- return netdev_priv(dev);
-}
-
-#define KEY_TYPE_NA 0x0
-#define KEY_TYPE_WEP40 0x1
-#define KEY_TYPE_TKIP 0x2
-#define KEY_TYPE_CCMP 0x4
-#define KEY_TYPE_WEP104 0x5
-/* added for rtl819x tx procedure */
-#define MAX_QUEUE_SIZE 0x10
-
-#define BK_QUEUE 0
-#define BE_QUEUE 1
-#define VI_QUEUE 2
-#define VO_QUEUE 3
-#define HCCA_QUEUE 4
-#define TXCMD_QUEUE 5
-#define MGNT_QUEUE 6
-#define HIGH_QUEUE 7
-#define BEACON_QUEUE 8
-
-#define IE_CISCO_FLAG_POSITION 0x08
-#define SUPPORT_CKIP_MIC 0x08
-#define SUPPORT_CKIP_PK 0x10
-#define RT_RF_OFF_LEVL_HALT_NIC BIT(3)
-#define RT_IN_PS_LEVEL(psc, _PS_FLAG) \
- ((psc->cur_ps_level & _PS_FLAG) ? true : false)
-#define RT_CLEAR_PS_LEVEL(psc, _PS_FLAG) \
- (psc->cur_ps_level &= (~(_PS_FLAG)))
-
-/* defined for skb cb field */
-/* At most 28 byte */
-struct cb_desc {
- /* Tx Desc Related flags (8-9) */
- u8 last_ini_pkt:1;
- u8 cmd_or_init:1;
- u8 tx_dis_rate_fallback:1;
- u8 tx_use_drv_assinged_rate:1;
- u8 hw_sec:1;
-
- u8 stuck_count;
-
- /* Tx Firmware Related flags (10-11)*/
- u8 cts_enable:1;
- u8 rts_enable:1;
- u8 use_short_gi:1;
- u8 use_short_preamble:1;
- u8 tx_enable_fw_calc_dur:1;
- u8 ampdu_enable:1;
- u8 rtsstbc:1;
- u8 RTSSC:1;
-
- u8 rts_bw:1;
- u8 packet_bw:1;
- u8 rts_use_short_preamble:1;
- u8 rts_use_short_gi:1;
- u8 multicast:1;
- u8 broadcast:1;
- u8 drv_agg_enable:1;
- u8 reserved2:1;
-
- /* Tx Desc related element(12-19) */
- u8 rata_index;
- u8 queue_index;
- u16 txbuf_size;
- u8 ratr_index;
- u8 bAMSDU:1;
- u8 bFromAggrQ:1;
- u8 reserved6:6;
- u8 priority;
-
- /* Tx firmware related element(20-27) */
- u8 data_rate;
- u8 rts_rate;
- u8 ampdu_factor;
- u8 ampdu_density;
- u8 DrvAggrNum;
- u8 bdhcp;
- u16 pkt_size;
- u8 bIsSpecialDataFrame;
-
- u8 bBTTxPacket;
- u8 bIsBTProbRsp;
-};
-
-enum sw_chnl_cmd_id {
- cmd_id_end,
- cmd_id_set_tx_power_level,
- cmd_id_bbreg_write10,
- cmd_id_write_port_ulong,
- cmd_id_write_port_ushort,
- cmd_id_write_port_uchar,
- cmd_id_rf_write_reg,
-};
-
-struct sw_chnl_cmd {
- enum sw_chnl_cmd_id cmd_id;
- u32 para1;
- u32 para2;
- u32 ms_delay;
-};
-
-/*--------------------------Define -------------------------------------------*/
-#define MGN_1M 0x02
-#define MGN_2M 0x04
-#define MGN_5_5M 0x0b
-#define MGN_11M 0x16
-
-#define MGN_6M 0x0c
-#define MGN_9M 0x12
-#define MGN_12M 0x18
-#define MGN_18M 0x24
-#define MGN_24M 0x30
-#define MGN_36M 0x48
-#define MGN_48M 0x60
-#define MGN_54M 0x6c
-
-#define MGN_MCS0 0x80
-#define MGN_MCS1 0x81
-#define MGN_MCS2 0x82
-#define MGN_MCS3 0x83
-#define MGN_MCS4 0x84
-#define MGN_MCS5 0x85
-#define MGN_MCS6 0x86
-#define MGN_MCS7 0x87
-#define MGN_MCS8 0x88
-#define MGN_MCS9 0x89
-#define MGN_MCS10 0x8a
-#define MGN_MCS11 0x8b
-#define MGN_MCS12 0x8c
-#define MGN_MCS13 0x8d
-#define MGN_MCS14 0x8e
-#define MGN_MCS15 0x8f
-
-enum hw_variables {
- HW_VAR_ETHER_ADDR,
- HW_VAR_MULTICAST_REG,
- HW_VAR_BASIC_RATE,
- HW_VAR_BSSID,
- HW_VAR_MEDIA_STATUS,
- HW_VAR_SECURITY_CONF,
- HW_VAR_BEACON_INTERVAL,
- HW_VAR_ATIM_WINDOW,
- HW_VAR_LISTEN_INTERVAL,
- HW_VAR_CS_COUNTER,
- HW_VAR_DEFAULTKEY0,
- HW_VAR_DEFAULTKEY1,
- HW_VAR_DEFAULTKEY2,
- HW_VAR_DEFAULTKEY3,
- HW_VAR_SIFS,
- HW_VAR_DIFS,
- HW_VAR_EIFS,
- HW_VAR_SLOT_TIME,
- HW_VAR_ACK_PREAMBLE,
- HW_VAR_CW_CONFIG,
- HW_VAR_CW_VALUES,
- HW_VAR_RATE_FALLBACK_CONTROL,
- HW_VAR_CONTENTION_WINDOW,
- HW_VAR_RETRY_COUNT,
- HW_VAR_TR_SWITCH,
- HW_VAR_COMMAND,
- HW_VAR_WPA_CONFIG,
- HW_VAR_AMPDU_MIN_SPACE,
- HW_VAR_SHORTGI_DENSITY,
- HW_VAR_AMPDU_FACTOR,
- HW_VAR_MCS_RATE_AVAILABLE,
- HW_VAR_AC_PARAM,
- HW_VAR_ACM_CTRL,
- HW_VAR_DIS_Req_Qsize,
- HW_VAR_CCX_CHNL_LOAD,
- HW_VAR_CCX_NOISE_HISTOGRAM,
- HW_VAR_CCX_CLM_NHM,
- HW_VAR_TxOPLimit,
- HW_VAR_TURBO_MODE,
- HW_VAR_RF_STATE,
- HW_VAR_RF_OFF_BY_HW,
- HW_VAR_BUS_SPEED,
- HW_VAR_SET_DEV_POWER,
-
- HW_VAR_RCR,
- HW_VAR_RATR_0,
- HW_VAR_RRSR,
- HW_VAR_CPU_RST,
- HW_VAR_CECHK_BSSID,
- HW_VAR_LBK_MODE,
- HW_VAR_AES_11N_FIX,
- HW_VAR_USB_RX_AGGR,
- HW_VAR_USER_CONTROL_TURBO_MODE,
- HW_VAR_RETRY_LIMIT,
- HW_VAR_INIT_TX_RATE,
- HW_VAR_TX_RATE_REG,
- HW_VAR_EFUSE_USAGE,
- HW_VAR_EFUSE_BYTES,
- HW_VAR_AUTOLOAD_STATUS,
- HW_VAR_RF_2R_DISABLE,
- HW_VAR_SET_RPWM,
- HW_VAR_H2C_FW_PWRMODE,
- HW_VAR_H2C_FW_JOINBSSRPT,
- HW_VAR_1X1_RECV_COMBINE,
- HW_VAR_STOP_SEND_BEACON,
- HW_VAR_TSF_TIMER,
- HW_VAR_IO_CMD,
-
- HW_VAR_RF_RECOVERY,
- HW_VAR_H2C_FW_UPDATE_GTK,
- HW_VAR_WF_MASK,
- HW_VAR_WF_CRC,
- HW_VAR_WF_IS_MAC_ADDR,
- HW_VAR_H2C_FW_OFFLOAD,
- HW_VAR_RESET_WFCRC,
-
- HW_VAR_HANDLE_FW_C2H,
- HW_VAR_DL_FW_RSVD_PAGE,
- HW_VAR_AID,
- HW_VAR_HW_SEQ_ENABLE,
- HW_VAR_CORRECT_TSF,
- HW_VAR_BCN_VALID,
- HW_VAR_FWLPS_RF_ON,
- HW_VAR_DUAL_TSF_RST,
- HW_VAR_SWITCH_EPHY_WoWLAN,
- HW_VAR_INT_MIGRATION,
- HW_VAR_INT_AC,
- HW_VAR_RF_TIMING,
-};
-
-enum rt_op_mode {
- RT_OP_MODE_AP,
- RT_OP_MODE_INFRASTRUCTURE,
- RT_OP_MODE_IBSS,
- RT_OP_MODE_NO_LINK,
-};
-
-#define asifs_time \
- ((priv->rtllib->current_network.mode == WIRELESS_MODE_N_24G) ? 16 : 10)
-
-#define MGMT_QUEUE_NUM 5
-
-#define MAX_IE_LEN 0xff
-
-#define msleep_interruptible_rsl msleep_interruptible
-
-/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
- * 6.2.1.1.2.
- *
- * The figure in section 7.1.2 suggests a body size of up to 2312
- * bytes is allowed, which is a bit confusing, I suspect this
- * represents the 2304 bytes of real data, plus a possible 8 bytes of
- * WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro)
- */
-#define RTLLIB_1ADDR_LEN 10
-#define RTLLIB_2ADDR_LEN 16
-#define RTLLIB_3ADDR_LEN 24
-#define RTLLIB_4ADDR_LEN 30
-#define RTLLIB_FCS_LEN 4
-
-#define RTLLIB_SKBBUFFER_SIZE 2500
-
-#define MIN_FRAG_THRESHOLD 256U
-#define MAX_FRAG_THRESHOLD 2346U
-
-#define RTLLIB_FTYPE_MGMT 0x0000
-#define RTLLIB_FTYPE_CTL 0x0004
-#define RTLLIB_FTYPE_DATA 0x0008
-
-#define RTLLIB_SCTL_FRAG 0x000F
-#define RTLLIB_SCTL_SEQ 0xFFF0
-
-/* QOS control */
-#define RTLLIB_QCTL_TID 0x000F
-
-#define FC_QOS_BIT BIT(7)
-#define is_data_frame(pdu) (((pdu[0] & 0x0C) == 0x08) ? true : false)
-#define is_legacy_data_frame(pdu) (is_data_frame(pdu) && (!(pdu[0] & FC_QOS_BIT)))
-#define is_qos_data_frame(pframe) \
- ((*(u16 *)pframe & (IEEE80211_STYPE_QOS_DATA | RTLLIB_FTYPE_DATA)) == \
- (IEEE80211_STYPE_QOS_DATA | RTLLIB_FTYPE_DATA))
-#define frame_order(pframe) (*(u16 *)pframe & IEEE80211_FCTL_ORDER)
-#define SN_LESS(a, b) (((a - b) & 0x800) != 0)
-#define SN_EQUAL(a, b) (a == b)
-#define MAX_DEV_ADDR_SIZE 8
-
-enum act_category {
- ACT_CAT_QOS = 1,
- ACT_CAT_DLS = 2,
- ACT_CAT_BA = 3,
- ACT_CAT_HT = 7,
- ACT_CAT_WMM = 17,
-};
-
-enum ba_action {
- ACT_ADDBAREQ = 0,
- ACT_ADDBARSP = 1,
- ACT_DELBA = 2,
-};
-
-enum init_gain_op_type {
- IG_Backup = 0,
- IG_Restore,
- IG_Max
-};
-
-enum wireless_mode {
- WIRELESS_MODE_UNKNOWN = 0x00,
- WIRELESS_MODE_A = 0x01,
- WIRELESS_MODE_B = 0x02,
- WIRELESS_MODE_G = 0x04,
- WIRELESS_MODE_AUTO = 0x08,
- WIRELESS_MODE_N_24G = 0x10,
-};
-
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#define ETH_P_IP 0x0800 /* Internet Protocol packet */
-#define ETH_P_ARP 0x0806 /* Address Resolution packet */
-#endif /* ETH_P_PAE */
-
-#ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
-#endif
-
-/* IEEE 802.11 defines */
-
-#define P80211_OUI_LEN 3
-
-struct rtllib_snap_hdr {
- u8 dsap; /* always 0xAA */
- u8 ssap; /* always 0xAA */
- u8 ctrl; /* always 0x03 */
- u8 oui[P80211_OUI_LEN]; /* organizational universal id */
-
-} __packed;
-
-enum _REG_PREAMBLE_MODE {
- PREAMBLE_LONG = 1,
- PREAMBLE_AUTO = 2,
- PREAMBLE_SHORT = 3,
-};
-
-#define SNAP_SIZE sizeof(struct rtllib_snap_hdr)
-
-#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
-#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
-#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA)
-
-#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTLLIB_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq) (((seq) & RTLLIB_SCTL_SEQ) >> 4)
-
-#define RTLLIB_STATMASK_SIGNAL (1 << 0)
-#define RTLLIB_STATMASK_RSSI (1 << 1)
-#define RTLLIB_STATMASK_NOISE (1 << 2)
-#define RTLLIB_STATMASK_WEMASK 0x7
-
-#define RTLLIB_CCK_MODULATION (1 << 0)
-#define RTLLIB_OFDM_MODULATION (1 << 1)
-
-#define RTLLIB_CCK_RATE_LEN 4
-#define RTLLIB_CCK_RATE_1MB 0x02
-#define RTLLIB_CCK_RATE_2MB 0x04
-#define RTLLIB_CCK_RATE_5MB 0x0B
-#define RTLLIB_CCK_RATE_11MB 0x16
-#define RTLLIB_OFDM_RATE_LEN 8
-#define RTLLIB_OFDM_RATE_6MB 0x0C
-#define RTLLIB_OFDM_RATE_9MB 0x12
-#define RTLLIB_OFDM_RATE_12MB 0x18
-#define RTLLIB_OFDM_RATE_18MB 0x24
-#define RTLLIB_OFDM_RATE_24MB 0x30
-#define RTLLIB_OFDM_RATE_36MB 0x48
-#define RTLLIB_OFDM_RATE_48MB 0x60
-#define RTLLIB_OFDM_RATE_54MB 0x6C
-#define RTLLIB_BASIC_RATE_MASK 0x80
-
-/* this is stolen and modified from the madwifi driver*/
-#define RTLLIB_FC0_TYPE_MASK 0x0c
-#define RTLLIB_FC0_TYPE_DATA 0x08
-#define RTLLIB_FC0_SUBTYPE_MASK 0xB0
-#define RTLLIB_FC0_SUBTYPE_QOS 0x80
-
-#define RTLLIB_QOS_HAS_SEQ(fc) \
- (((fc) & (RTLLIB_FC0_TYPE_MASK | RTLLIB_FC0_SUBTYPE_MASK)) == \
- (RTLLIB_FC0_TYPE_DATA | RTLLIB_FC0_SUBTYPE_QOS))
-
-/* this is stolen from ipw2200 driver */
-#define IEEE_IBSS_MAC_HASH_SIZE 31
-
-/* NOTE: This data is for statistical purposes; not all hardware provides this
- * information for frames received. Not setting these will not cause
- * any adverse affects.
- */
-struct rtllib_rx_stats {
- s8 rssi;
- u8 signal;
- u8 noise;
- u16 rate; /* in 100 kbps */
- u8 control;
- u8 mask;
- u16 len;
- u16 Length;
- u8 signal_quality;
- s32 RecvSignalPower;
- u8 signal_strength;
- u16 hw_error:1;
- u16 bCRC:1;
- u16 bICV:1;
- u16 decrypted:1;
- u32 time_stamp_low;
- u32 time_stamp_high;
-
- u8 rx_drv_info_size;
- u8 rx_buf_shift;
- bool bIsAMPDU;
- bool bFirstMPDU;
- bool contain_htc;
- u32 RxPWDBAll;
- u8 RxMIMOSignalStrength[2];
- s8 RxMIMOSignalQuality[2];
- bool bPacketMatchBSSID;
- bool bIsCCK;
- bool packet_to_self;
- bool bPacketBeacon;
- bool bToSelfBA;
-};
-
-/* IEEE 802.11 requires that STA supports concurrent reception of at least
- * three fragmented frames. This define can be increased to support more
- * concurrent frames, but it should be noted that each entry can consume about
- * 2 kB of RAM and increasing cache size will slow down frame reassembly.
- */
-#define RTLLIB_FRAG_CACHE_LEN 4
-
-struct rtllib_frag_entry {
- unsigned long first_frag_time;
- unsigned int seq;
- unsigned int last_frag;
- struct sk_buff *skb;
- u8 src_addr[ETH_ALEN];
- u8 dst_addr[ETH_ALEN];
-};
-
-struct rtllib_device;
-
-#define SEC_ACTIVE_KEY (1 << 4)
-#define SEC_AUTH_MODE (1 << 5)
-#define SEC_UNICAST_GROUP (1 << 6)
-#define SEC_LEVEL (1 << 7)
-#define SEC_ENABLED (1 << 8)
-
-#define SEC_LEVEL_0 0 /* None */
-#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
-
-#define SEC_ALG_NONE 0
-#define SEC_ALG_WEP 1
-#define SEC_ALG_TKIP 2
-#define SEC_ALG_CCMP 4
-
-#define WEP_KEY_LEN 13
-#define SCM_KEY_LEN 32
-
-struct rtllib_security {
- u16 active_key:2,
- enabled:1,
- auth_mode:2,
- auth_algo:4,
- unicast_uses_group:1,
- encrypt:1;
- u8 key_sizes[NUM_WEP_KEYS];
- u8 keys[NUM_WEP_KEYS][SCM_KEY_LEN];
- u8 level;
- u16 flags;
-} __packed;
-
-/* 802.11 data frame from AP
- * ,-------------------------------------------------------------------.
- * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
- * |------|------|---------|---------|---------|------|---------|------|
- * Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
- * | | tion | (BSSID) | | | ence | data | |
- * `-------------------------------------------------------------------'
- * Total: 28-2340 bytes
- */
-
-/* Management Frame Information Element Types */
-enum rtllib_mfie {
- MFIE_TYPE_SSID = 0,
- MFIE_TYPE_RATES = 1,
- MFIE_TYPE_FH_SET = 2,
- MFIE_TYPE_DS_SET = 3,
- MFIE_TYPE_CF_SET = 4,
- MFIE_TYPE_TIM = 5,
- MFIE_TYPE_IBSS_SET = 6,
- MFIE_TYPE_COUNTRY = 7,
- MFIE_TYPE_HOP_PARAMS = 8,
- MFIE_TYPE_HOP_TABLE = 9,
- MFIE_TYPE_REQUEST = 10,
- MFIE_TYPE_CHALLENGE = 16,
- MFIE_TYPE_POWER_CONSTRAINT = 32,
- MFIE_TYPE_POWER_CAPABILITY = 33,
- MFIE_TYPE_TPC_REQUEST = 34,
- MFIE_TYPE_TPC_REPORT = 35,
- MFIE_TYPE_SUPP_CHANNELS = 36,
- MFIE_TYPE_CSA = 37,
- MFIE_TYPE_MEASURE_REQUEST = 38,
- MFIE_TYPE_MEASURE_REPORT = 39,
- MFIE_TYPE_QUIET = 40,
- MFIE_TYPE_IBSS_DFS = 41,
- MFIE_TYPE_ERP = 42,
- MFIE_TYPE_HT_CAP = 45,
- MFIE_TYPE_RSN = 48,
- MFIE_TYPE_RATES_EX = 50,
- MFIE_TYPE_HT_INFO = 61,
- MFIE_TYPE_AIRONET = 133,
- MFIE_TYPE_GENERIC = 221,
- MFIE_TYPE_QOS_PARAMETER = 222,
-};
-
-/* Minimal header; can be used for passing 802.11 frames with sufficient
- * information to determine what type of underlying data type is actually
- * stored in the data.
- */
-struct rtllib_info_element {
- u8 id;
- u8 len;
- u8 data[];
-} __packed;
-
-struct rtllib_authentication {
- struct ieee80211_hdr_3addr header;
- __le16 algorithm;
- __le16 transaction;
- __le16 status;
- /*challenge*/
- struct rtllib_info_element info_element[];
-} __packed __aligned(2);
-
-struct rtllib_disauth {
- struct ieee80211_hdr_3addr header;
- __le16 reason;
-} __packed __aligned(2);
-
-struct rtllib_disassoc {
- struct ieee80211_hdr_3addr header;
- __le16 reason;
-} __packed __aligned(2);
-
-struct rtllib_probe_request {
- struct ieee80211_hdr_3addr header;
- /* SSID, supported rates */
- struct rtllib_info_element info_element[];
-} __packed __aligned(2);
-
-struct rtllib_probe_response {
- struct ieee80211_hdr_3addr header;
- u32 time_stamp[2];
- __le16 beacon_interval;
- __le16 capability;
- /* SSID, supported rates, FH params, DS params,
- * CF params, IBSS params, TIM (if beacon), RSN
- */
- struct rtllib_info_element info_element[];
-} __packed __aligned(2);
-
-/* Alias beacon for probe_response */
-#define rtllib_beacon rtllib_probe_response
-
-struct rtllib_assoc_request_frame {
- struct ieee80211_hdr_3addr header;
- __le16 capability;
- __le16 listen_interval;
- /* SSID, supported rates, RSN */
- struct rtllib_info_element info_element[];
-} __packed __aligned(2);
-
-struct rtllib_assoc_response_frame {
- struct ieee80211_hdr_3addr header;
- __le16 capability;
- __le16 status;
- __le16 aid;
- struct rtllib_info_element info_element[]; /* supported rates */
-} __packed __aligned(2);
-
-struct rtllib_txb {
- u8 nr_frags;
- u8 encrypted;
- u8 queue_index;
- u8 rts_included;
- u16 reserved;
- __le16 frag_size;
- __le16 payload_size;
- struct sk_buff *fragments[] __counted_by(nr_frags);
-};
-
-#define MAX_SUBFRAME_COUNT 64
-struct rtllib_rxb {
- u8 nr_subframes;
- struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
-};
-
-union frameqos {
- u16 shortdata;
- u8 chardata[2];
- struct {
- u16 tid:4;
- u16 eosp:1;
- u16 ack_policy:2;
- u16 reserved:1;
- u16 txop:8;
- } field;
-};
-
-/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
- * only use 8, and then use extended rates for the remaining supported
- * rates. Other APs, however, stick all of their supported rates on the
- * main rates information element...
- */
-#define MAX_RATES_LENGTH ((u8)12)
-#define MAX_RATES_EX_LENGTH ((u8)16)
-#define MAX_NETWORK_COUNT 96
-
-#define MAX_CHANNEL_NUMBER 161
-#define RTLLIB_SOFTMAC_SCAN_TIME 100
-#define RTLLIB_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
-
-#define MAX_WPA_IE_LEN 64
-#define MAX_WZC_IE_LEN 256
-
-#define NETWORK_EMPTY_ESSID (1 << 0)
-#define NETWORK_HAS_OFDM (1 << 1)
-#define NETWORK_HAS_CCK (1 << 2)
-
-/* QoS structure */
-#define NETWORK_HAS_QOS_PARAMETERS (1 << 3)
-#define NETWORK_HAS_QOS_INFORMATION (1 << 4)
-#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \
- NETWORK_HAS_QOS_INFORMATION)
-/* 802.11h */
-#define NETWORK_HAS_ERP_VALUE (1 << 10)
-
-#define QOS_QUEUE_NUM 4
-#define QOS_OUI_LEN 3
-#define QOS_OUI_TYPE 2
-#define QOS_ELEMENT_ID 221
-#define QOS_OUI_INFO_SUB_TYPE 0
-#define QOS_OUI_PARAM_SUB_TYPE 1
-#define QOS_VERSION_1 1
-
-struct rtllib_qos_information_element {
- u8 element_id;
- u8 length;
- u8 qui[QOS_OUI_LEN];
- u8 qui_type;
- u8 qui_subtype;
- u8 version;
- u8 ac_info;
-} __packed;
-
-struct rtllib_qos_ac_parameter {
- u8 aci_aifsn;
- u8 ecw_min_max;
- __le16 tx_op_limit;
-} __packed;
-
-struct rtllib_qos_parameter_info {
- struct rtllib_qos_information_element info_element;
- u8 reserved;
- struct rtllib_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
-} __packed;
-
-struct rtllib_qos_parameters {
- __le16 cw_min[QOS_QUEUE_NUM];
- __le16 cw_max[QOS_QUEUE_NUM];
- u8 aifs[QOS_QUEUE_NUM];
- u8 flag[QOS_QUEUE_NUM];
- __le16 tx_op_limit[QOS_QUEUE_NUM];
-} __packed;
-
-struct rtllib_qos_data {
- struct rtllib_qos_parameters parameters;
- unsigned int wmm_acm;
- int active;
- int supported;
- u8 param_count;
- u8 old_param_count;
-};
-
-struct rtllib_tim_parameters {
- u8 tim_count;
- u8 tim_period;
-} __packed;
-
-struct rtllib_wmm_ac_param {
- u8 ac_aci_acm_aifsn;
- u8 ac_ecwmin_ecwmax;
- u16 ac_txop_limit;
-};
-
-enum eap_type {
- EAP_PACKET = 0,
- EAPOL_START,
- EAPOL_LOGOFF,
- EAPOL_KEY,
- EAPOL_ENCAP_ASF_ALERT
-};
-
-static const char * const eap_types[] = {
- [EAP_PACKET] = "EAP-Packet",
- [EAPOL_START] = "EAPOL-Start",
- [EAPOL_LOGOFF] = "EAPOL-Logoff",
- [EAPOL_KEY] = "EAPOL-Key",
- [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
-};
-
-static inline const char *eap_get_type(int type)
-{
- return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" :
- eap_types[type];
-}
-
-static inline u8 frame_qos_tid(u8 *buf)
-{
- struct ieee80211_hdr_3addr *hdr;
- u16 fc;
-
- hdr = (struct ieee80211_hdr_3addr *)buf;
- fc = le16_to_cpu(hdr->frame_control);
- return (u8)((union frameqos *)(buf + (((fc & IEEE80211_FCTL_TODS) &&
- (fc & IEEE80211_FCTL_FROMDS)) ? 30 : 24)))->field.tid;
-}
-
-struct eapol {
- u8 snap[6];
- u16 ethertype;
- u8 version;
- u8 type;
- u16 length;
-} __packed;
-
-struct rtllib_softmac_stats {
- unsigned int rx_ass_ok;
- unsigned int rx_ass_err;
- unsigned int rx_probe_rq;
- unsigned int tx_probe_rs;
- unsigned int tx_beacons;
- unsigned int rx_auth_rq;
- unsigned int rx_auth_rs_ok;
- unsigned int rx_auth_rs_err;
- unsigned int tx_auth_rq;
- unsigned int no_auth_rs;
- unsigned int no_ass_rs;
- unsigned int tx_ass_rq;
- unsigned int rx_ass_rq;
- unsigned int tx_probe_rq;
- unsigned int reassoc;
- unsigned int swtxstop;
- unsigned int swtxawake;
- unsigned char CurrentShowTxate;
- unsigned char last_packet_rate;
- unsigned int txretrycount;
-};
-
-/* These are the data types that can make up management packets
- *
- * u16 auth_algorithm;
- * u16 auth_sequence;
- * u16 beacon_interval;
- * u16 capability;
- * u8 current_ap[ETH_ALEN];
- * u16 listen_interval;
- * struct {
- * u16 association_id:14, reserved:2;
- * } __packed;
- * u32 time_stamp[2];
- * u16 reason;
- * u16 status;
- */
-
-#define RTLLIB_DEFAULT_TX_ESSID "Penguin"
-#define RTLLIB_DEFAULT_BASIC_RATE 2
-
-enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
-#define MAX_SP_Len (WMM_all_frame << 4)
-#define RTLLIB_QOS_TID 0x0f
-#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
-
-#define RTLLIB_DTIM_MBCAST 4
-#define RTLLIB_DTIM_UCAST 2
-#define RTLLIB_DTIM_VALID 1
-#define RTLLIB_DTIM_INVALID 0
-
-#define RTLLIB_PS_DISABLED 0
-#define RTLLIB_PS_UNICAST RTLLIB_DTIM_UCAST
-#define RTLLIB_PS_MBCAST RTLLIB_DTIM_MBCAST
-
-#define WME_AC_BK 0x00
-#define WME_AC_BE 0x01
-#define WME_AC_VI 0x02
-#define WME_AC_VO 0x03
-#define WME_AC_PRAM_LEN 16
-
-#define MAX_RECEIVE_BUFFER_SIZE 9100
-
-#define UP2AC(up) ( \
- ((up) < 1) ? WME_AC_BE : \
- ((up) < 3) ? WME_AC_BK : \
- ((up) < 4) ? WME_AC_BE : \
- ((up) < 6) ? WME_AC_VI : \
- WME_AC_VO)
-
-#define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address
- * plus ether type
- */
-
-enum erp_t {
- ERP_NonERPpresent = 0x01,
- ERP_UseProtection = 0x02,
- ERP_BarkerPreambleMode = 0x04,
-};
-
-struct rtllib_network {
- /* These entries are used to identify a unique network */
- u8 bssid[ETH_ALEN];
- u8 channel;
- /* Ensure null-terminated for any debug msgs */
- u8 ssid[IW_ESSID_MAX_SIZE + 1];
- u8 ssid_len;
- u8 hidden_ssid[IW_ESSID_MAX_SIZE + 1];
- u8 hidden_ssid_len;
- struct rtllib_qos_data qos_data;
-
- bool with_aironet_ie;
- bool ckip_supported;
- bool ccx_rm_enable;
- u8 ccx_rm_state[2];
- bool mb_ssid_valid;
- u8 mb_ssid_mask;
- u8 mb_ssid[ETH_ALEN];
- bool with_ccx_ver_num;
- u8 bss_ccx_ver_number;
- /* These are network statistics */
- struct rtllib_rx_stats stats;
- u16 capability;
- u8 rates[MAX_RATES_LENGTH];
- u8 rates_len;
- u8 rates_ex[MAX_RATES_EX_LENGTH];
- u8 rates_ex_len;
- unsigned long last_scanned;
- u8 mode;
- u32 flags;
- u32 time_stamp[2];
- u16 beacon_interval;
- u16 listen_interval;
- u16 atim_window;
- u8 erp_value;
- u8 wpa_ie[MAX_WPA_IE_LEN];
- size_t wpa_ie_len;
- u8 rsn_ie[MAX_WPA_IE_LEN];
- size_t rsn_ie_len;
- u8 wzc_ie[MAX_WZC_IE_LEN];
- size_t wzc_ie_len;
-
- struct rtllib_tim_parameters tim;
- u8 dtim_period;
- u8 dtim_data;
- u64 last_dtim_sta_time;
-
- u8 wmm_info;
- struct rtllib_wmm_ac_param wmm_param[4];
- u8 turbo_enable;
- u16 country_ie_len;
- u8 country_ie_buf[MAX_IE_LEN];
- struct bss_ht bssht;
- bool broadcom_cap_exist;
- bool realtek_cap_exit;
- bool marvell_cap_exist;
- bool ralink_cap_exist;
- bool atheros_cap_exist;
- bool cisco_cap_exist;
- bool airgo_cap_exist;
- bool unknown_cap_exist;
- bool berp_info_valid;
- bool buseprotection;
- u8 signal_strength;
- u8 RSSI;
- struct list_head list;
-};
-
-enum rtl_link_state {
- /* the card is not linked at all */
- MAC80211_NOLINK = 0,
-
- /* RTLLIB_ASSOCIATING* are for BSS client mode
- * the driver shall not perform RX filtering unless
- * the state is LINKED.
- * The driver shall just check for the state LINKED and
- * defaults to NOLINK for ALL the other states (including
- * LINKED_SCANNING)
- */
-
- /* the association procedure will start (wq scheduling)*/
- RTLLIB_ASSOCIATING,
- RTLLIB_ASSOCIATING_RETRY,
-
- /* the association procedure is sending AUTH request*/
- RTLLIB_ASSOCIATING_AUTHENTICATING,
-
- /* the association procedure has successfully authenticated
- * and is sending association request
- */
- RTLLIB_ASSOCIATING_AUTHENTICATED,
-
- /* the link is ok. the card associated to a BSS or linked
- * to a ibss cell or acting as an AP and creating the bss
- */
- MAC80211_LINKED,
-
- /* same as LINKED, but the driver shall apply RX filter
- * rules as we are in NO_LINK mode. As the card is still
- * logically linked, but it is doing a syncro site survey
- * then it will be back to LINKED state.
- */
- MAC80211_LINKED_SCANNING,
-};
-
-#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
-#define DEFAULT_FTS 2346
-
-#define CFG_RTLLIB_RESERVE_FCS (1 << 0)
-#define CFG_RTLLIB_COMPUTE_FCS (1 << 1)
-
-struct tx_pending {
- int frag;
- struct rtllib_txb *txb;
-};
-
-struct bandwidth_autoswitch {
- long threshold_20Mhzto40Mhz;
- long threshold_40Mhzto20Mhz;
- bool forced_tx_20MHz;
- bool bautoswitch_enable;
-};
-
-#define REORDER_WIN_SIZE 128
-#define REORDER_ENTRY_NUM 128
-struct rx_reorder_entry {
- struct list_head list;
- u16 seq_num;
- struct rtllib_rxb *prxb;
-};
-
-enum fsync_state {
- DEFAULT_FSYNC,
- HW_FSYNC,
- SW_FSYNC
-};
-
-enum ips_callback_function {
- IPS_CALLBACK_NONE = 0,
- IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
- IPS_CALLBACK_JOIN_REQUEST = 2,
-};
-
-enum rt_rf_power_state {
- rf_on,
- rf_sleep,
- rf_off
-};
-
-struct rt_pwr_save_ctrl {
- bool bSwRfProcessing;
- enum rt_rf_power_state eInactivePowerState;
- enum ips_callback_function return_point;
-
- bool bLeisurePs;
- u8 lps_idle_count;
- u8 lps_awake_intvl;
-
- u32 cur_ps_level;
-};
-
-#define RT_RF_CHANGE_SOURCE u32
-
-#define RF_CHANGE_BY_SW BIT(31)
-#define RF_CHANGE_BY_HW BIT(30)
-#define RF_CHANGE_BY_PS BIT(29)
-#define RF_CHANGE_BY_IPS BIT(28)
-#define RF_CHANGE_BY_INIT 0
-
-enum country_code_type {
- COUNTRY_CODE_FCC = 0,
- COUNTRY_CODE_IC = 1,
- COUNTRY_CODE_ETSI = 2,
- COUNTRY_CODE_SPAIN = 3,
- COUNTRY_CODE_FRANCE = 4,
- COUNTRY_CODE_MKK = 5,
- COUNTRY_CODE_MKK1 = 6,
- COUNTRY_CODE_ISRAEL = 7,
- COUNTRY_CODE_TELEC = 8,
- COUNTRY_CODE_MIC = 9,
- COUNTRY_CODE_GLOBAL_DOMAIN = 10,
- COUNTRY_CODE_WORLD_WIDE_13 = 11,
- COUNTRY_CODE_TELEC_NETGEAR = 12,
- COUNTRY_CODE_MAX
-};
-
-enum scan_op_backup_opt {
- SCAN_OPT_BACKUP = 0,
- SCAN_OPT_RESTORE,
- SCAN_OPT_MAX
-};
-
-#define RT_MAX_LD_SLOT_NUM 10
-struct rt_link_detect {
- u32 num_recv_bcn_in_period;
- u32 num_recv_data_in_period;
-
- u32 RxBcnNum[RT_MAX_LD_SLOT_NUM];
- u32 RxDataNum[RT_MAX_LD_SLOT_NUM];
- u16 slot_num;
- u16 slot_index;
-
- u32 num_tx_ok_in_period;
- u32 num_rx_ok_in_period;
- u32 num_rx_unicast_ok_in_period;
- bool busy_traffic;
- bool bHigherBusyTraffic;
- bool bHigherBusyRxTraffic;
-};
-
-struct sw_cam_table {
- u8 macaddr[ETH_ALEN];
- bool bused;
- u8 key_buf[16];
- u16 key_type;
- u8 useDK;
- u8 key_index;
-
-};
-
-#define TOTAL_CAM_ENTRY 32
-struct rate_adaptive {
- u8 ratr_state;
- u16 reserve;
-
- u32 high_rssi_thresh_for_ra;
- u32 high2low_rssi_thresh_for_ra;
- u8 low2high_rssi_thresh_for_ra40M;
- u32 low_rssi_thresh_for_ra40M;
- u8 low2high_rssi_thresh_for_ra20M;
- u32 low_rssi_thresh_for_ra20M;
- u32 upper_rssi_threshold_ratr;
- u32 middle_rssi_threshold_ratr;
- u32 low_rssi_threshold_ratr;
- u32 low_rssi_threshold_ratr_40M;
- u32 low_rssi_threshold_ratr_20M;
- u8 ping_rssi_enable;
- u32 ping_rssi_ratr;
- u32 ping_rssi_thresh_for_ra;
- u8 PreRATRState;
-
-};
-
-#define NUM_PMKID_CACHE 16
-struct rt_pmkid_list {
- u8 bssid[ETH_ALEN];
- u8 PMKID[16];
- u8 SsidBuf[33];
- u8 used;
-};
-
-/*************** DRIVER STATUS *****/
-#define STATUS_SCANNING 0
-/*************** DRIVER STATUS *****/
-
-enum {
- LPS_IS_WAKE = 0,
- LPS_IS_SLEEP = 1,
- LPS_WAIT_NULL_DATA_SEND = 2,
-};
-
-struct rtllib_device {
- struct pci_dev *pdev;
- struct net_device *dev;
- struct rtllib_security sec;
-
- bool disable_mgnt_queue;
-
- unsigned long status;
- u8 cnt_after_link;
-
- enum rt_op_mode op_mode;
-
- /* The last AssocReq/Resp IEs */
- u8 *assocreq_ies, *assocresp_ies;
- size_t assocreq_ies_len, assocresp_ies_len;
-
- bool forced_bg_mode;
-
- u8 hwsec_active;
- bool is_roaming;
- bool ieee_up;
- bool cannot_notify;
- bool bSupportRemoteWakeUp;
- bool actscanning;
- bool first_ie_in_scan;
- bool be_scan_inprogress;
- bool beinretry;
- enum rt_rf_power_state rf_power_state;
- RT_RF_CHANGE_SOURCE rf_off_reason;
- bool is_set_key;
- bool wx_set_enc;
- struct rt_hi_throughput *ht_info;
-
- spinlock_t reorder_spinlock;
- u8 reg_dot11ht_oper_rate_set[16];
- u8 reg_dot11tx_ht_oper_rate_set[16];
- u8 dot11ht_oper_rate_set[16];
- u8 reg_ht_supp_rate_set[16];
- u8 ht_curr_op_rate;
- u8 HTHighestOperaRate;
- u8 tx_dis_rate_fallback;
- u8 tx_use_drv_assinged_rate;
- u8 tx_enable_fw_calc_dur;
- atomic_t atm_swbw;
-
- struct list_head Tx_TS_Admit_List;
- struct list_head Tx_TS_Pending_List;
- struct list_head Tx_TS_Unused_List;
- struct tx_ts_record tx_ts_records[TOTAL_TS_NUM];
- struct list_head Rx_TS_Admit_List;
- struct list_head Rx_TS_Pending_List;
- struct list_head Rx_TS_Unused_List;
- struct rx_ts_record rx_ts_records[TOTAL_TS_NUM];
- struct rx_reorder_entry RxReorderEntry[128];
- struct list_head RxReorder_Unused_List;
-
- /* Bookkeeping structures */
- struct net_device_stats stats;
- struct rtllib_softmac_stats softmac_stats;
-
- /* Probe / Beacon management */
- struct list_head network_free_list;
- struct list_head network_list;
- struct rtllib_network *networks;
- int scans;
- int scan_age;
-
- int iw_mode; /* operating mode (IW_MODE_*) */
-
- spinlock_t lock;
- spinlock_t wpax_suitlist_lock;
-
- int tx_headroom; /* Set to size of any additional room needed at front
- * of allocated Tx SKBs
- */
- u32 config;
-
- /* WEP and other encryption related settings at the device level */
- int open_wep; /* Set to 1 to allow unencrypted frames */
- int auth_mode;
- int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
- * WEP key changes
- */
-
- int ieee802_1x; /* is IEEE 802.1X used */
-
- /* WPA data */
- bool half_wireless_n24g_mode;
- int wpa_enabled;
- int drop_unencrypted;
- int tkip_countermeasures;
- int privacy_invoked;
- size_t wpa_ie_len;
- u8 *wpa_ie;
- size_t wps_ie_len;
- u8 *wps_ie;
- u8 ap_mac_addr[ETH_ALEN];
- u16 pairwise_key_type;
- u16 group_key_type;
-
- struct lib80211_crypt_info crypt_info;
-
- struct sw_cam_table swcamtable[TOTAL_CAM_ENTRY];
-
- struct rt_pmkid_list pmkid_list[NUM_PMKID_CACHE];
-
- /* Fragmentation structures */
- struct rtllib_frag_entry frag_cache[17][RTLLIB_FRAG_CACHE_LEN];
- unsigned int frag_next_idx[17];
- u16 fts; /* Fragmentation Threshold */
-#define DEFAULT_RTS_THRESHOLD 2346U
-#define MIN_RTS_THRESHOLD 1
-#define MAX_RTS_THRESHOLD 2346U
- u16 rts; /* RTS threshold */
-
- /* Association info */
- u8 bssid[ETH_ALEN];
-
- /* This stores infos for the current network.
- * Either the network we are associated in INFRASTRUCTURE
- * or the network that we are creating in MASTER mode.
- * ad-hoc is a mixture ;-).
- * Note that in infrastructure mode, even when not associated,
- * fields bssid and essid may be valid (if wpa_set and essid_set
- * are true) as thy carry the value set by the user via iwconfig
- */
- struct rtllib_network current_network;
-
- enum rtl_link_state link_state;
-
- int mode; /* A, B, G */
-
- /* used for forcing the ibss workqueue to terminate
- * without wait for the syncro scan to terminate
- */
- short sync_scan_hurryup;
- u16 scan_watch_dog;
-
- /* map of allowed channels. 0 is dummy */
- u8 active_channel_map[MAX_CHANNEL_NUMBER + 1];
-
- int rate; /* current rate */
- int basic_rate;
-
- /* this contains flags for selectively enable softmac support */
- u16 softmac_features;
-
- /* if the sequence control field is not filled by HW */
- u16 seq_ctrl[5];
-
- /* association procedure transaction sequence number */
- u16 associate_seq;
-
- /* AID for RTXed association responses */
- u16 assoc_id;
-
- /* power save mode related*/
- u8 ack_tx_to_ieee;
- short ps;
- short sta_sleep;
- int ps_timeout;
- int ps_period;
- struct work_struct ps_task;
- u64 ps_time;
- bool polling;
-
- /* used if IEEE_SOFTMAC_TX_QUEUE is set */
- short queue_stop;
- short scanning_continue;
- short proto_started;
- short proto_stoppping;
-
- struct mutex wx_mutex;
- struct mutex scan_mutex;
- struct mutex ips_mutex;
-
- spinlock_t mgmt_tx_lock;
- spinlock_t beacon_lock;
-
- short beacon_txing;
-
- short wap_set;
- short ssid_set;
-
- /* set on initialization */
- unsigned int wmm_acm;
-
- /* for discarding duplicated packets in IBSS */
- struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
-
- /* for discarding duplicated packets in BSS */
- u16 last_rxseq_num[17]; /* rx seq previous per-tid */
- u16 last_rxfrag_num[17];/* tx frag previous per-tid */
- unsigned long last_packet_time[17];
-
- /* for PS mode */
- unsigned long last_rx_ps_time;
- bool awake_pkt_sent;
- u8 lps_delay_cnt;
-
- /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
- struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
- int mgmt_queue_head;
- int mgmt_queue_tail;
- u8 asoc_retry_count;
- struct sk_buff_head skb_waitq[MAX_QUEUE_SIZE];
-
- bool bdynamic_txpower_enable;
-
- bool bCTSToSelfEnable;
-
- u32 fsync_time_interval;
- u32 fsync_rate_bitmap;
- u8 fsync_rssi_threshold;
- bool bfsync_enable;
-
- u8 fsync_multiple_timeinterval;
- u32 fsync_firstdiff_ratethreshold;
- u32 fsync_seconddiff_ratethreshold;
- enum fsync_state fsync_state;
- bool bis_any_nonbepkts;
- struct bandwidth_autoswitch bandwidth_auto_switch;
- bool FwRWRF;
-
- struct rt_link_detect link_detect_info;
- bool is_aggregate_frame;
- struct rt_pwr_save_ctrl pwr_save_ctrl;
-
- /* used if IEEE_SOFTMAC_TX_QUEUE is set */
- struct tx_pending tx_pending;
-
- /* used if IEEE_SOFTMAC_ASSOCIATE is set */
- struct timer_list associate_timer;
-
- /* used if IEEE_SOFTMAC_BEACONS is set */
- u8 need_sw_enc;
- struct work_struct associate_complete_wq;
- struct work_struct ips_leave_wq;
- struct delayed_work associate_procedure_wq;
- struct delayed_work softmac_scan_wq;
- struct delayed_work associate_retry_wq;
- struct delayed_work hw_wakeup_wq;
- struct delayed_work hw_sleep_wq;
- struct delayed_work link_change_wq;
- struct work_struct wx_sync_scan_wq;
-
- union {
- struct rtllib_rxb *rfd_array[REORDER_WIN_SIZE];
- struct rtllib_rxb *stats_IndicateArray[REORDER_WIN_SIZE];
- struct rtllib_rxb *prxb_indicate_array[REORDER_WIN_SIZE];
- struct {
- struct sw_chnl_cmd PreCommonCmd[MAX_PRECMD_CNT];
- struct sw_chnl_cmd PostCommonCmd[MAX_POSTCMD_CNT];
- struct sw_chnl_cmd RfDependCmd[MAX_RFDEPENDCMD_CNT];
- };
- };
-
- /* Callback functions */
-
- /* Softmac-generated frames (management) are TXed via this
- * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
- * not set. As some cards may have different HW queues that
- * one might want to use for data and management frames
- * the option to have two callbacks might be useful.
- * This function can't sleep.
- */
- int (*softmac_hard_start_xmit)(struct sk_buff *skb,
- struct net_device *dev);
-
- /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
- * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
- * frames. If the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
- * then also management frames are sent via this callback.
- * This function can't sleep.
- */
- void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
- struct net_device *dev, int rate);
-
- /* ask to the driver to retune the radio.
- * This function can sleep. the driver should ensure
- * the radio has been switched before return.
- */
- void (*set_chan)(struct net_device *dev, u8 ch);
-
- /* indicate the driver that the link state is changed
- * for example it may indicate the card is associated now.
- * Driver might be interested in this to apply RX filter
- * rules or simply light the LINK led
- */
- void (*link_change)(struct net_device *dev);
-
- /* power save mode related */
- void (*sta_wake_up)(struct net_device *dev);
- void (*enter_sleep_state)(struct net_device *dev, u64 time);
- short (*ps_is_queue_empty)(struct net_device *dev);
- int (*handle_beacon)(struct net_device *dev,
- struct rtllib_beacon *beacon,
- struct rtllib_network *network);
- int (*handle_assoc_response)(struct net_device *dev,
- struct rtllib_assoc_response_frame *resp,
- struct rtllib_network *network);
-
- /* check whether Tx hw resource available */
- short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
- void (*set_bw_mode_handler)(struct net_device *dev,
- enum ht_channel_width bandwidth,
- enum ht_extchnl_offset Offset);
- bool (*get_nmode_support_by_sec_cfg)(struct net_device *dev);
- void (*set_wireless_mode)(struct net_device *dev, u8 wireless_mode);
- bool (*get_half_nmode_support_by_aps_handler)(struct net_device *dev);
- u8 (*rtllib_ap_sec_type)(struct rtllib_device *ieee);
- void (*init_gain_handler)(struct net_device *dev, u8 operation);
- void (*scan_operation_backup_handler)(struct net_device *dev,
- u8 operation);
- void (*set_hw_reg_handler)(struct net_device *dev, u8 variable, u8 *val);
-
- void (*allow_all_dest_addr_handler)(struct net_device *dev,
- bool allow_all_da,
- bool write_into_reg);
-
- void (*rtllib_ips_leave_wq)(struct net_device *dev);
- void (*rtllib_ips_leave)(struct net_device *dev);
- void (*leisure_ps_leave)(struct net_device *dev);
-
- /* This must be the last item so that it points to the data
- * allocated beyond this structure by alloc_rtllib
- */
- u8 priv[];
-};
-
-#define IEEE_MODE_MASK (WIRELESS_MODE_B | WIRELESS_MODE_G)
-
-/* Generate a 802.11 header */
-
-/* Uses the channel change callback directly
- * instead of [start/stop] scan callbacks
- */
-#define IEEE_SOFTMAC_SCAN (1 << 2)
-
-/* Perform authentication and association handshake */
-#define IEEE_SOFTMAC_ASSOCIATE (1 << 3)
-
-/* Generate probe requests */
-#define IEEE_SOFTMAC_PROBERQ (1 << 4)
-
-/* Generate response to probe requests */
-#define IEEE_SOFTMAC_PROBERS (1 << 5)
-
-/* The ieee802.11 stack will manage the netif queue
- * wake/stop for the driver, taking care of 802.11
- * fragmentation. See softmac.c for details.
- */
-#define IEEE_SOFTMAC_TX_QUEUE (1 << 7)
-
-/* Uses only the softmac_data_hard_start_xmit
- * even for TX management frames.
- */
-#define IEEE_SOFTMAC_SINGLE_QUEUE (1 << 8)
-
-/* Generate beacons. The stack will enqueue beacons
- * to the card
- */
-#define IEEE_SOFTMAC_BEACONS (1 << 6)
-
-static inline void *rtllib_priv(struct net_device *dev)
-{
- return ((struct rtllib_device *)netdev_priv(dev))->priv;
-}
-
-static inline int rtllib_is_empty_essid(const char *essid, int essid_len)
-{
- /* Single white space is for Linksys APs */
- if (essid_len == 1 && essid[0] == ' ')
- return 1;
-
- /* Otherwise, if the entire essid is 0, we assume it is hidden */
- while (essid_len) {
- essid_len--;
- if (essid[essid_len] != '\0')
- return 0;
- }
-
- return 1;
-}
-
-static inline int rtllib_get_hdrlen(u16 fc)
-{
- int hdrlen = RTLLIB_3ADDR_LEN;
-
- switch (WLAN_FC_GET_TYPE(fc)) {
- case RTLLIB_FTYPE_DATA:
- if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
- hdrlen = RTLLIB_4ADDR_LEN; /* Addr4 */
- if (RTLLIB_QOS_HAS_SEQ(fc))
- hdrlen += 2; /* QOS ctrl*/
- break;
- case RTLLIB_FTYPE_CTL:
- switch (WLAN_FC_GET_STYPE(fc)) {
- case IEEE80211_STYPE_CTS:
- case IEEE80211_STYPE_ACK:
- hdrlen = RTLLIB_1ADDR_LEN;
- break;
- default:
- hdrlen = RTLLIB_2ADDR_LEN;
- break;
- }
- break;
- }
-
- return hdrlen;
-}
-
-static inline int rtllib_is_ofdm_rate(u8 rate)
-{
- switch (rate & ~RTLLIB_BASIC_RATE_MASK) {
- case RTLLIB_OFDM_RATE_6MB:
- case RTLLIB_OFDM_RATE_9MB:
- case RTLLIB_OFDM_RATE_12MB:
- case RTLLIB_OFDM_RATE_18MB:
- case RTLLIB_OFDM_RATE_24MB:
- case RTLLIB_OFDM_RATE_36MB:
- case RTLLIB_OFDM_RATE_48MB:
- case RTLLIB_OFDM_RATE_54MB:
- return 1;
- }
- return 0;
-}
-
-static inline int rtllib_is_cck_rate(u8 rate)
-{
- switch (rate & ~RTLLIB_BASIC_RATE_MASK) {
- case RTLLIB_CCK_RATE_1MB:
- case RTLLIB_CCK_RATE_2MB:
- case RTLLIB_CCK_RATE_5MB:
- case RTLLIB_CCK_RATE_11MB:
- return 1;
- }
- return 0;
-}
-
-/* rtllib.c */
-void free_rtllib(struct net_device *dev);
-struct net_device *alloc_rtllib(int sizeof_priv);
-
-/* rtllib_tx.c */
-
-int rtllib_encrypt_fragment(struct rtllib_device *ieee,
- struct sk_buff *frag,
- int hdr_len);
-
-netdev_tx_t rtllib_xmit(struct sk_buff *skb, struct net_device *dev);
-void rtllib_txb_free(struct rtllib_txb *txb);
-
-/* rtllib_rx.c */
-int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats);
-int rtllib_legal_channel(struct rtllib_device *rtllib, u8 channel);
-
-/* rtllib_wx.c */
-int rtllib_wx_get_scan(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key);
-int rtllib_wx_set_encode(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key);
-int rtllib_wx_get_encode(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key);
-int rtllib_wx_set_encode_ext(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-int rtllib_wx_set_auth(struct rtllib_device *ieee,
- struct iw_request_info *info,
- struct iw_param *data, char *extra);
-int rtllib_wx_set_mlme(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len);
-
-/* rtllib_softmac.c */
-int rtllib_rx_frame_softmac(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats, u16 type,
- u16 stype);
-void rtllib_softmac_new_net(struct rtllib_device *ieee,
- struct rtllib_network *net);
-
-void send_disassociation(struct rtllib_device *ieee, bool deauth, u16 rsn);
-void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee);
-
-int rtllib_softmac_init(struct rtllib_device *ieee);
-void rtllib_softmac_free(struct rtllib_device *ieee);
-void rtllib_disassociate(struct rtllib_device *ieee);
-void rtllib_stop_scan(struct rtllib_device *ieee);
-bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan);
-void rtllib_stop_scan_syncro(struct rtllib_device *ieee);
-void rtllib_start_scan_syncro(struct rtllib_device *ieee);
-void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr);
-void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee);
-void rtllib_start_protocol(struct rtllib_device *ieee);
-void rtllib_stop_protocol(struct rtllib_device *ieee);
-
-void rtllib_enable_net_monitor_mode(struct net_device *dev, bool init_state);
-void rtllib_disable_net_monitor_mode(struct net_device *dev, bool init_state);
-
-void rtllib_softmac_stop_protocol(struct rtllib_device *ieee);
-void rtllib_softmac_start_protocol(struct rtllib_device *ieee);
-
-void rtllib_reset_queue(struct rtllib_device *ieee);
-void rtllib_wake_all_queues(struct rtllib_device *ieee);
-void rtllib_stop_all_queues(struct rtllib_device *ieee);
-
-void notify_wx_assoc_event(struct rtllib_device *ieee);
-void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success);
-
-void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee);
-u8 rtllib_ap_sec_type(struct rtllib_device *ieee);
-
-/* rtllib_softmac_wx.c */
-
-int rtllib_wx_get_wap(struct rtllib_device *ieee, struct iw_request_info *info,
- union iwreq_data *wrqu, char *ext);
-
-int rtllib_wx_set_wap(struct rtllib_device *ieee, struct iw_request_info *info,
- union iwreq_data *awrq, char *extra);
-
-int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-int rtllib_wx_set_rate(struct rtllib_device *ieee, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int rtllib_wx_get_rate(struct rtllib_device *ieee, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-int rtllib_wx_set_essid(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *extra);
-
-int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-int rtllib_wx_get_freq(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-void rtllib_wx_sync_scan_wq(void *data);
-
-int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int rtllib_wx_set_power(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int rtllib_wx_get_power(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int rtllib_wx_set_rts(struct rtllib_device *ieee, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int rtllib_wx_get_rts(struct rtllib_device *ieee, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-#define MAX_RECEIVE_BUFFER_SIZE 9100
-
-void ht_set_connect_bw_mode(struct rtllib_device *ieee,
- enum ht_channel_width bandwidth,
- enum ht_extchnl_offset Offset);
-void ht_update_default_setting(struct rtllib_device *ieee);
-void ht_construct_capability_element(struct rtllib_device *ieee,
- u8 *pos_ht_cap, u8 *len,
- u8 is_encrypt, bool assoc);
-void ht_construct_rt2rt_agg_element(struct rtllib_device *ieee,
- u8 *posRT2RTAgg, u8 *len);
-void ht_on_assoc_rsp(struct rtllib_device *ieee);
-void ht_initialize_ht_info(struct rtllib_device *ieee);
-void ht_initialize_bss_desc(struct bss_ht *bss_ht);
-void ht_reset_self_and_save_peer_setting(struct rtllib_device *ieee,
- struct rtllib_network *network);
-void HT_update_self_and_peer_setting(struct rtllib_device *ieee,
- struct rtllib_network *network);
-u8 ht_get_highest_mcs_rate(struct rtllib_device *ieee, u8 *pMCSRateSet,
- u8 *pMCSFilter);
-extern u8 MCS_FILTER_ALL[];
-extern u16 MCS_DATA_RATE[2][2][77];
-u8 ht_c_check(struct rtllib_device *ieee, u8 *frame);
-void ht_reset_iot_setting(struct rt_hi_throughput *ht_info);
-bool is_ht_half_nmode_aps(struct rtllib_device *ieee);
-u16 tx_count_to_data_rate(struct rtllib_device *ieee, u8 nDataRate);
-int rtllib_rx_add_ba_req(struct rtllib_device *ieee, struct sk_buff *skb);
-int rtllib_rx_add_ba_rsp(struct rtllib_device *ieee, struct sk_buff *skb);
-int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb);
-void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts,
- u8 policy, u8 overwrite_pending);
-void rtllib_ts_init_del_ba(struct rtllib_device *ieee,
- struct ts_common_info *ts_common_info,
- enum tr_select tx_rx_select);
-void rtllib_ba_setup_timeout(struct timer_list *t);
-void rtllib_tx_ba_inact_timeout(struct timer_list *t);
-void rtllib_rx_ba_inact_timeout(struct timer_list *t);
-void rtllib_reset_ba_entry(struct ba_record *ba);
-bool rtllib_get_ts(struct rtllib_device *ieee, struct ts_common_info **ppTS, u8 *addr,
- u8 TID, enum tr_select tx_rx_select, bool add_new_ts);
-void rtllib_ts_init(struct rtllib_device *ieee);
-void rtllib_ts_start_add_ba_process(struct rtllib_device *ieee,
- struct tx_ts_record *pTxTS);
-void remove_peer_ts(struct rtllib_device *ieee, u8 *addr);
-void remove_all_ts(struct rtllib_device *ieee);
-
-static inline const char *escape_essid(const char *essid, u8 essid_len)
-{
- static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-
- if (rtllib_is_empty_essid(essid, essid_len)) {
- memcpy(escaped, "<hidden>", sizeof("<hidden>"));
- return escaped;
- }
-
- snprintf(escaped, sizeof(escaped), "%*pE", essid_len, essid);
- return escaped;
-}
-
-/* fun with the built-in rtllib stack... */
-bool rtllib_mgnt_disconnect(struct rtllib_device *rtllib, u8 rsn);
-
-/* For the function is more related to hardware setting, it's better to use the
- * ieee handler to refer to it.
- */
-void rtllib_flush_rx_ts_pending_pkts(struct rtllib_device *ieee,
- struct rx_ts_record *ts);
-int rtllib_parse_info_param(struct rtllib_device *ieee,
- struct rtllib_info_element *info_element,
- u16 length,
- struct rtllib_network *network,
- struct rtllib_rx_stats *stats);
-
-void rtllib_indicate_packets(struct rtllib_device *ieee,
- struct rtllib_rxb **prxb_indicate_array, u8 index);
-#define RT_ASOC_RETRY_LIMIT 5
-u8 mgnt_query_tx_rate_exclude_cck_rates(struct rtllib_device *ieee);
-
-#endif /* RTLLIB_H */
diff --git a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c
deleted file mode 100644
index 138733cb00e2..000000000000
--- a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c
+++ /dev/null
@@ -1,411 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Host AP crypt: host-based CCMP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/string.h>
-#include <linux/wireless.h>
-#include "rtllib.h"
-
-#include <linux/crypto.h>
-#include <crypto/aead.h>
-
-#include <linux/scatterlist.h>
-
-#define AES_BLOCK_LEN 16
-#define CCMP_HDR_LEN 8
-#define CCMP_MIC_LEN 8
-#define CCMP_TK_LEN 16
-#define CCMP_PN_LEN 6
-
-struct rtllib_ccmp_data {
- u8 key[CCMP_TK_LEN];
- int key_set;
-
- u8 tx_pn[CCMP_PN_LEN];
- u8 rx_pn[CCMP_PN_LEN];
-
- u32 dot11rsna_stats_ccmp_format_errors;
- u32 dot11rsna_stats_ccmp_replays;
- u32 dot11rsna_stats_ccmp_decrypt_errors;
-
- int key_idx;
-
- struct crypto_aead *tfm;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 tx_aad[2 * AES_BLOCK_LEN];
- u8 rx_aad[2 * AES_BLOCK_LEN];
-};
-
-static void *rtllib_ccmp_init(int key_idx)
-{
- struct rtllib_ccmp_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (!priv)
- goto fail;
- priv->key_idx = key_idx;
-
- priv->tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tfm)) {
- pr_debug("Could not allocate crypto API aes\n");
- priv->tfm = NULL;
- goto fail;
- }
- return priv;
-
-fail:
- if (priv) {
- if (priv->tfm)
- crypto_free_aead(priv->tfm);
- kfree(priv);
- }
-
- return NULL;
-}
-
-static void rtllib_ccmp_deinit(void *priv)
-{
- struct rtllib_ccmp_data *_priv = priv;
-
- if (_priv && _priv->tfm)
- crypto_free_aead(_priv->tfm);
- kfree(priv);
-}
-
-static int ccmp_init_iv_and_aad(struct ieee80211_hdr *hdr,
- u8 *pn, u8 *iv, u8 *aad)
-{
- u8 *pos, qc = 0;
- size_t aad_len;
- u16 fc;
- int a4_included, qc_included;
-
- fc = le16_to_cpu(hdr->frame_control);
- a4_included = ieee80211_has_a4(hdr->frame_control);
-
- qc_included = ((WLAN_FC_GET_TYPE(fc) == RTLLIB_FTYPE_DATA) &&
- (WLAN_FC_GET_STYPE(fc) & 0x80));
- aad_len = 22;
- if (a4_included)
- aad_len += 6;
- if (qc_included) {
- pos = (u8 *)&hdr->addr4;
- if (a4_included)
- pos += 6;
- qc = *pos & 0x0f;
- aad_len += 2;
- }
- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
- * mode authentication are not allowed to collide, yet both are derived
- * from the same vector. We only set L := 1 here to indicate that the
- * data size can be represented in (L+1) bytes. The CCM layer will take
- * care of storing the data length in the top (L+1) bytes and setting
- * and clearing the other bits as is required to derive the two IVs.
- */
- iv[0] = 0x1;
-
- /* Nonce: QC | A2 | PN */
- iv[1] = qc;
- memcpy(iv + 2, hdr->addr2, ETH_ALEN);
- memcpy(iv + 8, pn, CCMP_PN_LEN);
-
- /* AAD:
- * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
- * A1 | A2 | A3
- * SC with bits 4..15 (seq#) masked to zero
- * A4 (if present)
- * QC (if present)
- */
- pos = (u8 *)hdr;
- aad[0] = pos[0] & 0x8f;
- aad[1] = pos[1] & 0xc7;
- memcpy(&aad[2], &hdr->addr1, ETH_ALEN);
- memcpy(&aad[8], &hdr->addr2, ETH_ALEN);
- memcpy(&aad[14], &hdr->addr3, ETH_ALEN);
- pos = (u8 *)&hdr->seq_ctrl;
- aad[20] = pos[0] & 0x0f;
- aad[21] = 0; /* all bits masked */
- memset(aad + 22, 0, 8);
- if (a4_included)
- memcpy(aad + 22, hdr->addr4, ETH_ALEN);
- if (qc_included) {
- aad[a4_included ? 28 : 22] = qc;
- /* rest of QC masked */
- }
-
- return aad_len;
-}
-
-static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct rtllib_ccmp_data *key = priv;
- int i;
- u8 *pos;
- struct ieee80211_hdr *hdr;
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
- MAX_DEV_ADDR_SIZE);
- if (skb_headroom(skb) < CCMP_HDR_LEN ||
- skb_tailroom(skb) < CCMP_MIC_LEN ||
- skb->len < hdr_len)
- return -1;
-
- pos = skb_push(skb, CCMP_HDR_LEN);
- memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
- pos += hdr_len;
-
- i = CCMP_PN_LEN - 1;
- while (i >= 0) {
- key->tx_pn[i]++;
- if (key->tx_pn[i] != 0)
- break;
- i--;
- }
-
- *pos++ = key->tx_pn[5];
- *pos++ = key->tx_pn[4];
- *pos++ = 0;
- *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
- *pos++ = key->tx_pn[3];
- *pos++ = key->tx_pn[2];
- *pos++ = key->tx_pn[1];
- *pos++ = key->tx_pn[0];
-
- hdr = (struct ieee80211_hdr *)skb->data;
- if (!tcb_desc->hw_sec) {
- struct aead_request *req;
- struct scatterlist sg[2];
- u8 *aad = key->tx_aad;
- u8 iv[AES_BLOCK_LEN];
- int aad_len, ret;
- int data_len = skb->len - hdr_len - CCMP_HDR_LEN;
-
- req = aead_request_alloc(key->tfm, GFP_ATOMIC);
- if (!req)
- return -ENOMEM;
-
- aad_len = ccmp_init_iv_and_aad(hdr, key->tx_pn, iv, aad);
-
- skb_put(skb, CCMP_MIC_LEN);
- sg_init_table(sg, 2);
- sg_set_buf(&sg[0], aad, aad_len);
- sg_set_buf(&sg[1], skb->data + hdr_len + CCMP_HDR_LEN,
- data_len + CCMP_MIC_LEN);
-
- aead_request_set_callback(req, 0, NULL, NULL);
- aead_request_set_ad(req, aad_len);
- aead_request_set_crypt(req, sg, sg, data_len, iv);
-
- ret = crypto_aead_encrypt(req);
- aead_request_free(req);
-
- return ret;
- }
-
- return 0;
-}
-
-static int rtllib_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct rtllib_ccmp_data *key = priv;
- u8 keyidx, *pos;
- struct ieee80211_hdr *hdr;
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
- MAX_DEV_ADDR_SIZE);
- u8 pn[6];
-
- if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
- key->dot11rsna_stats_ccmp_format_errors++;
- return -1;
- }
-
- hdr = (struct ieee80211_hdr *)skb->data;
- pos = skb->data + hdr_len;
- keyidx = pos[3];
- if (!(keyidx & (1 << 5))) {
- if (net_ratelimit()) {
- pr_debug("CCMP: received packet without ExtIV flag from %pM\n",
- hdr->addr2);
- }
- key->dot11rsna_stats_ccmp_format_errors++;
- return -2;
- }
- keyidx >>= 6;
- if (key->key_idx != keyidx) {
- pr_debug("CCMP: RX tkey->key_idx=%d frame keyidx=%d priv=%p\n",
- key->key_idx, keyidx, priv);
- return -6;
- }
- if (!key->key_set) {
- if (net_ratelimit()) {
- pr_debug("CCMP: received packet from %pM with keyid=%d that does not have a configured key\n",
- hdr->addr2, keyidx);
- }
- return -3;
- }
-
- pn[0] = pos[7];
- pn[1] = pos[6];
- pn[2] = pos[5];
- pn[3] = pos[4];
- pn[4] = pos[1];
- pn[5] = pos[0];
- pos += 8;
- if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
- key->dot11rsna_stats_ccmp_replays++;
- return -4;
- }
- if (!tcb_desc->hw_sec) {
- size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN;
- struct aead_request *req;
- struct scatterlist sg[2];
- u8 *aad = key->rx_aad;
- u8 iv[AES_BLOCK_LEN];
- int aad_len, ret;
-
- req = aead_request_alloc(key->tfm, GFP_ATOMIC);
- if (!req)
- return -ENOMEM;
-
- aad_len = ccmp_init_iv_and_aad(hdr, pn, iv, aad);
-
- sg_init_table(sg, 2);
- sg_set_buf(&sg[0], aad, aad_len);
- sg_set_buf(&sg[1], pos, data_len);
-
- aead_request_set_callback(req, 0, NULL, NULL);
- aead_request_set_ad(req, aad_len);
- aead_request_set_crypt(req, sg, sg, data_len, iv);
-
- ret = crypto_aead_decrypt(req);
- aead_request_free(req);
-
- if (ret) {
- if (net_ratelimit()) {
- pr_debug("CCMP: decrypt failed: STA= %pM\n",
- hdr->addr2);
- }
- key->dot11rsna_stats_ccmp_decrypt_errors++;
- return -5;
- }
-
- memcpy(key->rx_pn, pn, CCMP_PN_LEN);
- }
- /* Remove hdr and MIC */
- memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
- skb_pull(skb, CCMP_HDR_LEN);
- skb_trim(skb, skb->len - CCMP_MIC_LEN);
-
- return keyidx;
-}
-
-static int rtllib_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct rtllib_ccmp_data *data = priv;
- int keyidx;
- struct crypto_aead *tfm = data->tfm;
-
- keyidx = data->key_idx;
- memset(data, 0, sizeof(*data));
- data->key_idx = keyidx;
- data->tfm = tfm;
- if (len == CCMP_TK_LEN) {
- memcpy(data->key, key, CCMP_TK_LEN);
- data->key_set = 1;
- if (seq) {
- data->rx_pn[0] = seq[5];
- data->rx_pn[1] = seq[4];
- data->rx_pn[2] = seq[3];
- data->rx_pn[3] = seq[2];
- data->rx_pn[4] = seq[1];
- data->rx_pn[5] = seq[0];
- }
- if (crypto_aead_setauthsize(data->tfm, CCMP_MIC_LEN) ||
- crypto_aead_setkey(data->tfm, data->key, CCMP_TK_LEN))
- return -1;
- } else if (len == 0) {
- data->key_set = 0;
- } else {
- return -1;
- }
-
- return 0;
-}
-
-static int rtllib_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct rtllib_ccmp_data *data = priv;
-
- if (len < CCMP_TK_LEN)
- return -1;
-
- if (!data->key_set)
- return 0;
- memcpy(key, data->key, CCMP_TK_LEN);
-
- if (seq) {
- seq[0] = data->tx_pn[5];
- seq[1] = data->tx_pn[4];
- seq[2] = data->tx_pn[3];
- seq[3] = data->tx_pn[2];
- seq[4] = data->tx_pn[1];
- seq[5] = data->tx_pn[0];
- }
-
- return CCMP_TK_LEN;
-}
-
-static void rtllib_ccmp_print_stats(struct seq_file *m, void *priv)
-{
- struct rtllib_ccmp_data *ccmp = priv;
-
- seq_printf(m,
- "key[%d] alg=CCMP key_set=%d tx_pn=%pM rx_pn=%pM format_errors=%d replays=%d decrypt_errors=%d\n",
- ccmp->key_idx, ccmp->key_set,
- ccmp->tx_pn, ccmp->rx_pn,
- ccmp->dot11rsna_stats_ccmp_format_errors,
- ccmp->dot11rsna_stats_ccmp_replays,
- ccmp->dot11rsna_stats_ccmp_decrypt_errors);
-}
-
-static const struct lib80211_crypto_ops rtllib_crypt_ccmp = {
- .name = "R-CCMP",
- .init = rtllib_ccmp_init,
- .deinit = rtllib_ccmp_deinit,
- .encrypt_mpdu = rtllib_ccmp_encrypt,
- .decrypt_mpdu = rtllib_ccmp_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = rtllib_ccmp_set_key,
- .get_key = rtllib_ccmp_get_key,
- .print_stats = rtllib_ccmp_print_stats,
- .extra_mpdu_prefix_len = CCMP_HDR_LEN,
- .extra_mpdu_postfix_len = CCMP_MIC_LEN,
- .owner = THIS_MODULE,
-};
-
-static int __init rtllib_crypto_ccmp_init(void)
-{
- return lib80211_register_crypto_ops(&rtllib_crypt_ccmp);
-}
-
-static void __exit rtllib_crypto_ccmp_exit(void)
-{
- lib80211_unregister_crypto_ops(&rtllib_crypt_ccmp);
-}
-
-module_init(rtllib_crypto_ccmp_init);
-module_exit(rtllib_crypto_ccmp_exit);
-
-MODULE_DESCRIPTION("Support module for rtllib CCMP crypto");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c
deleted file mode 100644
index e544379bfa91..000000000000
--- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c
+++ /dev/null
@@ -1,706 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- */
-
-#include <crypto/arc4.h>
-#include <crypto/hash.h>
-#include <linux/fips.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/string.h>
-#include <linux/crc32.h>
-#include <linux/etherdevice.h>
-
-#include "rtllib.h"
-
-struct rtllib_tkip_data {
-#define TKIP_KEY_LEN 32
- u8 key[TKIP_KEY_LEN];
- int key_set;
-
- u32 tx_iv32;
- u16 tx_iv16;
- u16 tx_ttak[5];
- int tx_phase1_done;
-
- u32 rx_iv32;
- u16 rx_iv16;
- bool initialized;
- u16 rx_ttak[5];
- int rx_phase1_done;
- u32 rx_iv32_new;
- u16 rx_iv16_new;
-
- u32 dot11RSNAStatsTKIPReplays;
- u32 dot11RSNAStatsTKIPICVErrors;
- u32 dot11RSNAStatsTKIPLocalMICFailures;
-
- int key_idx;
- struct arc4_ctx rx_ctx_arc4;
- struct arc4_ctx tx_ctx_arc4;
- struct crypto_shash *rx_tfm_michael;
- struct crypto_shash *tx_tfm_michael;
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 rx_hdr[16];
- u8 tx_hdr[16];
-};
-
-static void *rtllib_tkip_init(int key_idx)
-{
- struct rtllib_tkip_data *priv;
-
- if (fips_enabled)
- return NULL;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (!priv)
- goto fail;
- priv->key_idx = key_idx;
-
- priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
- if (IS_ERR(priv->tx_tfm_michael)) {
- pr_debug("Could not allocate crypto API michael_mic\n");
- priv->tx_tfm_michael = NULL;
- goto fail;
- }
-
- priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
- if (IS_ERR(priv->rx_tfm_michael)) {
- pr_debug("Could not allocate crypto API michael_mic\n");
- priv->rx_tfm_michael = NULL;
- goto fail;
- }
- return priv;
-
-fail:
- if (priv) {
- crypto_free_shash(priv->tx_tfm_michael);
- crypto_free_shash(priv->rx_tfm_michael);
- kfree(priv);
- }
-
- return NULL;
-}
-
-static void rtllib_tkip_deinit(void *priv)
-{
- struct rtllib_tkip_data *_priv = priv;
-
- if (_priv) {
- crypto_free_shash(_priv->tx_tfm_michael);
- crypto_free_shash(_priv->rx_tfm_michael);
- }
- kfree_sensitive(priv);
-}
-
-static inline u16 RotR1(u16 val)
-{
- return (val >> 1) | (val << 15);
-}
-
-static inline u8 Lo8(u16 val)
-{
- return val & 0xff;
-}
-
-static inline u8 Hi8(u16 val)
-{
- return val >> 8;
-}
-
-static inline u16 Lo16(u32 val)
-{
- return val & 0xffff;
-}
-
-static inline u16 Hi16(u32 val)
-{
- return val >> 16;
-}
-
-static inline u16 Mk16(u8 hi, u8 lo)
-{
- return lo | (hi << 8);
-}
-
-static inline u16 Mk16_le(u16 *v)
-{
- return *v;
-}
-
-static const u16 Sbox[256] = {
- 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
- 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
- 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
- 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
- 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
- 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
- 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
- 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
- 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
- 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
- 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
- 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
- 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
- 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
- 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
- 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
- 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
- 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
- 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
- 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
- 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
- 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
- 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
- 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
- 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
- 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
- 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
- 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
- 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
- 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
- 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
- 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
-};
-
-static inline u16 _S_(u16 v)
-{
- u16 t = Sbox[Hi8(v)];
- return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
-}
-
-#define PHASE1_LOOP_COUNT 8
-
-static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
-{
- int i, j;
-
- /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
- TTAK[0] = Lo16(IV32);
- TTAK[1] = Hi16(IV32);
- TTAK[2] = Mk16(TA[1], TA[0]);
- TTAK[3] = Mk16(TA[3], TA[2]);
- TTAK[4] = Mk16(TA[5], TA[4]);
-
- for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
- j = 2 * (i & 1);
- TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
- TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
- TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
- TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
- TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
- }
-}
-
-static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
- u16 IV16)
-{
- /* Make temporary area overlap WEP seed so that the final copy can be
- * avoided on little endian hosts.
- */
- u16 *PPK = (u16 *)&WEPSeed[4];
-
- /* Step 1 - make copy of TTAK and bring in TSC */
- PPK[0] = TTAK[0];
- PPK[1] = TTAK[1];
- PPK[2] = TTAK[2];
- PPK[3] = TTAK[3];
- PPK[4] = TTAK[4];
- PPK[5] = TTAK[4] + IV16;
-
- /* Step 2 - 96-bit bijective mixing using S-box */
- PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *)&TK[0]));
- PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *)&TK[2]));
- PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *)&TK[4]));
- PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *)&TK[6]));
- PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *)&TK[8]));
- PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *)&TK[10]));
-
- PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *)&TK[12]));
- PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *)&TK[14]));
- PPK[2] += RotR1(PPK[1]);
- PPK[3] += RotR1(PPK[2]);
- PPK[4] += RotR1(PPK[3]);
- PPK[5] += RotR1(PPK[4]);
-
- /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
- * WEPSeed[0..2] is transmitted as WEP IV
- */
- WEPSeed[0] = Hi8(IV16);
- WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
- WEPSeed[2] = Lo8(IV16);
- WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *)&TK[0])) >> 1);
-
-#ifdef __BIG_ENDIAN
- {
- int i;
-
- for (i = 0; i < 6; i++)
- PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
- }
-#endif
-}
-
-static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct rtllib_tkip_data *tkey = priv;
- int len;
- u8 *pos;
- struct ieee80211_hdr *hdr;
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
- MAX_DEV_ADDR_SIZE);
- int ret = 0;
- u8 rc4key[16], *icv;
- u32 crc;
-
- if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len)
- return -1;
-
- hdr = (struct ieee80211_hdr *)skb->data;
-
- if (!tcb_desc->hw_sec) {
- if (!tkey->tx_phase1_done) {
- tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
- tkey->tx_iv32);
- tkey->tx_phase1_done = 1;
- }
- tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak,
- tkey->tx_iv16);
- } else {
- tkey->tx_phase1_done = 1;
- }
-
- len = skb->len - hdr_len;
- pos = skb_push(skb, 8);
- memmove(pos, pos + 8, hdr_len);
- pos += hdr_len;
-
- if (tcb_desc->hw_sec) {
- *pos++ = Hi8(tkey->tx_iv16);
- *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
- *pos++ = Lo8(tkey->tx_iv16);
- } else {
- *pos++ = rc4key[0];
- *pos++ = rc4key[1];
- *pos++ = rc4key[2];
- }
-
- *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
- *pos++ = tkey->tx_iv32 & 0xff;
- *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
- *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
- *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
-
- if (!tcb_desc->hw_sec) {
- icv = skb_put(skb, 4);
- crc = ~crc32_le(~0, pos, len);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- arc4_setkey(&tkey->tx_ctx_arc4, rc4key, 16);
- arc4_crypt(&tkey->tx_ctx_arc4, pos, pos, len + 4);
- }
-
- tkey->tx_iv16++;
- if (tkey->tx_iv16 == 0) {
- tkey->tx_phase1_done = 0;
- tkey->tx_iv32++;
- }
-
- if (!tcb_desc->hw_sec)
- return ret;
- return 0;
-}
-
-static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct rtllib_tkip_data *tkey = priv;
- u8 keyidx, *pos;
- u32 iv32;
- u16 iv16;
- struct ieee80211_hdr *hdr;
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
- MAX_DEV_ADDR_SIZE);
- u8 rc4key[16];
- u8 icv[4];
- u32 crc;
- int plen;
-
- if (skb->len < hdr_len + 8 + 4)
- return -1;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- pos = skb->data + hdr_len;
- keyidx = pos[3];
- if (!(keyidx & (1 << 5))) {
- if (net_ratelimit()) {
- netdev_dbg(skb->dev,
- "Received packet without ExtIV flag from %pM\n",
- hdr->addr2);
- }
- return -2;
- }
- keyidx >>= 6;
- if (tkey->key_idx != keyidx) {
- netdev_dbg(skb->dev,
- "RX tkey->key_idx=%d frame keyidx=%d priv=%p\n",
- tkey->key_idx, keyidx, priv);
- return -6;
- }
- if (!tkey->key_set) {
- if (net_ratelimit()) {
- netdev_dbg(skb->dev,
- "Received packet from %pM with keyid=%d that does not have a configured key\n",
- hdr->addr2, keyidx);
- }
- return -3;
- }
- iv16 = (pos[0] << 8) | pos[2];
- iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
- pos += 8;
-
- if (!tcb_desc->hw_sec || (skb->cb[0] == 1)) {
- if ((iv32 < tkey->rx_iv32 ||
- (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) &&
- tkey->initialized) {
- if (net_ratelimit()) {
- netdev_dbg(skb->dev,
- "Replay detected: STA= %pM previous TSC %08x%04x received TSC %08x%04x\n",
- hdr->addr2, tkey->rx_iv32,
- tkey->rx_iv16, iv32, iv16);
- }
- tkey->dot11RSNAStatsTKIPReplays++;
- return -4;
- }
- tkey->initialized = true;
-
- if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
- tkip_mixing_phase1(tkey->rx_ttak, tkey->key,
- hdr->addr2, iv32);
- tkey->rx_phase1_done = 1;
- }
- tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
-
- plen = skb->len - hdr_len - 12;
-
- arc4_setkey(&tkey->rx_ctx_arc4, rc4key, 16);
- arc4_crypt(&tkey->rx_ctx_arc4, pos, pos, plen + 4);
-
- crc = ~crc32_le(~0, pos, plen);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- if (memcmp(icv, pos + plen, 4) != 0) {
- if (iv32 != tkey->rx_iv32) {
- /* Previously cached Phase1 result was already
- * lost, so it needs to be recalculated for the
- * next packet.
- */
- tkey->rx_phase1_done = 0;
- }
- if (net_ratelimit()) {
- netdev_dbg(skb->dev,
- "ICV error detected: STA= %pM\n",
- hdr->addr2);
- }
- tkey->dot11RSNAStatsTKIPICVErrors++;
- return -5;
- }
- }
-
- /* Update real counters only after Michael MIC verification has
- * completed
- */
- tkey->rx_iv32_new = iv32;
- tkey->rx_iv16_new = iv16;
-
- /* Remove IV and ICV */
- memmove(skb->data + 8, skb->data, hdr_len);
- skb_pull(skb, 8);
- skb_trim(skb, skb->len - 4);
-
- return keyidx;
-}
-
-static int michael_mic(struct crypto_shash *tfm_michael, u8 *key, u8 *hdr,
- u8 *data, size_t data_len, u8 *mic)
-{
- SHASH_DESC_ON_STACK(desc, tfm_michael);
- int err;
-
- desc->tfm = tfm_michael;
-
- if (crypto_shash_setkey(tfm_michael, key, 8))
- return -1;
-
- err = crypto_shash_init(desc);
- if (err)
- goto out;
- err = crypto_shash_update(desc, hdr, 16);
- if (err)
- goto out;
- err = crypto_shash_update(desc, data, data_len);
- if (err)
- goto out;
- err = crypto_shash_final(desc, mic);
-
-out:
- shash_desc_zero(desc);
- return err;
-}
-
-static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
-{
- struct ieee80211_hdr *hdr11;
-
- hdr11 = (struct ieee80211_hdr *)skb->data;
- switch (le16_to_cpu(hdr11->frame_control) &
- (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_TODS:
- ether_addr_copy(hdr, hdr11->addr3); /* DA */
- ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS:
- ether_addr_copy(hdr, hdr11->addr1); /* DA */
- ether_addr_copy(hdr + ETH_ALEN, hdr11->addr3); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- ether_addr_copy(hdr, hdr11->addr3); /* DA */
- ether_addr_copy(hdr + ETH_ALEN, hdr11->addr4); /* SA */
- break;
- case 0:
- ether_addr_copy(hdr, hdr11->addr1); /* DA */
- ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */
- break;
- }
-
- /* priority */
- hdr[12] = 0;
-
- /* reserved */
- hdr[13] = 0;
- hdr[14] = 0;
- hdr[15] = 0;
-}
-
-static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct rtllib_tkip_data *tkey = priv;
- u8 *pos;
- struct ieee80211_hdr *hdr;
-
- hdr = (struct ieee80211_hdr *)skb->data;
-
- if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
- netdev_dbg(skb->dev,
- "Invalid packet for Michael MIC add (tailroom=%d hdr_len=%d skb->len=%d)\n",
- skb_tailroom(skb), hdr_len, skb->len);
- return -1;
- }
-
- michael_mic_hdr(skb, tkey->tx_hdr);
-
- if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_control)))
- tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
- pos = skb_put(skb, 8);
- if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
- return -1;
-
- return 0;
-}
-
-static void rtllib_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr *hdr,
- int keyidx)
-{
- union iwreq_data wrqu;
- struct iw_michaelmicfailure ev;
-
- /* TODO: needed parameters: count, keyid, key type, TSC */
- memset(&ev, 0, sizeof(ev));
- ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
- if (hdr->addr1[0] & 0x01)
- ev.flags |= IW_MICFAILURE_GROUP;
- else
- ev.flags |= IW_MICFAILURE_PAIRWISE;
- ev.src_addr.sa_family = ARPHRD_ETHER;
- ether_addr_copy(ev.src_addr.sa_data, hdr->addr2);
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = sizeof(ev);
- wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
-}
-
-static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx,
- int hdr_len, void *priv)
-{
- struct rtllib_tkip_data *tkey = priv;
- u8 mic[8];
- struct ieee80211_hdr *hdr;
-
- hdr = (struct ieee80211_hdr *)skb->data;
-
- if (!tkey->key_set)
- return -1;
-
- michael_mic_hdr(skb, tkey->rx_hdr);
- if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_control)))
- tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
-
- if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
- return -1;
-
- if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
- struct ieee80211_hdr *hdr;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- netdev_dbg(skb->dev,
- "Michael MIC verification failed for MSDU from %pM keyidx=%d\n",
- hdr->addr2, keyidx);
- netdev_dbg(skb->dev, "%d\n",
- memcmp(mic, skb->data + skb->len - 8, 8) != 0);
- if (skb->dev) {
- pr_info("skb->dev != NULL\n");
- rtllib_michael_mic_failure(skb->dev, hdr, keyidx);
- }
- tkey->dot11RSNAStatsTKIPLocalMICFailures++;
- return -1;
- }
-
- /* Update TSC counters for RX now that the packet verification has
- * completed.
- */
- tkey->rx_iv32 = tkey->rx_iv32_new;
- tkey->rx_iv16 = tkey->rx_iv16_new;
-
- skb_trim(skb, skb->len - 8);
-
- return 0;
-}
-
-static int rtllib_tkip_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct rtllib_tkip_data *tkey = priv;
- int keyidx;
- struct crypto_shash *tfm = tkey->tx_tfm_michael;
- struct crypto_shash *tfm3 = tkey->rx_tfm_michael;
-
- keyidx = tkey->key_idx;
- memset(tkey, 0, sizeof(*tkey));
- tkey->key_idx = keyidx;
- tkey->tx_tfm_michael = tfm;
- tkey->rx_tfm_michael = tfm3;
-
- if (len == TKIP_KEY_LEN) {
- memcpy(tkey->key, key, TKIP_KEY_LEN);
- tkey->key_set = 1;
- tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
- if (seq) {
- tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
- (seq[3] << 8) | seq[2];
- tkey->rx_iv16 = (seq[1] << 8) | seq[0];
- }
- } else if (len == 0) {
- tkey->key_set = 0;
- } else {
- return -1;
- }
-
- return 0;
-}
-
-static int rtllib_tkip_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct rtllib_tkip_data *tkey = priv;
-
- if (len < TKIP_KEY_LEN)
- return -1;
-
- if (!tkey->key_set)
- return 0;
- memcpy(key, tkey->key, TKIP_KEY_LEN);
-
- if (seq) {
- /* Return the sequence number of the last transmitted frame. */
- seq[0] = tkey->tx_iv16;
- seq[1] = tkey->tx_iv16 >> 8;
- seq[2] = tkey->tx_iv32;
- seq[3] = tkey->tx_iv32 >> 8;
- seq[4] = tkey->tx_iv32 >> 16;
- seq[5] = tkey->tx_iv32 >> 24;
- }
-
- return TKIP_KEY_LEN;
-}
-
-static void rtllib_tkip_print_stats(struct seq_file *m, void *priv)
-{
- struct rtllib_tkip_data *tkip = priv;
-
- seq_printf(m,
- "key[%d] alg=TKIP key_set=%d tx_pn=%02x%02x%02x%02x%02x%02x rx_pn=%02x%02x%02x%02x%02x%02x replays=%d icv_errors=%d local_mic_failures=%d\n",
- tkip->key_idx, tkip->key_set,
- (tkip->tx_iv32 >> 24) & 0xff,
- (tkip->tx_iv32 >> 16) & 0xff,
- (tkip->tx_iv32 >> 8) & 0xff,
- tkip->tx_iv32 & 0xff,
- (tkip->tx_iv16 >> 8) & 0xff,
- tkip->tx_iv16 & 0xff,
- (tkip->rx_iv32 >> 24) & 0xff,
- (tkip->rx_iv32 >> 16) & 0xff,
- (tkip->rx_iv32 >> 8) & 0xff,
- tkip->rx_iv32 & 0xff,
- (tkip->rx_iv16 >> 8) & 0xff,
- tkip->rx_iv16 & 0xff,
- tkip->dot11RSNAStatsTKIPReplays,
- tkip->dot11RSNAStatsTKIPICVErrors,
- tkip->dot11RSNAStatsTKIPLocalMICFailures);
-}
-
-static const struct lib80211_crypto_ops rtllib_crypt_tkip = {
- .name = "R-TKIP",
- .init = rtllib_tkip_init,
- .deinit = rtllib_tkip_deinit,
- .encrypt_mpdu = rtllib_tkip_encrypt,
- .decrypt_mpdu = rtllib_tkip_decrypt,
- .encrypt_msdu = rtllib_michael_mic_add,
- .decrypt_msdu = rtllib_michael_mic_verify,
- .set_key = rtllib_tkip_set_key,
- .get_key = rtllib_tkip_get_key,
- .print_stats = rtllib_tkip_print_stats,
- .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
- .extra_mpdu_postfix_len = 4, /* ICV */
- .extra_msdu_postfix_len = 8, /* MIC */
- .owner = THIS_MODULE,
-};
-
-static int __init rtllib_crypto_tkip_init(void)
-{
- return lib80211_register_crypto_ops(&rtllib_crypt_tkip);
-}
-
-static void __exit rtllib_crypto_tkip_exit(void)
-{
- lib80211_unregister_crypto_ops(&rtllib_crypt_tkip);
-}
-
-module_init(rtllib_crypto_tkip_init);
-module_exit(rtllib_crypto_tkip_exit);
-
-MODULE_DESCRIPTION("Support module for rtllib TKIP crypto");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/rtl8192e/rtllib_crypt_wep.c b/drivers/staging/rtl8192e/rtllib_crypt_wep.c
deleted file mode 100644
index aa18c060d727..000000000000
--- a/drivers/staging/rtl8192e/rtllib_crypt_wep.c
+++ /dev/null
@@ -1,242 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Host AP crypt: host-based WEP encryption implementation for Host AP driver
- *
- * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- */
-
-#include <crypto/arc4.h>
-#include <linux/fips.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/string.h>
-#include "rtllib.h"
-
-#include <linux/crc32.h>
-
-struct prism2_wep_data {
- u32 iv;
-#define WEP_KEY_LEN 13
- u8 key[WEP_KEY_LEN + 1];
- u8 key_len;
- u8 key_idx;
- struct arc4_ctx rx_ctx_arc4;
- struct arc4_ctx tx_ctx_arc4;
-};
-
-static void *prism2_wep_init(int keyidx)
-{
- struct prism2_wep_data *priv;
-
- if (fips_enabled)
- return NULL;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (!priv)
- return NULL;
- priv->key_idx = keyidx;
-
- /* start WEP IV from a random value */
- get_random_bytes(&priv->iv, 4);
-
- return priv;
-}
-
-static void prism2_wep_deinit(void *priv)
-{
- kfree_sensitive(priv);
-}
-
-/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
- * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
- * so the payload length increases with 8 bytes.
- *
- * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
- */
-static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- u32 klen, len;
- u8 key[WEP_KEY_LEN + 3];
- u8 *pos;
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
- MAX_DEV_ADDR_SIZE);
- u32 crc;
- u8 *icv;
-
- if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len){
- pr_err("Error!!! headroom=%d tailroom=%d skblen=%d hdr_len=%d\n",
- skb_headroom(skb), skb_tailroom(skb), skb->len, hdr_len);
- return -1;
- }
- len = skb->len - hdr_len;
- pos = skb_push(skb, 4);
- memmove(pos, pos + 4, hdr_len);
- pos += hdr_len;
-
- klen = 3 + wep->key_len;
-
- wep->iv++;
-
- /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
- * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
- * can be used to speedup attacks, so avoid using them.
- */
- if ((wep->iv & 0xff00) == 0xff00) {
- u8 B = (wep->iv >> 16) & 0xff;
-
- if (B >= 3 && B < klen)
- wep->iv += 0x0100;
- }
-
- /* Prepend 24-bit IV to RC4 key and TX frame */
- *pos++ = key[0] = (wep->iv >> 16) & 0xff;
- *pos++ = key[1] = (wep->iv >> 8) & 0xff;
- *pos++ = key[2] = wep->iv & 0xff;
- *pos++ = wep->key_idx << 6;
-
- /* Copy rest of the WEP key (the secret part) */
- memcpy(key + 3, wep->key, wep->key_len);
-
- if (!tcb_desc->hw_sec) {
- /* Append little-endian CRC32 and encrypt it to produce ICV */
- crc = ~crc32_le(~0, pos, len);
- icv = skb_put(skb, 4);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- arc4_setkey(&wep->tx_ctx_arc4, key, klen);
- arc4_crypt(&wep->tx_ctx_arc4, pos, pos, len + 4);
- }
-
- return 0;
-}
-
-/* Perform WEP decryption on given struct buffer. Buffer includes whole WEP
- * part of the frame: IV (4 bytes), encrypted payload (including SNAP header),
- * ICV (4 bytes). len includes both IV and ICV.
- *
- * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
- * failure. If frame is OK, IV and ICV will be removed.
- */
-static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- u32 klen, plen;
- u8 key[WEP_KEY_LEN + 3];
- u8 keyidx, *pos;
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
- MAX_DEV_ADDR_SIZE);
- u32 crc;
- u8 icv[4];
-
- if (skb->len < hdr_len + 8)
- return -1;
-
- pos = skb->data + hdr_len;
- key[0] = *pos++;
- key[1] = *pos++;
- key[2] = *pos++;
- keyidx = *pos++ >> 6;
- if (keyidx != wep->key_idx)
- return -1;
-
- klen = 3 + wep->key_len;
-
- /* Copy rest of the WEP key (the secret part) */
- memcpy(key + 3, wep->key, wep->key_len);
-
- /* Apply RC4 to data and compute CRC32 over decrypted data */
- plen = skb->len - hdr_len - 8;
-
- if (!tcb_desc->hw_sec) {
- arc4_setkey(&wep->rx_ctx_arc4, key, klen);
- arc4_crypt(&wep->rx_ctx_arc4, pos, pos, plen + 4);
-
- crc = ~crc32_le(~0, pos, plen);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
- if (memcmp(icv, pos + plen, 4) != 0) {
- /* ICV mismatch - drop frame */
- return -2;
- }
- }
- /* Remove IV and ICV */
- memmove(skb->data + 4, skb->data, hdr_len);
- skb_pull(skb, 4);
- skb_trim(skb, skb->len - 4);
-
- return 0;
-}
-
-static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- if (len < 0 || len > WEP_KEY_LEN)
- return -1;
-
- memcpy(wep->key, key, len);
- wep->key_len = len;
-
- return 0;
-}
-
-static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- if (len < wep->key_len)
- return -1;
-
- memcpy(key, wep->key, wep->key_len);
-
- return wep->key_len;
-}
-
-static void prism2_wep_print_stats(struct seq_file *m, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- seq_printf(m, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
-}
-
-static const struct lib80211_crypto_ops rtllib_crypt_wep = {
- .name = "R-WEP",
- .init = prism2_wep_init,
- .deinit = prism2_wep_deinit,
- .encrypt_mpdu = prism2_wep_encrypt,
- .decrypt_mpdu = prism2_wep_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = prism2_wep_set_key,
- .get_key = prism2_wep_get_key,
- .print_stats = prism2_wep_print_stats,
- .extra_mpdu_prefix_len = 4, /* IV */
- .extra_mpdu_postfix_len = 4, /* ICV */
- .owner = THIS_MODULE,
-};
-
-static int __init rtllib_crypto_wep_init(void)
-{
- return lib80211_register_crypto_ops(&rtllib_crypt_wep);
-}
-
-static void __exit rtllib_crypto_wep_exit(void)
-{
- lib80211_unregister_crypto_ops(&rtllib_crypt_wep);
-}
-
-module_init(rtllib_crypto_wep_init);
-module_exit(rtllib_crypto_wep_exit);
-
-MODULE_DESCRIPTION("Support module for rtllib WEP crypto");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c
deleted file mode 100644
index 469a69726c16..000000000000
--- a/drivers/staging/rtl8192e/rtllib_module.c
+++ /dev/null
@@ -1,179 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2004 Intel Corporation. All rights reserved.
- *
- * Portions of this file are based on the WEP enablement code provided by the
- * Host AP project hostap-drivers v0.1.3
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- */
-
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <linux/uaccess.h>
-#include <net/arp.h>
-#include "rtllib.h"
-
-static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
-{
- if (ieee->networks)
- return 0;
-
- ieee->networks = kcalloc(MAX_NETWORK_COUNT,
- sizeof(struct rtllib_network), GFP_KERNEL);
- if (!ieee->networks)
- return -ENOMEM;
-
- return 0;
-}
-
-static inline void rtllib_networks_free(struct rtllib_device *ieee)
-{
- if (!ieee->networks)
- return;
- kfree(ieee->networks);
- ieee->networks = NULL;
-}
-
-static inline void rtllib_networks_initialize(struct rtllib_device *ieee)
-{
- int i;
-
- INIT_LIST_HEAD(&ieee->network_free_list);
- INIT_LIST_HEAD(&ieee->network_list);
- for (i = 0; i < MAX_NETWORK_COUNT; i++)
- list_add_tail(&ieee->networks[i].list,
- &ieee->network_free_list);
-}
-
-struct net_device *alloc_rtllib(int sizeof_priv)
-{
- struct rtllib_device *ieee = NULL;
- struct net_device *dev;
- int i, err;
-
- pr_debug("rtllib: Initializing...\n");
-
- dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
- if (!dev) {
- pr_err("Unable to allocate net_device.\n");
- return NULL;
- }
- ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
- ieee->dev = dev;
-
- err = rtllib_networks_allocate(ieee);
- if (err) {
- pr_err("Unable to allocate beacon storage: %d\n", err);
- goto free_netdev;
- }
- rtllib_networks_initialize(ieee);
-
- /* Default fragmentation threshold is maximum payload size */
- ieee->fts = DEFAULT_FTS;
- ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
- ieee->open_wep = 1;
-
- ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
-
- ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
-
- spin_lock_init(&ieee->lock);
- spin_lock_init(&ieee->wpax_suitlist_lock);
- spin_lock_init(&ieee->reorder_spinlock);
- atomic_set(&ieee->atm_swbw, 0);
-
- /* SAM FIXME */
- lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock);
-
- ieee->wpa_enabled = 0;
- ieee->tkip_countermeasures = 0;
- ieee->drop_unencrypted = 0;
- ieee->privacy_invoked = 0;
- ieee->ieee802_1x = 1;
- ieee->hwsec_active = 0;
-
- memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
- err = rtllib_softmac_init(ieee);
- if (err)
- goto free_crypt_info;
-
- ieee->ht_info = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
- if (!ieee->ht_info)
- goto free_softmac;
-
- ht_update_default_setting(ieee);
- ht_initialize_ht_info(ieee);
- rtllib_ts_init(ieee);
- for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
- INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
-
- for (i = 0; i < 17; i++) {
- ieee->last_rxseq_num[i] = -1;
- ieee->last_rxfrag_num[i] = -1;
- ieee->last_packet_time[i] = 0;
- }
-
- return dev;
-
-free_softmac:
- rtllib_softmac_free(ieee);
-free_crypt_info:
- lib80211_crypt_info_free(&ieee->crypt_info);
- rtllib_networks_free(ieee);
-free_netdev:
- free_netdev(dev);
-
- return NULL;
-}
-EXPORT_SYMBOL(alloc_rtllib);
-
-void free_rtllib(struct net_device *dev)
-{
- struct rtllib_device *ieee = (struct rtllib_device *)
- netdev_priv_rsl(dev);
-
- kfree(ieee->ht_info);
- rtllib_softmac_free(ieee);
-
- lib80211_crypt_info_free(&ieee->crypt_info);
-
- rtllib_networks_free(ieee);
- free_netdev(dev);
-}
-EXPORT_SYMBOL(free_rtllib);
-
-static int __init rtllib_init(void)
-{
- return 0;
-}
-
-static void __exit rtllib_exit(void)
-{
-}
-
-module_init(rtllib_init);
-module_exit(rtllib_exit);
-
-MODULE_DESCRIPTION("Support module for rtllib wireless devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c
deleted file mode 100644
index 8fe224a83dd6..000000000000
--- a/drivers/staging/rtl8192e/rtllib_rx.c
+++ /dev/null
@@ -1,2564 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Original code based Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3 - hostap.o module, common routines
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Copyright (c) 2004, Intel Corporation
- *
- * Few modifications for Realtek's Wi-Fi drivers by
- * Andrea Merello <andrea.merello@gmail.com>
- *
- * A special thanks goes to Realtek for their support !
- */
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <linux/uaccess.h>
-#include <linux/ctype.h>
-
-#include "rtllib.h"
-
-static void rtllib_rx_mgt(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *stats);
-
-static inline void rtllib_monitor_rx(struct rtllib_device *ieee,
- struct sk_buff *skb,
- struct rtllib_rx_stats *rx_status,
- size_t hdr_length)
-{
- skb->dev = ieee->dev;
- skb_reset_mac_header(skb);
- skb_pull(skb, hdr_length);
- skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = htons(ETH_P_80211_RAW);
- memset(skb->cb, 0, sizeof(skb->cb));
- netif_rx(skb);
-}
-
-/* Called only as a tasklet (software IRQ) */
-static struct rtllib_frag_entry *
-rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq,
- unsigned int frag, u8 tid, u8 *src, u8 *dst)
-{
- struct rtllib_frag_entry *entry;
- int i;
-
- for (i = 0; i < RTLLIB_FRAG_CACHE_LEN; i++) {
- entry = &ieee->frag_cache[tid][i];
- if (entry->skb &&
- time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
- netdev_dbg(ieee->dev,
- "expiring fragment cache entry seq=%u last_frag=%u\n",
- entry->seq, entry->last_frag);
- dev_kfree_skb_any(entry->skb);
- entry->skb = NULL;
- }
-
- if (entry->skb && entry->seq == seq &&
- (entry->last_frag + 1 == frag || frag == -1) &&
- memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
- memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
- return entry;
- }
-
- return NULL;
-}
-
-/* Called only as a tasklet (software IRQ) */
-static struct sk_buff *
-rtllib_frag_cache_get(struct rtllib_device *ieee,
- struct ieee80211_hdr *hdr)
-{
- struct sk_buff *skb = NULL;
- u16 fc = le16_to_cpu(hdr->frame_control);
- u16 sc = le16_to_cpu(hdr->seq_ctrl);
- unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
- unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
- struct rtllib_frag_entry *entry;
- struct ieee80211_qos_hdr *hdr_3addrqos;
- struct ieee80211_qos_hdr_4addr *hdr_4addrqos;
- u8 tid;
-
- if (ieee80211_has_a4(hdr->frame_control) &&
- RTLLIB_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_qos_hdr_4addr *)hdr;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctrl) & RTLLIB_QCTL_TID;
- tid = UP2AC(tid);
- tid++;
- } else if (RTLLIB_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_qos_hdr *)hdr;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctrl) & RTLLIB_QCTL_TID;
- tid = UP2AC(tid);
- tid++;
- } else {
- tid = 0;
- }
-
- if (frag == 0) {
- /* Reserve enough space to fit maximum frame length */
- skb = dev_alloc_skb(ieee->dev->mtu +
- sizeof(struct ieee80211_hdr) +
- 8 /* LLC */ +
- 2 /* alignment */ +
- 8 /* WEP */ +
- ETH_ALEN /* WDS */ +
- /* QOS Control */
- (RTLLIB_QOS_HAS_SEQ(fc) ? 2 : 0));
- if (!skb)
- return NULL;
-
- entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
- ieee->frag_next_idx[tid]++;
- if (ieee->frag_next_idx[tid] >= RTLLIB_FRAG_CACHE_LEN)
- ieee->frag_next_idx[tid] = 0;
-
- if (entry->skb)
- dev_kfree_skb_any(entry->skb);
-
- entry->first_frag_time = jiffies;
- entry->seq = seq;
- entry->last_frag = frag;
- entry->skb = skb;
- ether_addr_copy(entry->src_addr, hdr->addr2);
- ether_addr_copy(entry->dst_addr, hdr->addr1);
- } else {
- /* received a fragment of a frame for which the head fragment
- * should have already been received
- */
- entry = rtllib_frag_cache_find(ieee, seq, frag, tid, hdr->addr2,
- hdr->addr1);
- if (entry) {
- entry->last_frag = frag;
- skb = entry->skb;
- }
- }
-
- return skb;
-}
-
-/* Called only as a tasklet (software IRQ) */
-static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee,
- struct ieee80211_hdr *hdr)
-{
- u16 fc = le16_to_cpu(hdr->frame_control);
- u16 sc = le16_to_cpu(hdr->seq_ctrl);
- unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
- struct rtllib_frag_entry *entry;
- struct ieee80211_qos_hdr *hdr_3addrqos;
- struct ieee80211_qos_hdr_4addr *hdr_4addrqos;
- u8 tid;
-
- if (ieee80211_has_a4(hdr->frame_control) &&
- RTLLIB_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_qos_hdr_4addr *)hdr;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctrl) & RTLLIB_QCTL_TID;
- tid = UP2AC(tid);
- tid++;
- } else if (RTLLIB_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_qos_hdr *)hdr;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctrl) & RTLLIB_QCTL_TID;
- tid = UP2AC(tid);
- tid++;
- } else {
- tid = 0;
- }
-
- entry = rtllib_frag_cache_find(ieee, seq, -1, tid, hdr->addr2,
- hdr->addr1);
-
- if (!entry) {
- netdev_dbg(ieee->dev,
- "Couldn't invalidate fragment cache entry (seq=%u)\n",
- seq);
- return -1;
- }
-
- entry->skb = NULL;
- return 0;
-}
-
-/* rtllib_rx_frame_mgtmt
- *
- * Responsible for handling management control frames
- *
- * Called by rtllib_rx
- */
-static inline int
-rtllib_rx_frame_mgmt(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats, u16 type, u16 stype)
-{
- /* On the struct stats definition there is written that
- * this is not mandatory.... but seems that the probe
- * response parser uses it
- */
- struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)skb->data;
-
- rx_stats->len = skb->len;
- rtllib_rx_mgt(ieee, skb, rx_stats);
- if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN))) {
- dev_kfree_skb_any(skb);
- return 0;
- }
- rtllib_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
-
- dev_kfree_skb_any(skb);
-
- return 0;
-}
-
-/* No encapsulation header if EtherType < 0x600 (=length) */
-
-/* Called by rtllib_rx_frame_decrypt */
-static int rtllib_is_eapol_frame(struct rtllib_device *ieee,
- struct sk_buff *skb, size_t hdrlen)
-{
- struct net_device *dev = ieee->dev;
- u16 fc, ethertype;
- struct ieee80211_hdr *hdr;
- u8 *pos;
-
- if (skb->len < 24)
- return 0;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = le16_to_cpu(hdr->frame_control);
-
- /* check that the frame is unicast frame to us */
- if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_TODS &&
- memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
- memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
- /* ToDS frame with own addr BSSID and DA */
- } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_FROMDS &&
- memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
- /* FromDS frame with own addr as DA */
- } else {
- return 0;
- }
-
- if (skb->len < 24 + 8)
- return 0;
-
- /* check for port access entity Ethernet type */
- pos = skb->data + hdrlen;
- ethertype = (pos[6] << 8) | pos[7];
- if (ethertype == ETH_P_PAE)
- return 1;
-
- return 0;
-}
-
-/* Called only as a tasklet (software IRQ), by rtllib_rx */
-static inline int
-rtllib_rx_frame_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
- struct lib80211_crypt_data *crypt)
-{
- struct ieee80211_hdr *hdr;
- int res, hdrlen;
-
- if (!crypt || !crypt->ops->decrypt_mpdu)
- return 0;
-
- if (ieee->hwsec_active) {
- struct cb_desc *tcb_desc = (struct cb_desc *)
- (skb->cb + MAX_DEV_ADDR_SIZE);
-
- tcb_desc->hw_sec = 1;
-
- if (ieee->need_sw_enc)
- tcb_desc->hw_sec = 0;
- }
-
- hdr = (struct ieee80211_hdr *)skb->data;
- hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_control));
-
- atomic_inc(&crypt->refcnt);
- res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- netdev_dbg(ieee->dev, "decryption failed (SA= %pM) res=%d\n",
- hdr->addr2, res);
- if (res == -2)
- netdev_dbg(ieee->dev,
- "Decryption failed ICV mismatch (key %d)\n",
- skb->data[hdrlen + 3] >> 6);
- return -1;
- }
-
- return res;
-}
-
-/* Called only as a tasklet (software IRQ), by rtllib_rx */
-static inline int
-rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb,
- int keyidx, struct lib80211_crypt_data *crypt)
-{
- struct ieee80211_hdr *hdr;
- int res, hdrlen;
-
- if (!crypt || !crypt->ops->decrypt_msdu)
- return 0;
- if (ieee->hwsec_active) {
- struct cb_desc *tcb_desc = (struct cb_desc *)
- (skb->cb + MAX_DEV_ADDR_SIZE);
-
- tcb_desc->hw_sec = 1;
-
- if (ieee->need_sw_enc)
- tcb_desc->hw_sec = 0;
- }
-
- hdr = (struct ieee80211_hdr *)skb->data;
- hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_control));
-
- atomic_inc(&crypt->refcnt);
- res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- netdev_dbg(ieee->dev,
- "MSDU decryption/MIC verification failed (SA= %pM keyidx=%d)\n",
- hdr->addr2, keyidx);
- return -1;
- }
-
- return 0;
-}
-
-/* this function is stolen from ipw2200 driver*/
-#define IEEE_PACKET_RETRY_TIME (5 * HZ)
-static int is_duplicate_packet(struct rtllib_device *ieee,
- struct ieee80211_hdr *header)
-{
- u16 fc = le16_to_cpu(header->frame_control);
- u16 sc = le16_to_cpu(header->seq_ctrl);
- u16 seq = WLAN_GET_SEQ_SEQ(sc);
- u16 frag = WLAN_GET_SEQ_FRAG(sc);
- u16 *last_seq, *last_frag;
- unsigned long *last_time;
- struct ieee80211_qos_hdr *hdr_3addrqos;
- struct ieee80211_qos_hdr_4addr *hdr_4addrqos;
- u8 tid;
-
- if (ieee80211_has_a4(header->frame_control) &&
- RTLLIB_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_qos_hdr_4addr *)header;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctrl) & RTLLIB_QCTL_TID;
- tid = UP2AC(tid);
- tid++;
- } else if (RTLLIB_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_qos_hdr *)header;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctrl) & RTLLIB_QCTL_TID;
- tid = UP2AC(tid);
- tid++;
- } else {
- tid = 0;
- }
-
- switch (ieee->iw_mode) {
- case IW_MODE_INFRA:
- last_seq = &ieee->last_rxseq_num[tid];
- last_frag = &ieee->last_rxfrag_num[tid];
- last_time = &ieee->last_packet_time[tid];
- break;
- default:
- return 0;
- }
-
- if ((*last_seq == seq) &&
- time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
- if (*last_frag == frag)
- goto drop;
- if (*last_frag + 1 != frag)
- /* out-of-order fragment */
- goto drop;
- } else {
- *last_seq = seq;
- }
-
- *last_frag = frag;
- *last_time = jiffies;
- return 0;
-
-drop:
-
- return 1;
-}
-
-static bool add_reorder_entry(struct rx_ts_record *ts,
- struct rx_reorder_entry *reorder_entry)
-{
- struct list_head *list = &ts->rx_pending_pkt_list;
-
- while (list->next != &ts->rx_pending_pkt_list) {
- if (SN_LESS(reorder_entry->seq_num, ((struct rx_reorder_entry *)
- list_entry(list->next, struct rx_reorder_entry,
- list))->seq_num))
- list = list->next;
- else if (SN_EQUAL(reorder_entry->seq_num,
- ((struct rx_reorder_entry *)list_entry(list->next,
- struct rx_reorder_entry, list))->seq_num))
- return false;
- else
- break;
- }
- reorder_entry->list.next = list->next;
- reorder_entry->list.next->prev = &reorder_entry->list;
- reorder_entry->list.prev = list;
- list->next = &reorder_entry->list;
-
- return true;
-}
-
-void rtllib_indicate_packets(struct rtllib_device *ieee,
- struct rtllib_rxb **prxb_indicate_array, u8 index)
-{
- struct net_device_stats *stats = &ieee->stats;
- u8 i = 0, j = 0;
- u16 ethertype;
-
- for (j = 0; j < index; j++) {
- struct rtllib_rxb *prxb = prxb_indicate_array[j];
-
- for (i = 0; i < prxb->nr_subframes; i++) {
- struct sk_buff *sub_skb = prxb->subframes[i];
-
- /* convert hdr + possible LLC headers into Ethernet header */
- ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
- if (sub_skb->len >= 8 &&
- ((memcmp(sub_skb->data, rfc1042_header,
- SNAP_SIZE) == 0 &&
- ethertype != ETH_P_AARP &&
- ethertype != ETH_P_IPX) ||
- memcmp(sub_skb->data, bridge_tunnel_header,
- SNAP_SIZE) == 0)) {
- /* remove RFC1042 or Bridge-Tunnel encapsulation
- * and replace EtherType
- */
- skb_pull(sub_skb, SNAP_SIZE);
- memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
- memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
- } else {
- u16 len;
- /* Leave Ethernet header part of hdr and full payload */
- len = sub_skb->len;
- memcpy(skb_push(sub_skb, 2), &len, 2);
- memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
- memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
- }
-
- /* Indicate the packets to upper layer */
- if (sub_skb) {
- stats->rx_packets++;
- stats->rx_bytes += sub_skb->len;
-
- memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
- sub_skb->protocol = eth_type_trans(sub_skb,
- ieee->dev);
- sub_skb->dev = ieee->dev;
- sub_skb->dev->stats.rx_packets++;
- sub_skb->dev->stats.rx_bytes += sub_skb->len;
- /* 802.11 crc not sufficient */
- sub_skb->ip_summed = CHECKSUM_NONE;
- ieee->last_rx_ps_time = jiffies;
- netif_rx(sub_skb);
- }
- }
- kfree(prxb);
- prxb = NULL;
- }
-}
-
-void rtllib_flush_rx_ts_pending_pkts(struct rtllib_device *ieee,
- struct rx_ts_record *ts)
-{
- struct rx_reorder_entry *pRxReorderEntry;
- u8 rfd_cnt = 0;
-
- del_timer_sync(&ts->rx_pkt_pending_timer);
- while (!list_empty(&ts->rx_pending_pkt_list)) {
- if (rfd_cnt >= REORDER_WIN_SIZE) {
- netdev_info(ieee->dev,
- "-------------->%s() error! rfd_cnt >= REORDER_WIN_SIZE\n",
- __func__);
- break;
- }
-
- pRxReorderEntry = (struct rx_reorder_entry *)
- list_entry(ts->rx_pending_pkt_list.prev,
- struct rx_reorder_entry, list);
- netdev_dbg(ieee->dev, "%s(): Indicate seq_num %d!\n", __func__,
- pRxReorderEntry->seq_num);
- list_del_init(&pRxReorderEntry->list);
-
- ieee->rfd_array[rfd_cnt] = pRxReorderEntry->prxb;
-
- rfd_cnt = rfd_cnt + 1;
- list_add_tail(&pRxReorderEntry->list,
- &ieee->RxReorder_Unused_List);
- }
- rtllib_indicate_packets(ieee, ieee->rfd_array, rfd_cnt);
-
- ts->rx_indicate_seq = 0xffff;
-}
-
-static void rx_reorder_indicate_packet(struct rtllib_device *ieee,
- struct rtllib_rxb *prxb,
- struct rx_ts_record *ts, u16 seq_num)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
- struct rx_reorder_entry *reorder_entry = NULL;
- u8 win_size = ht_info->rx_reorder_win_size;
- u16 win_end = 0;
- u8 index = 0;
- bool match_win_start = false, pkt_in_buf = false;
- unsigned long flags;
-
- netdev_dbg(ieee->dev,
- "%s(): Seq is %d, ts->rx_indicate_seq is %d, win_size is %d\n",
- __func__, seq_num, ts->rx_indicate_seq, win_size);
-
- spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
-
- win_end = (ts->rx_indicate_seq + win_size - 1) % 4096;
- /* Rx Reorder initialize condition.*/
- if (ts->rx_indicate_seq == 0xffff)
- ts->rx_indicate_seq = seq_num;
-
- /* Drop out the packet which seq_num is smaller than WinStart */
- if (SN_LESS(seq_num, ts->rx_indicate_seq)) {
- netdev_dbg(ieee->dev,
- "Packet Drop! IndicateSeq: %d, NewSeq: %d\n",
- ts->rx_indicate_seq, seq_num);
- ht_info->rx_reorder_drop_counter++;
- {
- int i;
-
- for (i = 0; i < prxb->nr_subframes; i++)
- dev_kfree_skb(prxb->subframes[i]);
- kfree(prxb);
- prxb = NULL;
- }
- spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
- return;
- }
-
- /* Sliding window manipulation. Conditions includes:
- * 1. Incoming seq_num is equal to WinStart =>Window shift 1
- * 2. Incoming seq_num is larger than the win_end => Window shift N
- */
- if (SN_EQUAL(seq_num, ts->rx_indicate_seq)) {
- ts->rx_indicate_seq = (ts->rx_indicate_seq + 1) % 4096;
- match_win_start = true;
- } else if (SN_LESS(win_end, seq_num)) {
- if (seq_num >= (win_size - 1))
- ts->rx_indicate_seq = seq_num + 1 - win_size;
- else
- ts->rx_indicate_seq = 4095 -
- (win_size - (seq_num + 1)) + 1;
- netdev_dbg(ieee->dev,
- "Window Shift! IndicateSeq: %d, NewSeq: %d\n",
- ts->rx_indicate_seq, seq_num);
- }
-
- /* Indication process.
- * After Packet dropping and Sliding Window shifting as above, we can
- * now just indicate the packets with the seq_num smaller than latest
- * WinStart and struct buffer other packets.
- *
- * For Rx Reorder condition:
- * 1. All packets with seq_num smaller than WinStart => Indicate
- * 2. All packets with seq_num larger than or equal to
- * WinStart => Buffer it.
- */
- if (match_win_start) {
- /* Current packet is going to be indicated.*/
- netdev_dbg(ieee->dev,
- "Packets indication! IndicateSeq: %d, NewSeq: %d\n",
- ts->rx_indicate_seq, seq_num);
- ieee->prxb_indicate_array[0] = prxb;
- index = 1;
- } else {
- /* Current packet is going to be inserted into pending list.*/
- if (!list_empty(&ieee->RxReorder_Unused_List)) {
- reorder_entry = (struct rx_reorder_entry *)
- list_entry(ieee->RxReorder_Unused_List.next,
- struct rx_reorder_entry, list);
- list_del_init(&reorder_entry->list);
-
- /* Make a reorder entry and insert
- * into a the packet list.
- */
- reorder_entry->seq_num = seq_num;
- reorder_entry->prxb = prxb;
-
- if (!add_reorder_entry(ts, reorder_entry)) {
- int i;
-
- netdev_dbg(ieee->dev,
- "%s(): Duplicate packet is dropped. IndicateSeq: %d, NewSeq: %d\n",
- __func__, ts->rx_indicate_seq,
- seq_num);
- list_add_tail(&reorder_entry->list,
- &ieee->RxReorder_Unused_List);
-
- for (i = 0; i < prxb->nr_subframes; i++)
- dev_kfree_skb(prxb->subframes[i]);
- kfree(prxb);
- prxb = NULL;
- } else {
- netdev_dbg(ieee->dev,
- "Pkt insert into struct buffer. IndicateSeq: %d, NewSeq: %d\n",
- ts->rx_indicate_seq, seq_num);
- }
- } else {
- /* Packets are dropped if there are not enough reorder
- * entries. This part should be modified!! We can just
- * indicate all the packets in struct buffer and get
- * reorder entries.
- */
- netdev_err(ieee->dev,
- "%s(): There is no reorder entry! Packet is dropped!\n",
- __func__);
- {
- int i;
-
- for (i = 0; i < prxb->nr_subframes; i++)
- dev_kfree_skb(prxb->subframes[i]);
- kfree(prxb);
- prxb = NULL;
- }
- }
- }
-
- /* Check if there is any packet need indicate.*/
- while (!list_empty(&ts->rx_pending_pkt_list)) {
- netdev_dbg(ieee->dev, "%s(): start RREORDER indicate\n",
- __func__);
-
- reorder_entry = (struct rx_reorder_entry *)
- list_entry(ts->rx_pending_pkt_list.prev,
- struct rx_reorder_entry,
- list);
- if (SN_LESS(reorder_entry->seq_num, ts->rx_indicate_seq) ||
- SN_EQUAL(reorder_entry->seq_num, ts->rx_indicate_seq)) {
- /* This protect struct buffer from overflow. */
- if (index >= REORDER_WIN_SIZE) {
- netdev_err(ieee->dev,
- "%s(): Buffer overflow!\n",
- __func__);
- pkt_in_buf = true;
- break;
- }
-
- list_del_init(&reorder_entry->list);
-
- if (SN_EQUAL(reorder_entry->seq_num, ts->rx_indicate_seq))
- ts->rx_indicate_seq = (ts->rx_indicate_seq + 1) %
- 4096;
-
- ieee->prxb_indicate_array[index] = reorder_entry->prxb;
- netdev_dbg(ieee->dev, "%s(): Indicate seq_num %d!\n",
- __func__, reorder_entry->seq_num);
- index++;
-
- list_add_tail(&reorder_entry->list,
- &ieee->RxReorder_Unused_List);
- } else {
- pkt_in_buf = true;
- break;
- }
- }
-
- /* Handling pending timer. Set this timer to prevent from long time
- * Rx buffering.
- */
- if (index > 0) {
- spin_unlock_irqrestore(&ieee->reorder_spinlock, flags);
- if (timer_pending(&ts->rx_pkt_pending_timer))
- del_timer_sync(&ts->rx_pkt_pending_timer);
- spin_lock_irqsave(&ieee->reorder_spinlock, flags);
- ts->rx_timeout_indicate_seq = 0xffff;
-
- if (index > REORDER_WIN_SIZE) {
- netdev_err(ieee->dev,
- "%s(): Rx Reorder struct buffer full!\n",
- __func__);
- spin_unlock_irqrestore(&(ieee->reorder_spinlock),
- flags);
- return;
- }
- rtllib_indicate_packets(ieee, ieee->prxb_indicate_array, index);
- pkt_in_buf = false;
- }
-
- if (pkt_in_buf && ts->rx_timeout_indicate_seq == 0xffff) {
- netdev_dbg(ieee->dev, "%s(): SET rx timeout timer\n", __func__);
- ts->rx_timeout_indicate_seq = ts->rx_indicate_seq;
- spin_unlock_irqrestore(&ieee->reorder_spinlock, flags);
- mod_timer(&ts->rx_pkt_pending_timer, jiffies +
- msecs_to_jiffies(ht_info->rx_reorder_pending_time));
- spin_lock_irqsave(&ieee->reorder_spinlock, flags);
- }
- spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
-}
-
-static u8 parse_subframe(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats,
- struct rtllib_rxb *rxb, u8 *src, u8 *dst)
-{
- struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)skb->data;
- u16 fc = le16_to_cpu(hdr->frame_control);
-
- u16 llc_offset = sizeof(struct ieee80211_hdr_3addr);
- bool is_aggregate_frame = false;
- u16 subframe_len;
- u8 pad_len = 0;
- u16 seq_num = 0;
- struct sk_buff *sub_skb;
- /* just for debug purpose */
- seq_num = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctrl));
- if ((RTLLIB_QOS_HAS_SEQ(fc)) &&
- (((union frameqos *)(skb->data + RTLLIB_3ADDR_LEN))->field.reserved))
- is_aggregate_frame = true;
-
- if (RTLLIB_QOS_HAS_SEQ(fc))
- llc_offset += 2;
- if (rx_stats->contain_htc)
- llc_offset += sHTCLng;
-
- if (skb->len <= llc_offset)
- return 0;
-
- skb_pull(skb, llc_offset);
- ieee->is_aggregate_frame = is_aggregate_frame;
- if (!is_aggregate_frame) {
- rxb->nr_subframes = 1;
-
- /* altered by clark 3/30/2010
- * The struct buffer size of the skb indicated to upper layer
- * must be less than 5000, or the defraged IP datagram
- * in the IP layer will exceed "ipfrag_high_tresh" and be
- * discarded. so there must not use the function
- * "skb_copy" and "skb_clone" for "skb".
- */
-
- /* Allocate new skb for releasing to upper layer */
- sub_skb = dev_alloc_skb(RTLLIB_SKBBUFFER_SIZE);
- if (!sub_skb)
- return 0;
- skb_reserve(sub_skb, 12);
- skb_put_data(sub_skb, skb->data, skb->len);
- sub_skb->dev = ieee->dev;
-
- rxb->subframes[0] = sub_skb;
-
- memcpy(rxb->src, src, ETH_ALEN);
- memcpy(rxb->dst, dst, ETH_ALEN);
- rxb->subframes[0]->dev = ieee->dev;
- return 1;
- }
-
- rxb->nr_subframes = 0;
- memcpy(rxb->src, src, ETH_ALEN);
- memcpy(rxb->dst, dst, ETH_ALEN);
- while (skb->len > ETHERNET_HEADER_SIZE) {
- /* Offset 12 denote 2 mac address */
- subframe_len = *((u16 *)(skb->data + 12));
- subframe_len = (subframe_len >> 8) +
- (subframe_len << 8);
-
- if (skb->len < (ETHERNET_HEADER_SIZE + subframe_len)) {
- netdev_info(ieee->dev,
- "%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",
- __func__, rxb->nr_subframes);
- netdev_info(ieee->dev,
- "%s: A-MSDU parse error!! Subframe Length: %d\n",
- __func__, subframe_len);
- netdev_info(ieee->dev,
- "nRemain_Length is %d and subframe_len is : %d\n",
- skb->len, subframe_len);
- netdev_info(ieee->dev,
- "The Packet seq_num is %d\n",
- seq_num);
- return 0;
- }
-
- /* move the data point to data content */
- skb_pull(skb, ETHERNET_HEADER_SIZE);
-
- /* altered by clark 3/30/2010
- * The struct buffer size of the skb indicated to upper layer
- * must be less than 5000, or the defraged IP datagram
- * in the IP layer will exceed "ipfrag_high_tresh" and be
- * discarded. so there must not use the function
- * "skb_copy" and "skb_clone" for "skb".
- */
-
- /* Allocate new skb for releasing to upper layer */
- sub_skb = dev_alloc_skb(subframe_len + 12);
- if (!sub_skb)
- return 0;
- skb_reserve(sub_skb, 12);
- skb_put_data(sub_skb, skb->data, subframe_len);
-
- sub_skb->dev = ieee->dev;
- rxb->subframes[rxb->nr_subframes++] = sub_skb;
- if (rxb->nr_subframes >= MAX_SUBFRAME_COUNT) {
- netdev_dbg(ieee->dev,
- "ParseSubframe(): Too many Subframes! Packets dropped!\n");
- break;
- }
- skb_pull(skb, subframe_len);
-
- if (skb->len != 0) {
- pad_len = 4 - ((subframe_len +
- ETHERNET_HEADER_SIZE) % 4);
- if (pad_len == 4)
- pad_len = 0;
-
- if (skb->len < pad_len)
- return 0;
-
- skb_pull(skb, pad_len);
- }
- }
-
- return rxb->nr_subframes;
-}
-
-static size_t rtllib_rx_get_hdrlen(struct rtllib_device *ieee,
- struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- u16 fc = le16_to_cpu(hdr->frame_control);
- size_t hdrlen;
-
- hdrlen = rtllib_get_hdrlen(fc);
- if (ht_c_check(ieee, skb->data)) {
- if (net_ratelimit())
- netdev_info(ieee->dev, "%s: find HTCControl!\n",
- __func__);
- hdrlen += 4;
- rx_stats->contain_htc = true;
- }
-
- return hdrlen;
-}
-
-static int rtllib_rx_check_duplicate(struct rtllib_device *ieee,
- struct sk_buff *skb, u8 multicast)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- u16 fc, sc;
- u8 frag;
-
- fc = le16_to_cpu(hdr->frame_control);
- sc = le16_to_cpu(hdr->seq_ctrl);
- frag = WLAN_GET_SEQ_FRAG(sc);
-
- if (!ieee->ht_info->cur_rx_reorder_enable ||
- !ieee->current_network.qos_data.active ||
- !is_data_frame(skb->data) ||
- is_legacy_data_frame(skb->data)) {
- if (!ieee80211_is_beacon(hdr->frame_control)) {
- if (is_duplicate_packet(ieee, hdr))
- return -1;
- }
- } else {
- struct rx_ts_record *ts = NULL;
-
- if (rtllib_get_ts(ieee, (struct ts_common_info **)&ts, hdr->addr2,
- (u8)frame_qos_tid((u8 *)(skb->data)), RX_DIR, true)) {
- if ((fc & (1 << 11)) && (frag == ts->rx_last_frag_num) &&
- (WLAN_GET_SEQ_SEQ(sc) == ts->rx_last_seq_num))
- return -1;
- ts->rx_last_frag_num = frag;
- ts->rx_last_seq_num = WLAN_GET_SEQ_SEQ(sc);
- } else {
- netdev_warn(ieee->dev, "%s(): No TS! Skip the check!\n",
- __func__);
- return -1;
- }
- }
-
- return 0;
-}
-
-static void rtllib_rx_extract_addr(struct rtllib_device *ieee,
- struct ieee80211_hdr *hdr, u8 *dst,
- u8 *src, u8 *bssid)
-{
- u16 fc = le16_to_cpu(hdr->frame_control);
-
- switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_FROMDS:
- ether_addr_copy(dst, hdr->addr1);
- ether_addr_copy(src, hdr->addr3);
- ether_addr_copy(bssid, hdr->addr2);
- break;
- case IEEE80211_FCTL_TODS:
- ether_addr_copy(dst, hdr->addr3);
- ether_addr_copy(src, hdr->addr2);
- ether_addr_copy(bssid, hdr->addr1);
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- ether_addr_copy(dst, hdr->addr3);
- ether_addr_copy(src, hdr->addr4);
- ether_addr_copy(bssid, ieee->current_network.bssid);
- break;
- default:
- ether_addr_copy(dst, hdr->addr1);
- ether_addr_copy(src, hdr->addr2);
- ether_addr_copy(bssid, hdr->addr3);
- break;
- }
-}
-
-static int rtllib_rx_data_filter(struct rtllib_device *ieee, struct ieee80211_hdr *hdr,
- u8 *dst, u8 *src, u8 *bssid, u8 *addr2)
-{
- u16 fc = le16_to_cpu(hdr->frame_control);
- u8 type = WLAN_FC_GET_TYPE(fc);
- u8 stype = WLAN_FC_GET_STYPE(fc);
-
- /* Filter frames from different BSS */
- if (ieee80211_has_a4(hdr->frame_control) &&
- !ether_addr_equal(ieee->current_network.bssid, bssid) &&
- !is_zero_ether_addr(ieee->current_network.bssid)) {
- return -1;
- }
-
- /* Nullfunc frames may have PS-bit set, so they must be passed to
- * hostap_handle_sta_rx() before being dropped here.
- */
- if (stype != IEEE80211_STYPE_DATA &&
- stype != IEEE80211_STYPE_DATA_CFACK &&
- stype != IEEE80211_STYPE_DATA_CFPOLL &&
- stype != IEEE80211_STYPE_DATA_CFACKPOLL &&
- stype != IEEE80211_STYPE_QOS_DATA) {
- if (stype != IEEE80211_STYPE_NULLFUNC)
- netdev_dbg(ieee->dev,
- "RX: dropped data frame with no data (type=0x%02x, subtype=0x%02x)\n",
- type, stype);
- return -1;
- }
-
- /* packets from our adapter are dropped (echo) */
- if (!memcmp(src, ieee->dev->dev_addr, ETH_ALEN))
- return -1;
-
- /* {broad,multi}cast packets to our BSS go through */
- if (is_multicast_ether_addr(dst)) {
- if (memcmp(bssid, ieee->current_network.bssid,
- ETH_ALEN))
- return -1;
- }
- return 0;
-}
-
-static int rtllib_rx_get_crypt(struct rtllib_device *ieee, struct sk_buff *skb,
- struct lib80211_crypt_data **crypt, size_t hdrlen)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- u16 fc = le16_to_cpu(hdr->frame_control);
- int idx = 0;
-
- if (skb->len >= hdrlen + 3)
- idx = skb->data[hdrlen + 3] >> 6;
-
- *crypt = ieee->crypt_info.crypt[idx];
- /* allow NULL decrypt to indicate an station specific override
- * for default encryption
- */
- if (*crypt && (!(*crypt)->ops || !(*crypt)->ops->decrypt_mpdu))
- *crypt = NULL;
-
- if (!*crypt && (fc & IEEE80211_FCTL_PROTECTED)) {
- /* This seems to be triggered by some (multicast?)
- * frames from other than current BSS, so just drop the
- * frames silently instead of filling system log with
- * these reports.
- */
- netdev_dbg(ieee->dev,
- "Decryption failed (not set) (SA= %pM)\n",
- hdr->addr2);
- return -1;
- }
-
- return 0;
-}
-
-static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats,
- struct lib80211_crypt_data *crypt, size_t hdrlen)
-{
- struct ieee80211_hdr *hdr;
- int keyidx = 0;
- u16 fc, sc;
- u8 frag;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = le16_to_cpu(hdr->frame_control);
- sc = le16_to_cpu(hdr->seq_ctrl);
- frag = WLAN_GET_SEQ_FRAG(sc);
-
- if ((!rx_stats->decrypted))
- ieee->need_sw_enc = 1;
- else
- ieee->need_sw_enc = 0;
-
- keyidx = rtllib_rx_frame_decrypt(ieee, skb, crypt);
- if ((fc & IEEE80211_FCTL_PROTECTED) && (keyidx < 0)) {
- netdev_info(ieee->dev, "%s: decrypt frame error\n", __func__);
- return -1;
- }
-
- hdr = (struct ieee80211_hdr *)skb->data;
- if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
- int flen;
- struct sk_buff *frag_skb = rtllib_frag_cache_get(ieee, hdr);
-
- netdev_dbg(ieee->dev, "Rx Fragment received (%u)\n", frag);
-
- if (!frag_skb) {
- netdev_dbg(ieee->dev,
- "Rx cannot get skb from fragment cache (morefrag=%d seq=%u frag=%u)\n",
- (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
- WLAN_GET_SEQ_SEQ(sc), frag);
- return -1;
- }
- flen = skb->len;
- if (frag != 0)
- flen -= hdrlen;
-
- if (frag_skb->tail + flen > frag_skb->end) {
- netdev_warn(ieee->dev,
- "%s: host decrypted and reassembled frame did not fit skb\n",
- __func__);
- rtllib_frag_cache_invalidate(ieee, hdr);
- return -1;
- }
-
- if (frag == 0) {
- /* copy first fragment (including full headers) into
- * beginning of the fragment cache skb
- */
- skb_put_data(frag_skb, skb->data, flen);
- } else {
- /* append frame payload to the end of the fragment
- * cache skb
- */
- skb_put_data(frag_skb, skb->data + hdrlen, flen);
- }
- dev_kfree_skb_any(skb);
- skb = NULL;
-
- if (fc & IEEE80211_FCTL_MOREFRAGS) {
- /* more fragments expected - leave the skb in fragment
- * cache for now; it will be delivered to upper layers
- * after all fragments have been received
- */
- return -2;
- }
-
- /* this was the last fragment and the frame will be
- * delivered, so remove skb from fragment cache
- */
- skb = frag_skb;
- hdr = (struct ieee80211_hdr *)skb->data;
- rtllib_frag_cache_invalidate(ieee, hdr);
- }
-
- /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
- * encrypted/authenticated
- */
- if ((fc & IEEE80211_FCTL_PROTECTED) &&
- rtllib_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) {
- netdev_info(ieee->dev, "%s: ==>decrypt msdu error\n", __func__);
- return -1;
- }
-
- hdr = (struct ieee80211_hdr *)skb->data;
- if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
- if (/*ieee->ieee802_1x &&*/
- rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
- /* pass unencrypted EAPOL frames even if encryption is
- * configured
- */
- struct eapol *eap = (struct eapol *)(skb->data +
- 24);
- netdev_dbg(ieee->dev,
- "RX: IEEE 802.1X EAPOL frame: %s\n",
- eap_get_type(eap->type));
- } else {
- netdev_dbg(ieee->dev,
- "encryption configured, but RX frame not encrypted (SA= %pM)\n",
- hdr->addr2);
- return -1;
- }
- }
-
- if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) &&
- rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
- struct eapol *eap = (struct eapol *)(skb->data + 24);
-
- netdev_dbg(ieee->dev, "RX: IEEE 802.1X EAPOL frame: %s\n",
- eap_get_type(eap->type));
- }
-
- if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
- !rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
- netdev_dbg(ieee->dev,
- "dropped unencrypted RX data frame from %pM (drop_unencrypted=1)\n",
- hdr->addr2);
- return -1;
- }
-
- return 0;
-}
-
-static void rtllib_rx_check_leave_lps(struct rtllib_device *ieee, u8 unicast,
- u8 nr_subframes)
-{
- if (unicast) {
- if (ieee->link_state == MAC80211_LINKED) {
- if (((ieee->link_detect_info.num_rx_unicast_ok_in_period +
- ieee->link_detect_info.num_tx_ok_in_period) > 8) ||
- (ieee->link_detect_info.num_rx_unicast_ok_in_period > 2)) {
- ieee->leisure_ps_leave(ieee->dev);
- }
- }
- }
- ieee->last_rx_ps_time = jiffies;
-}
-
-static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee,
- struct rtllib_rx_stats *rx_stats,
- struct rtllib_rxb *rxb,
- u8 *dst,
- u8 *src)
-{
- struct net_device *dev = ieee->dev;
- u16 ethertype;
- int i = 0;
-
- if (!rxb) {
- netdev_info(dev, "%s: rxb is NULL!!\n", __func__);
- return;
- }
-
- for (i = 0; i < rxb->nr_subframes; i++) {
- struct sk_buff *sub_skb = rxb->subframes[i];
-
- if (sub_skb) {
- /* convert hdr + possible LLC headers
- * into Ethernet header
- */
- ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
- if (sub_skb->len >= 8 &&
- ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
- memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
- /* remove RFC1042 or Bridge-Tunnel encapsulation
- * and replace EtherType
- */
- skb_pull(sub_skb, SNAP_SIZE);
- ether_addr_copy(skb_push(sub_skb, ETH_ALEN),
- src);
- ether_addr_copy(skb_push(sub_skb, ETH_ALEN),
- dst);
- } else {
- u16 len;
- /* Leave Ethernet header part of hdr
- * and full payload
- */
- len = sub_skb->len;
- memcpy(skb_push(sub_skb, 2), &len, 2);
- ether_addr_copy(skb_push(sub_skb, ETH_ALEN),
- src);
- ether_addr_copy(skb_push(sub_skb, ETH_ALEN),
- dst);
- }
-
- ieee->stats.rx_packets++;
- ieee->stats.rx_bytes += sub_skb->len;
-
- if (is_multicast_ether_addr(dst))
- ieee->stats.multicast++;
-
- /* Indicate the packets to upper layer */
- memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
- sub_skb->protocol = eth_type_trans(sub_skb, dev);
- sub_skb->dev = dev;
- sub_skb->dev->stats.rx_packets++;
- sub_skb->dev->stats.rx_bytes += sub_skb->len;
- /* 802.11 crc not sufficient */
- sub_skb->ip_summed = CHECKSUM_NONE;
- netif_rx(sub_skb);
- }
- }
- kfree(rxb);
-}
-
-static int rtllib_rx_infra_adhoc(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats)
-{
- struct net_device *dev = ieee->dev;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct lib80211_crypt_data *crypt = NULL;
- struct rtllib_rxb *rxb = NULL;
- struct rx_ts_record *ts = NULL;
- u16 fc, sc, seq_num = 0;
- u8 type, stype, multicast = 0, unicast = 0, nr_subframes = 0, TID = 0;
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
- u8 bssid[ETH_ALEN] = {0};
-
- size_t hdrlen = 0;
- int ret = 0, i = 0;
-
- fc = le16_to_cpu(hdr->frame_control);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
- sc = le16_to_cpu(hdr->seq_ctrl);
-
- /*Filter pkt not to me*/
- multicast = is_multicast_ether_addr(hdr->addr1);
- unicast = !multicast;
- if (unicast && !ether_addr_equal(dev->dev_addr, hdr->addr1))
- goto rx_dropped;
-
- /*Filter pkt has too small length */
- hdrlen = rtllib_rx_get_hdrlen(ieee, skb, rx_stats);
- if (skb->len < hdrlen) {
- netdev_info(dev,
- "%s():ERR!!! skb->len is smaller than hdrlen\n",
- __func__);
- goto rx_dropped;
- }
-
- /* Filter Duplicate pkt */
- ret = rtllib_rx_check_duplicate(ieee, skb, multicast);
- if (ret < 0)
- goto rx_dropped;
-
- /* Filter CTRL Frame */
- if (type == RTLLIB_FTYPE_CTL)
- goto rx_dropped;
-
- /* Filter MGNT Frame */
- if (type == RTLLIB_FTYPE_MGMT) {
- if (rtllib_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
- goto rx_dropped;
- else
- goto rx_exit;
- }
-
- /* Filter WAPI DATA Frame */
-
- /* Update statstics for AP roaming */
- ieee->link_detect_info.num_recv_data_in_period++;
- ieee->link_detect_info.num_rx_ok_in_period++;
-
- /* Data frame - extract src/dst addresses */
- rtllib_rx_extract_addr(ieee, hdr, dst, src, bssid);
-
- /* Filter Data frames */
- ret = rtllib_rx_data_filter(ieee, hdr, dst, src, bssid, hdr->addr2);
- if (ret < 0)
- goto rx_dropped;
-
- if (skb->len == hdrlen)
- goto rx_dropped;
-
- /* Send pspoll based on moredata */
- if ((ieee->iw_mode == IW_MODE_INFRA) &&
- (ieee->sta_sleep == LPS_IS_SLEEP) &&
- (ieee->polling)) {
- if (WLAN_FC_MORE_DATA(fc)) {
- /* more data bit is set, let's request a new frame
- * from the AP
- */
- rtllib_sta_ps_send_pspoll_frame(ieee);
- } else {
- ieee->polling = false;
- }
- }
-
- /* Get crypt if encrypted */
- ret = rtllib_rx_get_crypt(ieee, skb, &crypt, hdrlen);
- if (ret == -1)
- goto rx_dropped;
-
- /* Decrypt data frame (including reassemble) */
- ret = rtllib_rx_decrypt(ieee, skb, rx_stats, crypt, hdrlen);
- if (ret == -1)
- goto rx_dropped;
- else if (ret == -2)
- goto rx_exit;
-
- /* Get TS for Rx Reorder */
- hdr = (struct ieee80211_hdr *)skb->data;
- if (ieee->current_network.qos_data.active && is_qos_data_frame(skb->data)
- && !is_multicast_ether_addr(hdr->addr1)) {
- TID = frame_qos_tid(skb->data);
- seq_num = WLAN_GET_SEQ_SEQ(sc);
- rtllib_get_ts(ieee, (struct ts_common_info **)&ts, hdr->addr2, TID,
- RX_DIR, true);
- if (TID != 0 && TID != 3)
- ieee->bis_any_nonbepkts = true;
- }
-
- /* Parse rx data frame (For AMSDU) */
- /* skb: hdr + (possible reassembled) full plaintext payload */
- rxb = kmalloc(sizeof(struct rtllib_rxb), GFP_ATOMIC);
- if (!rxb)
- goto rx_dropped;
-
- /* to parse amsdu packets */
- /* qos data packets & reserved bit is 1 */
- if (parse_subframe(ieee, skb, rx_stats, rxb, src, dst) == 0) {
- /* only to free rxb, and not submit the packets
- * to upper layer
- */
- for (i = 0; i < rxb->nr_subframes; i++)
- dev_kfree_skb(rxb->subframes[i]);
- kfree(rxb);
- rxb = NULL;
- goto rx_dropped;
- }
-
- /* Update WAPI PN */
-
- /* Check if leave LPS */
- if (ieee->is_aggregate_frame)
- nr_subframes = rxb->nr_subframes;
- else
- nr_subframes = 1;
- if (unicast)
- ieee->link_detect_info.num_rx_unicast_ok_in_period += nr_subframes;
- rtllib_rx_check_leave_lps(ieee, unicast, nr_subframes);
-
- /* Indicate packets to upper layer or Rx Reorder */
- if (!ieee->ht_info->cur_rx_reorder_enable || !ts)
- rtllib_rx_indicate_pkt_legacy(ieee, rx_stats, rxb, dst, src);
- else
- rx_reorder_indicate_packet(ieee, rxb, ts, seq_num);
-
- dev_kfree_skb(skb);
-
- rx_exit:
- return 1;
-
- rx_dropped:
- ieee->stats.rx_dropped++;
-
- /* Returning 0 indicates to caller that we have not handled the SKB--
- * so it is still allocated and can be used again by underlying
- * hardware as a DMA target
- */
- return 0;
-}
-
-static int rtllib_rx_monitor(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- u16 fc = le16_to_cpu(hdr->frame_control);
- size_t hdrlen = rtllib_get_hdrlen(fc);
-
- if (skb->len < hdrlen) {
- netdev_info(ieee->dev,
- "%s():ERR!!! skb->len is smaller than hdrlen\n",
- __func__);
- return 0;
- }
-
- if (ht_c_check(ieee, skb->data)) {
- if (net_ratelimit())
- netdev_info(ieee->dev, "%s: Find HTCControl!\n",
- __func__);
- hdrlen += 4;
- }
-
- ieee->stats.rx_packets++;
- ieee->stats.rx_bytes += skb->len;
- rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen);
-
- return 1;
-}
-
-/* All received frames are sent to this function. @skb contains the frame in
- * IEEE 802.11 format, i.e., in the format it was sent over air.
- * This function is called only as a tasklet (software IRQ).
- */
-int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats)
-{
- int ret = 0;
-
- if (!ieee || !skb || !rx_stats) {
- pr_info("%s: Input parameters NULL!\n", __func__);
- goto rx_dropped;
- }
- if (skb->len < 10) {
- netdev_info(ieee->dev, "%s: SKB length < 10\n", __func__);
- goto rx_dropped;
- }
-
- switch (ieee->iw_mode) {
- case IW_MODE_INFRA:
- ret = rtllib_rx_infra_adhoc(ieee, skb, rx_stats);
- break;
- case IW_MODE_MONITOR:
- ret = rtllib_rx_monitor(ieee, skb, rx_stats);
- break;
- default:
- netdev_info(ieee->dev, "%s: ERR iw mode!!!\n", __func__);
- break;
- }
-
- return ret;
-
- rx_dropped:
- if (ieee)
- ieee->stats.rx_dropped++;
- return 0;
-}
-EXPORT_SYMBOL(rtllib_rx);
-
-static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
-
-/* Make ther structure we read from the beacon packet has the right values */
-static int rtllib_verify_qos_info(struct rtllib_qos_information_element
- *info_element, int sub_type)
-{
- if (info_element->element_id != QOS_ELEMENT_ID)
- return -1;
- if (info_element->qui_subtype != sub_type)
- return -1;
- if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
- return -1;
- if (info_element->qui_type != QOS_OUI_TYPE)
- return -1;
- if (info_element->version != QOS_VERSION_1)
- return -1;
-
- return 0;
-}
-
-/* Parse a QoS parameter element */
-static int rtllib_read_qos_param_element(
- struct rtllib_qos_parameter_info *element_param,
- struct rtllib_info_element *info_element)
-{
- size_t size = sizeof(*element_param);
-
- if (!element_param || !info_element || info_element->len != size - 2)
- return -1;
-
- memcpy(element_param, info_element, size);
- return rtllib_verify_qos_info(&element_param->info_element,
- QOS_OUI_PARAM_SUB_TYPE);
-}
-
-/* Parse a QoS information element */
-static int rtllib_read_qos_info_element(
- struct rtllib_qos_information_element *element_info,
- struct rtllib_info_element *info_element)
-{
- size_t size = sizeof(*element_info);
-
- if (!element_info || !info_element || info_element->len != size - 2)
- return -1;
-
- memcpy(element_info, info_element, size);
- return rtllib_verify_qos_info(element_info, QOS_OUI_INFO_SUB_TYPE);
-}
-
-/* Write QoS parameters from the ac parameters. */
-static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info *param_elm,
- struct rtllib_qos_data *qos_data)
-{
- struct rtllib_qos_ac_parameter *ac_params;
- struct rtllib_qos_parameters *qos_param = &(qos_data->parameters);
- int i;
- u8 aci;
- u8 acm;
-
- qos_data->wmm_acm = 0;
- for (i = 0; i < QOS_QUEUE_NUM; i++) {
- ac_params = &(param_elm->ac_params_record[i]);
-
- aci = (ac_params->aci_aifsn & 0x60) >> 5;
- acm = (ac_params->aci_aifsn & 0x10) >> 4;
-
- if (aci >= QOS_QUEUE_NUM)
- continue;
- switch (aci) {
- case 1:
- /* BIT(0) | BIT(3) */
- if (acm)
- qos_data->wmm_acm |= (0x01 << 0) | (0x01 << 3);
- break;
- case 2:
- /* BIT(4) | BIT(5) */
- if (acm)
- qos_data->wmm_acm |= (0x01 << 4) | (0x01 << 5);
- break;
- case 3:
- /* BIT(6) | BIT(7) */
- if (acm)
- qos_data->wmm_acm |= (0x01 << 6) | (0x01 << 7);
- break;
- case 0:
- default:
- /* BIT(1) | BIT(2) */
- if (acm)
- qos_data->wmm_acm |= (0x01 << 1) | (0x01 << 2);
- break;
- }
-
- qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f;
-
- /* WMM spec P.11: The minimum value for AIFSN shall be 2 */
- qos_param->aifs[aci] = max_t(u8, qos_param->aifs[aci], 2);
-
- qos_param->cw_min[aci] = cpu_to_le16(ac_params->ecw_min_max &
- 0x0F);
-
- qos_param->cw_max[aci] = cpu_to_le16((ac_params->ecw_min_max &
- 0xF0) >> 4);
-
- qos_param->flag[aci] =
- (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
- qos_param->tx_op_limit[aci] = ac_params->tx_op_limit;
- }
- return 0;
-}
-
-/* we have a generic data element which it may contain QoS information or
- * parameters element. check the information element length to decide
- * which type to read
- */
-static int rtllib_parse_qos_info_param_IE(struct rtllib_device *ieee,
- struct rtllib_info_element
- *info_element,
- struct rtllib_network *network)
-{
- int rc = 0;
- struct rtllib_qos_information_element qos_info_element;
-
- rc = rtllib_read_qos_info_element(&qos_info_element, info_element);
-
- if (rc == 0) {
- network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
- network->flags |= NETWORK_HAS_QOS_INFORMATION;
- } else {
- struct rtllib_qos_parameter_info param_element;
-
- rc = rtllib_read_qos_param_element(&param_element,
- info_element);
- if (rc == 0) {
- rtllib_qos_convert_ac_to_parameters(&param_element,
- &(network->qos_data));
- network->flags |= NETWORK_HAS_QOS_PARAMETERS;
- network->qos_data.param_count =
- param_element.info_element.ac_info & 0x0F;
- }
- }
-
- if (rc == 0) {
- netdev_dbg(ieee->dev, "QoS is supported\n");
- network->qos_data.supported = 1;
- }
- return rc;
-}
-
-static const char *get_info_element_string(u16 id)
-{
- switch (id) {
- case MFIE_TYPE_SSID:
- return "SSID";
- case MFIE_TYPE_RATES:
- return "RATES";
- case MFIE_TYPE_FH_SET:
- return "FH_SET";
- case MFIE_TYPE_DS_SET:
- return "DS_SET";
- case MFIE_TYPE_CF_SET:
- return "CF_SET";
- case MFIE_TYPE_TIM:
- return "TIM";
- case MFIE_TYPE_IBSS_SET:
- return "IBSS_SET";
- case MFIE_TYPE_COUNTRY:
- return "COUNTRY";
- case MFIE_TYPE_HOP_PARAMS:
- return "HOP_PARAMS";
- case MFIE_TYPE_HOP_TABLE:
- return "HOP_TABLE";
- case MFIE_TYPE_REQUEST:
- return "REQUEST";
- case MFIE_TYPE_CHALLENGE:
- return "CHALLENGE";
- case MFIE_TYPE_POWER_CONSTRAINT:
- return "POWER_CONSTRAINT";
- case MFIE_TYPE_POWER_CAPABILITY:
- return "POWER_CAPABILITY";
- case MFIE_TYPE_TPC_REQUEST:
- return "TPC_REQUEST";
- case MFIE_TYPE_TPC_REPORT:
- return "TPC_REPORT";
- case MFIE_TYPE_SUPP_CHANNELS:
- return "SUPP_CHANNELS";
- case MFIE_TYPE_CSA:
- return "CSA";
- case MFIE_TYPE_MEASURE_REQUEST:
- return "MEASURE_REQUEST";
- case MFIE_TYPE_MEASURE_REPORT:
- return "MEASURE_REPORT";
- case MFIE_TYPE_QUIET:
- return "QUIET";
- case MFIE_TYPE_IBSS_DFS:
- return "IBSS_DFS";
- case MFIE_TYPE_RSN:
- return "RSN";
- case MFIE_TYPE_RATES_EX:
- return "RATES_EX";
- case MFIE_TYPE_GENERIC:
- return "GENERIC";
- case MFIE_TYPE_QOS_PARAMETER:
- return "QOS_PARAMETER";
- default:
- return "UNKNOWN";
- }
-}
-
-static void rtllib_parse_mife_generic(struct rtllib_device *ieee,
- struct rtllib_info_element *info_element,
- struct rtllib_network *network,
- u16 *tmp_htcap_len,
- u16 *tmp_htinfo_len)
-{
- u16 ht_realtek_agg_len = 0;
- u8 ht_realtek_agg_buf[MAX_IE_LEN];
-
- if (!rtllib_parse_qos_info_param_IE(ieee, info_element, network))
- return;
- if (info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x01) {
- network->wpa_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
- memcpy(network->wpa_ie, info_element, network->wpa_ie_len);
- return;
- }
- if (info_element->len == 7 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0xe0 &&
- info_element->data[2] == 0x4c &&
- info_element->data[3] == 0x01 &&
- info_element->data[4] == 0x02)
- network->turbo_enable = 1;
-
- if (*tmp_htcap_len == 0) {
- if (info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x90 &&
- info_element->data[2] == 0x4c &&
- info_element->data[3] == 0x033) {
- *tmp_htcap_len = min_t(u8, info_element->len,
- MAX_IE_LEN);
- if (*tmp_htcap_len != 0) {
- network->bssht.bd_ht_spec_ver = HT_SPEC_VER_EWC;
- network->bssht.bd_ht_cap_len = min_t(u16, *tmp_htcap_len,
- sizeof(network->bssht.bd_ht_cap_buf));
- memcpy(network->bssht.bd_ht_cap_buf,
- info_element->data,
- network->bssht.bd_ht_cap_len);
- }
- }
- if (*tmp_htcap_len != 0) {
- network->bssht.bd_support_ht = true;
- network->bssht.bd_ht_1r = ((((struct ht_capab_ele *)(network->bssht.bd_ht_cap_buf))->MCS[1]) == 0);
- } else {
- network->bssht.bd_support_ht = false;
- network->bssht.bd_ht_1r = false;
- }
- }
-
- if (*tmp_htinfo_len == 0) {
- if (info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x90 &&
- info_element->data[2] == 0x4c &&
- info_element->data[3] == 0x034) {
- *tmp_htinfo_len = min_t(u8, info_element->len,
- MAX_IE_LEN);
- if (*tmp_htinfo_len != 0) {
- network->bssht.bd_ht_spec_ver = HT_SPEC_VER_EWC;
- network->bssht.bd_ht_info_len = min_t(u16, *tmp_htinfo_len,
- sizeof(network->bssht.bd_ht_info_buf));
- memcpy(network->bssht.bd_ht_info_buf,
- info_element->data,
- network->bssht.bd_ht_info_len);
- }
- }
- }
-
- if (network->bssht.bd_support_ht) {
- if (info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0xe0 &&
- info_element->data[2] == 0x4c &&
- info_element->data[3] == 0x02) {
- ht_realtek_agg_len = min_t(u8, info_element->len,
- MAX_IE_LEN);
- memcpy(ht_realtek_agg_buf, info_element->data,
- info_element->len);
- }
- if (ht_realtek_agg_len >= 5) {
- network->realtek_cap_exit = true;
- network->bssht.bd_rt2rt_aggregation = true;
-
- if ((ht_realtek_agg_buf[4] == 1) &&
- (ht_realtek_agg_buf[5] & 0x02))
- network->bssht.bd_rt2rt_long_slot_time = true;
-
- if ((ht_realtek_agg_buf[4] == 1) &&
- (ht_realtek_agg_buf[5] & RT_HT_CAP_USE_92SE))
- network->bssht.rt2rt_ht_mode |= RT_HT_CAP_USE_92SE;
- }
- }
- if (ht_realtek_agg_len >= 5) {
- if ((ht_realtek_agg_buf[5] & RT_HT_CAP_USE_SOFTAP))
- network->bssht.rt2rt_ht_mode |= RT_HT_CAP_USE_SOFTAP;
- }
-
- if ((info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x05 &&
- info_element->data[2] == 0xb5) ||
- (info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x0a &&
- info_element->data[2] == 0xf7) ||
- (info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x10 &&
- info_element->data[2] == 0x18)) {
- network->broadcom_cap_exist = true;
- }
- if (info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x0c &&
- info_element->data[2] == 0x43)
- network->ralink_cap_exist = true;
- if ((info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x03 &&
- info_element->data[2] == 0x7f) ||
- (info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x13 &&
- info_element->data[2] == 0x74))
- network->atheros_cap_exist = true;
-
- if ((info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0x43))
- network->marvell_cap_exist = true;
- if (info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x40 &&
- info_element->data[2] == 0x96)
- network->cisco_cap_exist = true;
-
- if (info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x0a &&
- info_element->data[2] == 0xf5)
- network->airgo_cap_exist = true;
-
- if (info_element->len > 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x40 &&
- info_element->data[2] == 0x96 &&
- info_element->data[3] == 0x01) {
- if (info_element->len == 6) {
- memcpy(network->ccx_rm_state, &info_element->data[4], 2);
- if (network->ccx_rm_state[0] != 0)
- network->ccx_rm_enable = true;
- else
- network->ccx_rm_enable = false;
- network->mb_ssid_mask = network->ccx_rm_state[1] & 0x07;
- if (network->mb_ssid_mask != 0) {
- network->mb_ssid_valid = true;
- network->mb_ssid_mask = 0xff <<
- (network->mb_ssid_mask);
- ether_addr_copy(network->mb_ssid,
- network->bssid);
- network->mb_ssid[5] &= network->mb_ssid_mask;
- } else {
- network->mb_ssid_valid = false;
- }
- } else {
- network->ccx_rm_enable = false;
- }
- }
- if (info_element->len > 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x40 &&
- info_element->data[2] == 0x96 &&
- info_element->data[3] == 0x03) {
- if (info_element->len == 5) {
- network->with_ccx_ver_num = true;
- network->bss_ccx_ver_number = info_element->data[4];
- } else {
- network->with_ccx_ver_num = false;
- network->bss_ccx_ver_number = 0;
- }
- }
- if (info_element->len > 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x04) {
- netdev_dbg(ieee->dev, "MFIE_TYPE_WZC: %d bytes\n",
- info_element->len);
- network->wzc_ie_len = min(info_element->len + 2, MAX_WZC_IE_LEN);
- memcpy(network->wzc_ie, info_element, network->wzc_ie_len);
- }
-}
-
-static void rtllib_parse_mfie_ht_cap(struct rtllib_info_element *info_element,
- struct rtllib_network *network,
- u16 *tmp_htcap_len)
-{
- struct bss_ht *ht = &network->bssht;
-
- *tmp_htcap_len = min_t(u8, info_element->len, MAX_IE_LEN);
- if (*tmp_htcap_len != 0) {
- ht->bd_ht_spec_ver = HT_SPEC_VER_EWC;
- ht->bd_ht_cap_len = min_t(u16, *tmp_htcap_len,
- sizeof(ht->bd_ht_cap_buf));
- memcpy(ht->bd_ht_cap_buf, info_element->data, ht->bd_ht_cap_len);
-
- ht->bd_support_ht = true;
- ht->bd_ht_1r = ((((struct ht_capab_ele *)
- ht->bd_ht_cap_buf))->MCS[1]) == 0;
-
- ht->bd_bandwidth = (enum ht_channel_width)
- (((struct ht_capab_ele *)
- (ht->bd_ht_cap_buf))->chl_width);
- } else {
- ht->bd_support_ht = false;
- ht->bd_ht_1r = false;
- ht->bd_bandwidth = HT_CHANNEL_WIDTH_20;
- }
-}
-
-int rtllib_parse_info_param(struct rtllib_device *ieee,
- struct rtllib_info_element *info_element,
- u16 length,
- struct rtllib_network *network,
- struct rtllib_rx_stats *stats)
-{
- u8 i;
- short offset;
- u16 tmp_htcap_len = 0;
- u16 tmp_htinfo_len = 0;
- char rates_str[64];
- char *p;
-
- while (length >= sizeof(*info_element)) {
- if (sizeof(*info_element) + info_element->len > length) {
- netdev_dbg(ieee->dev,
- "Info elem: parse failed: info_element->len + 2 > left : info_element->len+2=%zd left=%d, id=%d.\n",
- info_element->len + sizeof(*info_element),
- length, info_element->id);
- /* We stop processing but don't return an error here
- * because some misbehaviour APs break this rule. ie.
- * Orinoco AP1000.
- */
- break;
- }
-
- switch (info_element->id) {
- case MFIE_TYPE_SSID:
- if (rtllib_is_empty_essid(info_element->data,
- info_element->len)) {
- network->flags |= NETWORK_EMPTY_ESSID;
- break;
- }
-
- network->ssid_len = min(info_element->len,
- (u8)IW_ESSID_MAX_SIZE);
- memcpy(network->ssid, info_element->data,
- network->ssid_len);
- if (network->ssid_len < IW_ESSID_MAX_SIZE)
- memset(network->ssid + network->ssid_len, 0,
- IW_ESSID_MAX_SIZE - network->ssid_len);
-
- netdev_dbg(ieee->dev, "MFIE_TYPE_SSID: '%s' len=%d.\n",
- network->ssid, network->ssid_len);
- break;
-
- case MFIE_TYPE_RATES:
- p = rates_str;
- network->rates_len = min(info_element->len,
- MAX_RATES_LENGTH);
- for (i = 0; i < network->rates_len; i++) {
- network->rates[i] = info_element->data[i];
- p += scnprintf(p, sizeof(rates_str) -
- (p - rates_str), "%02X ",
- network->rates[i]);
- if (rtllib_is_ofdm_rate
- (info_element->data[i])) {
- network->flags |= NETWORK_HAS_OFDM;
- if (info_element->data[i] &
- RTLLIB_BASIC_RATE_MASK)
- network->flags &=
- ~NETWORK_HAS_CCK;
- }
-
- if (rtllib_is_cck_rate
- (info_element->data[i])) {
- network->flags |= NETWORK_HAS_CCK;
- }
- }
-
- netdev_dbg(ieee->dev, "MFIE_TYPE_RATES: '%s' (%d)\n",
- rates_str, network->rates_len);
- break;
-
- case MFIE_TYPE_RATES_EX:
- p = rates_str;
- network->rates_ex_len = min(info_element->len,
- MAX_RATES_EX_LENGTH);
- for (i = 0; i < network->rates_ex_len; i++) {
- network->rates_ex[i] = info_element->data[i];
- p += scnprintf(p, sizeof(rates_str) -
- (p - rates_str), "%02X ",
- network->rates_ex[i]);
- if (rtllib_is_ofdm_rate
- (info_element->data[i])) {
- network->flags |= NETWORK_HAS_OFDM;
- if (info_element->data[i] &
- RTLLIB_BASIC_RATE_MASK)
- network->flags &=
- ~NETWORK_HAS_CCK;
- }
- }
-
- netdev_dbg(ieee->dev, "MFIE_TYPE_RATES_EX: '%s' (%d)\n",
- rates_str, network->rates_ex_len);
- break;
-
- case MFIE_TYPE_DS_SET:
- netdev_dbg(ieee->dev, "MFIE_TYPE_DS_SET: %d\n",
- info_element->data[0]);
- network->channel = info_element->data[0];
- break;
-
- case MFIE_TYPE_FH_SET:
- netdev_dbg(ieee->dev, "MFIE_TYPE_FH_SET: ignored\n");
- break;
-
- case MFIE_TYPE_CF_SET:
- netdev_dbg(ieee->dev, "MFIE_TYPE_CF_SET: ignored\n");
- break;
-
- case MFIE_TYPE_TIM:
- if (info_element->len < 4)
- break;
-
- network->tim.tim_count = info_element->data[0];
- network->tim.tim_period = info_element->data[1];
-
- network->dtim_period = info_element->data[1];
- if (ieee->link_state != MAC80211_LINKED)
- break;
- network->last_dtim_sta_time = jiffies;
-
- network->dtim_data = RTLLIB_DTIM_VALID;
-
- if (info_element->data[2] & 1)
- network->dtim_data |= RTLLIB_DTIM_MBCAST;
-
- offset = (info_element->data[2] >> 1) * 2;
-
- if (ieee->assoc_id < 8 * offset ||
- ieee->assoc_id > 8 * (offset + info_element->len - 3))
- break;
-
- offset = (ieee->assoc_id / 8) - offset;
- if (info_element->data[3 + offset] &
- (1 << (ieee->assoc_id % 8)))
- network->dtim_data |= RTLLIB_DTIM_UCAST;
-
- network->listen_interval = network->dtim_period;
- break;
-
- case MFIE_TYPE_ERP:
- network->erp_value = info_element->data[0];
- network->flags |= NETWORK_HAS_ERP_VALUE;
- netdev_dbg(ieee->dev, "MFIE_TYPE_ERP_SET: %d\n",
- network->erp_value);
- break;
- case MFIE_TYPE_IBSS_SET:
- network->atim_window = info_element->data[0];
- netdev_dbg(ieee->dev, "MFIE_TYPE_IBSS_SET: %d\n",
- network->atim_window);
- break;
-
- case MFIE_TYPE_CHALLENGE:
- netdev_dbg(ieee->dev, "MFIE_TYPE_CHALLENGE: ignored\n");
- break;
-
- case MFIE_TYPE_GENERIC:
- netdev_dbg(ieee->dev, "MFIE_TYPE_GENERIC: %d bytes\n",
- info_element->len);
-
- rtllib_parse_mife_generic(ieee, info_element, network,
- &tmp_htcap_len,
- &tmp_htinfo_len);
- break;
-
- case MFIE_TYPE_RSN:
- netdev_dbg(ieee->dev, "MFIE_TYPE_RSN: %d bytes\n",
- info_element->len);
- network->rsn_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
- memcpy(network->rsn_ie, info_element,
- network->rsn_ie_len);
- break;
-
- case MFIE_TYPE_HT_CAP:
- netdev_dbg(ieee->dev, "MFIE_TYPE_HT_CAP: %d bytes\n",
- info_element->len);
-
- rtllib_parse_mfie_ht_cap(info_element, network,
- &tmp_htcap_len);
- break;
-
- case MFIE_TYPE_HT_INFO:
- netdev_dbg(ieee->dev, "MFIE_TYPE_HT_INFO: %d bytes\n",
- info_element->len);
- tmp_htinfo_len = min_t(u8, info_element->len,
- MAX_IE_LEN);
- if (tmp_htinfo_len) {
- network->bssht.bd_ht_spec_ver = HT_SPEC_VER_IEEE;
- network->bssht.bd_ht_info_len = tmp_htinfo_len >
- sizeof(network->bssht.bd_ht_info_buf) ?
- sizeof(network->bssht.bd_ht_info_buf) :
- tmp_htinfo_len;
- memcpy(network->bssht.bd_ht_info_buf,
- info_element->data,
- network->bssht.bd_ht_info_len);
- }
- break;
-
- case MFIE_TYPE_AIRONET:
- netdev_dbg(ieee->dev, "MFIE_TYPE_AIRONET: %d bytes\n",
- info_element->len);
- if (info_element->len > IE_CISCO_FLAG_POSITION) {
- network->with_aironet_ie = true;
-
- if ((info_element->data[IE_CISCO_FLAG_POSITION]
- & SUPPORT_CKIP_MIC) ||
- (info_element->data[IE_CISCO_FLAG_POSITION]
- & SUPPORT_CKIP_PK))
- network->ckip_supported = true;
- else
- network->ckip_supported = false;
- } else {
- network->with_aironet_ie = false;
- network->ckip_supported = false;
- }
- break;
- case MFIE_TYPE_QOS_PARAMETER:
- netdev_err(ieee->dev,
- "QoS Error need to parse QOS_PARAMETER IE\n");
- break;
-
- case MFIE_TYPE_COUNTRY:
- netdev_dbg(ieee->dev, "MFIE_TYPE_COUNTRY: %d bytes\n",
- info_element->len);
- break;
-/* TODO */
- default:
- netdev_dbg(ieee->dev,
- "Unsupported info element: %s (%d)\n",
- get_info_element_string(info_element->id),
- info_element->id);
- break;
- }
-
- length -= sizeof(*info_element) + info_element->len;
- info_element =
- (struct rtllib_info_element *)&info_element->data[info_element->len];
- }
-
- if (!network->atheros_cap_exist && !network->broadcom_cap_exist &&
- !network->cisco_cap_exist && !network->ralink_cap_exist &&
- !network->bssht.bd_rt2rt_aggregation)
- network->unknown_cap_exist = true;
- else
- network->unknown_cap_exist = false;
- return 0;
-}
-
-static long rtllib_translate_todbm(u8 signal_strength_index)
-{
- long signal_power;
-
- signal_power = (long)((signal_strength_index + 1) >> 1);
- signal_power -= 95;
-
- return signal_power;
-}
-
-static inline int rtllib_network_init(
- struct rtllib_device *ieee,
- struct rtllib_probe_response *beacon,
- struct rtllib_network *network,
- struct rtllib_rx_stats *stats)
-{
- memset(&network->qos_data, 0, sizeof(struct rtllib_qos_data));
-
- /* Pull out fixed field data */
- ether_addr_copy(network->bssid, beacon->header.addr3);
- network->capability = le16_to_cpu(beacon->capability);
- network->last_scanned = jiffies;
- network->time_stamp[0] = beacon->time_stamp[0];
- network->time_stamp[1] = beacon->time_stamp[1];
- network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
- /* Where to pull this? beacon->listen_interval;*/
- network->listen_interval = 0x0A;
- network->rates_len = network->rates_ex_len = 0;
- network->ssid_len = 0;
- network->hidden_ssid_len = 0;
- memset(network->hidden_ssid, 0, sizeof(network->hidden_ssid));
- network->flags = 0;
- network->atim_window = 0;
- network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
- 0x3 : 0x0;
- network->berp_info_valid = false;
- network->broadcom_cap_exist = false;
- network->ralink_cap_exist = false;
- network->atheros_cap_exist = false;
- network->cisco_cap_exist = false;
- network->unknown_cap_exist = false;
- network->realtek_cap_exit = false;
- network->marvell_cap_exist = false;
- network->airgo_cap_exist = false;
- network->turbo_enable = 0;
- network->signal_strength = stats->signal_strength;
- network->RSSI = stats->signal_strength;
- network->country_ie_len = 0;
- memset(network->country_ie_buf, 0, MAX_IE_LEN);
- ht_initialize_bss_desc(&network->bssht);
- network->flags |= NETWORK_HAS_CCK;
-
- network->wpa_ie_len = 0;
- network->rsn_ie_len = 0;
- network->wzc_ie_len = 0;
-
- if (rtllib_parse_info_param(ieee,
- beacon->info_element,
- (stats->len - sizeof(*beacon)),
- network,
- stats))
- return 1;
-
- network->mode = 0;
-
- if (network->flags & NETWORK_HAS_OFDM)
- network->mode |= WIRELESS_MODE_G;
- if (network->flags & NETWORK_HAS_CCK)
- network->mode |= WIRELESS_MODE_B;
-
- if (network->mode == 0) {
- netdev_dbg(ieee->dev, "Filtered out '%s (%pM)' network.\n",
- escape_essid(network->ssid, network->ssid_len),
- network->bssid);
- return 1;
- }
-
- if (network->bssht.bd_support_ht) {
- if (network->mode & (WIRELESS_MODE_G | WIRELESS_MODE_B))
- network->mode = WIRELESS_MODE_N_24G;
- }
- if (rtllib_is_empty_essid(network->ssid, network->ssid_len))
- network->flags |= NETWORK_EMPTY_ESSID;
- stats->signal = 30 + (stats->signal_strength * 70) / 100;
- stats->noise = rtllib_translate_todbm((u8)(100 - stats->signal)) - 25;
-
- memcpy(&network->stats, stats, sizeof(network->stats));
-
- return 0;
-}
-
-static inline int is_same_network(struct rtllib_network *src,
- struct rtllib_network *dst, u8 ssidbroad)
-{
- /* A network is only a duplicate if the channel, BSSID, ESSID
- * and the capability field (in particular IBSS and BSS) all match.
- * We treat all <hidden> with the same BSSID and channel
- * as one network
- */
- return (((src->ssid_len == dst->ssid_len) || (!ssidbroad)) &&
- (src->channel == dst->channel) &&
- !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
- (!memcmp(src->ssid, dst->ssid, src->ssid_len) ||
- (!ssidbroad)) &&
- ((src->capability & WLAN_CAPABILITY_IBSS) ==
- (dst->capability & WLAN_CAPABILITY_IBSS)) &&
- ((src->capability & WLAN_CAPABILITY_ESS) ==
- (dst->capability & WLAN_CAPABILITY_ESS)));
-}
-
-static inline void update_network(struct rtllib_device *ieee,
- struct rtllib_network *dst,
- struct rtllib_network *src)
-{
- int qos_active;
- u8 old_param;
-
- memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats));
- dst->capability = src->capability;
- memcpy(dst->rates, src->rates, src->rates_len);
- dst->rates_len = src->rates_len;
- memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
- dst->rates_ex_len = src->rates_ex_len;
- if (src->ssid_len > 0) {
- if (dst->ssid_len == 0) {
- memset(dst->hidden_ssid, 0, sizeof(dst->hidden_ssid));
- dst->hidden_ssid_len = src->ssid_len;
- memcpy(dst->hidden_ssid, src->ssid, src->ssid_len);
- } else {
- memset(dst->ssid, 0, dst->ssid_len);
- dst->ssid_len = src->ssid_len;
- memcpy(dst->ssid, src->ssid, src->ssid_len);
- }
- }
- dst->mode = src->mode;
- dst->flags = src->flags;
- dst->time_stamp[0] = src->time_stamp[0];
- dst->time_stamp[1] = src->time_stamp[1];
- if (src->flags & NETWORK_HAS_ERP_VALUE) {
- dst->erp_value = src->erp_value;
- dst->berp_info_valid = src->berp_info_valid = true;
- }
- dst->beacon_interval = src->beacon_interval;
- dst->listen_interval = src->listen_interval;
- dst->atim_window = src->atim_window;
- dst->dtim_period = src->dtim_period;
- dst->dtim_data = src->dtim_data;
- dst->last_dtim_sta_time = src->last_dtim_sta_time;
- memcpy(&dst->tim, &src->tim, sizeof(struct rtllib_tim_parameters));
-
- dst->bssht.bd_support_ht = src->bssht.bd_support_ht;
- dst->bssht.bd_rt2rt_aggregation = src->bssht.bd_rt2rt_aggregation;
- dst->bssht.bd_ht_cap_len = src->bssht.bd_ht_cap_len;
- memcpy(dst->bssht.bd_ht_cap_buf, src->bssht.bd_ht_cap_buf,
- src->bssht.bd_ht_cap_len);
- dst->bssht.bd_ht_info_len = src->bssht.bd_ht_info_len;
- memcpy(dst->bssht.bd_ht_info_buf, src->bssht.bd_ht_info_buf,
- src->bssht.bd_ht_info_len);
- dst->bssht.bd_ht_spec_ver = src->bssht.bd_ht_spec_ver;
- dst->bssht.bd_rt2rt_long_slot_time = src->bssht.bd_rt2rt_long_slot_time;
- dst->broadcom_cap_exist = src->broadcom_cap_exist;
- dst->ralink_cap_exist = src->ralink_cap_exist;
- dst->atheros_cap_exist = src->atheros_cap_exist;
- dst->realtek_cap_exit = src->realtek_cap_exit;
- dst->marvell_cap_exist = src->marvell_cap_exist;
- dst->cisco_cap_exist = src->cisco_cap_exist;
- dst->airgo_cap_exist = src->airgo_cap_exist;
- dst->unknown_cap_exist = src->unknown_cap_exist;
- memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
- dst->wpa_ie_len = src->wpa_ie_len;
- memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
- dst->rsn_ie_len = src->rsn_ie_len;
- memcpy(dst->wzc_ie, src->wzc_ie, src->wzc_ie_len);
- dst->wzc_ie_len = src->wzc_ie_len;
-
- dst->last_scanned = jiffies;
- /* qos related parameters */
- qos_active = dst->qos_data.active;
- old_param = dst->qos_data.param_count;
- dst->qos_data.supported = src->qos_data.supported;
- if (dst->flags & NETWORK_HAS_QOS_PARAMETERS)
- memcpy(&dst->qos_data, &src->qos_data,
- sizeof(struct rtllib_qos_data));
- if (dst->qos_data.supported == 1) {
- if (dst->ssid_len)
- netdev_dbg(ieee->dev,
- "QoS the network %s is QoS supported\n",
- dst->ssid);
- else
- netdev_dbg(ieee->dev,
- "QoS the network is QoS supported\n");
- }
- dst->qos_data.active = qos_active;
- dst->qos_data.old_param_count = old_param;
-
- dst->wmm_info = src->wmm_info;
- if (src->wmm_param[0].ac_aci_acm_aifsn ||
- src->wmm_param[1].ac_aci_acm_aifsn ||
- src->wmm_param[2].ac_aci_acm_aifsn ||
- src->wmm_param[3].ac_aci_acm_aifsn)
- memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
-
- dst->signal_strength = src->signal_strength;
- dst->RSSI = src->RSSI;
- dst->turbo_enable = src->turbo_enable;
-
- dst->country_ie_len = src->country_ie_len;
- memcpy(dst->country_ie_buf, src->country_ie_buf, src->country_ie_len);
-
- dst->with_aironet_ie = src->with_aironet_ie;
- dst->ckip_supported = src->ckip_supported;
- memcpy(dst->ccx_rm_state, src->ccx_rm_state, 2);
- dst->ccx_rm_enable = src->ccx_rm_enable;
- dst->mb_ssid_mask = src->mb_ssid_mask;
- dst->mb_ssid_valid = src->mb_ssid_valid;
- memcpy(dst->mb_ssid, src->mb_ssid, 6);
- dst->with_ccx_ver_num = src->with_ccx_ver_num;
- dst->bss_ccx_ver_number = src->bss_ccx_ver_number;
-}
-
-static int is_passive_channel(struct rtllib_device *rtllib, u8 channel)
-{
- if (channel > MAX_CHANNEL_NUMBER) {
- netdev_info(rtllib->dev, "%s(): Invalid Channel\n", __func__);
- return 0;
- }
-
- if (rtllib->active_channel_map[channel] == 2)
- return 1;
-
- return 0;
-}
-
-int rtllib_legal_channel(struct rtllib_device *rtllib, u8 channel)
-{
- if (channel > MAX_CHANNEL_NUMBER) {
- netdev_info(rtllib->dev, "%s(): Invalid Channel\n", __func__);
- return 0;
- }
- if (rtllib->active_channel_map[channel] > 0)
- return 1;
-
- return 0;
-}
-EXPORT_SYMBOL(rtllib_legal_channel);
-
-static inline void rtllib_process_probe_response(
- struct rtllib_device *ieee,
- struct rtllib_probe_response *beacon,
- struct rtllib_rx_stats *stats)
-{
- struct rtllib_network *target;
- struct rtllib_network *oldest = NULL;
- struct rtllib_info_element *info_element = &beacon->info_element[0];
- unsigned long flags;
- short renew;
- struct rtllib_network *network = kzalloc(sizeof(struct rtllib_network),
- GFP_ATOMIC);
- __le16 frame_ctl = beacon->header.frame_control;
-
- if (!network)
- return;
-
- netdev_dbg(ieee->dev,
- "'%s' ( %pM ): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
- escape_essid(info_element->data, info_element->len),
- beacon->header.addr3,
- (le16_to_cpu(beacon->capability) & (1 << 0xf)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0xe)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0xd)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0xc)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0xb)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0xa)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0x9)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0x8)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0x7)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0x6)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0x5)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0x4)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0x3)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0x2)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0x1)) ? '1' : '0',
- (le16_to_cpu(beacon->capability) & (1 << 0x0)) ? '1' : '0');
-
- if (rtllib_network_init(ieee, beacon, network, stats)) {
- netdev_dbg(ieee->dev, "Dropped '%s' ( %pM) via %s.\n",
- escape_essid(info_element->data, info_element->len),
- beacon->header.addr3,
- ieee80211_is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE");
- goto free_network;
- }
-
- if (!rtllib_legal_channel(ieee, network->channel))
- goto free_network;
-
- if (ieee80211_is_probe_resp(frame_ctl)) {
- if (is_passive_channel(ieee, network->channel)) {
- netdev_info(ieee->dev,
- "GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n",
- network->channel);
- goto free_network;
- }
- }
-
- /* The network parsed correctly -- so now we scan our known networks
- * to see if we can find it in our list.
- *
- * NOTE: This search is definitely not optimized. Once its doing
- * the "right thing" we'll optimize it for efficiency if
- * necessary
- */
-
- /* Search for this entry in the list and update it if it is
- * already there.
- */
-
- spin_lock_irqsave(&ieee->lock, flags);
- if (is_same_network(&ieee->current_network, network,
- (network->ssid_len ? 1 : 0))) {
- update_network(ieee, &ieee->current_network, network);
- if ((ieee->current_network.mode == WIRELESS_MODE_N_24G ||
- ieee->current_network.mode == WIRELESS_MODE_G) &&
- ieee->current_network.berp_info_valid) {
- if (ieee->current_network.erp_value & ERP_UseProtection)
- ieee->current_network.buseprotection = true;
- else
- ieee->current_network.buseprotection = false;
- }
- if (ieee80211_is_beacon(frame_ctl)) {
- if (ieee->link_state >= MAC80211_LINKED)
- ieee->link_detect_info.num_recv_bcn_in_period++;
- }
- }
- list_for_each_entry(target, &ieee->network_list, list) {
- if (is_same_network(target, network,
- (target->ssid_len ? 1 : 0)))
- break;
- if (!oldest || (target->last_scanned < oldest->last_scanned))
- oldest = target;
- }
-
- /* If we didn't find a match, then get a new network slot to initialize
- * with this beacon's information
- */
- if (&target->list == &ieee->network_list) {
- if (list_empty(&ieee->network_free_list)) {
- /* If there are no more slots, expire the oldest */
- list_del(&oldest->list);
- target = oldest;
- netdev_dbg(ieee->dev,
- "Expired '%s' ( %pM) from network list.\n",
- escape_essid(target->ssid, target->ssid_len),
- target->bssid);
- } else {
- /* Otherwise just pull from the free list */
- target = list_entry(ieee->network_free_list.next,
- struct rtllib_network, list);
- list_del(ieee->network_free_list.next);
- }
-
- netdev_dbg(ieee->dev, "Adding '%s' ( %pM) via %s.\n",
- escape_essid(network->ssid, network->ssid_len),
- network->bssid,
- ieee80211_is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE");
-
- memcpy(target, network, sizeof(*target));
- list_add_tail(&target->list, &ieee->network_list);
- if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
- rtllib_softmac_new_net(ieee, network);
- } else {
- netdev_dbg(ieee->dev, "Updating '%s' ( %pM) via %s.\n",
- escape_essid(target->ssid, target->ssid_len),
- target->bssid,
- ieee80211_is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE");
-
- /* we have an entry and we are going to update it. But this
- * entry may be already expired. In this case we do the same
- * as we found a new net and call the new_net handler
- */
- renew = !time_after(target->last_scanned + ieee->scan_age,
- jiffies);
- if ((!target->ssid_len) &&
- (((network->ssid_len > 0) && (target->hidden_ssid_len == 0))
- || ((ieee->current_network.ssid_len == network->ssid_len) &&
- (strncmp(ieee->current_network.ssid, network->ssid,
- network->ssid_len) == 0) &&
- (ieee->link_state == MAC80211_NOLINK))))
- renew = 1;
- update_network(ieee, target, network);
- if (renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
- rtllib_softmac_new_net(ieee, network);
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
- if (ieee80211_is_beacon(frame_ctl) &&
- is_same_network(&ieee->current_network, network,
- (network->ssid_len ? 1 : 0)) &&
- (ieee->link_state == MAC80211_LINKED)) {
- ieee->handle_beacon(ieee->dev, beacon, &ieee->current_network);
- }
-free_network:
- kfree(network);
-}
-
-static void rtllib_rx_mgt(struct rtllib_device *ieee,
- struct sk_buff *skb,
- struct rtllib_rx_stats *stats)
-{
- struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data;
-
- if (!ieee80211_is_probe_resp(header->frame_control) &&
- (!ieee80211_is_beacon(header->frame_control)))
- ieee->last_rx_ps_time = jiffies;
-
- if (ieee80211_is_beacon(header->frame_control)) {
- netdev_dbg(ieee->dev, "received BEACON\n");
- rtllib_process_probe_response(
- ieee, (struct rtllib_probe_response *)header,
- stats);
-
- if (ieee->sta_sleep || (ieee->ps != RTLLIB_PS_DISABLED &&
- ieee->iw_mode == IW_MODE_INFRA &&
- ieee->link_state == MAC80211_LINKED))
- schedule_work(&ieee->ps_task);
- } else if (ieee80211_is_probe_resp(header->frame_control)) {
- netdev_dbg(ieee->dev, "received PROBE RESPONSE\n");
- rtllib_process_probe_response(ieee, (struct rtllib_probe_response *)header,
- stats);
- }
-}
diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c
deleted file mode 100644
index 0fc97c868f81..000000000000
--- a/drivers/staging/rtl8192e/rtllib_softmac.c
+++ /dev/null
@@ -1,2309 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* IEEE 802.11 SoftMAC layer
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * Mostly extracted from the rtl8180-sa2400 driver for the
- * in-kernel generic ieee802.11 stack.
- *
- * Few lines might be stolen from other part of the rtllib
- * stack. Copyright who own it's copyright
- *
- * WPA code stolen from the ipw2200 driver.
- * Copyright who own it's copyright.
- */
-#include "rtllib.h"
-
-#include <linux/random.h>
-#include <linux/delay.h>
-#include <linux/uaccess.h>
-#include <linux/etherdevice.h>
-#include <linux/ieee80211.h>
-
-static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl);
-
-static short rtllib_is_54g(struct rtllib_network *net)
-{
- return (net->rates_ex_len > 0) || (net->rates_len > 4);
-}
-
-/* returns the total length needed for placing the RATE MFIE
- * tag and the EXTENDED RATE MFIE tag if needed.
- * It encludes two bytes per tag for the tag itself and its len
- */
-static unsigned int rtllib_MFIE_rate_len(struct rtllib_device *ieee)
-{
- unsigned int rate_len = 0;
-
- rate_len = RTLLIB_CCK_RATE_LEN + 2;
- rate_len += RTLLIB_OFDM_RATE_LEN + 2;
-
- return rate_len;
-}
-
-/* place the MFIE rate, tag to the memory (double) pointed.
- * Then it updates the pointer so that
- * it points after the new MFIE tag added.
- */
-static void rtllib_mfie_brate(struct rtllib_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- *tag++ = MFIE_TYPE_RATES;
- *tag++ = 4;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB;
-
- /* We may add an option for custom rates that specific HW
- * might support
- */
- *tag_p = tag;
-}
-
-static void rtllib_mfie_grate(struct rtllib_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- *tag++ = MFIE_TYPE_RATES_EX;
- *tag++ = 8;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_6MB;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_9MB;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_12MB;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_18MB;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_24MB;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_36MB;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_48MB;
- *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_54MB;
-
- /* We may add an option for custom rates that specific HW might
- * support
- */
- *tag_p = tag;
-}
-
-static void rtllib_wmm_info(struct rtllib_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- *tag++ = MFIE_TYPE_GENERIC;
- *tag++ = 7;
- *tag++ = 0x00;
- *tag++ = 0x50;
- *tag++ = 0xf2;
- *tag++ = 0x02;
- *tag++ = 0x00;
- *tag++ = 0x01;
- *tag++ = MAX_SP_Len;
- *tag_p = tag;
-}
-
-static void rtllib_turbo_info(struct rtllib_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- *tag++ = MFIE_TYPE_GENERIC;
- *tag++ = 7;
- *tag++ = 0x00;
- *tag++ = 0xe0;
- *tag++ = 0x4c;
- *tag++ = 0x01;
- *tag++ = 0x02;
- *tag++ = 0x11;
- *tag++ = 0x00;
-
- *tag_p = tag;
- netdev_alert(ieee->dev, "This is enable turbo mode IE process\n");
-}
-
-static void enqueue_mgmt(struct rtllib_device *ieee, struct sk_buff *skb)
-{
- int nh;
-
- nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM;
-
-/* if the queue is full but we have newer frames then
- * just overwrites the oldest.
- *
- * if (nh == ieee->mgmt_queue_tail)
- * return -1;
- */
- ieee->mgmt_queue_head = nh;
- ieee->mgmt_queue_ring[nh] = skb;
-}
-
-static void init_mgmt_queue(struct rtllib_device *ieee)
-{
- ieee->mgmt_queue_tail = 0;
- ieee->mgmt_queue_head = 0;
-}
-
-u8 mgnt_query_tx_rate_exclude_cck_rates(struct rtllib_device *ieee)
-{
- u16 i;
- u8 query_rate = 0;
- u8 basic_rate;
-
- for (i = 0; i < ieee->current_network.rates_len; i++) {
- basic_rate = ieee->current_network.rates[i] & 0x7F;
- if (!rtllib_is_cck_rate(basic_rate)) {
- if (query_rate == 0) {
- query_rate = basic_rate;
- } else {
- if (basic_rate < query_rate)
- query_rate = basic_rate;
- }
- }
- }
-
- if (query_rate == 0) {
- query_rate = 12;
- netdev_info(ieee->dev, "No basic_rate found!!\n");
- }
- return query_rate;
-}
-
-static u8 mgnt_query_mgnt_frame_tx_rate(struct rtllib_device *ieee)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
- u8 rate;
-
- if (ht_info->iot_action & HT_IOT_ACT_MGNT_USE_CCK_6M)
- rate = 0x0c;
- else
- rate = ieee->basic_rate & 0x7f;
-
- if (rate == 0)
- rate = 0x02;
-
- return rate;
-}
-
-inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
-{
- unsigned long flags;
- short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
- struct ieee80211_hdr_3addr *header =
- (struct ieee80211_hdr_3addr *)skb->data;
-
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /* called with 2nd param 0, no mgmt lock required */
- rtllib_sta_wakeup(ieee, 0);
-
- if (ieee80211_is_beacon(header->frame_control))
- tcb_desc->queue_index = BEACON_QUEUE;
- else
- tcb_desc->queue_index = MGNT_QUEUE;
-
- if (ieee->disable_mgnt_queue)
- tcb_desc->queue_index = HIGH_QUEUE;
-
- tcb_desc->data_rate = mgnt_query_mgnt_frame_tx_rate(ieee);
- tcb_desc->ratr_index = 7;
- tcb_desc->tx_dis_rate_fallback = 1;
- tcb_desc->tx_use_drv_assinged_rate = 1;
- if (single) {
- if (ieee->queue_stop) {
- enqueue_mgmt(ieee, skb);
- } else {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* avoid watchdog triggers */
- ieee->softmac_data_hard_start_xmit(skb, ieee->dev,
- ieee->basic_rate);
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
- } else {
- spin_unlock_irqrestore(&ieee->lock, flags);
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
-
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* check whether the managed packet queued greater than 5 */
- if (!ieee->check_nic_enough_desc(ieee->dev,
- tcb_desc->queue_index) ||
- skb_queue_len(&ieee->skb_waitq[tcb_desc->queue_index]) ||
- ieee->queue_stop) {
- /* insert the skb packet to the management queue
- *
- * as for the completion function, it does not need
- * to check it any more.
- */
- netdev_info(ieee->dev,
- "%s():insert to waitqueue, queue_index:%d!\n",
- __func__, tcb_desc->queue_index);
- skb_queue_tail(&ieee->skb_waitq[tcb_desc->queue_index],
- skb);
- } else {
- ieee->softmac_hard_start_xmit(skb, ieee->dev);
- }
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
- }
-}
-
-static inline void
-softmac_ps_mgmt_xmit(struct sk_buff *skb,
- struct rtllib_device *ieee)
-{
- short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
- struct ieee80211_hdr_3addr *header =
- (struct ieee80211_hdr_3addr *)skb->data;
- u16 fc, type, stype;
- struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
-
- fc = le16_to_cpu(header->frame_control);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
-
- if (stype != IEEE80211_STYPE_PSPOLL)
- tcb_desc->queue_index = MGNT_QUEUE;
- else
- tcb_desc->queue_index = HIGH_QUEUE;
-
- if (ieee->disable_mgnt_queue)
- tcb_desc->queue_index = HIGH_QUEUE;
-
- tcb_desc->data_rate = mgnt_query_mgnt_frame_tx_rate(ieee);
- tcb_desc->ratr_index = 7;
- tcb_desc->tx_dis_rate_fallback = 1;
- tcb_desc->tx_use_drv_assinged_rate = 1;
- if (single) {
- if (type != RTLLIB_FTYPE_CTL) {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
- }
- /* avoid watchdog triggers */
- ieee->softmac_data_hard_start_xmit(skb, ieee->dev,
- ieee->basic_rate);
-
- } else {
- if (type != RTLLIB_FTYPE_CTL) {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
- }
- ieee->softmac_hard_start_xmit(skb, ieee->dev);
- }
-}
-
-static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee)
-{
- unsigned int len, rate_len;
- u8 *tag;
- struct sk_buff *skb;
- struct rtllib_probe_request *req;
-
- len = ieee->current_network.ssid_len;
-
- rate_len = rtllib_MFIE_rate_len(ieee);
-
- skb = dev_alloc_skb(sizeof(struct rtllib_probe_request) +
- 2 + len + rate_len + ieee->tx_headroom);
-
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- req = skb_put(skb, sizeof(struct rtllib_probe_request));
- req->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- req->header.duration_id = 0;
-
- eth_broadcast_addr(req->header.addr1);
- ether_addr_copy(req->header.addr2, ieee->dev->dev_addr);
- eth_broadcast_addr(req->header.addr3);
-
- tag = skb_put(skb, len + 2 + rate_len);
-
- *tag++ = MFIE_TYPE_SSID;
- *tag++ = len;
- memcpy(tag, ieee->current_network.ssid, len);
- tag += len;
-
- rtllib_mfie_brate(ieee, &tag);
- rtllib_mfie_grate(ieee, &tag);
-
- return skb;
-}
-
-/* Enables network monitor mode, all rx packets will be received. */
-void rtllib_enable_net_monitor_mode(struct net_device *dev,
- bool init_state)
-{
- struct rtllib_device *ieee = netdev_priv_rsl(dev);
-
- netdev_info(dev, "========>Enter Monitor Mode\n");
-
- ieee->allow_all_dest_addr_handler(dev, true, !init_state);
-}
-
-/* Disables network monitor mode. Only packets destinated to
- * us will be received.
- */
-void rtllib_disable_net_monitor_mode(struct net_device *dev, bool init_state)
-{
- struct rtllib_device *ieee = netdev_priv_rsl(dev);
-
- netdev_info(dev, "========>Exit Monitor Mode\n");
-
- ieee->allow_all_dest_addr_handler(dev, false, !init_state);
-}
-
-static void rtllib_send_probe(struct rtllib_device *ieee)
-{
- struct sk_buff *skb;
-
- skb = rtllib_probe_req(ieee);
- if (skb) {
- softmac_mgmt_xmit(skb, ieee);
- ieee->softmac_stats.tx_probe_rq++;
- }
-}
-
-static void rtllib_send_probe_requests(struct rtllib_device *ieee)
-{
- if (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ) {
- rtllib_send_probe(ieee);
- rtllib_send_probe(ieee);
- }
-}
-
-/* this performs syncro scan blocking the caller until all channels
- * in the allowed channel map has been checked.
- */
-static void rtllib_softmac_scan_syncro(struct rtllib_device *ieee)
-{
- union iwreq_data wrqu;
- short ch = 0;
-
- ieee->be_scan_inprogress = true;
-
- mutex_lock(&ieee->scan_mutex);
-
- while (1) {
- do {
- ch++;
- if (ch > MAX_CHANNEL_NUMBER)
- goto out; /* scan completed */
- } while (!ieee->active_channel_map[ch]);
-
- /* this function can be called in two situations
- * 1- We have switched to ad-hoc mode and we are
- * performing a complete syncro scan before conclude
- * there are no interesting cell and to create a
- * new one. In this case the link state is
- * MAC80211_NOLINK until we found an interesting cell.
- * If so the ieee8021_new_net, called by the RX path
- * will set the state to MAC80211_LINKED, so we stop
- * scanning
- * 2- We are linked and the root uses run iwlist scan.
- * So we switch to MAC80211_LINKED_SCANNING to remember
- * that we are still logically linked (not interested in
- * new network events, despite for updating the net list,
- * but we are temporarily 'unlinked' as the driver shall
- * not filter RX frames and the channel is changing.
- * So the only situation in which are interested is to check
- * if the state become LINKED because of the #1 situation
- */
-
- if (ieee->link_state == MAC80211_LINKED)
- goto out;
- if (ieee->sync_scan_hurryup) {
- netdev_info(ieee->dev,
- "============>sync_scan_hurryup out\n");
- goto out;
- }
-
- ieee->set_chan(ieee->dev, ch);
- if (ieee->active_channel_map[ch] == 1)
- rtllib_send_probe_requests(ieee);
-
- /* this prevent excessive time wait when we
- * need to wait for a syncro scan to end..
- */
- msleep_interruptible_rsl(RTLLIB_SOFTMAC_SCAN_TIME);
- }
-out:
- ieee->actscanning = false;
- ieee->sync_scan_hurryup = 0;
-
- mutex_unlock(&ieee->scan_mutex);
-
- ieee->be_scan_inprogress = false;
-
- memset(&wrqu, 0, sizeof(wrqu));
- wireless_send_event(ieee->dev, SIOCGIWSCAN, &wrqu, NULL);
-}
-
-static void rtllib_softmac_scan_wq(void *data)
-{
- struct rtllib_device *ieee = container_of_dwork_rsl(data,
- struct rtllib_device, softmac_scan_wq);
- u8 last_channel = ieee->current_network.channel;
-
- if (!ieee->ieee_up)
- return;
- if (rtllib_act_scanning(ieee, true))
- return;
-
- mutex_lock(&ieee->scan_mutex);
-
- if (ieee->rf_power_state == rf_off) {
- netdev_info(ieee->dev,
- "======>%s():rf state is rf_off, return\n",
- __func__);
- goto out1;
- }
-
- do {
- ieee->current_network.channel =
- (ieee->current_network.channel + 1) %
- MAX_CHANNEL_NUMBER;
- if (ieee->scan_watch_dog++ > MAX_CHANNEL_NUMBER) {
- if (!ieee->active_channel_map[ieee->current_network.channel])
- ieee->current_network.channel = 6;
- goto out; /* no good chans */
- }
- } while (!ieee->active_channel_map[ieee->current_network.channel]);
-
- if (ieee->scanning_continue == 0)
- goto out;
-
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- if (ieee->active_channel_map[ieee->current_network.channel] == 1)
- rtllib_send_probe_requests(ieee);
-
- schedule_delayed_work(&ieee->softmac_scan_wq,
- msecs_to_jiffies(RTLLIB_SOFTMAC_SCAN_TIME));
-
- mutex_unlock(&ieee->scan_mutex);
- return;
-
-out:
- ieee->current_network.channel = last_channel;
-
-out1:
- ieee->actscanning = false;
- ieee->scan_watch_dog = 0;
- ieee->scanning_continue = 0;
- mutex_unlock(&ieee->scan_mutex);
-}
-
-static void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
-{
- mutex_lock(&ieee->scan_mutex);
- ieee->scan_watch_dog = 0;
- if (ieee->scanning_continue == 1) {
- ieee->scanning_continue = 0;
- ieee->actscanning = false;
- mutex_unlock(&ieee->scan_mutex);
- cancel_delayed_work_sync(&ieee->softmac_scan_wq);
- } else {
- mutex_unlock(&ieee->scan_mutex);
- }
-}
-
-void rtllib_stop_scan(struct rtllib_device *ieee)
-{
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- rtllib_softmac_stop_scan(ieee);
-}
-EXPORT_SYMBOL(rtllib_stop_scan);
-
-void rtllib_stop_scan_syncro(struct rtllib_device *ieee)
-{
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- ieee->sync_scan_hurryup = 1;
-}
-EXPORT_SYMBOL(rtllib_stop_scan_syncro);
-
-bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan)
-{
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
- if (sync_scan)
- return ieee->be_scan_inprogress;
- else
- return ieee->actscanning || ieee->be_scan_inprogress;
- } else {
- return test_bit(STATUS_SCANNING, &ieee->status);
- }
-}
-EXPORT_SYMBOL(rtllib_act_scanning);
-
-/* called with ieee->lock held */
-static void rtllib_start_scan(struct rtllib_device *ieee)
-{
- ieee->rtllib_ips_leave_wq(ieee->dev);
-
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
- if (ieee->scanning_continue == 0) {
- ieee->actscanning = true;
- ieee->scanning_continue = 1;
- schedule_delayed_work(&ieee->softmac_scan_wq, 0);
- }
- }
-}
-
-/* called with wx_mutex held */
-void rtllib_start_scan_syncro(struct rtllib_device *ieee)
-{
- ieee->sync_scan_hurryup = 0;
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- rtllib_softmac_scan_syncro(ieee);
-}
-EXPORT_SYMBOL(rtllib_start_scan_syncro);
-
-static inline struct sk_buff *
-rtllib_authentication_req(struct rtllib_network *beacon,
- struct rtllib_device *ieee,
- int challengelen, u8 *daddr)
-{
- struct sk_buff *skb;
- struct rtllib_authentication *auth;
- int len;
-
- len = sizeof(struct rtllib_authentication) + challengelen +
- ieee->tx_headroom + 4;
- skb = dev_alloc_skb(len);
-
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- auth = skb_put(skb, sizeof(struct rtllib_authentication));
-
- auth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_AUTH);
- if (challengelen)
- auth->header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-
- auth->header.duration_id = cpu_to_le16(0x013a);
- ether_addr_copy(auth->header.addr1, beacon->bssid);
- ether_addr_copy(auth->header.addr2, ieee->dev->dev_addr);
- ether_addr_copy(auth->header.addr3, beacon->bssid);
- if (ieee->auth_mode == 0)
- auth->algorithm = WLAN_AUTH_OPEN;
- else if (ieee->auth_mode == 1)
- auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY);
- else if (ieee->auth_mode == 2)
- auth->algorithm = WLAN_AUTH_OPEN;
- auth->transaction = cpu_to_le16(ieee->associate_seq);
- ieee->associate_seq++;
-
- auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
-
- return skb;
-}
-
-static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr)
-{
- struct sk_buff *skb;
- struct ieee80211_hdr_3addr *hdr;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr) + ieee->tx_headroom);
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- hdr = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
-
- ether_addr_copy(hdr->addr1, ieee->current_network.bssid);
- ether_addr_copy(hdr->addr2, ieee->dev->dev_addr);
- ether_addr_copy(hdr->addr3, ieee->current_network.bssid);
-
- hdr->frame_control = cpu_to_le16(RTLLIB_FTYPE_DATA |
- IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
- (pwr ? IEEE80211_FCTL_PM : 0));
-
- return skb;
-}
-
-static struct sk_buff *rtllib_pspoll_func(struct rtllib_device *ieee)
-{
- struct sk_buff *skb;
- struct ieee80211_pspoll *hdr;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll) + ieee->tx_headroom);
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- hdr = skb_put(skb, sizeof(struct ieee80211_pspoll));
-
- ether_addr_copy(hdr->bssid, ieee->current_network.bssid);
- ether_addr_copy(hdr->ta, ieee->dev->dev_addr);
-
- hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
- hdr->frame_control = cpu_to_le16(RTLLIB_FTYPE_CTL | IEEE80211_STYPE_PSPOLL |
- IEEE80211_FCTL_PM);
-
- return skb;
-}
-
-static inline int sec_is_in_pmkid_list(struct rtllib_device *ieee, u8 *bssid)
-{
- int i = 0;
-
- do {
- if ((ieee->pmkid_list[i].used) &&
- (memcmp(ieee->pmkid_list[i].bssid, bssid, ETH_ALEN) == 0))
- break;
- i++;
- } while (i < NUM_PMKID_CACHE);
-
- if (i == NUM_PMKID_CACHE)
- i = -1;
- return i;
-}
-
-static inline struct sk_buff *
-rtllib_association_req(struct rtllib_network *beacon,
- struct rtllib_device *ieee)
-{
- struct sk_buff *skb;
- struct rtllib_assoc_request_frame *hdr;
- u8 *tag, *ies;
- int i;
- u8 *ht_cap_buf = NULL;
- u8 ht_cap_len = 0;
- u8 *realtek_ie_buf = NULL;
- u8 realtek_ie_len = 0;
- int wpa_ie_len = ieee->wpa_ie_len;
- int wps_ie_len = ieee->wps_ie_len;
- unsigned int ckip_ie_len = 0;
- unsigned int ccxrm_ie_len = 0;
- unsigned int cxvernum_ie_len = 0;
- struct lib80211_crypt_data *crypt;
- int encrypt;
- int pmk_cache_idx;
-
- unsigned int rate_len = (beacon->rates_len ?
- (beacon->rates_len + 2) : 0) +
- (beacon->rates_ex_len ? (beacon->rates_ex_len) +
- 2 : 0);
-
- unsigned int wmm_info_len = beacon->qos_data.supported ? 9 : 0;
- unsigned int turbo_info_len = beacon->turbo_enable ? 9 : 0;
-
- int len = 0;
-
- crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
- if (crypt)
- encrypt = crypt && crypt->ops &&
- ((strcmp(crypt->ops->name, "R-WEP") == 0 ||
- wpa_ie_len));
- else
- encrypt = 0;
-
- if ((ieee->rtllib_ap_sec_type &&
- (ieee->rtllib_ap_sec_type(ieee) & SEC_ALG_TKIP)) ||
- ieee->forced_bg_mode) {
- ieee->ht_info->enable_ht = 0;
- ieee->mode = WIRELESS_MODE_G;
- }
-
- if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) {
- ht_cap_buf = (u8 *)&ieee->ht_info->self_ht_cap;
- ht_cap_len = sizeof(ieee->ht_info->self_ht_cap);
- ht_construct_capability_element(ieee, ht_cap_buf, &ht_cap_len,
- encrypt, true);
- if (ieee->ht_info->current_rt2rt_aggregation) {
- realtek_ie_buf = ieee->ht_info->sz_rt2rt_agg_buf;
- realtek_ie_len =
- sizeof(ieee->ht_info->sz_rt2rt_agg_buf);
- ht_construct_rt2rt_agg_element(ieee, realtek_ie_buf,
- &realtek_ie_len);
- }
- }
-
- if (beacon->ckip_supported)
- ckip_ie_len = 30 + 2;
- if (beacon->ccx_rm_enable)
- ccxrm_ie_len = 6 + 2;
- if (beacon->bss_ccx_ver_number >= 2)
- cxvernum_ie_len = 5 + 2;
-
- pmk_cache_idx = sec_is_in_pmkid_list(ieee, ieee->current_network.bssid);
- if (pmk_cache_idx >= 0) {
- wpa_ie_len += 18;
- netdev_info(ieee->dev, "[PMK cache]: WPA2 IE length: %x\n",
- wpa_ie_len);
- }
- len = sizeof(struct rtllib_assoc_request_frame) + 2
- + beacon->ssid_len
- + rate_len
- + wpa_ie_len
- + wps_ie_len
- + wmm_info_len
- + turbo_info_len
- + ht_cap_len
- + realtek_ie_len
- + ckip_ie_len
- + ccxrm_ie_len
- + cxvernum_ie_len
- + ieee->tx_headroom;
-
- skb = dev_alloc_skb(len);
-
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- hdr = skb_put(skb, sizeof(struct rtllib_assoc_request_frame) + 2);
-
- hdr->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ);
- hdr->header.duration_id = cpu_to_le16(37);
- ether_addr_copy(hdr->header.addr1, beacon->bssid);
- ether_addr_copy(hdr->header.addr2, ieee->dev->dev_addr);
- ether_addr_copy(hdr->header.addr3, beacon->bssid);
-
- ether_addr_copy(ieee->ap_mac_addr, beacon->bssid);
-
- hdr->capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
- if (beacon->capability & WLAN_CAPABILITY_PRIVACY)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
- if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
-
- if (beacon->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
-
- hdr->listen_interval = cpu_to_le16(beacon->listen_interval);
-
- hdr->info_element[0].id = MFIE_TYPE_SSID;
-
- hdr->info_element[0].len = beacon->ssid_len;
- skb_put_data(skb, beacon->ssid, beacon->ssid_len);
-
- tag = skb_put(skb, rate_len);
-
- if (beacon->rates_len) {
- *tag++ = MFIE_TYPE_RATES;
- *tag++ = beacon->rates_len;
- for (i = 0; i < beacon->rates_len; i++)
- *tag++ = beacon->rates[i];
- }
-
- if (beacon->rates_ex_len) {
- *tag++ = MFIE_TYPE_RATES_EX;
- *tag++ = beacon->rates_ex_len;
- for (i = 0; i < beacon->rates_ex_len; i++)
- *tag++ = beacon->rates_ex[i];
- }
-
- if (beacon->ckip_supported) {
- static const u8 aironet_ie_oui[] = {0x00, 0x01, 0x66};
- u8 ccx_aironet_buf[30];
- struct octet_string os_ccx_aironet_ie;
-
- memset(ccx_aironet_buf, 0, 30);
- os_ccx_aironet_ie.octet = ccx_aironet_buf;
- os_ccx_aironet_ie.Length = sizeof(ccx_aironet_buf);
- memcpy(os_ccx_aironet_ie.octet, aironet_ie_oui,
- sizeof(aironet_ie_oui));
-
- os_ccx_aironet_ie.octet[IE_CISCO_FLAG_POSITION] |=
- (SUPPORT_CKIP_PK | SUPPORT_CKIP_MIC);
- tag = skb_put(skb, ckip_ie_len);
- *tag++ = MFIE_TYPE_AIRONET;
- *tag++ = os_ccx_aironet_ie.Length;
- memcpy(tag, os_ccx_aironet_ie.octet, os_ccx_aironet_ie.Length);
- tag += os_ccx_aironet_ie.Length;
- }
-
- if (beacon->ccx_rm_enable) {
- static const u8 ccx_rm_cap_buf[] = {0x00, 0x40, 0x96, 0x01, 0x01,
- 0x00};
- struct octet_string os_ccx_rm_cap;
-
- os_ccx_rm_cap.octet = (u8 *)ccx_rm_cap_buf;
- os_ccx_rm_cap.Length = sizeof(ccx_rm_cap_buf);
- tag = skb_put(skb, ccxrm_ie_len);
- *tag++ = MFIE_TYPE_GENERIC;
- *tag++ = os_ccx_rm_cap.Length;
- memcpy(tag, os_ccx_rm_cap.octet, os_ccx_rm_cap.Length);
- tag += os_ccx_rm_cap.Length;
- }
-
- if (beacon->bss_ccx_ver_number >= 2) {
- u8 ccx_ver_num_buf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
- struct octet_string os_ccx_ver_num;
-
- ccx_ver_num_buf[4] = beacon->bss_ccx_ver_number;
- os_ccx_ver_num.octet = ccx_ver_num_buf;
- os_ccx_ver_num.Length = sizeof(ccx_ver_num_buf);
- tag = skb_put(skb, cxvernum_ie_len);
- *tag++ = MFIE_TYPE_GENERIC;
- *tag++ = os_ccx_ver_num.Length;
- memcpy(tag, os_ccx_ver_num.octet, os_ccx_ver_num.Length);
- tag += os_ccx_ver_num.Length;
- }
- if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) {
- if (ieee->ht_info->peer_ht_spec_ver != HT_SPEC_VER_EWC) {
- tag = skb_put(skb, ht_cap_len);
- *tag++ = MFIE_TYPE_HT_CAP;
- *tag++ = ht_cap_len - 2;
- memcpy(tag, ht_cap_buf, ht_cap_len - 2);
- tag += ht_cap_len - 2;
- }
- }
-
- if (wpa_ie_len) {
- skb_put_data(skb, ieee->wpa_ie, ieee->wpa_ie_len);
-
- if (pmk_cache_idx >= 0) {
- tag = skb_put(skb, 18);
- *tag = 1;
- *(tag + 1) = 0;
- memcpy((tag + 2), &ieee->pmkid_list[pmk_cache_idx].PMKID,
- 16);
- }
- }
- if (wmm_info_len) {
- tag = skb_put(skb, wmm_info_len);
- rtllib_wmm_info(ieee, &tag);
- }
-
- if (wps_ie_len && ieee->wps_ie)
- skb_put_data(skb, ieee->wps_ie, wps_ie_len);
-
- if (turbo_info_len) {
- tag = skb_put(skb, turbo_info_len);
- rtllib_turbo_info(ieee, &tag);
- }
-
- if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) {
- if (ieee->ht_info->peer_ht_spec_ver == HT_SPEC_VER_EWC) {
- tag = skb_put(skb, ht_cap_len);
- *tag++ = MFIE_TYPE_GENERIC;
- *tag++ = ht_cap_len - 2;
- memcpy(tag, ht_cap_buf, ht_cap_len - 2);
- tag += ht_cap_len - 2;
- }
-
- if (ieee->ht_info->current_rt2rt_aggregation) {
- tag = skb_put(skb, realtek_ie_len);
- *tag++ = MFIE_TYPE_GENERIC;
- *tag++ = realtek_ie_len - 2;
- memcpy(tag, realtek_ie_buf, realtek_ie_len - 2);
- }
- }
-
- kfree(ieee->assocreq_ies);
- ieee->assocreq_ies = NULL;
- ies = &hdr->info_element[0].id;
- ieee->assocreq_ies_len = (skb->data + skb->len) - ies;
- ieee->assocreq_ies = kmemdup(ies, ieee->assocreq_ies_len, GFP_ATOMIC);
- if (!ieee->assocreq_ies)
- ieee->assocreq_ies_len = 0;
-
- return skb;
-}
-
-static void rtllib_associate_abort(struct rtllib_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- ieee->associate_seq++;
-
- /* don't scan, and avoid to have the RX path possibly
- * try again to associate. Even do not react to AUTH or
- * ASSOC response. Just wait for the retry wq to be scheduled.
- * Here we will check if there are good nets to associate
- * with, so we retry or just get back to NO_LINK and scanning
- */
- if (ieee->link_state == RTLLIB_ASSOCIATING_AUTHENTICATING) {
- netdev_dbg(ieee->dev, "Authentication failed\n");
- ieee->softmac_stats.no_auth_rs++;
- } else {
- netdev_dbg(ieee->dev, "Association failed\n");
- ieee->softmac_stats.no_ass_rs++;
- }
-
- ieee->link_state = RTLLIB_ASSOCIATING_RETRY;
-
- schedule_delayed_work(&ieee->associate_retry_wq,
- RTLLIB_SOFTMAC_ASSOC_RETRY_TIME);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-static void rtllib_associate_abort_cb(struct timer_list *t)
-{
- struct rtllib_device *dev = from_timer(dev, t, associate_timer);
-
- rtllib_associate_abort(dev);
-}
-
-static void rtllib_associate_step1(struct rtllib_device *ieee, u8 *daddr)
-{
- struct rtllib_network *beacon = &ieee->current_network;
- struct sk_buff *skb;
-
- netdev_dbg(ieee->dev, "Stopping scan\n");
-
- ieee->softmac_stats.tx_auth_rq++;
-
- skb = rtllib_authentication_req(beacon, ieee, 0, daddr);
-
- if (!skb) {
- rtllib_associate_abort(ieee);
- } else {
- ieee->link_state = RTLLIB_ASSOCIATING_AUTHENTICATING;
- netdev_dbg(ieee->dev, "Sending authentication request\n");
- softmac_mgmt_xmit(skb, ieee);
- if (!timer_pending(&ieee->associate_timer)) {
- ieee->associate_timer.expires = jiffies + (HZ / 2);
- add_timer(&ieee->associate_timer);
- }
- }
-}
-
-static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge,
- int chlen)
-{
- u8 *c;
- struct sk_buff *skb;
- struct rtllib_network *beacon = &ieee->current_network;
-
- ieee->associate_seq++;
- ieee->softmac_stats.tx_auth_rq++;
-
- skb = rtllib_authentication_req(beacon, ieee, chlen + 2, beacon->bssid);
-
- if (!skb) {
- rtllib_associate_abort(ieee);
- } else {
- c = skb_put(skb, chlen + 2);
- *(c++) = MFIE_TYPE_CHALLENGE;
- *(c++) = chlen;
- memcpy(c, challenge, chlen);
-
- netdev_dbg(ieee->dev,
- "Sending authentication challenge response\n");
-
- rtllib_encrypt_fragment(ieee, skb,
- sizeof(struct ieee80211_hdr_3addr));
-
- softmac_mgmt_xmit(skb, ieee);
- mod_timer(&ieee->associate_timer, jiffies + (HZ / 2));
- }
- kfree(challenge);
-}
-
-static void rtllib_associate_step2(struct rtllib_device *ieee)
-{
- struct sk_buff *skb;
- struct rtllib_network *beacon = &ieee->current_network;
-
- del_timer_sync(&ieee->associate_timer);
-
- netdev_dbg(ieee->dev, "Sending association request\n");
-
- ieee->softmac_stats.tx_ass_rq++;
- skb = rtllib_association_req(beacon, ieee);
- if (!skb) {
- rtllib_associate_abort(ieee);
- } else {
- softmac_mgmt_xmit(skb, ieee);
- mod_timer(&ieee->associate_timer, jiffies + (HZ / 2));
- }
-}
-
-static void rtllib_associate_complete_wq(void *data)
-{
- struct rtllib_device *ieee = (struct rtllib_device *)
- container_of(data,
- struct rtllib_device,
- associate_complete_wq);
- struct rt_pwr_save_ctrl *psc = &ieee->pwr_save_ctrl;
-
- netdev_info(ieee->dev, "Associated successfully with %pM\n",
- ieee->current_network.bssid);
- netdev_info(ieee->dev, "normal associate\n");
- notify_wx_assoc_event(ieee);
-
- netif_carrier_on(ieee->dev);
- ieee->is_roaming = false;
- if (rtllib_is_54g(&ieee->current_network)) {
- ieee->rate = 108;
- netdev_info(ieee->dev, "Using G rates:%d\n", ieee->rate);
- } else {
- ieee->rate = 22;
- ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_B);
- netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate);
- }
- if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) {
- netdev_info(ieee->dev, "Successfully associated, ht enabled\n");
- ht_on_assoc_rsp(ieee);
- } else {
- netdev_info(ieee->dev,
- "Successfully associated, ht not enabled(%d, %d)\n",
- ieee->ht_info->current_ht_support,
- ieee->ht_info->enable_ht);
- memset(ieee->dot11ht_oper_rate_set, 0, 16);
- }
- ieee->link_detect_info.slot_num = 2 * (1 +
- ieee->current_network.beacon_interval /
- 500);
- if (ieee->link_detect_info.num_recv_bcn_in_period == 0 ||
- ieee->link_detect_info.num_recv_data_in_period == 0) {
- ieee->link_detect_info.num_recv_bcn_in_period = 1;
- ieee->link_detect_info.num_recv_data_in_period = 1;
- }
- psc->lps_idle_count = 0;
- ieee->link_change(ieee->dev);
-}
-
-static void rtllib_sta_send_associnfo(struct rtllib_device *ieee)
-{
-}
-
-static void rtllib_associate_complete(struct rtllib_device *ieee)
-{
- del_timer_sync(&ieee->associate_timer);
-
- ieee->link_state = MAC80211_LINKED;
- rtllib_sta_send_associnfo(ieee);
-
- schedule_work(&ieee->associate_complete_wq);
-}
-
-static void rtllib_associate_procedure_wq(void *data)
-{
- struct rtllib_device *ieee = container_of_dwork_rsl(data,
- struct rtllib_device,
- associate_procedure_wq);
- rtllib_stop_scan_syncro(ieee);
- ieee->rtllib_ips_leave(ieee->dev);
- mutex_lock(&ieee->wx_mutex);
-
- rtllib_stop_scan(ieee);
- ht_set_connect_bw_mode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
- if (ieee->rf_power_state == rf_off) {
- ieee->rtllib_ips_leave_wq(ieee->dev);
- mutex_unlock(&ieee->wx_mutex);
- return;
- }
- ieee->associate_seq = 1;
-
- rtllib_associate_step1(ieee, ieee->current_network.bssid);
-
- mutex_unlock(&ieee->wx_mutex);
-}
-
-inline void rtllib_softmac_new_net(struct rtllib_device *ieee,
- struct rtllib_network *net)
-{
- u8 tmp_ssid[IW_ESSID_MAX_SIZE + 1];
- int tmp_ssid_len = 0;
-
- short apset, ssidset, ssidbroad, apmatch, ssidmatch;
-
- /* we are interested in new only if we are not associated
- * and we are not associating / authenticating
- */
- if (ieee->link_state != MAC80211_NOLINK)
- return;
-
- if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability &
- WLAN_CAPABILITY_ESS))
- return;
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- /* if the user specified the AP MAC, we need also the essid
- * This could be obtained by beacons or, if the network does not
- * broadcast it, it can be put manually.
- */
- apset = ieee->wap_set;
- ssidset = ieee->ssid_set;
- ssidbroad = !(net->ssid_len == 0 || net->ssid[0] == '\0');
- apmatch = (memcmp(ieee->current_network.bssid, net->bssid,
- ETH_ALEN) == 0);
- if (!ssidbroad) {
- ssidmatch = (ieee->current_network.ssid_len ==
- net->hidden_ssid_len) &&
- (!strncmp(ieee->current_network.ssid,
- net->hidden_ssid, net->hidden_ssid_len));
- if (net->hidden_ssid_len > 0) {
- strncpy(net->ssid, net->hidden_ssid,
- net->hidden_ssid_len);
- net->ssid_len = net->hidden_ssid_len;
- ssidbroad = 1;
- }
- } else {
- ssidmatch =
- (ieee->current_network.ssid_len == net->ssid_len) &&
- (!strncmp(ieee->current_network.ssid, net->ssid,
- net->ssid_len));
- }
-
- /* if the user set the AP check if match.
- * if the network does not broadcast essid we check the
- * user supplied ANY essid
- * if the network does broadcast and the user does not set
- * essid it is OK
- * if the network does broadcast and the user did set essid
- * check if essid match
- * if the ap is not set, check that the user set the bssid
- * and the network does broadcast and that those two bssid match
- */
- if ((apset && apmatch &&
- ((ssidset && ssidbroad && ssidmatch) ||
- (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
- (!apset && ssidset && ssidbroad && ssidmatch) ||
- (ieee->is_roaming && ssidset && ssidbroad && ssidmatch)) {
- /* Save the essid so that if it is hidden, it is
- * replaced with the essid provided by the user.
- */
- if (!ssidbroad) {
- memcpy(tmp_ssid, ieee->current_network.ssid,
- ieee->current_network.ssid_len);
- tmp_ssid_len = ieee->current_network.ssid_len;
- }
- memcpy(&ieee->current_network, net,
- sizeof(ieee->current_network));
- if (!ssidbroad) {
- memcpy(ieee->current_network.ssid, tmp_ssid,
- tmp_ssid_len);
- ieee->current_network.ssid_len = tmp_ssid_len;
- }
- netdev_info(ieee->dev,
- "Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d, mode:%x cur_net.flags:0x%x\n",
- ieee->current_network.ssid,
- ieee->current_network.channel,
- ieee->current_network.qos_data.supported,
- ieee->ht_info->enable_ht,
- ieee->current_network.bssht.bd_support_ht,
- ieee->current_network.mode,
- ieee->current_network.flags);
-
- if ((rtllib_act_scanning(ieee, false)) &&
- !(ieee->softmac_features & IEEE_SOFTMAC_SCAN))
- rtllib_stop_scan_syncro(ieee);
-
- ht_reset_iot_setting(ieee->ht_info);
- ieee->wmm_acm = 0;
- if (ieee->iw_mode == IW_MODE_INFRA) {
- /* Join the network for the first time */
- ieee->asoc_retry_count = 0;
- if ((ieee->current_network.qos_data.supported == 1) &&
- ieee->current_network.bssht.bd_support_ht)
- ht_reset_self_and_save_peer_setting(ieee,
- &ieee->current_network);
- else
- ieee->ht_info->current_ht_support = false;
-
- ieee->link_state = RTLLIB_ASSOCIATING;
- schedule_delayed_work(&ieee->associate_procedure_wq, 0);
- } else {
- if (rtllib_is_54g(&ieee->current_network)) {
- ieee->rate = 108;
- ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_G);
- netdev_info(ieee->dev,
- "Using G rates\n");
- } else {
- ieee->rate = 22;
- ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_B);
- netdev_info(ieee->dev,
- "Using B rates\n");
- }
- memset(ieee->dot11ht_oper_rate_set, 0, 16);
- ieee->link_state = MAC80211_LINKED;
- }
- }
- }
-}
-
-static void rtllib_softmac_check_all_nets(struct rtllib_device *ieee)
-{
- unsigned long flags;
- struct rtllib_network *target;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- list_for_each_entry(target, &ieee->network_list, list) {
- /* if the state become different that NOLINK means
- * we had found what we are searching for
- */
-
- if (ieee->link_state != MAC80211_NOLINK)
- break;
-
- if (ieee->scan_age == 0 || time_after(target->last_scanned +
- ieee->scan_age, jiffies))
- rtllib_softmac_new_net(ieee, target);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-static inline int auth_parse(struct net_device *dev, struct sk_buff *skb,
- u8 **challenge, int *chlen)
-{
- struct rtllib_authentication *a;
- u8 *t;
-
- if (skb->len < (sizeof(struct rtllib_authentication) -
- sizeof(struct rtllib_info_element))) {
- netdev_dbg(dev, "invalid len in auth resp: %d\n", skb->len);
- return -EINVAL;
- }
- *challenge = NULL;
- a = (struct rtllib_authentication *)skb->data;
- if (skb->len > (sizeof(struct rtllib_authentication) + 3)) {
- t = skb->data + sizeof(struct rtllib_authentication);
-
- if (*(t++) == MFIE_TYPE_CHALLENGE) {
- *chlen = *(t++);
- *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
- if (!*challenge)
- return -ENOMEM;
- }
- }
-
- if (a->status) {
- netdev_dbg(dev, "auth_parse() failed\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb,
- int *aid)
-{
- struct rtllib_assoc_response_frame *response_head;
- u16 status_code;
-
- if (skb->len < sizeof(struct rtllib_assoc_response_frame)) {
- netdev_dbg(ieee->dev, "Invalid len in auth resp: %d\n",
- skb->len);
- return 0xcafe;
- }
-
- response_head = (struct rtllib_assoc_response_frame *)skb->data;
- *aid = le16_to_cpu(response_head->aid) & 0x3fff;
-
- status_code = le16_to_cpu(response_head->status);
- if ((status_code == WLAN_STATUS_ASSOC_DENIED_RATES ||
- status_code == WLAN_STATUS_CAPS_UNSUPPORTED) &&
- ((ieee->mode == WIRELESS_MODE_G) &&
- (ieee->current_network.mode == WIRELESS_MODE_N_24G) &&
- (ieee->asoc_retry_count++ < (RT_ASOC_RETRY_LIMIT - 1)))) {
- ieee->ht_info->iot_action |= HT_IOT_ACT_PURE_N_MODE;
- } else {
- ieee->asoc_retry_count = 0;
- }
-
- return le16_to_cpu(response_head->status);
-}
-
-void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr)
-{
- struct sk_buff *buf = rtllib_null_func(ieee, pwr);
-
- if (buf)
- softmac_ps_mgmt_xmit(buf, ieee);
-}
-EXPORT_SYMBOL(rtllib_sta_ps_send_null_frame);
-
-void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee)
-{
- struct sk_buff *buf = rtllib_pspoll_func(ieee);
-
- if (buf)
- softmac_ps_mgmt_xmit(buf, ieee);
-}
-
-static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time)
-{
- int timeout;
- u8 dtim;
- struct rt_pwr_save_ctrl *psc = &ieee->pwr_save_ctrl;
-
- if (ieee->lps_delay_cnt) {
- ieee->lps_delay_cnt--;
- return 0;
- }
-
- dtim = ieee->current_network.dtim_data;
- if (!(dtim & RTLLIB_DTIM_VALID))
- return 0;
- timeout = ieee->current_network.beacon_interval;
- ieee->current_network.dtim_data = RTLLIB_DTIM_INVALID;
- /* there's no need to notify AP that I find you buffered
- * with broadcast packet
- */
- if (dtim & (RTLLIB_DTIM_UCAST & ieee->ps))
- return 2;
-
- if (!time_after(jiffies,
- dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout)))
- return 0;
- if (!time_after(jiffies,
- ieee->last_rx_ps_time + msecs_to_jiffies(timeout)))
- return 0;
- if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) &&
- (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
- return 0;
-
- if (time) {
- if (ieee->awake_pkt_sent) {
- psc->lps_awake_intvl = 1;
- } else {
- u8 max_period = 5;
-
- if (psc->lps_awake_intvl == 0)
- psc->lps_awake_intvl = 1;
- psc->lps_awake_intvl = (psc->lps_awake_intvl >=
- max_period) ? max_period :
- (psc->lps_awake_intvl + 1);
- }
- {
- u8 lps_awake_intvl_tmp = 0;
- u8 period = ieee->current_network.dtim_period;
- u8 count = ieee->current_network.tim.tim_count;
-
- if (count == 0) {
- if (psc->lps_awake_intvl > period)
- lps_awake_intvl_tmp = period +
- (psc->lps_awake_intvl -
- period) -
- ((psc->lps_awake_intvl - period) %
- period);
- else
- lps_awake_intvl_tmp = psc->lps_awake_intvl;
-
- } else {
- if (psc->lps_awake_intvl >
- ieee->current_network.tim.tim_count)
- lps_awake_intvl_tmp = count +
- (psc->lps_awake_intvl - count) -
- ((psc->lps_awake_intvl - count) % period);
- else
- lps_awake_intvl_tmp = psc->lps_awake_intvl;
- }
-
- *time = ieee->current_network.last_dtim_sta_time
- + msecs_to_jiffies(ieee->current_network.beacon_interval *
- lps_awake_intvl_tmp);
- }
- }
-
- return 1;
-}
-
-static inline void rtllib_sta_ps(struct work_struct *work)
-{
- struct rtllib_device *ieee;
- u64 time;
- short sleep;
- unsigned long flags, flags2;
-
- ieee = container_of(work, struct rtllib_device, ps_task);
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if ((ieee->ps == RTLLIB_PS_DISABLED ||
- ieee->iw_mode != IW_MODE_INFRA ||
- ieee->link_state != MAC80211_LINKED)) {
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- rtllib_sta_wakeup(ieee, 1);
-
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
- sleep = rtllib_sta_ps_sleep(ieee, &time);
- /* 2 wake, 1 sleep, 0 do nothing */
- if (sleep == 0)
- goto out;
- if (sleep == 1) {
- if (ieee->sta_sleep == LPS_IS_SLEEP) {
- ieee->enter_sleep_state(ieee->dev, time);
- } else if (ieee->sta_sleep == LPS_IS_WAKE) {
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
- if (ieee->ps_is_queue_empty(ieee->dev)) {
- ieee->sta_sleep = LPS_WAIT_NULL_DATA_SEND;
- ieee->ack_tx_to_ieee = 1;
- rtllib_sta_ps_send_null_frame(ieee, 1);
- ieee->ps_time = time;
- }
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
-
- ieee->awake_pkt_sent = false;
-
- } else if (sleep == 2) {
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
- rtllib_sta_wakeup(ieee, 1);
-
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
-
-out:
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl)
-{
- if (ieee->sta_sleep == LPS_IS_WAKE) {
- if (nl) {
- if (ieee->ht_info->iot_action &
- HT_IOT_ACT_NULL_DATA_POWER_SAVING) {
- ieee->ack_tx_to_ieee = 1;
- rtllib_sta_ps_send_null_frame(ieee, 0);
- } else {
- ieee->ack_tx_to_ieee = 1;
- rtllib_sta_ps_send_pspoll_frame(ieee);
- }
- }
- return;
- }
-
- if (ieee->sta_sleep == LPS_IS_SLEEP)
- ieee->sta_wake_up(ieee->dev);
- if (nl) {
- if (ieee->ht_info->iot_action &
- HT_IOT_ACT_NULL_DATA_POWER_SAVING) {
- ieee->ack_tx_to_ieee = 1;
- rtllib_sta_ps_send_null_frame(ieee, 0);
- } else {
- ieee->ack_tx_to_ieee = 1;
- ieee->polling = true;
- rtllib_sta_ps_send_pspoll_frame(ieee);
- }
-
- } else {
- ieee->sta_sleep = LPS_IS_WAKE;
- ieee->polling = false;
- }
-}
-
-void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success)
-{
- unsigned long flags, flags2;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->sta_sleep == LPS_WAIT_NULL_DATA_SEND) {
- /* Null frame with PS bit set */
- if (success) {
- ieee->sta_sleep = LPS_IS_SLEEP;
- ieee->enter_sleep_state(ieee->dev, ieee->ps_time);
- }
- /* if the card report not success we can't be sure the AP
- * has not RXed so we can't assume the AP believe us awake
- */
- } else {/* 21112005 - tx again null without PS bit if lost */
-
- if ((ieee->sta_sleep == LPS_IS_WAKE) && !success) {
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- if (ieee->ht_info->iot_action &
- HT_IOT_ACT_NULL_DATA_POWER_SAVING)
- rtllib_sta_ps_send_null_frame(ieee, 0);
- else
- rtllib_sta_ps_send_pspoll_frame(ieee);
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-EXPORT_SYMBOL(rtllib_ps_tx_ack);
-
-static void rtllib_process_action(struct rtllib_device *ieee,
- struct sk_buff *skb)
-{
- u8 *act = skb->data + RTLLIB_3ADDR_LEN;
- u8 category = 0;
-
- category = *act;
- act++;
- switch (category) {
- case ACT_CAT_BA:
- switch (*act) {
- case ACT_ADDBAREQ:
- rtllib_rx_add_ba_req(ieee, skb);
- break;
- case ACT_ADDBARSP:
- rtllib_rx_add_ba_rsp(ieee, skb);
- break;
- case ACT_DELBA:
- rtllib_rx_DELBA(ieee, skb);
- break;
- }
- break;
- default:
- break;
- }
-}
-
-static inline int
-rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats)
-{
- u16 errcode;
- int aid;
- u8 *ies;
- struct rtllib_assoc_response_frame *assoc_resp;
- struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data;
- u16 frame_ctl = le16_to_cpu(header->frame_control);
-
- netdev_dbg(ieee->dev, "received [RE]ASSOCIATION RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(frame_ctl));
-
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- ieee->link_state == RTLLIB_ASSOCIATING_AUTHENTICATED &&
- (ieee->iw_mode == IW_MODE_INFRA)) {
- errcode = assoc_parse(ieee, skb, &aid);
- if (!errcode) {
- struct rtllib_network *network =
- kzalloc(sizeof(struct rtllib_network),
- GFP_ATOMIC);
-
- if (!network)
- return 1;
- ieee->link_state = MAC80211_LINKED;
- ieee->assoc_id = aid;
- ieee->softmac_stats.rx_ass_ok++;
- /* station support qos */
- /* Let the register setting default with Legacy station */
- assoc_resp = (struct rtllib_assoc_response_frame *)skb->data;
- if (ieee->current_network.qos_data.supported == 1) {
- if (rtllib_parse_info_param(ieee, assoc_resp->info_element,
- rx_stats->len - sizeof(*assoc_resp),
- network, rx_stats)) {
- kfree(network);
- return 1;
- }
- memcpy(ieee->ht_info->peer_ht_cap_buf,
- network->bssht.bd_ht_cap_buf,
- network->bssht.bd_ht_cap_len);
- memcpy(ieee->ht_info->peer_ht_info_buf,
- network->bssht.bd_ht_info_buf,
- network->bssht.bd_ht_info_len);
- ieee->handle_assoc_response(ieee->dev,
- (struct rtllib_assoc_response_frame *)header, network);
- }
- kfree(network);
-
- kfree(ieee->assocresp_ies);
- ieee->assocresp_ies = NULL;
- ies = &assoc_resp->info_element[0].id;
- ieee->assocresp_ies_len = (skb->data + skb->len) - ies;
- ieee->assocresp_ies = kmemdup(ies,
- ieee->assocresp_ies_len,
- GFP_ATOMIC);
- if (!ieee->assocresp_ies)
- ieee->assocresp_ies_len = 0;
-
- rtllib_associate_complete(ieee);
- } else {
- /* aid could not been allocated */
- ieee->softmac_stats.rx_ass_err++;
- netdev_info(ieee->dev,
- "Association response status code 0x%x\n",
- errcode);
- if (ieee->asoc_retry_count < RT_ASOC_RETRY_LIMIT)
- schedule_delayed_work(&ieee->associate_procedure_wq, 0);
- else
- rtllib_associate_abort(ieee);
- }
- }
- return 0;
-}
-
-static void rtllib_rx_auth_resp(struct rtllib_device *ieee, struct sk_buff *skb)
-{
- int errcode;
- u8 *challenge;
- int chlen = 0;
- bool support_nmode = true, half_support_nmode = false;
-
- errcode = auth_parse(ieee->dev, skb, &challenge, &chlen);
-
- if (errcode) {
- ieee->softmac_stats.rx_auth_rs_err++;
- netdev_info(ieee->dev,
- "Authentication response status code %d", errcode);
- rtllib_associate_abort(ieee);
- return;
- }
-
- if (ieee->open_wep || !challenge) {
- ieee->link_state = RTLLIB_ASSOCIATING_AUTHENTICATED;
- ieee->softmac_stats.rx_auth_rs_ok++;
- if (!(ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE)) {
- if (!ieee->get_nmode_support_by_sec_cfg(ieee->dev)) {
- if (is_ht_half_nmode_aps(ieee)) {
- support_nmode = true;
- half_support_nmode = true;
- } else {
- support_nmode = false;
- half_support_nmode = false;
- }
- }
- }
- /* Dummy wirless mode setting to avoid encryption issue */
- if (support_nmode) {
- ieee->set_wireless_mode(ieee->dev,
- ieee->current_network.mode);
- } else {
- /*TODO*/
- ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_G);
- }
-
- if ((ieee->current_network.mode == WIRELESS_MODE_N_24G) &&
- half_support_nmode) {
- netdev_info(ieee->dev, "======>enter half N mode\n");
- ieee->half_wireless_n24g_mode = true;
- } else {
- ieee->half_wireless_n24g_mode = false;
- }
- rtllib_associate_step2(ieee);
- } else {
- rtllib_auth_challenge(ieee, challenge, chlen);
- }
-}
-
-static inline int
-rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats)
-{
- if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
- if (ieee->link_state == RTLLIB_ASSOCIATING_AUTHENTICATING &&
- (ieee->iw_mode == IW_MODE_INFRA)) {
- netdev_dbg(ieee->dev,
- "Received authentication response");
- rtllib_rx_auth_resp(ieee, skb);
- }
- }
- return 0;
-}
-
-static inline int
-rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb)
-{
- struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data;
- u16 frame_ctl;
-
- if (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0)
- return 0;
-
- /* FIXME for now repeat all the association procedure
- * both for disassociation and deauthentication
- */
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- ieee->link_state == MAC80211_LINKED &&
- (ieee->iw_mode == IW_MODE_INFRA)) {
- frame_ctl = le16_to_cpu(header->frame_control);
- netdev_info(ieee->dev,
- "==========>received disassoc/deauth(%x) frame, reason code:%x\n",
- WLAN_FC_GET_STYPE(frame_ctl),
- ((struct rtllib_disassoc *)skb->data)->reason);
- ieee->link_state = RTLLIB_ASSOCIATING;
- ieee->softmac_stats.reassoc++;
- ieee->is_roaming = true;
- ieee->link_detect_info.busy_traffic = false;
- rtllib_disassociate(ieee);
- remove_peer_ts(ieee, header->addr2);
- if (!(ieee->rtllib_ap_sec_type(ieee) & (SEC_ALG_CCMP | SEC_ALG_TKIP)))
- schedule_delayed_work(&ieee->associate_procedure_wq, 5);
- }
- return 0;
-}
-
-inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee,
- struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats, u16 type,
- u16 stype)
-{
- struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data;
- u16 frame_ctl;
-
- if (!ieee->proto_started)
- return 0;
-
- frame_ctl = le16_to_cpu(header->frame_control);
- switch (WLAN_FC_GET_STYPE(frame_ctl)) {
- case IEEE80211_STYPE_ASSOC_RESP:
- case IEEE80211_STYPE_REASSOC_RESP:
- if (rtllib_rx_assoc_resp(ieee, skb, rx_stats) == 1)
- return 1;
- break;
- case IEEE80211_STYPE_ASSOC_REQ:
- case IEEE80211_STYPE_REASSOC_REQ:
- break;
- case IEEE80211_STYPE_AUTH:
- rtllib_rx_auth(ieee, skb, rx_stats);
- break;
- case IEEE80211_STYPE_DISASSOC:
- case IEEE80211_STYPE_DEAUTH:
- rtllib_rx_deauth(ieee, skb);
- break;
- case IEEE80211_STYPE_ACTION:
- rtllib_process_action(ieee, skb);
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-/* following are for a simpler TX queue management.
- * Instead of using netif_[stop/wake]_queue the driver
- * will use these two functions (plus a reset one), that
- * will internally use the kernel netif_* and takes
- * care of the ieee802.11 fragmentation.
- * So the driver receives a fragment per time and might
- * call the stop function when it wants to not
- * have enough room to TX an entire packet.
- * This might be useful if each fragment needs it's own
- * descriptor, thus just keep a total free memory > than
- * the max fragmentation threshold is not enough.. If the
- * ieee802.11 stack passed a TXB struct then you need
- * to keep N free descriptors where
- * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
- * In this way you need just one and the 802.11 stack
- * will take care of buffering fragments and pass them to
- * the driver later, when it wakes the queue.
- */
-void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee)
-{
- unsigned int queue_index = txb->queue_index;
- unsigned long flags;
- int i;
- struct cb_desc *tcb_desc = NULL;
- unsigned long queue_len = 0;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /* called with 2nd param 0, no tx mgmt lock required */
- rtllib_sta_wakeup(ieee, 0);
-
- /* update the tx status */
- tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb +
- MAX_DEV_ADDR_SIZE);
- if (tcb_desc->multicast)
- ieee->stats.multicast++;
-
- /* if xmit available, just xmit it immediately, else just insert it to
- * the wait queue
- */
- for (i = 0; i < txb->nr_frags; i++) {
- queue_len = skb_queue_len(&ieee->skb_waitq[queue_index]);
- if ((queue_len != 0) ||
- (!ieee->check_nic_enough_desc(ieee->dev, queue_index)) ||
- (ieee->queue_stop)) {
- /* insert the skb packet to the wait queue
- * as for the completion function, it does not need
- * to check it any more.
- */
- if (queue_len < 200)
- skb_queue_tail(&ieee->skb_waitq[queue_index],
- txb->fragments[i]);
- else
- kfree_skb(txb->fragments[i]);
- } else {
- ieee->softmac_data_hard_start_xmit(txb->fragments[i],
- ieee->dev, ieee->rate);
- }
- }
-
- rtllib_txb_free(txb);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void rtllib_reset_queue(struct rtllib_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->lock, flags);
- init_mgmt_queue(ieee);
- if (ieee->tx_pending.txb) {
- rtllib_txb_free(ieee->tx_pending.txb);
- ieee->tx_pending.txb = NULL;
- }
- ieee->queue_stop = 0;
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-EXPORT_SYMBOL(rtllib_reset_queue);
-
-void rtllib_stop_all_queues(struct rtllib_device *ieee)
-{
- unsigned int i;
-
- for (i = 0; i < ieee->dev->num_tx_queues; i++)
- txq_trans_cond_update(netdev_get_tx_queue(ieee->dev, i));
-
- netif_tx_stop_all_queues(ieee->dev);
-}
-
-void rtllib_wake_all_queues(struct rtllib_device *ieee)
-{
- netif_tx_wake_all_queues(ieee->dev);
-}
-
-/* this is called only in user context, with wx_mutex held */
-static void rtllib_start_bss(struct rtllib_device *ieee)
-{
- unsigned long flags;
-
- /* check if we have already found the net we
- * are interested in (if any).
- * if not (we are disassociated and we are not
- * in associating / authenticating phase) start the background scanning.
- */
- rtllib_softmac_check_all_nets(ieee);
-
- /* ensure no-one start an associating process (thus setting
- * the ieee->link_state to rtllib_ASSOCIATING) while we
- * have just checked it and we are going to enable scan.
- * The rtllib_new_net function is always called with
- * lock held (from both rtllib_softmac_check_all_nets and
- * the rx path), so we cannot be in the middle of such function
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->link_state == MAC80211_NOLINK)
- rtllib_start_scan(ieee);
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-static void rtllib_link_change_wq(void *data)
-{
- struct rtllib_device *ieee = container_of_dwork_rsl(data,
- struct rtllib_device, link_change_wq);
- ieee->link_change(ieee->dev);
-}
-
-/* called only in userspace context */
-void rtllib_disassociate(struct rtllib_device *ieee)
-{
- netif_carrier_off(ieee->dev);
- if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
- rtllib_reset_queue(ieee);
-
- ieee->link_state = MAC80211_NOLINK;
- ieee->is_set_key = false;
- ieee->wap_set = 0;
-
- schedule_delayed_work(&ieee->link_change_wq, 0);
-
- notify_wx_assoc_event(ieee);
-}
-
-static void rtllib_associate_retry_wq(void *data)
-{
- struct rtllib_device *ieee = container_of_dwork_rsl(data,
- struct rtllib_device, associate_retry_wq);
- unsigned long flags;
-
- mutex_lock(&ieee->wx_mutex);
- if (!ieee->proto_started)
- goto exit;
-
- if (ieee->link_state != RTLLIB_ASSOCIATING_RETRY)
- goto exit;
-
- /* until we do not set the state to MAC80211_NOLINK
- * there are no possibility to have someone else trying
- * to start an association procedure (we get here with
- * ieee->link_state = RTLLIB_ASSOCIATING).
- * When we set the state to MAC80211_NOLINK it is possible
- * that the RX path run an attempt to associate, but
- * both rtllib_softmac_check_all_nets and the
- * RX path works with ieee->lock held so there are no
- * problems. If we are still disassociated then start a scan.
- * the lock here is necessary to ensure no one try to start
- * an association procedure when we have just checked the
- * state and we are going to start the scan.
- */
- ieee->beinretry = true;
- ieee->link_state = MAC80211_NOLINK;
-
- rtllib_softmac_check_all_nets(ieee);
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->link_state == MAC80211_NOLINK)
- rtllib_start_scan(ieee);
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- ieee->beinretry = false;
-exit:
- mutex_unlock(&ieee->wx_mutex);
-}
-
-void rtllib_softmac_stop_protocol(struct rtllib_device *ieee)
-{
- rtllib_stop_scan_syncro(ieee);
- mutex_lock(&ieee->wx_mutex);
- rtllib_stop_protocol(ieee);
- mutex_unlock(&ieee->wx_mutex);
-}
-EXPORT_SYMBOL(rtllib_softmac_stop_protocol);
-
-void rtllib_stop_protocol(struct rtllib_device *ieee)
-{
- if (!ieee->proto_started)
- return;
-
- ieee->proto_started = 0;
- ieee->proto_stoppping = 1;
- ieee->rtllib_ips_leave(ieee->dev);
-
- del_timer_sync(&ieee->associate_timer);
- mutex_unlock(&ieee->wx_mutex);
- cancel_delayed_work_sync(&ieee->associate_retry_wq);
- mutex_lock(&ieee->wx_mutex);
- cancel_delayed_work_sync(&ieee->link_change_wq);
- rtllib_stop_scan(ieee);
-
- if (ieee->link_state <= RTLLIB_ASSOCIATING_AUTHENTICATED)
- ieee->link_state = MAC80211_NOLINK;
-
- if (ieee->link_state == MAC80211_LINKED) {
- if (ieee->iw_mode == IW_MODE_INFRA)
- send_disassociation(ieee, 1, WLAN_REASON_DEAUTH_LEAVING);
- rtllib_disassociate(ieee);
- }
-
- remove_all_ts(ieee);
- ieee->proto_stoppping = 0;
-
- kfree(ieee->assocreq_ies);
- ieee->assocreq_ies = NULL;
- ieee->assocreq_ies_len = 0;
- kfree(ieee->assocresp_ies);
- ieee->assocresp_ies = NULL;
- ieee->assocresp_ies_len = 0;
-}
-
-void rtllib_softmac_start_protocol(struct rtllib_device *ieee)
-{
- mutex_lock(&ieee->wx_mutex);
- rtllib_start_protocol(ieee);
- mutex_unlock(&ieee->wx_mutex);
-}
-EXPORT_SYMBOL(rtllib_softmac_start_protocol);
-
-void rtllib_start_protocol(struct rtllib_device *ieee)
-{
- short ch = 0;
- int i = 0;
-
- if (ieee->proto_started)
- return;
-
- ieee->proto_started = 1;
-
- if (ieee->current_network.channel == 0) {
- do {
- ch++;
- if (ch > MAX_CHANNEL_NUMBER)
- return; /* no channel found */
- } while (!ieee->active_channel_map[ch]);
- ieee->current_network.channel = ch;
- }
-
- if (ieee->current_network.beacon_interval == 0)
- ieee->current_network.beacon_interval = 100;
-
- for (i = 0; i < 17; i++) {
- ieee->last_rxseq_num[i] = -1;
- ieee->last_rxfrag_num[i] = -1;
- ieee->last_packet_time[i] = 0;
- }
-
- ieee->wmm_acm = 0;
- /* if the user set the MAC of the ad-hoc cell and then
- * switch to managed mode, shall we make sure that association
- * attempts does not fail just because the user provide the essid
- * and the nic is still checking for the AP MAC ??
- */
- switch (ieee->iw_mode) {
- case IW_MODE_INFRA:
- rtllib_start_bss(ieee);
- break;
- }
-}
-
-int rtllib_softmac_init(struct rtllib_device *ieee)
-{
- int i;
-
- memset(&ieee->current_network, 0, sizeof(struct rtllib_network));
-
- ieee->link_state = MAC80211_NOLINK;
- for (i = 0; i < 5; i++)
- ieee->seq_ctrl[i] = 0;
-
- ieee->link_detect_info.slot_index = 0;
- ieee->link_detect_info.slot_num = 2;
- ieee->link_detect_info.num_recv_bcn_in_period = 0;
- ieee->link_detect_info.num_recv_data_in_period = 0;
- ieee->link_detect_info.num_tx_ok_in_period = 0;
- ieee->link_detect_info.num_rx_ok_in_period = 0;
- ieee->link_detect_info.num_rx_unicast_ok_in_period = 0;
- ieee->is_aggregate_frame = false;
- ieee->assoc_id = 0;
- ieee->queue_stop = 0;
- ieee->scanning_continue = 0;
- ieee->softmac_features = 0;
- ieee->wap_set = 0;
- ieee->ssid_set = 0;
- ieee->proto_started = 0;
- ieee->proto_stoppping = 0;
- ieee->basic_rate = RTLLIB_DEFAULT_BASIC_RATE;
- ieee->rate = 22;
- ieee->ps = RTLLIB_PS_DISABLED;
- ieee->sta_sleep = LPS_IS_WAKE;
-
- ieee->reg_dot11ht_oper_rate_set[0] = 0xff;
- ieee->reg_dot11ht_oper_rate_set[1] = 0xff;
- ieee->reg_dot11ht_oper_rate_set[4] = 0x01;
-
- ieee->reg_dot11tx_ht_oper_rate_set[0] = 0xff;
- ieee->reg_dot11tx_ht_oper_rate_set[1] = 0xff;
- ieee->reg_dot11tx_ht_oper_rate_set[4] = 0x01;
-
- ieee->first_ie_in_scan = false;
- ieee->actscanning = false;
- ieee->beinretry = false;
- ieee->is_set_key = false;
- init_mgmt_queue(ieee);
-
- ieee->tx_pending.txb = NULL;
-
- timer_setup(&ieee->associate_timer, rtllib_associate_abort_cb, 0);
-
- INIT_DELAYED_WORK(&ieee->link_change_wq, (void *)rtllib_link_change_wq);
- INIT_WORK(&ieee->associate_complete_wq, (void *)rtllib_associate_complete_wq);
- INIT_DELAYED_WORK(&ieee->associate_procedure_wq, (void *)rtllib_associate_procedure_wq);
- INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *)rtllib_softmac_scan_wq);
- INIT_DELAYED_WORK(&ieee->associate_retry_wq, (void *)rtllib_associate_retry_wq);
- INIT_WORK(&ieee->wx_sync_scan_wq, (void *)rtllib_wx_sync_scan_wq);
-
- mutex_init(&ieee->wx_mutex);
- mutex_init(&ieee->scan_mutex);
- mutex_init(&ieee->ips_mutex);
-
- spin_lock_init(&ieee->mgmt_tx_lock);
- spin_lock_init(&ieee->beacon_lock);
-
- INIT_WORK(&ieee->ps_task, rtllib_sta_ps);
-
- return 0;
-}
-
-void rtllib_softmac_free(struct rtllib_device *ieee)
-{
- del_timer_sync(&ieee->associate_timer);
-
- cancel_delayed_work_sync(&ieee->associate_retry_wq);
- cancel_delayed_work_sync(&ieee->associate_procedure_wq);
- cancel_delayed_work_sync(&ieee->softmac_scan_wq);
- cancel_delayed_work_sync(&ieee->hw_wakeup_wq);
- cancel_delayed_work_sync(&ieee->hw_sleep_wq);
- cancel_delayed_work_sync(&ieee->link_change_wq);
- cancel_work_sync(&ieee->associate_complete_wq);
- cancel_work_sync(&ieee->ips_leave_wq);
- cancel_work_sync(&ieee->wx_sync_scan_wq);
- cancel_work_sync(&ieee->ps_task);
-}
-
-static inline struct sk_buff *
-rtllib_disauth_skb(struct rtllib_network *beacon,
- struct rtllib_device *ieee, u16 rsn)
-{
- struct sk_buff *skb;
- struct rtllib_disauth *disauth;
- int len = sizeof(struct rtllib_disauth) + ieee->tx_headroom;
-
- skb = dev_alloc_skb(len);
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- disauth = skb_put(skb, sizeof(struct rtllib_disauth));
- disauth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DEAUTH);
- disauth->header.duration_id = 0;
-
- ether_addr_copy(disauth->header.addr1, beacon->bssid);
- ether_addr_copy(disauth->header.addr2, ieee->dev->dev_addr);
- ether_addr_copy(disauth->header.addr3, beacon->bssid);
-
- disauth->reason = cpu_to_le16(rsn);
- return skb;
-}
-
-static inline struct sk_buff *
-rtllib_disassociate_skb(struct rtllib_network *beacon,
- struct rtllib_device *ieee, u16 rsn)
-{
- struct sk_buff *skb;
- struct rtllib_disassoc *disass;
- int len = sizeof(struct rtllib_disassoc) + ieee->tx_headroom;
-
- skb = dev_alloc_skb(len);
-
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- disass = skb_put(skb, sizeof(struct rtllib_disassoc));
- disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
- disass->header.duration_id = 0;
-
- ether_addr_copy(disass->header.addr1, beacon->bssid);
- ether_addr_copy(disass->header.addr2, ieee->dev->dev_addr);
- ether_addr_copy(disass->header.addr3, beacon->bssid);
-
- disass->reason = cpu_to_le16(rsn);
- return skb;
-}
-
-void send_disassociation(struct rtllib_device *ieee, bool deauth, u16 rsn)
-{
- struct rtllib_network *beacon = &ieee->current_network;
- struct sk_buff *skb;
-
- if (deauth)
- skb = rtllib_disauth_skb(beacon, ieee, rsn);
- else
- skb = rtllib_disassociate_skb(beacon, ieee, rsn);
-
- if (skb)
- softmac_mgmt_xmit(skb, ieee);
-}
-
-u8 rtllib_ap_sec_type(struct rtllib_device *ieee)
-{
- static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04};
- static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
- int wpa_ie_len = ieee->wpa_ie_len;
- struct lib80211_crypt_data *crypt;
- int encrypt;
-
- crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
- encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY)
- || (crypt && crypt->ops && (strcmp(crypt->ops->name, "R-WEP") == 0));
-
- /* simply judge */
- if (encrypt && (wpa_ie_len == 0)) {
- return SEC_ALG_WEP;
- } else if ((wpa_ie_len != 0)) {
- if (((ieee->wpa_ie[0] == 0xdd) &&
- (!memcmp(&ieee->wpa_ie[14], ccmp_ie, 4))) ||
- ((ieee->wpa_ie[0] == 0x30) &&
- (!memcmp(&ieee->wpa_ie[10], ccmp_rsn_ie, 4))))
- return SEC_ALG_CCMP;
- else
- return SEC_ALG_TKIP;
- } else {
- return SEC_ALG_NONE;
- }
-}
-
-static void rtllib_mlme_disassociate_request(struct rtllib_device *rtllib,
- u8 *addr, u8 rsn)
-{
- u8 i;
- u8 op_mode;
-
- remove_peer_ts(rtllib, addr);
-
- if (memcmp(rtllib->current_network.bssid, addr, 6) == 0) {
- rtllib->link_state = MAC80211_NOLINK;
-
- for (i = 0; i < 6; i++)
- rtllib->current_network.bssid[i] = 0x22;
- op_mode = RT_OP_MODE_NO_LINK;
- rtllib->op_mode = RT_OP_MODE_NO_LINK;
- rtllib->set_hw_reg_handler(rtllib->dev, HW_VAR_MEDIA_STATUS,
- (u8 *)(&op_mode));
- rtllib_disassociate(rtllib);
-
- rtllib->set_hw_reg_handler(rtllib->dev, HW_VAR_BSSID,
- rtllib->current_network.bssid);
- }
-}
-
-static void rtllib_mgnt_disconnect_ap(struct rtllib_device *rtllib, u8 rsn)
-{
- bool filter_out_nonassociated_bssid = false;
-
- filter_out_nonassociated_bssid = false;
- rtllib->set_hw_reg_handler(rtllib->dev, HW_VAR_CECHK_BSSID,
- (u8 *)(&filter_out_nonassociated_bssid));
- rtllib_mlme_disassociate_request(rtllib, rtllib->current_network.bssid,
- rsn);
-
- rtllib->link_state = MAC80211_NOLINK;
-}
-
-bool rtllib_mgnt_disconnect(struct rtllib_device *rtllib, u8 rsn)
-{
- if (rtllib->ps != RTLLIB_PS_DISABLED)
- rtllib->sta_wake_up(rtllib->dev);
-
- if (rtllib->link_state == MAC80211_LINKED) {
- if (rtllib->iw_mode == IW_MODE_INFRA)
- rtllib_mgnt_disconnect_ap(rtllib, rsn);
- }
-
- return true;
-}
-EXPORT_SYMBOL(rtllib_mgnt_disconnect);
-
-void notify_wx_assoc_event(struct rtllib_device *ieee)
-{
- union iwreq_data wrqu;
-
- if (ieee->cannot_notify)
- return;
-
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- if (ieee->link_state == MAC80211_LINKED) {
- memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid,
- ETH_ALEN);
- } else {
- netdev_info(ieee->dev, "%s(): Tell user space disconnected\n",
- __func__);
- eth_zero_addr(wrqu.ap_addr.sa_data);
- }
- wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
-}
-EXPORT_SYMBOL(notify_wx_assoc_event);
diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c
deleted file mode 100644
index c59686d68a33..000000000000
--- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c
+++ /dev/null
@@ -1,534 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* IEEE 802.11 SoftMAC layer
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * Mostly extracted from the rtl8180-sa2400 driver for the
- * in-kernel generic ieee802.11 stack.
- *
- * Some pieces of code might be stolen from ipw2100 driver
- * copyright of who own it's copyright ;-)
- *
- * PS wx handler mostly stolen from hostap, copyright who
- * own it's copyright ;-)
- */
-#include <linux/etherdevice.h>
-
-#include "rtllib.h"
-
-int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct iw_freq *fwrq = &wrqu->freq;
-
- mutex_lock(&ieee->wx_mutex);
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- ret = 0;
- goto out;
- }
-
- /* if setting by freq convert to channel */
- if (fwrq->e == 1) {
- if ((fwrq->m >= (int)2.412e8 &&
- fwrq->m <= (int)2.487e8)) {
- fwrq->m = ieee80211_freq_khz_to_channel(fwrq->m / 100);
- fwrq->e = 0;
- }
- }
-
- if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) {
- ret = -EOPNOTSUPP;
- goto out;
-
- } else { /* Set the channel */
-
- if (ieee->active_channel_map[fwrq->m] != 1) {
- ret = -EINVAL;
- goto out;
- }
- ieee->current_network.channel = fwrq->m;
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- }
-
- ret = 0;
-out:
- mutex_unlock(&ieee->wx_mutex);
- return ret;
-}
-EXPORT_SYMBOL(rtllib_wx_set_freq);
-
-int rtllib_wx_get_freq(struct rtllib_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct iw_freq *fwrq = &wrqu->freq;
-
- if (ieee->current_network.channel == 0)
- return -1;
- fwrq->m = ieee80211_channel_to_freq_khz(ieee->current_network.channel,
- NL80211_BAND_2GHZ) * 100;
- fwrq->e = 1;
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_get_freq);
-
-int rtllib_wx_get_wap(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- unsigned long flags;
-
- wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- /* We want avoid to give to the user inconsistent infos*/
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->link_state != MAC80211_LINKED &&
- ieee->link_state != MAC80211_LINKED_SCANNING &&
- ieee->wap_set == 0)
-
- eth_zero_addr(wrqu->ap_addr.sa_data);
- else
- memcpy(wrqu->ap_addr.sa_data,
- ieee->current_network.bssid, ETH_ALEN);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_get_wap);
-
-int rtllib_wx_set_wap(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *awrq,
- char *extra)
-{
- int ret = 0;
- unsigned long flags;
-
- short ifup = ieee->proto_started;
- struct sockaddr *temp = (struct sockaddr *)awrq;
-
- rtllib_stop_scan_syncro(ieee);
-
- mutex_lock(&ieee->wx_mutex);
- /* use ifconfig hw ether */
-
- if (temp->sa_family != ARPHRD_ETHER) {
- ret = -EINVAL;
- goto out;
- }
-
- if (is_zero_ether_addr(temp->sa_data)) {
- spin_lock_irqsave(&ieee->lock, flags);
- ether_addr_copy(ieee->current_network.bssid, temp->sa_data);
- ieee->wap_set = 0;
- spin_unlock_irqrestore(&ieee->lock, flags);
- ret = -1;
- goto out;
- }
-
- if (ifup)
- rtllib_stop_protocol(ieee);
-
- /* just to avoid to give inconsistent infos in the
- * get wx method. not really needed otherwise
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- ieee->cannot_notify = false;
- ether_addr_copy(ieee->current_network.bssid, temp->sa_data);
- ieee->wap_set = !is_zero_ether_addr(temp->sa_data);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- if (ifup)
- rtllib_start_protocol(ieee);
-out:
- mutex_unlock(&ieee->wx_mutex);
- return ret;
-}
-EXPORT_SYMBOL(rtllib_wx_set_wap);
-
-int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int len, ret = 0;
- unsigned long flags;
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- /* We want avoid to give to the user inconsistent infos*/
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->current_network.ssid[0] == '\0' ||
- ieee->current_network.ssid_len == 0) {
- ret = -1;
- goto out;
- }
-
- if (ieee->link_state != MAC80211_LINKED &&
- ieee->link_state != MAC80211_LINKED_SCANNING &&
- ieee->ssid_set == 0) {
- ret = -1;
- goto out;
- }
- len = ieee->current_network.ssid_len;
- wrqu->essid.length = len;
- strncpy(b, ieee->current_network.ssid, len);
- wrqu->essid.flags = 1;
-
-out:
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(rtllib_wx_get_essid);
-
-int rtllib_wx_set_rate(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- u32 target_rate = wrqu->bitrate.value;
-
- ieee->rate = target_rate / 100000;
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_set_rate);
-
-int rtllib_wx_get_rate(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- u32 tmp_rate;
-
- tmp_rate = tx_count_to_data_rate(ieee,
- ieee->softmac_stats.CurrentShowTxate);
- wrqu->bitrate.value = tmp_rate * 500000;
-
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_get_rate);
-
-int rtllib_wx_set_rts(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- if (wrqu->rts.disabled || !wrqu->rts.fixed) {
- ieee->rts = DEFAULT_RTS_THRESHOLD;
- } else {
- if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
- wrqu->rts.value > MAX_RTS_THRESHOLD)
- return -EINVAL;
- ieee->rts = wrqu->rts.value;
- }
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_set_rts);
-
-int rtllib_wx_get_rts(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- wrqu->rts.value = ieee->rts;
- wrqu->rts.fixed = 0; /* no auto select */
- wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_get_rts);
-
-int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int set_mode_status = 0;
-
- rtllib_stop_scan_syncro(ieee);
- mutex_lock(&ieee->wx_mutex);
- switch (wrqu->mode) {
- case IW_MODE_MONITOR:
- case IW_MODE_INFRA:
- break;
- case IW_MODE_AUTO:
- wrqu->mode = IW_MODE_INFRA;
- break;
- default:
- set_mode_status = -EINVAL;
- goto out;
- }
-
- if (wrqu->mode == ieee->iw_mode)
- goto out;
-
- if (wrqu->mode == IW_MODE_MONITOR) {
- ieee->dev->type = ARPHRD_IEEE80211;
- rtllib_enable_net_monitor_mode(ieee->dev, false);
- } else {
- ieee->dev->type = ARPHRD_ETHER;
- if (ieee->iw_mode == IW_MODE_MONITOR)
- rtllib_disable_net_monitor_mode(ieee->dev, false);
- }
-
- if (!ieee->proto_started) {
- ieee->iw_mode = wrqu->mode;
- } else {
- rtllib_stop_protocol(ieee);
- ieee->iw_mode = wrqu->mode;
- rtllib_start_protocol(ieee);
- }
-
-out:
- mutex_unlock(&ieee->wx_mutex);
- return set_mode_status;
-}
-EXPORT_SYMBOL(rtllib_wx_set_mode);
-
-void rtllib_wx_sync_scan_wq(void *data)
-{
- struct rtllib_device *ieee = container_of(data, struct rtllib_device, wx_sync_scan_wq);
- short chan;
- enum ht_extchnl_offset chan_offset = 0;
- enum ht_channel_width bandwidth = 0;
- int b40M = 0;
-
- mutex_lock(&ieee->wx_mutex);
- if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) {
- rtllib_start_scan_syncro(ieee);
- goto out;
- }
-
- chan = ieee->current_network.channel;
-
- ieee->leisure_ps_leave(ieee->dev);
- /* notify AP to be in PS mode */
- rtllib_sta_ps_send_null_frame(ieee, 1);
- rtllib_sta_ps_send_null_frame(ieee, 1);
-
- rtllib_stop_all_queues(ieee);
- ieee->link_state = MAC80211_LINKED_SCANNING;
- ieee->link_change(ieee->dev);
- /* wait for ps packet to be kicked out successfully */
- msleep(50);
-
- ieee->scan_operation_backup_handler(ieee->dev, SCAN_OPT_BACKUP);
-
- if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht &&
- ieee->ht_info->cur_bw_40mhz) {
- b40M = 1;
- chan_offset = ieee->ht_info->cur_sta_ext_chnl_offset;
- bandwidth = (enum ht_channel_width)ieee->ht_info->cur_bw_40mhz;
- ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20,
- HT_EXTCHNL_OFFSET_NO_EXT);
- }
-
- rtllib_start_scan_syncro(ieee);
-
- if (b40M) {
- if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
- ieee->set_chan(ieee->dev, chan + 2);
- else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
- ieee->set_chan(ieee->dev, chan - 2);
- else
- ieee->set_chan(ieee->dev, chan);
- ieee->set_bw_mode_handler(ieee->dev, bandwidth, chan_offset);
- } else {
- ieee->set_chan(ieee->dev, chan);
- }
-
- ieee->scan_operation_backup_handler(ieee->dev, SCAN_OPT_RESTORE);
-
- ieee->link_state = MAC80211_LINKED;
- ieee->link_change(ieee->dev);
-
- /* Notify AP that I wake up again */
- rtllib_sta_ps_send_null_frame(ieee, 0);
-
- if (ieee->link_detect_info.num_recv_bcn_in_period == 0 ||
- ieee->link_detect_info.num_recv_data_in_period == 0) {
- ieee->link_detect_info.num_recv_bcn_in_period = 1;
- ieee->link_detect_info.num_recv_data_in_period = 1;
- }
- rtllib_wake_all_queues(ieee);
-
-out:
- mutex_unlock(&ieee->wx_mutex);
-}
-
-int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret = 0;
-
- if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) {
- ret = -1;
- goto out;
- }
-
- if (ieee->link_state == MAC80211_LINKED) {
- schedule_work(&ieee->wx_sync_scan_wq);
- /* intentionally forget to up sem */
- return 0;
- }
-
-out:
- return ret;
-}
-EXPORT_SYMBOL(rtllib_wx_set_scan);
-
-int rtllib_wx_set_essid(struct rtllib_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0, len;
- short proto_started;
- unsigned long flags;
-
- rtllib_stop_scan_syncro(ieee);
- mutex_lock(&ieee->wx_mutex);
-
- proto_started = ieee->proto_started;
-
- len = min_t(__u16, wrqu->essid.length, IW_ESSID_MAX_SIZE);
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- ret = -1;
- goto out;
- }
-
- if (proto_started)
- rtllib_stop_protocol(ieee);
-
- /* this is just to be sure that the GET wx callback
- * has consistent infos. not needed otherwise
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (wrqu->essid.flags && wrqu->essid.length) {
- strncpy(ieee->current_network.ssid, extra, len);
- ieee->current_network.ssid_len = len;
- ieee->cannot_notify = false;
- ieee->ssid_set = 1;
- } else {
- ieee->ssid_set = 0;
- ieee->current_network.ssid[0] = '\0';
- ieee->current_network.ssid_len = 0;
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- if (proto_started)
- rtllib_start_protocol(ieee);
-out:
- mutex_unlock(&ieee->wx_mutex);
- return ret;
-}
-EXPORT_SYMBOL(rtllib_wx_set_essid);
-
-int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- wrqu->mode = ieee->iw_mode;
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_get_mode);
-
-int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- const char *n = ieee->mode & (WIRELESS_MODE_N_24G) ? "n" : "";
-
- scnprintf(wrqu->name, sizeof(wrqu->name), "802.11bg%s", n);
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_get_name);
-
-/* this is mostly stolen from hostap */
-int rtllib_wx_set_power(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
-
- if ((!ieee->sta_wake_up) ||
- (!ieee->enter_sleep_state) ||
- (!ieee->ps_is_queue_empty)) {
- netdev_warn(ieee->dev,
- "%s(): PS mode is tried to be use but driver missed a callback\n",
- __func__);
- return -1;
- }
-
- mutex_lock(&ieee->wx_mutex);
-
- if (wrqu->power.disabled) {
- ieee->ps = RTLLIB_PS_DISABLED;
- goto exit;
- }
- if (wrqu->power.flags & IW_POWER_TIMEOUT)
- ieee->ps_timeout = wrqu->power.value / 1000;
-
- if (wrqu->power.flags & IW_POWER_PERIOD)
- ieee->ps_period = wrqu->power.value / 1000;
-
- switch (wrqu->power.flags & IW_POWER_MODE) {
- case IW_POWER_UNICAST_R:
- ieee->ps = RTLLIB_PS_UNICAST;
- break;
- case IW_POWER_MULTICAST_R:
- ieee->ps = RTLLIB_PS_MBCAST;
- break;
- case IW_POWER_ALL_R:
- ieee->ps = RTLLIB_PS_UNICAST | RTLLIB_PS_MBCAST;
- break;
-
- case IW_POWER_ON:
- break;
-
- default:
- ret = -EINVAL;
- goto exit;
- }
-exit:
- mutex_unlock(&ieee->wx_mutex);
- return ret;
-}
-EXPORT_SYMBOL(rtllib_wx_set_power);
-
-/* this is stolen from hostap */
-int rtllib_wx_get_power(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- mutex_lock(&ieee->wx_mutex);
-
- if (ieee->ps == RTLLIB_PS_DISABLED) {
- wrqu->power.disabled = 1;
- goto exit;
- }
-
- wrqu->power.disabled = 0;
-
- if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- wrqu->power.flags = IW_POWER_TIMEOUT;
- wrqu->power.value = ieee->ps_timeout * 1000;
- } else {
- wrqu->power.flags = IW_POWER_PERIOD;
- wrqu->power.value = ieee->ps_period * 1000;
- }
-
- if ((ieee->ps & (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST)) ==
- (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST))
- wrqu->power.flags |= IW_POWER_ALL_R;
- else if (ieee->ps & RTLLIB_PS_MBCAST)
- wrqu->power.flags |= IW_POWER_MULTICAST_R;
- else
- wrqu->power.flags |= IW_POWER_UNICAST_R;
-
-exit:
- mutex_unlock(&ieee->wx_mutex);
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_get_power);
diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c
deleted file mode 100644
index 8e2abd16eb86..000000000000
--- a/drivers/staging/rtl8192e/rtllib_tx.c
+++ /dev/null
@@ -1,901 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
- *
- * Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * Few modifications for Realtek's Wi-Fi drivers by
- * Andrea Merello <andrea.merello@gmail.com>
- *
- * A special thanks goes to Realtek for their support !
- */
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <linux/uaccess.h>
-#include <linux/if_vlan.h>
-
-#include "rtllib.h"
-
-/* 802.11 Data Frame
- *
- *
- * 802.11 frame_control for data frames - 2 bytes
- * ,--------------------------------------------------------------------.
- * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
- * |---|---|---|---|---|---|---|---|---|----|----|-----|-----|-----|----|
- * val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
- * |---|---|---|---|---|---|---|---|---|----|----|-----|-----|-----|----|
- * desc | ver | type | ^-subtype-^ |to |from|more|retry| pwr |more |wep |
- * | | | x=0 data |DS | DS |frag| | mgm |data | |
- * | | | x=1 data+ack | | | | | | | |
- * '--------------------------------------------------------------------'
- * /\
- * |
- * 802.11 Data Frame |
- * ,--------- 'ctrl' expands to >---'
- * |
- * ,--'---,-------------------------------------------------------------.
- * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
- * |------|------|---------|---------|---------|------|---------|------|
- * Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
- * | | tion | (BSSID) | | | ence | data | |
- * `--------------------------------------------------| |------'
- * Total: 28 non-data bytes `----.----'
- * |
- * .- 'Frame data' expands to <---------------------------'
- * |
- * V
- * ,---------------------------------------------------.
- * Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
- * |------|------|---------|----------|------|---------|
- * Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
- * | DSAP | SSAP | | | | Packet |
- * | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
- * `-----------------------------------------| |
- * Total: 8 non-data bytes `----.----'
- * |
- * .- 'IP Packet' expands, if WEP enabled, to <--'
- * |
- * V
- * ,-----------------------.
- * Bytes | 4 | 0-2296 | 4 |
- * |-----|-----------|-----|
- * Desc. | IV | Encrypted | ICV |
- * | | IP Packet | |
- * `-----------------------'
- * Total: 8 non-data bytes
- *
- *
- * 802.3 Ethernet Data Frame
- *
- * ,-----------------------------------------.
- * Bytes | 6 | 6 | 2 | Variable | 4 |
- * |-------|-------|------|-----------|------|
- * Desc. | Dest. | Source| Type | IP Packet | fcs |
- * | MAC | MAC | | | |
- * `-----------------------------------------'
- * Total: 18 non-data bytes
- *
- * In the event that fragmentation is required, the incoming payload is split
- * into N parts of size ieee->fts. The first fragment contains the SNAP header
- * and the remaining packets are just data.
- *
- * If encryption is enabled, each fragment payload size is reduced by enough
- * space to add the prefix and postfix (IV and ICV totalling 8 bytes in
- * the case of WEP) So if you have 1500 bytes of payload with ieee->fts set to
- * 500 without encryption it will take 3 frames. With WEP it will take 4 frames
- * as the payload of each frame is reduced to 492 bytes.
- *
- * SKB visualization
- *
- * ,- skb->data
- * |
- * | ETHERNET HEADER ,-<-- PAYLOAD
- * | | 14 bytes from skb->data
- * | 2 bytes for Type --> ,T. | (sizeof ethhdr)
- * | | | |
- * |,-Dest.--. ,--Src.---. | | |
- * | 6 bytes| | 6 bytes | | | |
- * v | | | | | |
- * 0 | v 1 | v | v 2
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * ^ | ^ | ^ |
- * | | | | | |
- * | | | | `T' <---- 2 bytes for Type
- * | | | |
- * | | '---SNAP--' <-------- 6 bytes for SNAP
- * | |
- * `-IV--' <-------------------- 4 bytes for IV (WEP)
- *
- * SNAP HEADER
- *
- */
-
-static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
-static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-
-static int rtllib_put_snap(u8 *data, u16 h_proto)
-{
- struct rtllib_snap_hdr *snap;
- u8 *oui;
-
- snap = (struct rtllib_snap_hdr *)data;
- snap->dsap = 0xaa;
- snap->ssap = 0xaa;
- snap->ctrl = 0x03;
-
- if (h_proto == 0x8137 || h_proto == 0x80f3)
- oui = P802_1H_OUI;
- else
- oui = RFC1042_OUI;
- snap->oui[0] = oui[0];
- snap->oui[1] = oui[1];
- snap->oui[2] = oui[2];
-
- *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
-
- return SNAP_SIZE + sizeof(u16);
-}
-
-int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag,
- int hdr_len)
-{
- struct lib80211_crypt_data *crypt = NULL;
- int res;
-
- crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
-
- if (!(crypt && crypt->ops)) {
- netdev_info(ieee->dev, "=========>%s(), crypt is null\n",
- __func__);
- return -1;
- }
- /* To encrypt, frame format is:
- * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes)
- */
-
- /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
- * call both MSDU and MPDU encryption functions from here.
- */
- atomic_inc(&crypt->refcnt);
- res = 0;
- if (crypt->ops->encrypt_msdu)
- res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
- if (res == 0 && crypt->ops->encrypt_mpdu)
- res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
-
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- netdev_info(ieee->dev, "%s: Encryption failed: len=%d.\n",
- ieee->dev->name, frag->len);
- return -1;
- }
-
- return 0;
-}
-
-void rtllib_txb_free(struct rtllib_txb *txb)
-{
- if (unlikely(!txb))
- return;
- kfree(txb);
-}
-
-static struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size,
- gfp_t gfp_mask)
-{
- struct rtllib_txb *txb;
- int i;
-
- txb = kzalloc(struct_size(txb, fragments, nr_frags), gfp_mask);
- if (!txb)
- return NULL;
-
- txb->nr_frags = nr_frags;
- txb->frag_size = cpu_to_le16(txb_size);
-
- for (i = 0; i < nr_frags; i++) {
- txb->fragments[i] = dev_alloc_skb(txb_size);
- if (unlikely(!txb->fragments[i]))
- goto err_free;
- memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
- }
-
- return txb;
-
-err_free:
- while (--i >= 0)
- dev_kfree_skb_any(txb->fragments[i]);
- kfree(txb);
-
- return NULL;
-}
-
-static int rtllib_classify(struct sk_buff *skb)
-{
- struct ethhdr *eth;
- struct iphdr *ip;
-
- eth = (struct ethhdr *)skb->data;
- if (eth->h_proto != htons(ETH_P_IP))
- return 0;
-
-#ifdef VERBOSE_DEBUG
- print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE, skb->data,
- skb->len);
-#endif
- ip = ip_hdr(skb);
- switch (ip->tos & 0xfc) {
- case 0x20:
- return 2;
- case 0x40:
- return 1;
- case 0x60:
- return 3;
- case 0x80:
- return 4;
- case 0xa0:
- return 5;
- case 0xc0:
- return 6;
- case 0xe0:
- return 7;
- default:
- return 0;
- }
-}
-
-static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee,
- struct sk_buff *skb,
- struct cb_desc *tcb_desc)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
- struct tx_ts_record *ts = NULL;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-
- if (rtllib_act_scanning(ieee, false))
- return;
-
- if (!ht_info->current_ht_support || !ht_info->enable_ht)
- return;
- if (!is_qos_data_frame(skb->data))
- return;
- if (is_multicast_ether_addr(hdr->addr1))
- return;
-
- if (tcb_desc->bdhcp || ieee->cnt_after_link < 2)
- return;
-
- if (ht_info->iot_action & HT_IOT_ACT_TX_NO_AGGREGATION)
- return;
-
- if (!ieee->get_nmode_support_by_sec_cfg(ieee->dev))
- return;
- if (ht_info->current_ampdu_enable) {
- if (!rtllib_get_ts(ieee, (struct ts_common_info **)(&ts), hdr->addr1,
- skb->priority, TX_DIR, true)) {
- netdev_info(ieee->dev, "%s: can't get TS\n", __func__);
- return;
- }
- if (!ts->tx_admitted_ba_record.b_valid) {
- if (ieee->wpa_ie_len && (ieee->pairwise_key_type ==
- KEY_TYPE_NA)) {
- ;
- } else if (tcb_desc->bdhcp == 1) {
- ;
- } else if (!ts->disable_add_ba) {
- rtllib_ts_start_add_ba_process(ieee, ts);
- }
- return;
- } else if (!ts->using_ba) {
- if (SN_LESS(ts->tx_admitted_ba_record.ba_start_seq_ctrl.field.seq_num,
- (ts->tx_cur_seq + 1) % 4096))
- ts->using_ba = true;
- else
- return;
- }
- if (ieee->iw_mode == IW_MODE_INFRA) {
- tcb_desc->ampdu_enable = true;
- tcb_desc->ampdu_factor = ht_info->current_ampdu_factor;
- tcb_desc->ampdu_density = ht_info->current_mpdu_density;
- }
- }
-}
-
-static void rtllib_query_short_preamble_mode(struct rtllib_device *ieee,
- struct cb_desc *tcb_desc)
-{
- tcb_desc->use_short_preamble = false;
- if (tcb_desc->data_rate == 2)
- return;
- else if (ieee->current_network.capability &
- WLAN_CAPABILITY_SHORT_PREAMBLE)
- tcb_desc->use_short_preamble = true;
-}
-
-static void rtllib_query_ht_cap_short_gi(struct rtllib_device *ieee,
- struct cb_desc *tcb_desc)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
-
- tcb_desc->use_short_gi = false;
-
- if (!ht_info->current_ht_support || !ht_info->enable_ht)
- return;
-
- if (ht_info->cur_bw_40mhz && ht_info->cur_short_gi_40mhz)
- tcb_desc->use_short_gi = true;
- else if (!ht_info->cur_bw_40mhz && ht_info->cur_short_gi_20mhz)
- tcb_desc->use_short_gi = true;
-}
-
-static void rtllib_query_bandwidth_mode(struct rtllib_device *ieee,
- struct cb_desc *tcb_desc)
-{
- struct rt_hi_throughput *ht_info = ieee->ht_info;
-
- tcb_desc->packet_bw = false;
-
- if (!ht_info->current_ht_support || !ht_info->enable_ht)
- return;
-
- if (tcb_desc->multicast || tcb_desc->broadcast)
- return;
-
- if ((tcb_desc->data_rate & 0x80) == 0)
- return;
- if (ht_info->cur_bw_40mhz && ht_info->cur_tx_bw40mhz &&
- !ieee->bandwidth_auto_switch.forced_tx_20MHz)
- tcb_desc->packet_bw = true;
-}
-
-static void rtllib_query_protectionmode(struct rtllib_device *ieee,
- struct cb_desc *tcb_desc,
- struct sk_buff *skb)
-{
- struct rt_hi_throughput *ht_info;
-
- tcb_desc->rtsstbc = false;
- tcb_desc->rts_use_short_gi = false;
- tcb_desc->cts_enable = false;
- tcb_desc->RTSSC = 0;
- tcb_desc->rts_bw = false;
-
- if (tcb_desc->broadcast || tcb_desc->multicast)
- return;
-
- if (is_broadcast_ether_addr(skb->data + 16))
- return;
-
- if (ieee->mode < WIRELESS_MODE_N_24G) {
- if (skb->len > ieee->rts) {
- tcb_desc->rts_enable = true;
- tcb_desc->rts_rate = MGN_24M;
- } else if (ieee->current_network.buseprotection) {
- tcb_desc->rts_enable = true;
- tcb_desc->cts_enable = true;
- tcb_desc->rts_rate = MGN_24M;
- }
- return;
- }
-
- ht_info = ieee->ht_info;
-
- while (true) {
- if (ht_info->iot_action & HT_IOT_ACT_FORCED_CTS2SELF) {
- tcb_desc->cts_enable = true;
- tcb_desc->rts_rate = MGN_24M;
- tcb_desc->rts_enable = true;
- break;
- } else if (ht_info->iot_action & (HT_IOT_ACT_FORCED_RTS |
- HT_IOT_ACT_PURE_N_MODE)) {
- tcb_desc->rts_enable = true;
- tcb_desc->rts_rate = MGN_24M;
- break;
- }
- if (ieee->current_network.buseprotection) {
- tcb_desc->rts_enable = true;
- tcb_desc->cts_enable = true;
- tcb_desc->rts_rate = MGN_24M;
- break;
- }
- if (ht_info->current_ht_support && ht_info->enable_ht) {
- u8 ht_op_mode = ht_info->current_op_mode;
-
- if ((ht_info->cur_bw_40mhz && (ht_op_mode == 2 ||
- ht_op_mode == 3)) ||
- (!ht_info->cur_bw_40mhz && ht_op_mode == 3)) {
- tcb_desc->rts_rate = MGN_24M;
- tcb_desc->rts_enable = true;
- break;
- }
- }
- if (skb->len > ieee->rts) {
- tcb_desc->rts_rate = MGN_24M;
- tcb_desc->rts_enable = true;
- break;
- }
- if (tcb_desc->ampdu_enable) {
- tcb_desc->rts_rate = MGN_24M;
- tcb_desc->rts_enable = false;
- break;
- }
- goto NO_PROTECTION;
- }
- if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
- tcb_desc->use_short_preamble = true;
- return;
-NO_PROTECTION:
- tcb_desc->rts_enable = false;
- tcb_desc->cts_enable = false;
- tcb_desc->rts_rate = 0;
- tcb_desc->RTSSC = 0;
- tcb_desc->rts_bw = false;
-}
-
-static void rtllib_txrate_selectmode(struct rtllib_device *ieee,
- struct cb_desc *tcb_desc)
-{
- if (ieee->tx_dis_rate_fallback)
- tcb_desc->tx_dis_rate_fallback = true;
-
- if (ieee->tx_use_drv_assinged_rate)
- tcb_desc->tx_use_drv_assinged_rate = true;
- if (!tcb_desc->tx_dis_rate_fallback ||
- !tcb_desc->tx_use_drv_assinged_rate) {
- if (ieee->iw_mode == IW_MODE_INFRA)
- tcb_desc->ratr_index = 0;
- }
-}
-
-static u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb,
- u8 *dst)
-{
- u16 seqnum = 0;
-
- if (is_multicast_ether_addr(dst))
- return 0;
- if (is_qos_data_frame(skb->data)) {
- struct tx_ts_record *ts = NULL;
-
- if (!rtllib_get_ts(ieee, (struct ts_common_info **)(&ts), dst,
- skb->priority, TX_DIR, true))
- return 0;
- seqnum = ts->tx_cur_seq;
- ts->tx_cur_seq = (ts->tx_cur_seq + 1) % 4096;
- return seqnum;
- }
- return 0;
-}
-
-static int wme_downgrade_ac(struct sk_buff *skb)
-{
- switch (skb->priority) {
- case 6:
- case 7:
- skb->priority = 5; /* VO -> VI */
- return 0;
- case 4:
- case 5:
- skb->priority = 3; /* VI -> BE */
- return 0;
- case 0:
- case 3:
- skb->priority = 1; /* BE -> BK */
- return 0;
- default:
- return -1;
- }
-}
-
-static u8 rtllib_current_rate(struct rtllib_device *ieee)
-{
- if (ieee->mode & IEEE_MODE_MASK)
- return ieee->rate;
-
- if (ieee->ht_curr_op_rate)
- return ieee->ht_curr_op_rate;
- else
- return ieee->rate & 0x7F;
-}
-
-static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
-{
- struct rtllib_device *ieee = (struct rtllib_device *)
- netdev_priv_rsl(dev);
- struct rtllib_txb *txb = NULL;
- struct ieee80211_qos_hdr *frag_hdr;
- int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
- unsigned long flags;
- struct net_device_stats *stats = &ieee->stats;
- int ether_type = 0, encrypt;
- int bytes, fc, qos_ctl = 0, hdr_len;
- struct sk_buff *skb_frag;
- struct ieee80211_qos_hdr header = { /* Ensure zero initialized */
- .duration_id = 0,
- .seq_ctrl = 0,
- .qos_ctrl = 0
- };
- int qos_activated = ieee->current_network.qos_data.active;
- u8 dest[ETH_ALEN];
- u8 src[ETH_ALEN];
- struct lib80211_crypt_data *crypt = NULL;
- struct cb_desc *tcb_desc;
- u8 is_multicast = false;
- bool bdhcp = false;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /* If there is no driver handler to take the TXB, don't bother
- * creating it...
- */
- if (!(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) ||
- ((!ieee->softmac_data_hard_start_xmit &&
- (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
- netdev_warn(ieee->dev, "No xmit handler.\n");
- goto success;
- }
-
- if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
- netdev_warn(ieee->dev, "skb too small (%d).\n",
- skb->len);
- goto success;
- }
- /* Save source and destination addresses */
- ether_addr_copy(dest, skb->data);
- ether_addr_copy(src, skb->data + ETH_ALEN);
-
- memset(skb->cb, 0, sizeof(skb->cb));
- ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC);
- if (unlikely(!txb)) {
- netdev_warn(ieee->dev,
- "Could not allocate TXB\n");
- goto failed;
- }
-
- txb->encrypted = 0;
- txb->payload_size = cpu_to_le16(skb->len);
- skb_put_data(txb->fragments[0], skb->data, skb->len);
-
- goto success;
- }
-
- if (skb->len > 282) {
- if (ether_type == ETH_P_IP) {
- const struct iphdr *ip = (struct iphdr *)
- ((u8 *)skb->data + 14);
- if (ip->protocol == IPPROTO_UDP) {
- struct udphdr *udp;
-
- udp = (struct udphdr *)((u8 *)ip +
- (ip->ihl << 2));
- if (((((u8 *)udp)[1] == 68) &&
- (((u8 *)udp)[3] == 67)) ||
- ((((u8 *)udp)[1] == 67) &&
- (((u8 *)udp)[3] == 68))) {
- bdhcp = true;
- ieee->lps_delay_cnt = 200;
- }
- }
- } else if (ether_type == ETH_P_ARP) {
- netdev_info(ieee->dev,
- "=================>DHCP Protocol start tx ARP pkt!!\n");
- bdhcp = true;
- ieee->lps_delay_cnt =
- ieee->current_network.tim.tim_count;
- }
- }
-
- skb->priority = rtllib_classify(skb);
- crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
- encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && crypt && crypt->ops;
- if (!encrypt && ieee->ieee802_1x &&
- ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
- stats->tx_dropped++;
- goto success;
- }
- if (crypt && !encrypt && ether_type == ETH_P_PAE) {
- struct eapol *eap = (struct eapol *)(skb->data +
- sizeof(struct ethhdr) - SNAP_SIZE -
- sizeof(u16));
- netdev_dbg(ieee->dev,
- "TX: IEEE 802.11 EAPOL frame: %s\n",
- eap_get_type(eap->type));
- }
-
- /* Advance the SKB to the start of the payload */
- skb_pull(skb, sizeof(struct ethhdr));
-
- /* Determine total amount of storage required for TXB packets */
- bytes = skb->len + SNAP_SIZE + sizeof(u16);
-
- if (encrypt)
- fc = RTLLIB_FTYPE_DATA | IEEE80211_FCTL_PROTECTED;
- else
- fc = RTLLIB_FTYPE_DATA;
-
- if (qos_activated)
- fc |= IEEE80211_STYPE_QOS_DATA;
- else
- fc |= IEEE80211_STYPE_DATA;
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- fc |= IEEE80211_FCTL_TODS;
- /* To DS: Addr1 = BSSID, Addr2 = SA,
- * Addr3 = DA
- */
- ether_addr_copy(header.addr1,
- ieee->current_network.bssid);
- ether_addr_copy(header.addr2, src);
- ether_addr_copy(header.addr3, dest);
- }
-
- is_multicast = is_multicast_ether_addr(header.addr1);
-
- header.frame_control = cpu_to_le16(fc);
-
- /* Determine fragmentation size based on destination (multicast
- * and broadcast are not fragmented)
- */
- if (is_multicast) {
- frag_size = MAX_FRAG_THRESHOLD;
- qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
- } else {
- frag_size = ieee->fts;
- qos_ctl = 0;
- }
-
- if (qos_activated) {
- hdr_len = RTLLIB_3ADDR_LEN + 2;
-
- /* in case we are a client verify acm is not set for this ac */
- while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) {
- netdev_info(ieee->dev, "skb->priority = %x\n",
- skb->priority);
- if (wme_downgrade_ac(skb))
- break;
- netdev_info(ieee->dev, "converted skb->priority = %x\n",
- skb->priority);
- }
-
- qos_ctl |= skb->priority;
- header.qos_ctrl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID);
-
- } else {
- hdr_len = RTLLIB_3ADDR_LEN;
- }
- /* Determine amount of payload per fragment. Regardless of if
- * this stack is providing the full 802.11 header, one will
- * eventually be affixed to this fragment -- so we must account
- * for it when determining the amount of payload space.
- */
- bytes_per_frag = frag_size - hdr_len;
- if (ieee->config &
- (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS))
- bytes_per_frag -= RTLLIB_FCS_LEN;
-
- /* Each fragment may need to have room for encrypting
- * pre/postfix
- */
- if (encrypt) {
- bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
- crypt->ops->extra_mpdu_postfix_len +
- crypt->ops->extra_msdu_prefix_len +
- crypt->ops->extra_msdu_postfix_len;
- }
- /* Number of fragments is the total bytes_per_frag /
- * payload_per_fragment
- */
- nr_frags = bytes / bytes_per_frag;
- bytes_last_frag = bytes % bytes_per_frag;
- if (bytes_last_frag)
- nr_frags++;
- else
- bytes_last_frag = bytes_per_frag;
-
- /* When we allocate the TXB we allocate enough space for the
- * reserve and full fragment bytes (bytes_per_frag doesn't
- * include prefix, postfix, header, FCS, etc.)
- */
- txb = rtllib_alloc_txb(nr_frags, frag_size +
- ieee->tx_headroom, GFP_ATOMIC);
- if (unlikely(!txb)) {
- netdev_warn(ieee->dev, "Could not allocate TXB\n");
- goto failed;
- }
- txb->encrypted = encrypt;
- txb->payload_size = cpu_to_le16(bytes);
-
- if (qos_activated)
- txb->queue_index = UP2AC(skb->priority);
- else
- txb->queue_index = WME_AC_BE;
-
- for (i = 0; i < nr_frags; i++) {
- skb_frag = txb->fragments[i];
- tcb_desc = (struct cb_desc *)(skb_frag->cb +
- MAX_DEV_ADDR_SIZE);
- if (qos_activated) {
- skb_frag->priority = skb->priority;
- tcb_desc->queue_index = UP2AC(skb->priority);
- } else {
- skb_frag->priority = WME_AC_BE;
- tcb_desc->queue_index = WME_AC_BE;
- }
- skb_reserve(skb_frag, ieee->tx_headroom);
-
- if (encrypt) {
- if (ieee->hwsec_active)
- tcb_desc->hw_sec = 1;
- else
- tcb_desc->hw_sec = 0;
- skb_reserve(skb_frag,
- crypt->ops->extra_mpdu_prefix_len +
- crypt->ops->extra_msdu_prefix_len);
- } else {
- tcb_desc->hw_sec = 0;
- }
- frag_hdr = skb_put_data(skb_frag, &header, hdr_len);
-
- /* If this is not the last fragment, then add the
- * MOREFRAGS bit to the frame control
- */
- if (i != nr_frags - 1) {
- frag_hdr->frame_control = cpu_to_le16(fc |
- IEEE80211_FCTL_MOREFRAGS);
- bytes = bytes_per_frag;
-
- } else {
- /* The last fragment has the remaining length */
- bytes = bytes_last_frag;
- }
- if ((qos_activated) && (!is_multicast)) {
- frag_hdr->seq_ctrl =
- cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag,
- header.addr1));
- frag_hdr->seq_ctrl =
- cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctrl) << 4 | i);
- } else {
- frag_hdr->seq_ctrl =
- cpu_to_le16(ieee->seq_ctrl[0] << 4 | i);
- }
- /* Put a SNAP header on the first fragment */
- if (i == 0) {
- rtllib_put_snap(skb_put(skb_frag,
- SNAP_SIZE +
- sizeof(u16)), ether_type);
- bytes -= SNAP_SIZE + sizeof(u16);
- }
-
- skb_put_data(skb_frag, skb->data, bytes);
-
- /* Advance the SKB... */
- skb_pull(skb, bytes);
-
- /* Encryption routine will move the header forward in
- * order to insert the IV between the header and the
- * payload
- */
- if (encrypt)
- rtllib_encrypt_fragment(ieee, skb_frag,
- hdr_len);
- if (ieee->config &
- (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS))
- skb_put(skb_frag, 4);
- }
-
- if ((qos_activated) && (!is_multicast)) {
- if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
- ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
- else
- ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
- } else {
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
- }
-
- success:
- if (txb) {
- tcb_desc = (struct cb_desc *)
- (txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
- tcb_desc->tx_enable_fw_calc_dur = 1;
- tcb_desc->priority = skb->priority;
-
- if (ether_type == ETH_P_PAE) {
- if (ieee->ht_info->iot_action &
- HT_IOT_ACT_WA_IOT_Broadcom) {
- tcb_desc->data_rate =
- mgnt_query_tx_rate_exclude_cck_rates(ieee);
- tcb_desc->tx_dis_rate_fallback = false;
- } else {
- tcb_desc->data_rate = ieee->basic_rate;
- tcb_desc->tx_dis_rate_fallback = 1;
- }
-
- tcb_desc->ratr_index = 7;
- tcb_desc->tx_use_drv_assinged_rate = 1;
- } else {
- if (is_multicast_ether_addr(header.addr1))
- tcb_desc->multicast = 1;
- if (is_broadcast_ether_addr(header.addr1))
- tcb_desc->broadcast = 1;
- rtllib_txrate_selectmode(ieee, tcb_desc);
- if (tcb_desc->multicast || tcb_desc->broadcast)
- tcb_desc->data_rate = ieee->basic_rate;
- else
- tcb_desc->data_rate = rtllib_current_rate(ieee);
-
- if (bdhcp) {
- if (ieee->ht_info->iot_action &
- HT_IOT_ACT_WA_IOT_Broadcom) {
- tcb_desc->data_rate =
- mgnt_query_tx_rate_exclude_cck_rates(ieee);
- tcb_desc->tx_dis_rate_fallback = false;
- } else {
- tcb_desc->data_rate = MGN_1M;
- tcb_desc->tx_dis_rate_fallback = 1;
- }
-
- tcb_desc->ratr_index = 7;
- tcb_desc->tx_use_drv_assinged_rate = 1;
- tcb_desc->bdhcp = 1;
- }
-
- rtllib_query_short_preamble_mode(ieee, tcb_desc);
- rtllib_tx_query_agg_cap(ieee, txb->fragments[0],
- tcb_desc);
- rtllib_query_ht_cap_short_gi(ieee, tcb_desc);
- rtllib_query_bandwidth_mode(ieee, tcb_desc);
- rtllib_query_protectionmode(ieee, tcb_desc,
- txb->fragments[0]);
- }
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
- dev_kfree_skb_any(skb);
- if (txb) {
- if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) {
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += le16_to_cpu(txb->payload_size);
- rtllib_softmac_xmit(txb, ieee);
- } else {
- rtllib_txb_free(txb);
- }
- }
-
- return 0;
-
- failed:
- spin_unlock_irqrestore(&ieee->lock, flags);
- netif_stop_queue(dev);
- stats->tx_errors++;
- return 1;
-}
-
-netdev_tx_t rtllib_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- memset(skb->cb, 0, sizeof(skb->cb));
- return rtllib_xmit_inter(skb, dev) ? NETDEV_TX_BUSY : NETDEV_TX_OK;
-}
-EXPORT_SYMBOL(rtllib_xmit);
diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c
deleted file mode 100644
index c730d921463d..000000000000
--- a/drivers/staging/rtl8192e/rtllib_wx.c
+++ /dev/null
@@ -1,752 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2004 Intel Corporation. All rights reserved.
- *
- * Portions of this file are based on the WEP enablement code provided by the
- * Host AP project hostap-drivers v0.1.3
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- */
-#include <linux/wireless.h>
-#include <linux/kmod.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-#include "rtllib.h"
-
-static const char * const rtllib_modes[] = {
- "a", "b", "g", "?", "N-24G"
-};
-
-#define MAX_CUSTOM_LEN 64
-static inline char *rtl819x_translate_scan(struct rtllib_device *ieee,
- char *start, char *stop,
- struct rtllib_network *network,
- struct iw_request_info *info)
-{
- char custom[MAX_CUSTOM_LEN];
- char proto_name[6];
- char *pname = proto_name;
- char *p;
- struct iw_event iwe;
- int i, j;
- u16 max_rate, rate;
- static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
-
- /* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- ether_addr_copy(iwe.u.ap_addr.sa_data, network->bssid);
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
- /* Remaining entries will be displayed in the order we provide them */
-
- /* Add the ESSID */
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- if (network->ssid_len > 0) {
- iwe.u.data.length = min_t(u8, network->ssid_len, 32);
- start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
- } else if (network->hidden_ssid_len == 0) {
- iwe.u.data.length = sizeof("<hidden>");
- start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
- } else {
- iwe.u.data.length = min_t(u8, network->hidden_ssid_len, 32);
- start = iwe_stream_add_point(info, start, stop, &iwe, network->hidden_ssid);
- }
- /* Add the protocol name */
- iwe.cmd = SIOCGIWNAME;
- for (i = 0; i < ARRAY_SIZE(rtllib_modes); i++) {
- if (network->mode & BIT(i)) {
- strcpy(pname, rtllib_modes[i]);
- pname += strlen(rtllib_modes[i]);
- }
- }
- *pname = '\0';
- snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
- /* Add mode */
- iwe.cmd = SIOCGIWMODE;
- if (network->capability &
- (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
- if (network->capability & WLAN_CAPABILITY_ESS)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
- }
-
- /* Add frequency/channel */
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = network->channel;
- iwe.u.freq.e = 0;
- iwe.u.freq.i = 0;
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
-
- /* Add encryption capability */
- iwe.cmd = SIOCGIWENCODE;
- if (network->capability & WLAN_CAPABILITY_PRIVACY)
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- else
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- iwe.u.data.length = 0;
- start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
- /* Add basic and extended rates */
- max_rate = 0;
- p = custom;
- p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
- for (i = 0, j = 0; i < network->rates_len;) {
- if (j < network->rates_ex_len &&
- ((network->rates_ex[j] & 0x7F) <
- (network->rates[i] & 0x7F)))
- rate = network->rates_ex[j++] & 0x7F;
- else
- rate = network->rates[i++] & 0x7F;
- if (rate > max_rate)
- max_rate = rate;
- p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
- "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
- }
- for (; j < network->rates_ex_len; j++) {
- rate = network->rates_ex[j] & 0x7F;
- p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
- "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
- if (rate > max_rate)
- max_rate = rate;
- }
-
- if (network->mode >= WIRELESS_MODE_N_24G) {
- struct ht_capab_ele *ht_cap = NULL;
- bool is40M = false, isShortGI = false;
- u8 max_mcs = 0;
-
- if (!memcmp(network->bssht.bd_ht_cap_buf, EWC11NHTCap, 4))
- ht_cap = (struct ht_capab_ele *)
- &network->bssht.bd_ht_cap_buf[4];
- else
- ht_cap = (struct ht_capab_ele *)
- &network->bssht.bd_ht_cap_buf[0];
- is40M = (ht_cap->chl_width) ? 1 : 0;
- isShortGI = (ht_cap->chl_width) ?
- ((ht_cap->short_gi_40mhz) ? 1 : 0) :
- ((ht_cap->short_gi_20mhz) ? 1 : 0);
-
- max_mcs = ht_get_highest_mcs_rate(ieee, ht_cap->MCS,
- MCS_FILTER_ALL);
- rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs & 0x7f];
- if (rate > max_rate)
- max_rate = rate;
- }
- iwe.cmd = SIOCGIWRATE;
- iwe.u.bitrate.disabled = 0;
- iwe.u.bitrate.fixed = 0;
- iwe.u.bitrate.value = max_rate * 500000;
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
- /* Add quality statistics */
- /* TODO: Fix these values... */
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = network->stats.signal;
- iwe.u.qual.level = network->stats.rssi;
- iwe.u.qual.noise = network->stats.noise;
- iwe.u.qual.updated = network->stats.mask & RTLLIB_STATMASK_WEMASK;
- if (!(network->stats.mask & RTLLIB_STATMASK_RSSI))
- iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
- if (!(network->stats.mask & RTLLIB_STATMASK_NOISE))
- iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
- if (!(network->stats.mask & RTLLIB_STATMASK_SIGNAL))
- iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
- iwe.u.qual.updated = 7;
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
-
- iwe.cmd = IWEVCUSTOM;
- p = custom;
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- memset(&iwe, 0, sizeof(iwe));
- if (network->wpa_ie_len) {
- char buf[MAX_WPA_IE_LEN];
-
- memcpy(buf, network->wpa_ie, network->wpa_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->wpa_ie_len;
- start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- }
- memset(&iwe, 0, sizeof(iwe));
- if (network->rsn_ie_len) {
- char buf[MAX_WPA_IE_LEN];
-
- memcpy(buf, network->rsn_ie, network->rsn_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->rsn_ie_len;
- start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- }
-
- /* add info for WZC */
- memset(&iwe, 0, sizeof(iwe));
- if (network->wzc_ie_len) {
- char buf[MAX_WZC_IE_LEN];
-
- memcpy(buf, network->wzc_ie, network->wzc_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->wzc_ie_len;
- start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- }
-
- /* Add EXTRA: Age to display seconds since last beacon/probe response
- * for given network.
- */
- iwe.cmd = IWEVCUSTOM;
- p = custom;
- p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
- " Last beacon: %lums ago",
- (100 * (jiffies - network->last_scanned)) / HZ);
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- return start;
-}
-
-int rtllib_wx_get_scan(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct rtllib_network *network;
- unsigned long flags;
-
- char *ev = extra;
- char *stop = ev + wrqu->data.length;
- int i = 0;
- int err = 0;
-
- netdev_dbg(ieee->dev, "Getting scan\n");
- mutex_lock(&ieee->wx_mutex);
- spin_lock_irqsave(&ieee->lock, flags);
-
- list_for_each_entry(network, &ieee->network_list, list) {
- i++;
- if ((stop - ev) < 200) {
- err = -E2BIG;
- break;
- }
- if (ieee->scan_age == 0 ||
- time_after(network->last_scanned + ieee->scan_age, jiffies))
- ev = rtl819x_translate_scan(ieee, ev, stop, network,
- info);
- else
- netdev_dbg(ieee->dev,
- "Network '%s ( %pM)' hidden due to age (%lums).\n",
- escape_essid(network->ssid,
- network->ssid_len),
- network->bssid,
- (100 * (jiffies - network->last_scanned)) /
- HZ);
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
- mutex_unlock(&ieee->wx_mutex);
- wrqu->data.length = ev - extra;
- wrqu->data.flags = 0;
-
- netdev_dbg(ieee->dev, "%s(): %d networks returned.\n", __func__, i);
-
- return err;
-}
-EXPORT_SYMBOL(rtllib_wx_get_scan);
-
-int rtllib_wx_set_encode(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *keybuf)
-{
- struct iw_point *erq = &wrqu->encoding;
- struct net_device *dev = ieee->dev;
- struct rtllib_security sec = {
- .flags = 0
- };
- int i, key, key_provided, len;
- struct lib80211_crypt_data **crypt;
-
- key = erq->flags & IW_ENCODE_INDEX;
- if (key) {
- if (key > NUM_WEP_KEYS)
- return -EINVAL;
- key--;
- key_provided = 1;
- } else {
- key_provided = 0;
- key = ieee->crypt_info.tx_keyidx;
- }
-
- netdev_dbg(ieee->dev, "Key: %d [%s]\n", key, key_provided ?
- "provided" : "default");
- crypt = &ieee->crypt_info.crypt[key];
- if (erq->flags & IW_ENCODE_DISABLED) {
- if (key_provided && *crypt) {
- netdev_dbg(ieee->dev,
- "Disabling encryption on key %d.\n", key);
- lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
- } else {
- netdev_dbg(ieee->dev, "Disabling encryption.\n");
- }
-
- /* Check all the keys to see if any are still configured,
- * and if no key index was provided, de-init them all
- */
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- if (ieee->crypt_info.crypt[i]) {
- if (key_provided)
- break;
- lib80211_crypt_delayed_deinit(&ieee->crypt_info,
- &ieee->crypt_info.crypt[i]);
- }
- }
-
- if (i == NUM_WEP_KEYS) {
- sec.enabled = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL;
- }
-
- goto done;
- }
-
- sec.enabled = 1;
- sec.flags |= SEC_ENABLED;
-
- if (*crypt && (*crypt)->ops &&
- strcmp((*crypt)->ops->name, "R-WEP") != 0) {
- /* changing to use WEP; deinit previously used algorithm
- * on this key
- */
- lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
- }
-
- if (!*crypt) {
- struct lib80211_crypt_data *new_crypt;
-
- /* take WEP into use */
- new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
- if (!new_crypt)
- return -ENOMEM;
- new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
- if (!new_crypt->ops) {
- request_module("rtllib_crypt_wep");
- new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
- }
-
- if (new_crypt->ops)
- new_crypt->priv = new_crypt->ops->init(key);
-
- if (!new_crypt->ops || !new_crypt->priv) {
- kfree(new_crypt);
- new_crypt = NULL;
-
- netdev_warn(dev,
- "%s: could not initialize WEP: load module rtllib_crypt_wep\n",
- dev->name);
- return -EOPNOTSUPP;
- }
- *crypt = new_crypt;
- }
-
- /* If a new key was provided, set it up */
- if (erq->length > 0) {
- len = erq->length <= 5 ? 5 : 13;
- memcpy(sec.keys[key], keybuf, erq->length);
- if (len > erq->length)
- memset(sec.keys[key] + erq->length, 0,
- len - erq->length);
- netdev_dbg(ieee->dev, "Setting key %d to '%s' (%d:%d bytes)\n",
- key, escape_essid(sec.keys[key], len), erq->length,
- len);
- sec.key_sizes[key] = len;
- (*crypt)->ops->set_key(sec.keys[key], len, NULL,
- (*crypt)->priv);
- sec.flags |= (1 << key);
- /* This ensures a key will be activated if no key is
- * explicitly set
- */
- if (key == sec.active_key)
- sec.flags |= SEC_ACTIVE_KEY;
- ieee->crypt_info.tx_keyidx = key;
-
- } else {
- len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
- NULL, (*crypt)->priv);
- if (len == 0) {
- /* Set a default key of all 0 */
- netdev_info(ieee->dev, "Setting key %d to all zero.\n", key);
-
- memset(sec.keys[key], 0, 13);
- (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
- (*crypt)->priv);
- sec.key_sizes[key] = 13;
- sec.flags |= (1 << key);
- }
-
- /* No key data - just set the default TX key index */
- if (key_provided) {
- netdev_dbg(ieee->dev,
- "Setting key %d as default Tx key.\n", key);
- ieee->crypt_info.tx_keyidx = key;
- sec.active_key = key;
- sec.flags |= SEC_ACTIVE_KEY;
- }
- }
- done:
- ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
- ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
- WLAN_AUTH_SHARED_KEY;
- sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
- sec.flags |= SEC_AUTH_MODE;
- netdev_dbg(ieee->dev, "Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
- "OPEN" : "SHARED KEY");
-
- /* For now we just support WEP, so only set that security level...
- * TODO: When WPA is added this is one place that needs to change
- */
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_set_encode);
-
-int rtllib_wx_get_encode(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *keybuf)
-{
- struct iw_point *erq = &wrqu->encoding;
- int len, key;
- struct lib80211_crypt_data *crypt;
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- key = erq->flags & IW_ENCODE_INDEX;
- if (key) {
- if (key > NUM_WEP_KEYS)
- return -EINVAL;
- key--;
- } else {
- key = ieee->crypt_info.tx_keyidx;
- }
- crypt = ieee->crypt_info.crypt[key];
-
- erq->flags = key + 1;
-
- if (!crypt || !crypt->ops) {
- erq->length = 0;
- erq->flags |= IW_ENCODE_DISABLED;
- return 0;
- }
- len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
-
- erq->length = max(len, 0);
-
- erq->flags |= IW_ENCODE_ENABLED;
-
- if (ieee->open_wep)
- erq->flags |= IW_ENCODE_OPEN;
- else
- erq->flags |= IW_ENCODE_RESTRICTED;
-
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_get_encode);
-
-int rtllib_wx_set_encode_ext(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct net_device *dev = ieee->dev;
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int i, idx;
- int group_key = 0;
- const char *alg, *module;
- const struct lib80211_crypto_ops *ops;
- struct lib80211_crypt_data **crypt;
-
- struct rtllib_security sec = {
- .flags = 0,
- };
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if (idx < 1 || idx > NUM_WEP_KEYS)
- return -EINVAL;
- idx--;
- } else {
- idx = ieee->crypt_info.tx_keyidx;
- }
- if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
- crypt = &ieee->crypt_info.crypt[idx];
- group_key = 1;
- } else {
- /* some Cisco APs use idx>0 for unicast in dynamic WEP */
- if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
- return -EINVAL;
- if (ieee->iw_mode == IW_MODE_INFRA)
- crypt = &ieee->crypt_info.crypt[idx];
- else
- return -EINVAL;
- }
-
- sec.flags |= SEC_ENABLED;
- if ((encoding->flags & IW_ENCODE_DISABLED) ||
- ext->alg == IW_ENCODE_ALG_NONE) {
- if (*crypt)
- lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
-
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- if (ieee->crypt_info.crypt[i])
- break;
- }
- if (i == NUM_WEP_KEYS) {
- sec.enabled = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_LEVEL;
- }
- goto done;
- }
-
- sec.enabled = 1;
- switch (ext->alg) {
- case IW_ENCODE_ALG_WEP:
- alg = "R-WEP";
- module = "rtllib_crypt_wep";
- break;
- case IW_ENCODE_ALG_TKIP:
- alg = "R-TKIP";
- module = "rtllib_crypt_tkip";
- break;
- case IW_ENCODE_ALG_CCMP:
- alg = "R-CCMP";
- module = "rtllib_crypt_ccmp";
- break;
- default:
- netdev_dbg(ieee->dev, "Unknown crypto alg %d\n", ext->alg);
- ret = -EINVAL;
- goto done;
- }
- netdev_dbg(dev, "alg name:%s\n", alg);
-
- ops = lib80211_get_crypto_ops(alg);
- if (!ops) {
- char tempbuf[100];
-
- memset(tempbuf, 0x00, 100);
- sprintf(tempbuf, "%s", module);
- request_module("%s", tempbuf);
- ops = lib80211_get_crypto_ops(alg);
- }
- if (!ops) {
- netdev_info(dev, "========>unknown crypto alg %d\n", ext->alg);
- ret = -EINVAL;
- goto done;
- }
-
- if (!*crypt || (*crypt)->ops != ops) {
- struct lib80211_crypt_data *new_crypt;
-
- lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
-
- new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
- if (!new_crypt) {
- ret = -ENOMEM;
- goto done;
- }
- new_crypt->ops = ops;
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
- new_crypt->priv = new_crypt->ops->init(idx);
-
- if (!new_crypt->priv) {
- kfree(new_crypt);
- ret = -EINVAL;
- goto done;
- }
- *crypt = new_crypt;
- }
-
- if (ext->key_len > 0 && (*crypt)->ops->set_key &&
- (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
- (*crypt)->priv) < 0) {
- netdev_info(dev, "key setting failed\n");
- ret = -EINVAL;
- goto done;
- }
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- ieee->crypt_info.tx_keyidx = idx;
- sec.active_key = idx;
- sec.flags |= SEC_ACTIVE_KEY;
- }
- if (ext->alg != IW_ENCODE_ALG_NONE) {
- sec.key_sizes[idx] = ext->key_len;
- sec.flags |= (1 << idx);
- if (ext->alg == IW_ENCODE_ALG_WEP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_2;
- } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_3;
- }
- /* Don't set sec level for group keys. */
- if (group_key)
- sec.flags &= ~SEC_LEVEL;
- }
-done:
- return ret;
-}
-EXPORT_SYMBOL(rtllib_wx_set_encode_ext);
-
-int rtllib_wx_set_mlme(struct rtllib_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- u8 i = 0;
- bool deauth = false;
- struct iw_mlme *mlme = (struct iw_mlme *)extra;
-
- if (ieee->link_state != MAC80211_LINKED)
- return -ENOLINK;
-
- mutex_lock(&ieee->wx_mutex);
-
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- deauth = true;
- fallthrough;
- case IW_MLME_DISASSOC:
- if (deauth)
- netdev_info(ieee->dev, "disauth packet !\n");
- else
- netdev_info(ieee->dev, "dis associate packet!\n");
-
- ieee->cannot_notify = true;
-
- send_disassociation(ieee, deauth, mlme->reason_code);
- rtllib_disassociate(ieee);
-
- ieee->wap_set = 0;
- for (i = 0; i < 6; i++)
- ieee->current_network.bssid[i] = 0x55;
-
- ieee->ssid_set = 0;
- ieee->current_network.ssid[0] = '\0';
- ieee->current_network.ssid_len = 0;
- break;
- default:
- mutex_unlock(&ieee->wx_mutex);
- return -EOPNOTSUPP;
- }
-
- mutex_unlock(&ieee->wx_mutex);
-
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_set_mlme);
-
-int rtllib_wx_set_auth(struct rtllib_device *ieee,
- struct iw_request_info *info,
- struct iw_param *data, char *extra)
-{
- switch (data->flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- break;
- case IW_AUTH_CIPHER_PAIRWISE:
- case IW_AUTH_CIPHER_GROUP:
- case IW_AUTH_KEY_MGMT:
- /* Host AP driver does not use these parameters and allows
- * wpa_supplicant to control them internally.
- */
- break;
- case IW_AUTH_TKIP_COUNTERMEASURES:
- ieee->tkip_countermeasures = data->value;
- break;
- case IW_AUTH_DROP_UNENCRYPTED:
- ieee->drop_unencrypted = data->value;
- break;
-
- case IW_AUTH_80211_AUTH_ALG:
- if (data->value & IW_AUTH_ALG_SHARED_KEY) {
- ieee->open_wep = 0;
- ieee->auth_mode = 1;
- } else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM) {
- ieee->open_wep = 1;
- ieee->auth_mode = 0;
- } else if (data->value & IW_AUTH_ALG_LEAP) {
- ieee->open_wep = 1;
- ieee->auth_mode = 2;
- } else {
- return -EINVAL;
- }
- break;
-
- case IW_AUTH_WPA_ENABLED:
- ieee->wpa_enabled = (data->value) ? 1 : 0;
- break;
-
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ieee->ieee802_1x = data->value;
- break;
- case IW_AUTH_PRIVACY_INVOKED:
- ieee->privacy_invoked = data->value;
- break;
- default:
- return -EOPNOTSUPP;
- }
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_set_auth);
-
-int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
-{
- u8 *buf;
- u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
-
- if (len > MAX_WPA_IE_LEN || (len && !ie))
- return -EINVAL;
-
- if (len) {
- eid = ie[0];
- if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2], wps_oui, 4))) {
- ieee->wps_ie_len = min_t(size_t, len, MAX_WZC_IE_LEN);
- buf = kmemdup(ie, ieee->wps_ie_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- ieee->wps_ie = buf;
- return 0;
- }
- }
- ieee->wps_ie_len = 0;
- kfree(ieee->wps_ie);
- ieee->wps_ie = NULL;
- if (len) {
- if (len != ie[1] + 2)
- return -EINVAL;
- buf = kmemdup(ie, len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = buf;
- ieee->wpa_ie_len = len;
- } else {
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = NULL;
- ieee->wpa_ie_len = 0;
- }
- return 0;
-}
-EXPORT_SYMBOL(rtllib_wx_set_gen_ie);
diff --git a/drivers/staging/rtl8712/TODO b/drivers/staging/rtl8712/TODO
index 847c8c41f4f7..5aed36efa7cb 100644
--- a/drivers/staging/rtl8712/TODO
+++ b/drivers/staging/rtl8712/TODO
@@ -1,6 +1,5 @@
TODO:
- merge Realtek's bugfixes and new features into the driver
-- switch to use LIB80211
- switch to use MAC80211
- checkpatch.pl fixes - only a few remain
diff --git a/drivers/staging/rtl8723bs/TODO b/drivers/staging/rtl8723bs/TODO
index 3d8f5a634a10..4c413f9d3df0 100644
--- a/drivers/staging/rtl8723bs/TODO
+++ b/drivers/staging/rtl8723bs/TODO
@@ -5,7 +5,6 @@ TODO:
- checkpatch.pl fixes - most of the remaining ones are lines too long. Many
of them will require refactoring
- merge Realtek's bugfixes and new features into the driver
-- switch to use LIB80211
- switch to use MAC80211
Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
diff --git a/drivers/staging/vt6655/TODO b/drivers/staging/vt6655/TODO
index 529bc22cd608..27654bd0ff5d 100644
--- a/drivers/staging/vt6655/TODO
+++ b/drivers/staging/vt6655/TODO
@@ -8,7 +8,6 @@ TODO:
- abstract VT3253 chipset specific code
- add common vt665x infrastructure
- kill ttype.h
-- switch to use LIB80211
- switch to use MAC80211
- verify unsigned long usage for x86-64 arch
- reduce .data footprint
diff --git a/drivers/staging/vt6656/TODO b/drivers/staging/vt6656/TODO
index 876cdccb6948..cca78d2d3cfe 100644
--- a/drivers/staging/vt6656/TODO
+++ b/drivers/staging/vt6656/TODO
@@ -8,7 +8,6 @@ TODO:
- abstract VT3184 chipset specific code
- add common vt665x infrastructure
- kill ttype.h -- done
-- switch to use LIB80211
- switch to use MAC80211
- use kernel coding style
- sparse fixes
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 67299e8b734e..47dc96dfe386 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -100,8 +100,16 @@ int debugfs_file_get(struct dentry *dentry)
if (!fsd)
return -ENOMEM;
- fsd->real_fops = (void *)((unsigned long)d_fsd &
- ~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT);
+ if ((unsigned long)d_fsd & DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT) {
+ fsd->real_fops = NULL;
+ fsd->short_fops = (void *)((unsigned long)d_fsd &
+ ~(DEBUGFS_FSDATA_IS_REAL_FOPS_BIT |
+ DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT));
+ } else {
+ fsd->real_fops = (void *)((unsigned long)d_fsd &
+ ~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT);
+ fsd->short_fops = NULL;
+ }
refcount_set(&fsd->active_users, 1);
init_completion(&fsd->active_users_drained);
INIT_LIST_HEAD(&fsd->cancellations);
@@ -241,9 +249,10 @@ static int debugfs_locked_down(struct inode *inode,
{
if ((inode->i_mode & 07777 & ~0444) == 0 &&
!(filp->f_mode & FMODE_WRITE) &&
- !real_fops->unlocked_ioctl &&
- !real_fops->compat_ioctl &&
- !real_fops->mmap)
+ (!real_fops ||
+ (!real_fops->unlocked_ioctl &&
+ !real_fops->compat_ioctl &&
+ !real_fops->mmap)))
return 0;
if (security_locked_down(LOCKDOWN_DEBUGFS))
@@ -316,19 +325,38 @@ static ret_type full_proxy_ ## name(proto) \
return r; \
}
-FULL_PROXY_FUNC(llseek, loff_t, filp,
- PROTO(struct file *filp, loff_t offset, int whence),
- ARGS(filp, offset, whence));
+#define FULL_PROXY_FUNC_BOTH(name, ret_type, filp, proto, args) \
+static ret_type full_proxy_ ## name(proto) \
+{ \
+ struct dentry *dentry = F_DENTRY(filp); \
+ struct debugfs_fsdata *fsd; \
+ ret_type r; \
+ \
+ r = debugfs_file_get(dentry); \
+ if (unlikely(r)) \
+ return r; \
+ fsd = dentry->d_fsdata; \
+ if (fsd->real_fops) \
+ r = fsd->real_fops->name(args); \
+ else \
+ r = fsd->short_fops->name(args); \
+ debugfs_file_put(dentry); \
+ return r; \
+}
+
+FULL_PROXY_FUNC_BOTH(llseek, loff_t, filp,
+ PROTO(struct file *filp, loff_t offset, int whence),
+ ARGS(filp, offset, whence));
-FULL_PROXY_FUNC(read, ssize_t, filp,
- PROTO(struct file *filp, char __user *buf, size_t size,
- loff_t *ppos),
- ARGS(filp, buf, size, ppos));
+FULL_PROXY_FUNC_BOTH(read, ssize_t, filp,
+ PROTO(struct file *filp, char __user *buf, size_t size,
+ loff_t *ppos),
+ ARGS(filp, buf, size, ppos));
-FULL_PROXY_FUNC(write, ssize_t, filp,
- PROTO(struct file *filp, const char __user *buf, size_t size,
- loff_t *ppos),
- ARGS(filp, buf, size, ppos));
+FULL_PROXY_FUNC_BOTH(write, ssize_t, filp,
+ PROTO(struct file *filp, const char __user *buf,
+ size_t size, loff_t *ppos),
+ ARGS(filp, buf, size, ppos));
FULL_PROXY_FUNC(unlocked_ioctl, long, filp,
PROTO(struct file *filp, unsigned int cmd, unsigned long arg),
@@ -363,7 +391,7 @@ static int full_proxy_release(struct inode *inode, struct file *filp)
* not to leak any resources. Releasers must not assume that
* ->i_private is still being meaningful here.
*/
- if (real_fops->release)
+ if (real_fops && real_fops->release)
r = real_fops->release(inode, filp);
replace_fops(filp, d_inode(dentry)->i_fop);
@@ -373,39 +401,48 @@ static int full_proxy_release(struct inode *inode, struct file *filp)
}
static void __full_proxy_fops_init(struct file_operations *proxy_fops,
- const struct file_operations *real_fops)
+ struct debugfs_fsdata *fsd)
{
proxy_fops->release = full_proxy_release;
- if (real_fops->llseek)
+
+ if ((fsd->real_fops && fsd->real_fops->llseek) ||
+ (fsd->short_fops && fsd->short_fops->llseek))
proxy_fops->llseek = full_proxy_llseek;
- if (real_fops->read)
+
+ if ((fsd->real_fops && fsd->real_fops->read) ||
+ (fsd->short_fops && fsd->short_fops->read))
proxy_fops->read = full_proxy_read;
- if (real_fops->write)
+
+ if ((fsd->real_fops && fsd->real_fops->write) ||
+ (fsd->short_fops && fsd->short_fops->write))
proxy_fops->write = full_proxy_write;
- if (real_fops->poll)
+
+ if (fsd->real_fops && fsd->real_fops->poll)
proxy_fops->poll = full_proxy_poll;
- if (real_fops->unlocked_ioctl)
+
+ if (fsd->real_fops && fsd->real_fops->unlocked_ioctl)
proxy_fops->unlocked_ioctl = full_proxy_unlocked_ioctl;
}
static int full_proxy_open(struct inode *inode, struct file *filp)
{
struct dentry *dentry = F_DENTRY(filp);
- const struct file_operations *real_fops = NULL;
+ const struct file_operations *real_fops;
struct file_operations *proxy_fops = NULL;
+ struct debugfs_fsdata *fsd;
int r;
r = debugfs_file_get(dentry);
if (r)
return r == -EIO ? -ENOENT : r;
- real_fops = debugfs_real_fops(filp);
-
+ fsd = dentry->d_fsdata;
+ real_fops = fsd->real_fops;
r = debugfs_locked_down(inode, filp, real_fops);
if (r)
goto out;
- if (!fops_get(real_fops)) {
+ if (real_fops && !fops_get(real_fops)) {
#ifdef CONFIG_MODULES
if (real_fops->owner &&
real_fops->owner->state == MODULE_STATE_GOING) {
@@ -426,11 +463,14 @@ static int full_proxy_open(struct inode *inode, struct file *filp)
r = -ENOMEM;
goto free_proxy;
}
- __full_proxy_fops_init(proxy_fops, real_fops);
+ __full_proxy_fops_init(proxy_fops, fsd);
replace_fops(filp, proxy_fops);
- if (real_fops->open) {
- r = real_fops->open(inode, filp);
+ if (!real_fops || real_fops->open) {
+ if (real_fops)
+ r = real_fops->open(inode, filp);
+ else
+ r = simple_open(inode, filp);
if (r) {
replace_fops(filp, d_inode(dentry)->i_fop);
goto free_proxy;
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 66d9b3b4c588..38a9c7eb97e6 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -412,7 +412,7 @@ static struct dentry *end_creating(struct dentry *dentry)
static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *proxy_fops,
- const struct file_operations *real_fops)
+ const void *real_fops)
{
struct dentry *dentry;
struct inode *inode;
@@ -450,49 +450,38 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
return end_creating(dentry);
}
-/**
- * debugfs_create_file - create a file in the debugfs filesystem
- * @name: a pointer to a string containing the name of the file to create.
- * @mode: the permission that the file should have.
- * @parent: a pointer to the parent dentry for this file. This should be a
- * directory dentry if set. If this parameter is NULL, then the
- * file will be created in the root of the debugfs filesystem.
- * @data: a pointer to something that the caller will want to get to later
- * on. The inode.i_private pointer will point to this value on
- * the open() call.
- * @fops: a pointer to a struct file_operations that should be used for
- * this file.
- *
- * This is the basic "create a file" function for debugfs. It allows for a
- * wide range of flexibility in creating a file, or a directory (if you want
- * to create a directory, the debugfs_create_dir() function is
- * recommended to be used instead.)
- *
- * This function will return a pointer to a dentry if it succeeds. This
- * pointer must be passed to the debugfs_remove() function when the file is
- * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
- * returned.
- *
- * If debugfs is not enabled in the kernel, the value -%ENODEV will be
- * returned.
- *
- * NOTE: it's expected that most callers should _ignore_ the errors returned
- * by this function. Other debugfs functions handle the fact that the "dentry"
- * passed to them could be an error and they don't crash in that case.
- * Drivers should generally work fine even if debugfs fails to init anyway.
- */
-struct dentry *debugfs_create_file(const char *name, umode_t mode,
- struct dentry *parent, void *data,
- const struct file_operations *fops)
+struct dentry *debugfs_create_file_full(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops)
{
+ if (WARN_ON((unsigned long)fops &
+ (DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT |
+ DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)))
+ return ERR_PTR(-EINVAL);
return __debugfs_create_file(name, mode, parent, data,
fops ? &debugfs_full_proxy_file_operations :
&debugfs_noop_file_operations,
fops);
}
-EXPORT_SYMBOL_GPL(debugfs_create_file);
+EXPORT_SYMBOL_GPL(debugfs_create_file_full);
+
+struct dentry *debugfs_create_file_short(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct debugfs_short_fops *fops)
+{
+ if (WARN_ON((unsigned long)fops &
+ (DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT |
+ DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)))
+ return ERR_PTR(-EINVAL);
+
+ return __debugfs_create_file(name, mode, parent, data,
+ fops ? &debugfs_full_proxy_file_operations :
+ &debugfs_noop_file_operations,
+ (const void *)((unsigned long)fops |
+ DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT));
+}
+EXPORT_SYMBOL_GPL(debugfs_create_file_short);
/**
* debugfs_create_file_unsafe - create a file in the debugfs filesystem
diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h
index dae80c2a469e..a3edfa4f0d8e 100644
--- a/fs/debugfs/internal.h
+++ b/fs/debugfs/internal.h
@@ -18,6 +18,7 @@ extern const struct file_operations debugfs_full_proxy_file_operations;
struct debugfs_fsdata {
const struct file_operations *real_fops;
+ const struct debugfs_short_fops *short_fops;
union {
/* automount_fn is used when real_fops is NULL */
debugfs_automount_t automount;
@@ -39,6 +40,11 @@ struct debugfs_fsdata {
* pointer gets its lowest bit set.
*/
#define DEBUGFS_FSDATA_IS_REAL_FOPS_BIT BIT(0)
+/*
+ * A dentry's ->d_fsdata, when pointing to real fops, is with
+ * short fops instead of full fops.
+ */
+#define DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT BIT(1)
/* Access BITS */
#define DEBUGFS_ALLOW_API BIT(0)
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index 0928a6c8ae1e..59444b495d49 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -71,9 +71,63 @@ typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *);
struct dentry *debugfs_lookup(const char *name, struct dentry *parent);
-struct dentry *debugfs_create_file(const char *name, umode_t mode,
- struct dentry *parent, void *data,
- const struct file_operations *fops);
+struct debugfs_short_fops {
+ ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
+ ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
+ loff_t (*llseek) (struct file *, loff_t, int);
+};
+
+struct dentry *debugfs_create_file_full(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops);
+struct dentry *debugfs_create_file_short(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct debugfs_short_fops *fops);
+
+/**
+ * debugfs_create_file - create a file in the debugfs filesystem
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have.
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ * on. The inode.i_private pointer will point to this value on
+ * the open() call.
+ * @fops: a pointer to a struct file_operations or struct debugfs_short_fops that
+ * should be used for this file.
+ *
+ * This is the basic "create a file" function for debugfs. It allows for a
+ * wide range of flexibility in creating a file, or a directory (if you want
+ * to create a directory, the debugfs_create_dir() function is
+ * recommended to be used instead.)
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
+ * returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ *
+ * If fops points to a struct debugfs_short_fops, then simple_open() will be
+ * used for the open, and only read/write/llseek are supported and are proxied,
+ * so no module reference or release are needed.
+ *
+ * NOTE: it's expected that most callers should _ignore_ the errors returned
+ * by this function. Other debugfs functions handle the fact that the "dentry"
+ * passed to them could be an error and they don't crash in that case.
+ * Drivers should generally work fine even if debugfs fails to init anyway.
+ */
+#define debugfs_create_file(name, mode, parent, data, fops) \
+ _Generic(fops, \
+ const struct file_operations *: debugfs_create_file_full, \
+ const struct debugfs_short_fops *: debugfs_create_file_short, \
+ struct file_operations *: debugfs_create_file_full, \
+ struct debugfs_short_fops *: debugfs_create_file_short) \
+ (name, mode, parent, data, fops)
+
struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);
@@ -207,7 +261,7 @@ static inline struct dentry *debugfs_lookup(const char *name,
static inline struct dentry *debugfs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
- const struct file_operations *fops)
+ const void *fops)
{
return ERR_PTR(-ENODEV);
}
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 389f92e4d980..3c552b648b27 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1793,7 +1793,6 @@ enum netdev_reg_state {
* @wireless_handlers: List of functions to handle Wireless Extensions,
* instead of ioctl,
* see <net/iw_handler.h> for details.
- * @wireless_data: Instance data managed by the core of wireless extensions
*
* @netdev_ops: Includes several pointers to callbacks,
* if one wants to override the ndo_*() functions
@@ -2172,7 +2171,6 @@ struct net_device {
#ifdef CONFIG_WIRELESS_EXT
const struct iw_handler_def *wireless_handlers;
- struct iw_public_data *wireless_data;
#endif
const struct ethtool_ops *ethtool_ops;
#ifdef CONFIG_NET_L3_MASTER_DEV
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index e6e34d74dda0..03e5d3fe226d 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -21,8 +21,7 @@ struct compat_iw_point {
__u16 length;
__u16 flags;
};
-#endif
-#ifdef CONFIG_COMPAT
+
struct __compat_iw_event {
__u16 len; /* Real length of this stuff */
__u16 cmd; /* Wireless IOCTL */
@@ -49,5 +48,5 @@ struct __compat_iw_event {
#define IW_EV_COMPAT_POINT_LEN \
(IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
IW_EV_COMPAT_POINT_OFF)
-#endif
+#endif /* CONFIG_COMPAT */
#endif /* _LINUX_WIRELESS_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 69ec1eb41a09..8f9853b1a5d1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1460,7 +1460,6 @@ struct cfg80211_unsol_bcast_probe_resp {
* @crypto: crypto settings
* @privacy: the BSS uses privacy
* @auth_type: Authentication type (algorithm)
- * @smps_mode: SMPS mode
* @inactivity_timeout: time in seconds to determine station's inactivity.
* @p2p_ctwindow: P2P CT Window
* @p2p_opp_ps: P2P opportunistic PS
@@ -1498,7 +1497,6 @@ struct cfg80211_ap_settings {
struct cfg80211_crypto_settings crypto;
bool privacy;
enum nl80211_auth_type auth_type;
- enum nl80211_smps_mode smps_mode;
int inactivity_timeout;
u8 p2p_ctwindow;
bool p2p_opp_ps;
@@ -2269,6 +2267,7 @@ static inline int cfg80211_get_station(struct net_device *dev,
* @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering
* @MONITOR_FLAG_COOK_FRAMES: report frames after processing
* @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address
+ * @MONITOR_FLAG_SKIP_TX: do not pass locally transmitted frames
*/
enum monitor_flags {
MONITOR_FLAG_CHANGED = BIT(__NL80211_MNTR_FLAG_INVALID),
@@ -2278,6 +2277,7 @@ enum monitor_flags {
MONITOR_FLAG_OTHER_BSS = BIT(NL80211_MNTR_FLAG_OTHER_BSS),
MONITOR_FLAG_COOK_FRAMES = BIT(NL80211_MNTR_FLAG_COOK_FRAMES),
MONITOR_FLAG_ACTIVE = BIT(NL80211_MNTR_FLAG_ACTIVE),
+ MONITOR_FLAG_SKIP_TX = BIT(NL80211_MNTR_FLAG_SKIP_TX),
};
/**
@@ -4696,6 +4696,7 @@ struct cfg80211_ops {
struct ieee80211_channel *chan);
int (*set_monitor_channel)(struct wiphy *wiphy,
+ struct net_device *dev,
struct cfg80211_chan_def *chandef);
int (*scan)(struct wiphy *wiphy,
@@ -5436,6 +5437,8 @@ struct wiphy_radio_freq_range {
* @iface_combinations: Valid interface combinations array, should not
* list single interface types.
* @n_iface_combinations: number of entries in @iface_combinations array.
+ *
+ * @antenna_mask: bitmask of antennas connected to this radio.
*/
struct wiphy_radio {
const struct wiphy_radio_freq_range *freq_range;
@@ -5443,6 +5446,8 @@ struct wiphy_radio {
const struct ieee80211_iface_combination *iface_combinations;
int n_iface_combinations;
+
+ u32 antenna_mask;
};
#define CFG80211_HW_TIMESTAMP_ALL_PEERS 0xffff
@@ -6223,6 +6228,7 @@ enum ieee80211_ap_reg_power {
* entered.
* @links.cac_time_ms: CAC time in ms
* @valid_links: bitmap describing what elements of @links are valid
+ * @radio_mask: Bitmask of radios that this interface is allowed to operate on.
*/
struct wireless_dev {
struct wiphy *wiphy;
@@ -6335,6 +6341,8 @@ struct wireless_dev {
unsigned int cac_time_ms;
} links[IEEE80211_MLD_MAX_NUM_LINKS];
u16 valid_links;
+
+ u32 radio_mask;
};
static inline const u8 *wdev_address(struct wireless_dev *wdev)
@@ -6521,6 +6529,17 @@ bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
const struct cfg80211_chan_def *chandef);
/**
+ * cfg80211_wdev_channel_allowed - Check if the wdev may use the channel
+ *
+ * @wdev: the wireless device
+ * @chan: channel to check
+ *
+ * Return: whether or not the wdev may use the channel
+ */
+bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev,
+ struct ieee80211_channel *chan);
+
+/**
* ieee80211_get_response_rate - get basic rate for a given rate
*
* @sband: the band to look for rates in
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index 7af1082ea9a0..b80e474cb0aa 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -279,8 +279,6 @@
#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */
/* SET : Omit payload from generated iwevent */
#define IW_DESCR_FLAG_NOMAX 0x0008 /* GET : no limit on request size */
-/* Driver level flags */
-#define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */
/****************************** TYPES ******************************/
@@ -373,11 +371,10 @@ struct iw_handler_def {
*/
struct iw_ioctl_description {
__u8 header_type; /* NULL, iw_point or other */
- __u8 token_type; /* Future */
+ __u8 flags; /* Special handling of the request */
__u16 token_size; /* Granularity of payload */
__u16 min_tokens; /* Min acceptable token number */
__u16 max_tokens; /* Max acceptable token number */
- __u32 flags; /* Special handling of the request */
};
/* Need to think of short header translation table. Later. */
@@ -404,26 +401,6 @@ struct iw_spy_data {
u_char spy_thr_under[IW_MAX_SPY];
};
-/* --------------------- DEVICE WIRELESS DATA --------------------- */
-/*
- * This is all the wireless data specific to a device instance that
- * is managed by the core of Wireless Extensions or the 802.11 layer.
- * We only keep pointer to those structures, so that a driver is free
- * to share them between instances.
- * This structure should be initialised before registering the device.
- * Access to this data follow the same rules as any other struct net_device
- * data (i.e. valid as long as struct net_device exist, same locking rules).
- */
-/* Forward declaration */
-struct libipw_device;
-/* The struct */
-struct iw_public_data {
- /* Driver enhanced spy support */
- struct iw_spy_data * spy_data;
- /* Legacy structure managed by the ipw2x00-specific IEEE 802.11 layer */
- struct libipw_device * libipw;
-};
-
/**************************** PROTOTYPES ****************************/
/*
* Functions part of the Wireless Extensions (defined in net/wireless/wext-core.c).
@@ -443,22 +420,6 @@ static inline void wireless_nlevent_flush(void) {}
/* We may need a function to send a stream of events to user space.
* More on that later... */
-/* Standard handler for SIOCSIWSPY */
-int iw_handler_set_spy(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-/* Standard handler for SIOCGIWSPY */
-int iw_handler_get_spy(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-/* Standard handler for SIOCSIWTHRSPY */
-int iw_handler_set_thrspy(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-/* Standard handler for SIOCGIWTHRSPY */
-int iw_handler_get_thrspy(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-/* Driver call to update spy records */
-void wireless_spy_update(struct net_device *dev, unsigned char *address,
- struct iw_quality *wstats);
-
/************************* INLINE FUNCTIONS *************************/
/*
* Function that are so simple that it's more efficient inlining them
diff --git a/include/net/lib80211.h b/include/net/lib80211.h
deleted file mode 100644
index fd0f15d87d80..000000000000
--- a/include/net/lib80211.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * lib80211.h -- common bits for IEEE802.11 wireless drivers
- *
- * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
- *
- * Some bits copied from old ieee80211 component, w/ original copyright
- * notices below:
- *
- * Original code based on Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <j@w1.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- *
- * Copyright (c) 2004, Intel Corporation
- *
- */
-
-#ifndef LIB80211_H
-#define LIB80211_H
-
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/atomic.h>
-#include <linux/if.h>
-#include <linux/skbuff.h>
-#include <linux/ieee80211.h>
-#include <linux/timer.h>
-#include <linux/seq_file.h>
-
-#define NUM_WEP_KEYS 4
-
-enum {
- IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
-};
-
-struct module;
-
-struct lib80211_crypto_ops {
- const char *name;
- struct list_head list;
-
- /* init new crypto context (e.g., allocate private data space,
- * select IV, etc.); returns NULL on failure or pointer to allocated
- * private data on success */
- void *(*init) (int keyidx);
-
- /* deinitialize crypto context and free allocated private data */
- void (*deinit) (void *priv);
-
- /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
- * value from decrypt_mpdu is passed as the keyidx value for
- * decrypt_msdu. skb must have enough head and tail room for the
- * encryption; if not, error will be returned; these functions are
- * called for all MPDUs (i.e., fragments).
- */
- int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
- int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
-
- /* These functions are called for full MSDUs, i.e. full frames.
- * These can be NULL if full MSDU operations are not needed. */
- int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
- int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
- void *priv);
-
- int (*set_key) (void *key, int len, u8 * seq, void *priv);
- int (*get_key) (void *key, int len, u8 * seq, void *priv);
-
- /* procfs handler for printing out key information and possible
- * statistics */
- void (*print_stats) (struct seq_file *m, void *priv);
-
- /* Crypto specific flag get/set for configuration settings */
- unsigned long (*get_flags) (void *priv);
- unsigned long (*set_flags) (unsigned long flags, void *priv);
-
- /* maximum number of bytes added by encryption; encrypt buf is
- * allocated with extra_prefix_len bytes, copy of in_buf, and
- * extra_postfix_len; encrypt need not use all this space, but
- * the result must start at the beginning of the buffer and correct
- * length must be returned */
- int extra_mpdu_prefix_len, extra_mpdu_postfix_len;
- int extra_msdu_prefix_len, extra_msdu_postfix_len;
-
- struct module *owner;
-};
-
-struct lib80211_crypt_data {
- struct list_head list; /* delayed deletion list */
- const struct lib80211_crypto_ops *ops;
- void *priv;
- atomic_t refcnt;
-};
-
-struct lib80211_crypt_info {
- char *name;
- /* Most clients will already have a lock,
- so just point to that. */
- spinlock_t *lock;
-
- struct lib80211_crypt_data *crypt[NUM_WEP_KEYS];
- int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
- struct list_head crypt_deinit_list;
- struct timer_list crypt_deinit_timer;
- int crypt_quiesced;
-};
-
-int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name,
- spinlock_t *lock);
-void lib80211_crypt_info_free(struct lib80211_crypt_info *info);
-int lib80211_register_crypto_ops(const struct lib80211_crypto_ops *ops);
-int lib80211_unregister_crypto_ops(const struct lib80211_crypto_ops *ops);
-const struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name);
-void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info,
- struct lib80211_crypt_data **crypt);
-
-#endif /* LIB80211_H */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 333e0fae6796..b4f246cdcca4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -213,7 +213,7 @@ struct ieee80211_low_level_stats {
* @IEEE80211_CHANCTX_CHANGE_RADAR: radar detection flag changed
* @IEEE80211_CHANCTX_CHANGE_CHANNEL: switched to another operating channel,
* this is used only with channel switching with CSA
- * @IEEE80211_CHANCTX_CHANGE_MIN_WIDTH: The min required channel width changed
+ * @IEEE80211_CHANCTX_CHANGE_MIN_DEF: The min chandef changed
* @IEEE80211_CHANCTX_CHANGE_AP: The AP channel definition changed, so (wider
* bandwidth) OFDMA settings need to be changed
* @IEEE80211_CHANCTX_CHANGE_PUNCTURING: The punctured channel(s) bitmap
@@ -224,7 +224,7 @@ enum ieee80211_chanctx_change {
IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1),
IEEE80211_CHANCTX_CHANGE_RADAR = BIT(2),
IEEE80211_CHANCTX_CHANGE_CHANNEL = BIT(3),
- IEEE80211_CHANCTX_CHANGE_MIN_WIDTH = BIT(4),
+ IEEE80211_CHANCTX_CHANGE_MIN_DEF = BIT(4),
IEEE80211_CHANCTX_CHANGE_AP = BIT(5),
IEEE80211_CHANCTX_CHANGE_PUNCTURING = BIT(6),
};
@@ -740,6 +740,19 @@ struct ieee80211_parsed_tpe {
* @eht_80mhz_full_bw_ul_mumimo: in AP-mode, does this BSS support the
* reception of an EHT TB PPDU on an RU that spans the entire PPDU
* bandwidth
+ * @bss_param_ch_cnt: in BSS-mode, the BSS params change count. This
+ * information is the latest known value. It can come from this link's
+ * beacon or from a beacon sent by another link.
+ * @bss_param_ch_cnt_link_id: in BSS-mode, the link_id to which the beacon
+ * that updated &bss_param_ch_cnt belongs. E.g. if link 1 doesn't hear
+ * its beacons, and link 2 sent a beacon with an RNR element that updated
+ * link 1's BSS params change count, then, link 1's
+ * bss_param_ch_cnt_link_id will be 2. That means that link 1 knows that
+ * link 2 was the link that updated its bss_param_ch_cnt value.
+ * In case link 1 hears its beacon again, bss_param_ch_cnt_link_id will
+ * be updated to 1, even if bss_param_ch_cnt didn't change. This allows
+ * the link to know that it heard the latest value from its own beacon
+ * (as opposed to hearing its value from another link's beacon).
*/
struct ieee80211_bss_conf {
struct ieee80211_vif *vif;
@@ -834,6 +847,8 @@ struct ieee80211_bss_conf {
bool eht_su_beamformee;
bool eht_mu_beamformer;
bool eht_80mhz_full_bw_ul_mumimo;
+ u8 bss_param_ch_cnt;
+ u8 bss_param_ch_cnt_link_id;
};
/**
@@ -1448,8 +1463,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* @RX_FLAG_AMPDU_IS_LAST: this subframe is the last subframe of the A-MPDU
* @RX_FLAG_AMPDU_DELIM_CRC_ERROR: A delimiter CRC error has been detected
* on this subframe
- * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
- * is stored in the @ampdu_delimiter_crc field)
* @RX_FLAG_MIC_STRIPPED: The mic was stripped of this packet. Decryption was
* done by the hardware
* @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without
@@ -1521,7 +1534,7 @@ enum mac80211_rx_flags {
RX_FLAG_AMPDU_LAST_KNOWN = BIT(12),
RX_FLAG_AMPDU_IS_LAST = BIT(13),
RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(14),
- RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(15),
+ /* one free bit at 15 */
RX_FLAG_MACTIME = BIT(16) | BIT(17),
RX_FLAG_MACTIME_PLCP_START = 1 << 16,
RX_FLAG_MACTIME_START = 2 << 16,
@@ -1618,7 +1631,6 @@ enum mac80211_rx_encoding {
* @rx_flags: internal RX flags for mac80211
* @ampdu_reference: A-MPDU reference number, must be a different value for
* each A-MPDU but the same for each subframe within one A-MPDU
- * @ampdu_delimiter_crc: A-MPDU delimiter CRC
* @zero_length_psdu_type: radiotap type of the 0-length PSDU
* @link_valid: if the link which is identified by @link_id is valid. This flag
* is set only when connection is MLO.
@@ -1656,7 +1668,6 @@ struct ieee80211_rx_status {
s8 signal;
u8 chains;
s8 chain_signal[IEEE80211_MAX_CHAINS];
- u8 ampdu_delimiter_crc;
u8 zero_length_psdu_type;
u8 link_valid:1, link_id:4;
};
@@ -2683,6 +2694,11 @@ struct ieee80211_txq {
* a virtual monitor interface when monitor interfaces are the only
* active interfaces.
*
+ * @IEEE80211_HW_NO_VIRTUAL_MONITOR: The driver would like to be informed
+ * of any monitor interface, as well as their configured channel.
+ * This is useful for supporting multiple monitor interfaces on different
+ * channels.
+ *
* @IEEE80211_HW_NO_AUTO_VIF: The driver would like for no wlanX to
* be created. It is expected user-space will create vifs as
* desired (and thus have them named as desired).
@@ -2842,6 +2858,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_DYNAMIC_PS,
IEEE80211_HW_MFP_CAPABLE,
IEEE80211_HW_WANT_MONITOR_VIF,
+ IEEE80211_HW_NO_VIRTUAL_MONITOR,
IEEE80211_HW_NO_AUTO_VIF,
IEEE80211_HW_SW_CRYPTO_CONTROL,
IEEE80211_HW_SUPPORT_FAST_XMIT,
@@ -4075,8 +4092,8 @@ struct ieee80211_prep_tx_info {
* in @sta_state.
* The callback can sleep.
*
- * @sta_rc_update: Notifies the driver of changes to the bitrates that can be
- * used to transmit to the station. The changes are advertised with bits
+ * @link_sta_rc_update: Notifies the driver of changes to the bitrates that can
+ * be used to transmit to the station. The changes are advertised with bits
* from &enum ieee80211_rate_control_changed and the values are reflected
* in the station data. This callback should only be used when the driver
* uses hardware rate control (%IEEE80211_HW_HAS_RATE_CONTROL) since
@@ -4444,6 +4461,12 @@ struct ieee80211_prep_tx_info {
* if the requested TID-To-Link mapping can be accepted or not.
* If it's not accepted the driver may suggest a preferred mapping and
* modify @ttlm parameter with the suggested TID-to-Link mapping.
+ * @prep_add_interface: prepare for interface addition. This can be used by
+ * drivers to prepare for the addition of a new interface, e.g., allocate
+ * the needed resources etc. This callback doesn't guarantee that an
+ * interface with the specified type would be added, and thus drivers that
+ * implement this callback need to handle such cases. The type is the full
+ * &enum nl80211_iftype.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -4560,10 +4583,10 @@ struct ieee80211_ops {
void (*sta_pre_rcu_remove)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
- void (*sta_rc_update)(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- u32 changed);
+ void (*link_sta_rc_update)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_link_sta *link_sta,
+ u32 changed);
void (*sta_rate_tbl_update)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
@@ -4828,6 +4851,8 @@ struct ieee80211_ops {
enum ieee80211_neg_ttlm_res
(*can_neg_ttlm)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_neg_ttlm *ttlm);
+ void (*prep_add_interface)(struct ieee80211_hw *hw,
+ enum nl80211_iftype type);
};
/**
@@ -7681,6 +7706,33 @@ void ieee80211_set_active_links_async(struct ieee80211_vif *vif,
*/
void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif);
+/**
+ * ieee80211_chan_width_to_rx_bw - convert channel width to STA RX bandwidth
+ * @width: the channel width value to convert
+ * Return: the STA RX bandwidth value for the channel width
+ */
+static inline enum ieee80211_sta_rx_bandwidth
+ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
+{
+ switch (width) {
+ default:
+ WARN_ON_ONCE(1);
+ fallthrough;
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
+ return IEEE80211_STA_RX_BW_20;
+ case NL80211_CHAN_WIDTH_40:
+ return IEEE80211_STA_RX_BW_40;
+ case NL80211_CHAN_WIDTH_80:
+ return IEEE80211_STA_RX_BW_80;
+ case NL80211_CHAN_WIDTH_160:
+ case NL80211_CHAN_WIDTH_80P80:
+ return IEEE80211_STA_RX_BW_160;
+ case NL80211_CHAN_WIDTH_320:
+ return IEEE80211_STA_RX_BW_320;
+ }
+}
+
/* for older drivers - let's not document these ... */
int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx);
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f97f5adc8d51..6d11437596b9 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2868,6 +2868,9 @@ enum nl80211_commands {
* nested item, it contains attributes defined in
* &enum nl80211_if_combination_attrs.
*
+ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32).
+ * A value of 0 means all radios.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3416,6 +3419,8 @@ enum nl80211_attrs {
NL80211_ATTR_WIPHY_RADIOS,
NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
+ NL80211_ATTR_VIF_RADIO_MASK,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -4698,6 +4703,7 @@ enum nl80211_survey_info {
* overrides all other flags.
* @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address
* and ACK incoming unicast packets.
+ * @NL80211_MNTR_FLAG_SKIP_TX: do not pass local tx packets
*
* @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
* @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
@@ -4710,6 +4716,7 @@ enum nl80211_mntr_flags {
NL80211_MNTR_FLAG_OTHER_BSS,
NL80211_MNTR_FLAG_COOK_FRAMES,
NL80211_MNTR_FLAG_ACTIVE,
+ NL80211_MNTR_FLAG_SKIP_TX,
/* keep last */
__NL80211_MNTR_FLAG_AFTER_LAST,
@@ -8031,6 +8038,8 @@ enum nl80211_ap_settings_flags {
* @NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION: Supported interface
* combination for this radio. Attribute may be present multiple times
* and contains attributes defined in &enum nl80211_if_combination_attrs.
+ * @NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK: bitmask (u32) of antennas
+ * connected to this radio.
*
* @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal
* @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute
@@ -8041,6 +8050,7 @@ enum nl80211_wiphy_radio_attrs {
NL80211_WIPHY_RADIO_ATTR_INDEX,
NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE,
NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION,
+ NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK,
/* keep last */
__NL80211_WIPHY_RADIO_ATTR_LAST,
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 1c18b862ef8c..04cb45cfb310 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -797,7 +797,7 @@ void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid,
if (!test_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state)) {
ieee80211_send_addba_with_timeout(sta, tid_tx);
- /* RESPONSE_RECEIVED state whould trigger the flow again */
+ /* RESPONSE_RECEIVED state would trigger the flow again */
return;
}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 847304a3a29a..6c0b228523cb 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -105,8 +105,11 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
}
/* also validate MU-MIMO change */
- monitor_sdata = wiphy_dereference(local->hw.wiphy,
- local->monitor_sdata);
+ if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
+ monitor_sdata = sdata;
+ else
+ monitor_sdata = wiphy_dereference(local->hw.wiphy,
+ local->monitor_sdata);
if (!monitor_sdata &&
(params->vht_mumimo_groups || params->vht_mumimo_follow_addr))
@@ -114,7 +117,9 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
/* apply all changes now - no failures allowed */
- if (monitor_sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
+ if (monitor_sdata &&
+ (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) ||
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)))
ieee80211_set_mu_mimo_follow(monitor_sdata, params);
if (params->flags) {
@@ -194,6 +199,24 @@ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
}
}
+ /* Let the driver know that an interface is going to be added.
+ * Indicate so only for interface types that will be added to the
+ * driver.
+ */
+ switch (type) {
+ case NL80211_IFTYPE_AP_VLAN:
+ break;
+ case NL80211_IFTYPE_MONITOR:
+ if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) ||
+ !(params->flags & MONITOR_FLAG_ACTIVE))
+ break;
+ fallthrough;
+ default:
+ drv_prep_add_interface(local,
+ ieee80211_vif_type_p2p(&sdata->vif));
+ break;
+ }
+
return wdev;
}
@@ -879,6 +902,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
}
static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
+ struct net_device *dev,
struct cfg80211_chan_def *chandef)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
@@ -888,22 +912,25 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
lockdep_assert_wiphy(local->hw.wiphy);
- if (cfg80211_chandef_identical(&local->monitor_chanreq.oper,
- &chanreq.oper))
- return 0;
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
+ if (cfg80211_chandef_identical(&local->monitor_chanreq.oper,
+ &chanreq.oper))
+ return 0;
- sdata = wiphy_dereference(local->hw.wiphy,
- local->monitor_sdata);
- if (!sdata)
- goto done;
+ sdata = wiphy_dereference(wiphy, local->monitor_sdata);
+ if (!sdata)
+ goto done;
+ }
- if (cfg80211_chandef_identical(&sdata->vif.bss_conf.chanreq.oper,
+ if (rcu_access_pointer(sdata->deflink.conf->chanctx_conf) &&
+ cfg80211_chandef_identical(&sdata->vif.bss_conf.chanreq.oper,
&chanreq.oper))
return 0;
ieee80211_link_release_channel(&sdata->deflink);
ret = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
- IEEE80211_CHANCTX_EXCLUSIVE);
+ IEEE80211_CHANCTX_SHARED);
if (ret)
return ret;
done:
@@ -1294,9 +1321,6 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
if (old)
return -EALREADY;
- if (params->smps_mode != NL80211_SMPS_OFF)
- return -EOPNOTSUPP;
-
link->smps_mode = IEEE80211_SMPS_OFF;
link->needed_rx_chains = sdata->local->rx_chains;
@@ -1705,7 +1729,7 @@ static int sta_apply_auth_flags(struct ieee80211_local *local,
* before drv_sta_state() is called.
*/
if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
- rate_control_rate_init(sta);
+ rate_control_rate_init_all_links(sta);
ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
if (ret)
@@ -2134,7 +2158,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
*/
if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
test_sta_flag(sta, WLAN_STA_ASSOC))
- rate_control_rate_init(sta);
+ rate_control_rate_init_all_links(sta);
return sta_info_insert(sta);
}
@@ -3046,13 +3070,30 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
enum nl80211_tx_power_setting txp_type = type;
bool update_txp_type = false;
bool has_monitor = false;
+ int user_power_level;
lockdep_assert_wiphy(local->hw.wiphy);
+ switch (type) {
+ case NL80211_TX_POWER_AUTOMATIC:
+ user_power_level = IEEE80211_UNSET_POWER_LEVEL;
+ txp_type = NL80211_TX_POWER_LIMITED;
+ break;
+ case NL80211_TX_POWER_LIMITED:
+ case NL80211_TX_POWER_FIXED:
+ if (mbm < 0 || (mbm % 100))
+ return -EOPNOTSUPP;
+ user_power_level = MBM_TO_DBM(mbm);
+ break;
+ default:
+ return -EINVAL;
+ }
+
if (wdev) {
sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
return -EOPNOTSUPP;
@@ -3062,57 +3103,67 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
return -EOPNOTSUPP;
}
- switch (type) {
- case NL80211_TX_POWER_AUTOMATIC:
- sdata->deflink.user_power_level =
- IEEE80211_UNSET_POWER_LEVEL;
- txp_type = NL80211_TX_POWER_LIMITED;
- break;
- case NL80211_TX_POWER_LIMITED:
- case NL80211_TX_POWER_FIXED:
- if (mbm < 0 || (mbm % 100))
- return -EOPNOTSUPP;
- sdata->deflink.user_power_level = MBM_TO_DBM(mbm);
- break;
- }
+ for (int link_id = 0;
+ link_id < ARRAY_SIZE(sdata->link);
+ link_id++) {
+ struct ieee80211_link_data *link =
+ wiphy_dereference(wiphy, sdata->link[link_id]);
- if (txp_type != sdata->vif.bss_conf.txpower_type) {
- update_txp_type = true;
- sdata->vif.bss_conf.txpower_type = txp_type;
- }
+ if (!link)
+ continue;
- ieee80211_recalc_txpower(sdata, update_txp_type);
+ link->user_power_level = user_power_level;
+
+ if (txp_type != link->conf->txpower_type) {
+ update_txp_type = true;
+ link->conf->txpower_type = txp_type;
+ }
+ ieee80211_recalc_txpower(link, update_txp_type);
+ }
return 0;
}
- switch (type) {
- case NL80211_TX_POWER_AUTOMATIC:
- local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
- txp_type = NL80211_TX_POWER_LIMITED;
- break;
- case NL80211_TX_POWER_LIMITED:
- case NL80211_TX_POWER_FIXED:
- if (mbm < 0 || (mbm % 100))
- return -EOPNOTSUPP;
- local->user_power_level = MBM_TO_DBM(mbm);
- break;
- }
+ local->user_power_level = user_power_level;
list_for_each_entry(sdata, &local->interfaces, list) {
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
has_monitor = true;
continue;
}
- sdata->deflink.user_power_level = local->user_power_level;
- if (txp_type != sdata->vif.bss_conf.txpower_type)
- update_txp_type = true;
- sdata->vif.bss_conf.txpower_type = txp_type;
+
+ for (int link_id = 0;
+ link_id < ARRAY_SIZE(sdata->link);
+ link_id++) {
+ struct ieee80211_link_data *link =
+ wiphy_dereference(wiphy, sdata->link[link_id]);
+
+ if (!link)
+ continue;
+
+ link->user_power_level = local->user_power_level;
+ if (txp_type != link->conf->txpower_type)
+ update_txp_type = true;
+ link->conf->txpower_type = txp_type;
+ }
}
list_for_each_entry(sdata, &local->interfaces, list) {
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
continue;
- ieee80211_recalc_txpower(sdata, update_txp_type);
+
+ for (int link_id = 0;
+ link_id < ARRAY_SIZE(sdata->link);
+ link_id++) {
+ struct ieee80211_link_data *link =
+ wiphy_dereference(wiphy, sdata->link[link_id]);
+
+ if (!link)
+ continue;
+
+ ieee80211_recalc_txpower(link, update_txp_type);
+ }
}
if (has_monitor) {
@@ -3124,7 +3175,8 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
update_txp_type = true;
sdata->vif.bss_conf.txpower_type = txp_type;
- ieee80211_recalc_txpower(sdata, update_txp_type);
+ ieee80211_recalc_txpower(&sdata->deflink,
+ update_txp_type);
}
}
@@ -4301,7 +4353,8 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
if (chanctx_conf) {
*chandef = link->conf->chanreq.oper;
ret = 0;
- } else if (local->open_count > 0 &&
+ } else if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) &&
+ local->open_count > 0 &&
local->open_count == local->monitors &&
sdata->vif.type == NL80211_IFTYPE_MONITOR) {
*chandef = local->monitor_chanreq.oper;
@@ -5023,6 +5076,13 @@ ieee80211_add_link_station(struct wiphy *wiphy, struct net_device *dev,
return ret;
}
+ if (test_sta_flag(sta, WLAN_STA_ASSOC)) {
+ struct link_sta_info *link_sta;
+
+ link_sta = sdata_dereference(sta->link[params->link_id], sdata);
+ rate_control_rate_init(link_sta);
+ }
+
/* ieee80211_sta_activate_link frees the link upon failure */
return ieee80211_sta_activate_link(sta, params->link_id);
}
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index cca6d14084d2..a442cb667520 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -323,22 +323,34 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
continue;
switch (link->sdata->vif.type) {
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_AP_VLAN:
- width = ieee80211_get_max_required_bw(link);
- break;
case NL80211_IFTYPE_STATION:
+ if (!link->sdata->vif.cfg.assoc) {
+ /*
+ * The AP's sta->bandwidth may not yet be set
+ * at this point (pre-association), so simply
+ * take the width from the chandef. We cannot
+ * have TDLS peers yet (only after association).
+ */
+ width = link->conf->chanreq.oper.width;
+ break;
+ }
/*
- * The ap's sta->bandwidth is not set yet at this
- * point, so take the width from the chandef, but
- * account also for TDLS peers
+ * otherwise just use min_def like in AP, depending on what
+ * we currently think the AP STA (and possibly TDLS peers)
+ * require(s)
*/
- width = max(link->conf->chanreq.oper.width,
- ieee80211_get_max_required_bw(link));
+ fallthrough;
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_AP_VLAN:
+ width = ieee80211_get_max_required_bw(link);
break;
case NL80211_IFTYPE_P2P_DEVICE:
case NL80211_IFTYPE_NAN:
continue;
+ case NL80211_IFTYPE_MONITOR:
+ WARN_ON_ONCE(!ieee80211_hw_check(&local->hw,
+ NO_VIRTUAL_MONITOR));
+ fallthrough;
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
case NL80211_IFTYPE_OCB:
@@ -347,7 +359,6 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
case NL80211_IFTYPE_WDS:
case NL80211_IFTYPE_UNSPECIFIED:
case NUM_NL80211_IFTYPES:
- case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_P2P_GO:
WARN_ON_ONCE(1);
@@ -409,7 +420,7 @@ _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
if (!ctx->driver_present)
return 0;
- return IEEE80211_CHANCTX_CHANGE_MIN_WIDTH;
+ return IEEE80211_CHANCTX_CHANGE_MIN_DEF;
}
static void ieee80211_chan_bw_change(struct ieee80211_local *local,
@@ -462,12 +473,12 @@ static void ieee80211_chan_bw_change(struct ieee80211_local *local,
continue;
/* vif changed to narrow BW and narrow BW for station wasn't
- * requested or vise versa */
+ * requested or vice versa */
if ((new_sta_bw < link_sta->pub->bandwidth) == !narrowed)
continue;
link_sta->pub->bandwidth = new_sta_bw;
- rate_control_rate_update(local, sband, sta, link_id,
+ rate_control_rate_update(local, sband, link_sta,
IEEE80211_RC_BW_CHANGED);
}
}
@@ -905,7 +916,7 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
}
if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
- ieee80211_recalc_txpower(sdata, false);
+ ieee80211_recalc_txpower(link, false);
ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL, false);
}
@@ -956,6 +967,10 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
if (!link->sdata->u.mgd.associated)
continue;
break;
+ case NL80211_IFTYPE_MONITOR:
+ if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
+ continue;
+ break;
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
@@ -968,6 +983,11 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
if (rcu_access_pointer(link->conf->chanctx_conf) != &chanctx->conf)
continue;
+ if (link->sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+ rx_chains_dynamic = rx_chains_static = local->rx_chains;
+ break;
+ }
+
switch (link->smps_mode) {
default:
WARN_ONCE(1, "Invalid SMPS mode %d\n",
@@ -1118,7 +1138,7 @@ ieee80211_replace_chanctx(struct ieee80211_local *local,
*
* Consider ctx1..3, link1..6, each ctx has 2 links. link1 and
* link2 from ctx1 request new different chandefs starting 2
- * in-place reserations with ctx4 and ctx5 replacing ctx1 and
+ * in-place reservations with ctx4 and ctx5 replacing ctx1 and
* ctx2 respectively. Next link5 and link6 from ctx3 reserve
* ctx4. If link3 and link4 remain on ctx2 as they are then this
* fails unless `replace_ctx` from ctx5 is replaced with ctx3.
@@ -1169,7 +1189,7 @@ ieee80211_replace_chanctx(struct ieee80211_local *local,
static bool
ieee80211_find_available_radio(struct ieee80211_local *local,
const struct ieee80211_chan_req *chanreq,
- int *radio_idx)
+ u32 radio_mask, int *radio_idx)
{
struct wiphy *wiphy = local->hw.wiphy;
const struct wiphy_radio *radio;
@@ -1180,6 +1200,9 @@ ieee80211_find_available_radio(struct ieee80211_local *local,
return true;
for (i = 0; i < wiphy->n_radio; i++) {
+ if (!(radio_mask & BIT(i)))
+ continue;
+
radio = &wiphy->radio[i];
if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper))
continue;
@@ -1213,7 +1236,9 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link,
new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode);
if (!new_ctx) {
if (ieee80211_can_create_new_chanctx(local, -1) &&
- ieee80211_find_available_radio(local, chanreq, &radio_idx))
+ ieee80211_find_available_radio(local, chanreq,
+ sdata->wdev.radio_mask,
+ &radio_idx))
new_ctx = ieee80211_new_chanctx(local, chanreq, mode,
false, radio_idx);
else
@@ -1712,7 +1737,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
link,
changed);
- ieee80211_recalc_txpower(sdata, false);
+ ieee80211_recalc_txpower(link, false);
}
ieee80211_recalc_chanctx_chantype(local, ctx);
@@ -1883,7 +1908,9 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link,
/* Note: context is now reserved */
if (ctx)
reserved = true;
- else if (!ieee80211_find_available_radio(local, chanreq, &radio_idx))
+ else if (!ieee80211_find_available_radio(local, chanreq,
+ sdata->wdev.radio_mask,
+ &radio_idx))
ctx = ERR_PTR(-EBUSY);
else
ctx = ieee80211_new_chanctx(local, chanreq, mode,
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 02b5476a4376..be2e486907f9 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -42,9 +42,8 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \
}
#define DEBUGFS_READONLY_FILE_OPS(name) \
-static const struct file_operations name## _ops = { \
+static const struct debugfs_short_fops name## _ops = { \
.read = name## _read, \
- .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -142,10 +141,9 @@ static ssize_t aqm_write(struct file *file,
return -EINVAL;
}
-static const struct file_operations aqm_ops = {
+static const struct debugfs_short_fops aqm_ops = {
.write = aqm_write,
.read = aqm_read,
- .open = simple_open,
.llseek = default_llseek,
};
@@ -194,10 +192,9 @@ static ssize_t airtime_flags_write(struct file *file,
return count;
}
-static const struct file_operations airtime_flags_ops = {
+static const struct debugfs_short_fops airtime_flags_ops = {
.write = airtime_flags_write,
.read = airtime_flags_read,
- .open = simple_open,
.llseek = default_llseek,
};
@@ -225,9 +222,8 @@ static ssize_t aql_pending_read(struct file *file,
buf, len);
}
-static const struct file_operations aql_pending_ops = {
+static const struct debugfs_short_fops aql_pending_ops = {
.read = aql_pending_read,
- .open = simple_open,
.llseek = default_llseek,
};
@@ -305,10 +301,9 @@ static ssize_t aql_txq_limit_write(struct file *file,
return count;
}
-static const struct file_operations aql_txq_limit_ops = {
+static const struct debugfs_short_fops aql_txq_limit_ops = {
.write = aql_txq_limit_write,
.read = aql_txq_limit_read,
- .open = simple_open,
.llseek = default_llseek,
};
@@ -355,10 +350,9 @@ static ssize_t aql_enable_write(struct file *file, const char __user *user_buf,
return count;
}
-static const struct file_operations aql_enable_ops = {
+static const struct debugfs_short_fops aql_enable_ops = {
.write = aql_enable_write,
.read = aql_enable_read,
- .open = simple_open,
.llseek = default_llseek,
};
@@ -406,10 +400,9 @@ static ssize_t force_tx_status_write(struct file *file,
return count;
}
-static const struct file_operations force_tx_status_ops = {
+static const struct debugfs_short_fops force_tx_status_ops = {
.write = force_tx_status_write,
.read = force_tx_status_read,
- .open = simple_open,
.llseek = default_llseek,
};
@@ -434,9 +427,8 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf,
return count;
}
-static const struct file_operations reset_ops = {
+static const struct debugfs_short_fops reset_ops = {
.write = reset_write,
- .open = simple_open,
.llseek = noop_llseek,
};
#endif
@@ -456,6 +448,7 @@ static const char *hw_flag_names[] = {
FLAG(SUPPORTS_DYNAMIC_PS),
FLAG(MFP_CAPABLE),
FLAG(WANT_MONITOR_VIF),
+ FLAG(NO_VIRTUAL_MONITOR),
FLAG(NO_AUTO_VIF),
FLAG(SW_CRYPTO_CONTROL),
FLAG(SUPPORT_FAST_XMIT),
@@ -623,9 +616,8 @@ static ssize_t stats_ ##name## _read(struct file *file, \
print_devstats_##name); \
} \
\
-static const struct file_operations stats_ ##name## _ops = { \
+static const struct debugfs_short_fops stats_ ##name## _ops = { \
.read = stats_ ##name## _read, \
- .open = simple_open, \
.llseek = generic_file_llseek, \
};
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 7e54da508765..b3a64edea0f2 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -26,17 +26,15 @@ static ssize_t key_##name##_read(struct file *file, \
#define KEY_READ_X(name) KEY_READ(name, name, "0x%x\n")
#define KEY_OPS(name) \
-static const struct file_operations key_ ##name## _ops = { \
+static const struct debugfs_short_fops key_ ##name## _ops = { \
.read = key_##name##_read, \
- .open = simple_open, \
.llseek = generic_file_llseek, \
}
#define KEY_OPS_W(name) \
-static const struct file_operations key_ ##name## _ops = { \
+static const struct debugfs_short_fops key_ ##name## _ops = { \
.read = key_##name##_read, \
.write = key_##name##_write, \
- .open = simple_open, \
.llseek = generic_file_llseek, \
}
@@ -49,9 +47,8 @@ static const struct file_operations key_ ##name## _ops = { \
#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, "%d\n")
#define KEY_CONF_OPS(name) \
-static const struct file_operations key_ ##name## _ops = { \
+static const struct debugfs_short_fops key_ ##name## _ops = { \
.read = key_conf_##name##_read, \
- .open = simple_open, \
.llseek = generic_file_llseek, \
}
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 68596ef78b15..a9bc2fd59f55 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -221,10 +221,9 @@ static ssize_t ieee80211_if_fmt_##name( \
}
#define _IEEE80211_IF_FILE_OPS(name, _read, _write) \
-static const struct file_operations name##_ops = { \
+static const struct debugfs_short_fops name##_ops = { \
.read = (_read), \
.write = (_write), \
- .open = simple_open, \
.llseek = generic_file_llseek, \
}
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 1e9389c49a57..a67a9d316008 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -30,17 +30,15 @@ static ssize_t sta_ ##name## _read(struct file *file, \
#define STA_READ_D(name, field) STA_READ(name, field, "%d\n")
#define STA_OPS(name) \
-static const struct file_operations sta_ ##name## _ops = { \
+static const struct debugfs_short_fops sta_ ##name## _ops = { \
.read = sta_##name##_read, \
- .open = simple_open, \
.llseek = generic_file_llseek, \
}
#define STA_OPS_RW(name) \
-static const struct file_operations sta_ ##name## _ops = { \
+static const struct debugfs_short_fops sta_ ##name## _ops = { \
.read = sta_##name##_read, \
.write = sta_##name##_write, \
- .open = simple_open, \
.llseek = generic_file_llseek, \
}
@@ -450,9 +448,8 @@ STA_OPS_RW(agg_status);
/* link sta attributes */
#define LINK_STA_OPS(name) \
-static const struct file_operations link_sta_ ##name## _ops = { \
+static const struct debugfs_short_fops link_sta_ ##name## _ops = { \
.read = link_sta_##name##_read, \
- .open = simple_open, \
.llseek = generic_file_llseek, \
}
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index fe868b521622..299d38e9e863 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -65,6 +65,7 @@ int drv_add_interface(struct ieee80211_local *local,
if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
(sdata->vif.type == NL80211_IFTYPE_MONITOR &&
!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) &&
!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))))
return -EINVAL;
@@ -181,9 +182,10 @@ int drv_sta_set_txpwr(struct ieee80211_local *local,
return ret;
}
-void drv_sta_rc_update(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata,
- struct ieee80211_sta *sta, u32 changed)
+void drv_link_sta_rc_update(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_link_sta *link_sta,
+ u32 changed)
{
sdata = get_bss_sdata(sdata);
if (!check_sdata_in_driver(sdata))
@@ -193,10 +195,10 @@ void drv_sta_rc_update(struct ieee80211_local *local,
(sdata->vif.type != NL80211_IFTYPE_ADHOC &&
sdata->vif.type != NL80211_IFTYPE_MESH_POINT));
- trace_drv_sta_rc_update(local, sdata, sta, changed);
- if (local->ops->sta_rc_update)
- local->ops->sta_rc_update(&local->hw, &sdata->vif,
- sta, changed);
+ trace_drv_link_sta_rc_update(local, sdata, link_sta, changed);
+ if (local->ops->link_sta_rc_update)
+ local->ops->link_sta_rc_update(&local->hw, &sdata->vif,
+ link_sta, changed);
trace_drv_return_void(local);
}
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index d382d9729e85..edd1e4d4ad9d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -594,9 +594,9 @@ int drv_sta_set_txpwr(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct sta_info *sta);
-void drv_sta_rc_update(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata,
- struct ieee80211_sta *sta, u32 changed);
+void drv_link_sta_rc_update(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_link_sta *link_sta, u32 changed);
static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
@@ -1728,4 +1728,16 @@ drv_can_neg_ttlm(struct ieee80211_local *local,
return res;
}
+
+static inline void
+drv_prep_add_interface(struct ieee80211_local *local,
+ enum nl80211_iftype type)
+{
+ trace_drv_prep_add_interface(local, type);
+ if (local->ops->prep_add_interface)
+ local->ops->prep_add_interface(&local->hw, type);
+
+ trace_drv_return_void(local);
+}
+
#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/eht.c b/net/mac80211/eht.c
index ddc7acc68335..7a3116c36df9 100644
--- a/net/mac80211/eht.c
+++ b/net/mac80211/eht.c
@@ -2,7 +2,7 @@
/*
* EHT handling
*
- * Copyright(c) 2021-2023 Intel Corporation
+ * Copyright(c) 2021-2024 Intel Corporation
*/
#include "ieee80211_i.h"
@@ -75,4 +75,23 @@ ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata,
link_sta->cur_max_bandwidth = ieee80211_sta_cap_rx_bw(link_sta);
link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta);
+
+ switch (u8_get_bits(eht_cap->eht_cap_elem.mac_cap_info[0],
+ IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK)) {
+ case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454:
+ link_sta->pub->agg.max_amsdu_len =
+ IEEE80211_MAX_MPDU_LEN_VHT_11454;
+ break;
+ case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991:
+ link_sta->pub->agg.max_amsdu_len =
+ IEEE80211_MAX_MPDU_LEN_VHT_7991;
+ break;
+ case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_3895:
+ default:
+ link_sta->pub->agg.max_amsdu_len =
+ IEEE80211_MAX_MPDU_LEN_VHT_3895;
+ break;
+ }
+
+ ieee80211_sta_recalc_aggregates(&link_sta->sta->sta);
}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 3f74bbceeca5..a1b4178deccf 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -569,7 +569,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
if (!sta->sdata->u.ibss.control_port)
sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
- rate_control_rate_init(sta);
+ rate_control_rate_init(&sta->deflink);
/* If it fails, maybe we raced another insertion? */
if (sta_info_insert_rcu(sta))
@@ -1068,11 +1068,12 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
/* Force rx_nss recalculation */
sta->sta.deflink.rx_nss = 0;
- rate_control_rate_init(sta);
+ rate_control_rate_init(&sta->deflink);
if (sta->sta.deflink.rx_nss != rx_nss)
changed |= IEEE80211_RC_NSS_CHANGED;
- drv_sta_rc_update(local, sdata, &sta->sta, changed);
+ drv_link_sta_rc_update(local, sdata, &sta->sta.deflink,
+ changed);
}
rcu_read_unlock();
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4f0390918b60..7dcb46120abc 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1015,8 +1015,6 @@ struct ieee80211_link_data_managed {
int wmm_last_param_set;
int mu_edca_last_param_set;
-
- u8 bss_param_ch_cnt;
};
struct ieee80211_link_data_ap {
@@ -1370,7 +1368,7 @@ struct ieee80211_local {
spinlock_t queue_stop_reason_lock;
int open_count;
- int monitors, cooked_mntrs;
+ int monitors, cooked_mntrs, tx_mntrs;
/* number of interfaces with corresponding FIF_ flags */
int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
fif_probe_req;
@@ -2035,8 +2033,8 @@ void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata);
int ieee80211_add_virtual_monitor(struct ieee80211_local *local);
void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
-bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
-void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
+bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link);
+void ieee80211_recalc_txpower(struct ieee80211_link_data *link,
bool update_bss);
void ieee80211_recalc_offload(struct ieee80211_local *local);
@@ -2196,8 +2194,6 @@ ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta)
return _ieee80211_sta_cur_vht_bw(link_sta, NULL);
}
void ieee80211_sta_init_nss(struct link_sta_info *link_sta);
-enum ieee80211_sta_rx_bandwidth
-ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width);
enum nl80211_chan_width
ieee80211_sta_cap_chan_bw(struct link_sta_info *link_sta);
void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata,
@@ -2452,7 +2448,7 @@ static inline bool ieee80211_can_run_worker(struct ieee80211_local *local)
/*
* If quiescing is set, we are racing with __ieee80211_suspend.
* __ieee80211_suspend flushes the workers after setting quiescing,
- * and we check quiescing / suspended before enqueing new workers.
+ * and we check quiescing / suspended before enqueuing new workers.
* We should abort the worker to avoid the races below.
*/
if (local->quiescing)
@@ -2545,8 +2541,8 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
const struct cfg80211_chan_def *chandef);
u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata);
-u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef);
-u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef,
+u8 *ieee80211_ie_build_he_oper(u8 *pos, const struct cfg80211_chan_def *chandef);
+u8 *ieee80211_ie_build_eht_oper(u8 *pos, const struct cfg80211_chan_def *chandef,
const struct ieee80211_sta_eht_cap *eht_cap);
int ieee80211_parse_bitrates(enum nl80211_chan_width width,
const struct ieee80211_supported_band *sband,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 6ef0990d3d29..a8fbedd530f4 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -44,13 +44,13 @@
static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work);
-bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
+bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link)
{
struct ieee80211_chanctx_conf *chanctx_conf;
int power;
rcu_read_lock();
- chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+ chanctx_conf = rcu_dereference(link->conf->chanctx_conf);
if (!chanctx_conf) {
rcu_read_unlock();
return false;
@@ -59,27 +59,26 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
power = ieee80211_chandef_max_power(&chanctx_conf->def);
rcu_read_unlock();
- if (sdata->deflink.user_power_level != IEEE80211_UNSET_POWER_LEVEL)
- power = min(power, sdata->deflink.user_power_level);
+ if (link->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
+ power = min(power, link->user_power_level);
- if (sdata->deflink.ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
- power = min(power, sdata->deflink.ap_power_level);
+ if (link->ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
+ power = min(power, link->ap_power_level);
- if (power != sdata->vif.bss_conf.txpower) {
- sdata->vif.bss_conf.txpower = power;
- ieee80211_hw_config(sdata->local, 0);
+ if (power != link->conf->txpower) {
+ link->conf->txpower = power;
return true;
}
return false;
}
-void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
+void ieee80211_recalc_txpower(struct ieee80211_link_data *link,
bool update_bss)
{
- if (__ieee80211_recalc_txpower(sdata) ||
- (update_bss && ieee80211_sdata_running(sdata)))
- ieee80211_link_info_change_notify(sdata, &sdata->deflink,
+ if (__ieee80211_recalc_txpower(link) ||
+ (update_bss && ieee80211_sdata_running(link->sdata)))
+ ieee80211_link_info_change_notify(link->sdata, link,
BSS_CHANGED_TXPOWER);
}
@@ -279,8 +278,13 @@ static int _ieee80211_change_mac(struct ieee80211_sub_if_data *sdata,
ret = eth_mac_addr(sdata->dev, sa);
if (ret == 0) {
- memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
- ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
+ if (check_dup) {
+ memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
+ ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
+ } else {
+ memset(sdata->vif.addr, 0, ETH_ALEN);
+ memset(sdata->vif.bss_conf.addr, 0, ETH_ALEN);
+ }
}
/* Regardless of eth_mac_addr() return we still want to add the
@@ -699,9 +703,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
ieee80211_recalc_idle(local);
ieee80211_recalc_offload(local);
- if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
+ if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) &&
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
break;
+ ieee80211_link_release_channel(&sdata->deflink);
fallthrough;
default:
if (!going_down)
@@ -1087,6 +1093,8 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
ADJUST(CONTROL, control);
ADJUST(CONTROL, pspoll);
ADJUST(OTHER_BSS, other_bss);
+ if (!(flags & MONITOR_FLAG_SKIP_TX))
+ local->tx_mntrs += offset;
#undef ADJUST
}
@@ -1131,7 +1139,8 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
ASSERT_RTNL();
lockdep_assert_wiphy(local->hw.wiphy);
- if (local->monitor_sdata)
+ if (local->monitor_sdata ||
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
return 0;
sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL);
@@ -1193,6 +1202,9 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
{
struct ieee80211_sub_if_data *sdata;
+ if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
+ return;
+
ASSERT_RTNL();
lockdep_assert_wiphy(local->hw.wiphy);
@@ -1328,7 +1340,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
break;
}
- if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
+ if ((sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) ||
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
res = drv_add_interface(local, sdata);
if (res)
goto err_stop;
@@ -2176,9 +2189,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
ieee80211_set_default_queues(sdata);
- sdata->deflink.ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
- sdata->deflink.user_power_level = local->user_power_level;
-
/* setup type-dependent data */
ieee80211_setup_sdata(sdata, type);
diff --git a/net/mac80211/link.c b/net/mac80211/link.c
index 0bbac64d5fa0..e8def387d0f8 100644
--- a/net/mac80211/link.c
+++ b/net/mac80211/link.c
@@ -36,6 +36,9 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
link->conf = link_conf;
link_conf->link_id = link_id;
link_conf->vif = &sdata->vif;
+ link->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
+ link->user_power_level = sdata->local->user_power_level;
+ link_conf->txpower = INT_MIN;
wiphy_work_init(&link->csa.finalize_work,
ieee80211_csa_finalize_work);
@@ -385,6 +388,37 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata,
jiffies);
}
+ for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
+ struct ieee80211_link_data *link;
+
+ link = sdata_dereference(sdata->link[link_id], sdata);
+
+ /*
+ * This call really should not fail. Unfortunately, it appears
+ * that this may happen occasionally with some drivers. Should
+ * it happen, we are stuck in a bad place as going backwards is
+ * not really feasible.
+ *
+ * So lets just tell link_use_channel that it must not fail to
+ * assign the channel context (from mac80211's perspective) and
+ * assume the driver is going to trigger a recovery flow if it
+ * had a failure.
+ * That really is not great nor guaranteed to work. But at least
+ * the internal mac80211 state remains consistent and there is
+ * a chance that we can recover.
+ */
+ ret = _ieee80211_link_use_channel(link,
+ &link->conf->chanreq,
+ IEEE80211_CHANCTX_SHARED,
+ true);
+ WARN_ON_ONCE(ret);
+
+ /*
+ * inform about the link info changed parameters after all
+ * stations are also added
+ */
+ }
+
list_for_each_entry(sta, &local->sta_list, list) {
if (sdata != sta->sdata)
continue;
@@ -428,26 +462,6 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata,
link = sdata_dereference(sdata->link[link_id], sdata);
- /*
- * This call really should not fail. Unfortunately, it appears
- * that this may happen occasionally with some drivers. Should
- * it happen, we are stuck in a bad place as going backwards is
- * not really feasible.
- *
- * So lets just tell link_use_channel that it must not fail to
- * assign the channel context (from mac80211's perspective) and
- * assume the driver is going to trigger a recovery flow if it
- * had a failure.
- * That really is not great nor guaranteed to work. But at least
- * the internal mac80211 state remains consistent and there is
- * a chance that we can recover.
- */
- ret = _ieee80211_link_use_channel(link,
- &link->conf->chanreq,
- IEEE80211_CHANCTX_SHARED,
- true);
- WARN_ON_ONCE(ret);
-
ieee80211_mgd_set_link_qos_params(link);
ieee80211_link_info_change_notify(sdata, link,
BSS_CHANGED_ERP_CTS_PROT |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 640239f4425b..cb5f16366b9c 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1482,7 +1482,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
if (!elems)
return;
- /* ignore non-mesh or secure / unsecure mismatch */
+ /* ignore non-mesh or secure / insecure mismatch */
if ((!elems->mesh_id || !elems->mesh_config) ||
(elems->rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) ||
(!elems->rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE))
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 579d0f24ac9d..4e9546e998b6 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -220,12 +220,12 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
/**
* mesh_path_error_tx - Sends a PERR mesh management frame
*
+ * @sdata: local mesh subif
* @ttl: allowed remaining hops
* @target: broken destination
* @target_sn: SN of the broken destination
* @target_rcode: reason code for this PERR
* @ra: node this frame is addressed to
- * @sdata: local mesh subif
*
* Note: This function may be called with driver locks taken that the driver
* also acquires in the TX path. To avoid a deadlock we don't transmit the
@@ -1137,8 +1137,8 @@ enddiscovery:
/**
* mesh_nexthop_resolve - lookup next hop; conditionally start path discovery
*
- * @skb: 802.11 frame to be sent
* @sdata: network subif the frame will be sent through
+ * @skb: 802.11 frame to be sent
*
* Lookup next hop for given skb and start path discovery if no
* forwarding information is found.
@@ -1245,8 +1245,8 @@ void mesh_path_refresh(struct ieee80211_sub_if_data *sdata,
* this function is considered "using" the associated mpath, so preempt a path
* refresh if this mpath expires soon.
*
- * @skb: 802.11 frame to be sent
* @sdata: network subif the frame will be sent through
+ * @skb: 802.11 frame to be sent
*
* Returns: 0 if the next hop was found. Nonzero otherwise.
*/
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 30c0d89203af..9f9cb5af0a97 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -300,8 +300,8 @@ __mesh_path_lookup_by_idx(struct mesh_table *tbl, int idx)
/**
* mesh_path_lookup_by_idx - look up a path in the mesh path table by its index
- * @idx: index
* @sdata: local subif, or NULL for all entries
+ * @idx: index
*
* Returns: pointer to the mesh path structure, or NULL if not found.
*
@@ -315,8 +315,8 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
/**
* mpp_path_lookup_by_idx - look up a path in the proxy path table by its index
- * @idx: index
* @sdata: local subif, or NULL for all entries
+ * @idx: index
*
* Returns: pointer to the proxy path structure, or NULL if not found.
*
@@ -670,8 +670,8 @@ void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata,
/**
* mesh_path_add - allocate and add a new path to the mesh path table
- * @dst: destination address of the path (ETH_ALEN length)
* @sdata: local subif
+ * @dst: destination address of the path (ETH_ALEN length)
*
* Returns: 0 on success
*
@@ -916,8 +916,8 @@ static int table_path_del(struct mesh_table *tbl,
/**
* mesh_path_del - delete a mesh path from the table
*
- * @addr: dst address (ETH_ALEN length)
* @sdata: local subif
+ * @addr: dst address (ETH_ALEN length)
*
* Returns: 0 if successful
*/
@@ -996,8 +996,8 @@ int mesh_path_send_to_gates(struct mesh_path *mpath)
/**
* mesh_path_discard_frame - discard a frame whose path could not be resolved
*
- * @skb: frame to discard
* @sdata: network subif the frame was to be sent through
+ * @skb: frame to discard
*
* Locking: the function must me called within a rcu_read_lock region
*/
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 8f2b492a9fe9..6ea35c88dc48 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -486,10 +486,11 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
sta->sta.deflink.bandwidth = IEEE80211_STA_RX_BW_20;
}
+ /* FIXME: this check is wrong without SW rate control */
if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
- rate_control_rate_init(sta);
+ rate_control_rate_init(&sta->deflink);
else
- rate_control_rate_update(local, sband, sta, 0, changed);
+ rate_control_rate_update(local, sband, &sta->deflink, changed);
out:
spin_unlock_bh(&sta->mesh->plink_lock);
}
@@ -667,7 +668,7 @@ void mesh_plink_timer(struct timer_list *t)
/*
* This STA is valid because sta_info_destroy() will
* del_timer_sync() this timer after having made sure
- * it cannot be readded (by deleting the plink.)
+ * it cannot be re-added (by deleting the plink.)
*/
sta = mesh->plink_sta;
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index 8cf3f395f52f..3a66b4cefca7 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -175,7 +175,7 @@ static void mesh_sync_offset_adjust_tsf(struct ieee80211_sub_if_data *sdata,
spin_lock_bh(&ifmsh->sync_offset_lock);
if (ifmsh->sync_offset_clockdrift_max > TOFFSET_MINIMUM_ADJUSTMENT) {
- /* Since ajusting the tsf here would
+ /* Since adjusting the tsf here would
* require a possibly blocking call
* to the driver tsf setter, we punt
* the tsf adjustment to the mesh tasklet
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 0303972c23e4..480b664151c9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -31,6 +31,8 @@
#include "led.h"
#include "fils_aead.h"
+#include <kunit/static_stub.h>
+
#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
#define IEEE80211_AUTH_TIMEOUT_LONG (HZ / 2)
#define IEEE80211_AUTH_TIMEOUT_SHORT (HZ / 10)
@@ -2643,9 +2645,91 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
&ifmgd->csa_connection_drop_work);
}
+struct sta_bss_param_ch_cnt_data {
+ struct ieee80211_sub_if_data *sdata;
+ u8 reporting_link_id;
+ u8 mld_id;
+};
+
+static enum cfg80211_rnr_iter_ret
+ieee80211_sta_bss_param_ch_cnt_iter(void *_data, u8 type,
+ const struct ieee80211_neighbor_ap_info *info,
+ const u8 *tbtt_info, u8 tbtt_info_len)
+{
+ struct sta_bss_param_ch_cnt_data *data = _data;
+ struct ieee80211_sub_if_data *sdata = data->sdata;
+ const struct ieee80211_tbtt_info_ge_11 *ti;
+ u8 bss_param_ch_cnt;
+ int link_id;
+
+ if (type != IEEE80211_TBTT_INFO_TYPE_TBTT)
+ return RNR_ITER_CONTINUE;
+
+ if (tbtt_info_len < sizeof(*ti))
+ return RNR_ITER_CONTINUE;
+
+ ti = (const void *)tbtt_info;
+
+ if (ti->mld_params.mld_id != data->mld_id)
+ return RNR_ITER_CONTINUE;
+
+ link_id = le16_get_bits(ti->mld_params.params,
+ IEEE80211_RNR_MLD_PARAMS_LINK_ID);
+ bss_param_ch_cnt =
+ le16_get_bits(ti->mld_params.params,
+ IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT);
+
+ if (bss_param_ch_cnt != 255 &&
+ link_id < ARRAY_SIZE(sdata->link)) {
+ struct ieee80211_link_data *link =
+ sdata_dereference(sdata->link[link_id], sdata);
+
+ if (link && link->conf->bss_param_ch_cnt != bss_param_ch_cnt) {
+ link->conf->bss_param_ch_cnt = bss_param_ch_cnt;
+ link->conf->bss_param_ch_cnt_link_id =
+ data->reporting_link_id;
+ }
+ }
+
+ return RNR_ITER_CONTINUE;
+}
+
+static void
+ieee80211_mgd_update_bss_param_ch_cnt(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_bss_conf *bss_conf,
+ struct ieee802_11_elems *elems)
+{
+ struct sta_bss_param_ch_cnt_data data = {
+ .reporting_link_id = bss_conf->link_id,
+ .sdata = sdata,
+ };
+ int bss_param_ch_cnt;
+
+ if (!elems->ml_basic)
+ return;
+
+ data.mld_id = ieee80211_mle_get_mld_id((const void *)elems->ml_basic);
+
+ cfg80211_iter_rnr(elems->ie_start, elems->total_len,
+ ieee80211_sta_bss_param_ch_cnt_iter, &data);
+
+ bss_param_ch_cnt =
+ ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic);
+
+ /*
+ * Update bss_param_ch_cnt_link_id even if bss_param_ch_cnt
+ * didn't change to indicate that we got a beacon on our own
+ * link.
+ */
+ if (bss_param_ch_cnt >= 0 && bss_param_ch_cnt != 255) {
+ bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
+ bss_conf->bss_param_ch_cnt_link_id =
+ bss_conf->link_id;
+ }
+}
+
static bool
-ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_channel *channel,
+ieee80211_find_80211h_pwr_constr(struct ieee80211_channel *channel,
const u8 *country_ie, u8 country_ie_len,
const u8 *pwr_constr_elem,
int *chan_pwr, int *pwr_reduction)
@@ -2715,8 +2799,7 @@ ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata,
return have_chan_pwr;
}
-static void ieee80211_find_cisco_dtpc(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_channel *channel,
+static void ieee80211_find_cisco_dtpc(struct ieee80211_channel *channel,
const u8 *cisco_dtpc_ie,
int *pwr_level)
{
@@ -2750,7 +2833,7 @@ static u64 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link,
(capab & cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT) ||
capab & cpu_to_le16(WLAN_CAPABILITY_RADIO_MEASURE))) {
has_80211h_pwr = ieee80211_find_80211h_pwr_constr(
- sdata, channel, country_ie, country_ie_len,
+ channel, country_ie, country_ie_len,
pwr_constr_ie, &chan_pwr, &pwr_reduction_80211h);
pwr_level_80211h =
max_t(int, 0, chan_pwr - pwr_reduction_80211h);
@@ -2758,7 +2841,7 @@ static u64 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link,
if (cisco_dtpc_ie) {
ieee80211_find_cisco_dtpc(
- sdata, channel, cisco_dtpc_ie, &pwr_level_cisco);
+ channel, cisco_dtpc_ie, &pwr_level_cisco);
has_cisco_pwr = true;
}
@@ -2791,7 +2874,7 @@ static u64 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link,
}
link->ap_power_level = new_ap_level;
- if (__ieee80211_recalc_txpower(sdata))
+ if (__ieee80211_recalc_txpower(link))
return BSS_CHANGED_TXPOWER;
return 0;
}
@@ -4101,8 +4184,13 @@ EXPORT_SYMBOL(ieee80211_beacon_loss);
void ieee80211_connection_loss(struct ieee80211_vif *vif)
{
- struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
- struct ieee80211_hw *hw = &sdata->local->hw;
+ struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_hw *hw;
+
+ KUNIT_STATIC_STUB_REDIRECT(ieee80211_connection_loss, vif);
+
+ sdata = vif_to_sdata(vif);
+ hw = &sdata->local->hw;
trace_api_connection_loss(sdata);
@@ -4667,7 +4755,8 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
ret = false;
goto out;
}
- link->u.mgd.bss_param_ch_cnt = bss_param_ch_cnt;
+ bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
+ bss_conf->bss_param_ch_cnt_link_id = link_id;
}
} else if (elems->parse_error & IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC ||
!elems->prof ||
@@ -4677,6 +4766,7 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
} else {
const u8 *ptr = elems->prof->variable +
elems->prof->sta_info_len - 1;
+ int bss_param_ch_cnt;
/*
* During parsing, we validated that these fields exist,
@@ -4684,8 +4774,10 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
*/
capab_info = get_unaligned_le16(ptr);
assoc_data->link[link_id].status = get_unaligned_le16(ptr + 2);
- link->u.mgd.bss_param_ch_cnt =
+ bss_param_ch_cnt =
ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(elems->prof);
+ bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
+ bss_conf->bss_param_ch_cnt_link_id = link_id;
if (assoc_data->link[link_id].status != WLAN_STATUS_SUCCESS) {
link_info(link, "association response status code=%u\n",
@@ -5665,7 +5757,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
/* links might have changed due to rejected ones, set them again */
ieee80211_vif_set_links(sdata, valid_links, dormant_links);
- rate_control_rate_init(sta);
+ rate_control_rate_init_all_links(sta);
if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) {
set_sta_flag(sta, WLAN_STA_MFP);
@@ -6913,6 +7005,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
/* note that after this elems->ml_basic can no longer be used fully */
ieee80211_mgd_check_cross_link_csa(sdata, rx_status->link_id, elems);
+ ieee80211_mgd_update_bss_param_ch_cnt(sdata, bss_conf, elems);
+
if (!link->u.mgd.disable_wmm_tracking &&
ieee80211_sta_wmm_params(local, link, elems->wmm_param,
elems->wmm_param_len,
diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c
index f4c51e4a1e29..6218abc3e441 100644
--- a/net/mac80211/ocb.c
+++ b/net/mac80211/ocb.c
@@ -4,7 +4,7 @@
*
* Copyright: (c) 2014 Czech Technical University in Prague
* (c) 2014 Volkswagen Group Research
- * Copyright (C) 2022 - 2023 Intel Corporation
+ * Copyright (C) 2022 - 2024 Intel Corporation
* Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz>
* Funded by: Volkswagen Group Research
*/
@@ -96,7 +96,7 @@ static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta)
sta_info_move_state(sta, IEEE80211_STA_ASSOC);
sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
- rate_control_rate_init(sta);
+ rate_control_rate_init(&sta->deflink);
/* If it fails, maybe we raced another insertion? */
if (sta_info_insert_rcu(sta))
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 3dc9752188d5..0d056db9f81e 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -28,8 +28,9 @@ module_param(ieee80211_default_rc_algo, charp, 0644);
MODULE_PARM_DESC(ieee80211_default_rc_algo,
"Default rate control algorithm for mac80211 to use");
-void rate_control_rate_init(struct sta_info *sta)
+void rate_control_rate_init(struct link_sta_info *link_sta)
{
+ struct sta_info *sta = link_sta->sta;
struct ieee80211_local *local = sta->sdata->local;
struct rate_control_ref *ref = sta->rate_ctrl;
struct ieee80211_sta *ista = &sta->sta;
@@ -37,11 +38,15 @@ void rate_control_rate_init(struct sta_info *sta)
struct ieee80211_supported_band *sband;
struct ieee80211_chanctx_conf *chanctx_conf;
- ieee80211_sta_init_nss(&sta->deflink);
+ ieee80211_sta_init_nss(link_sta);
if (!ref)
return;
+ /* SW rate control isn't supported with MLO right now */
+ if (WARN_ON(ieee80211_vif_is_mld(&sta->sdata->vif)))
+ return;
+
rcu_read_lock();
chanctx_conf = rcu_dereference(sta->sdata->vif.bss_conf.chanctx_conf);
@@ -67,6 +72,21 @@ void rate_control_rate_init(struct sta_info *sta)
set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
}
+void rate_control_rate_init_all_links(struct sta_info *sta)
+{
+ int link_id;
+
+ for (link_id = 0; link_id < ARRAY_SIZE(sta->link); link_id++) {
+ struct link_sta_info *link_sta;
+
+ link_sta = sdata_dereference(sta->link[link_id], sta->sdata);
+ if (!link_sta)
+ continue;
+
+ rate_control_rate_init(link_sta);
+ }
+}
+
void rate_control_tx_status(struct ieee80211_local *local,
struct ieee80211_tx_status *st)
{
@@ -93,16 +113,15 @@ void rate_control_tx_status(struct ieee80211_local *local,
void rate_control_rate_update(struct ieee80211_local *local,
struct ieee80211_supported_band *sband,
- struct sta_info *sta, unsigned int link_id,
+ struct link_sta_info *link_sta,
u32 changed)
{
struct rate_control_ref *ref = local->rate_ctrl;
+ struct sta_info *sta = link_sta->sta;
struct ieee80211_sta *ista = &sta->sta;
void *priv_sta = sta->rate_ctrl_priv;
struct ieee80211_chanctx_conf *chanctx_conf;
- WARN_ON(link_id != 0);
-
if (ref && ref->ops->rate_update) {
rcu_read_lock();
@@ -120,7 +139,8 @@ void rate_control_rate_update(struct ieee80211_local *local,
}
if (sta->uploaded)
- drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
+ drv_link_sta_rc_update(local, sta->sdata, link_sta->pub,
+ changed);
}
int ieee80211_rate_control_register(const struct rate_control_ops *ops)
@@ -229,9 +249,8 @@ static ssize_t rcname_read(struct file *file, char __user *userbuf,
ref->ops->name, len);
}
-const struct file_operations rcname_ops = {
+const struct debugfs_short_fops rcname_ops = {
.read = rcname_read,
- .open = simple_open,
.llseek = default_llseek,
};
#endif
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index d6190f10fe7c..5e4bde598212 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -3,7 +3,7 @@
* Copyright 2002-2005, Instant802 Networks, Inc.
* Copyright 2005, Devicescape Software, Inc.
* Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
- * Copyright (C) 2022 Intel Corporation
+ * Copyright (C) 2022, 2024 Intel Corporation
*/
#ifndef IEEE80211_RATE_H
@@ -29,11 +29,11 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
void rate_control_tx_status(struct ieee80211_local *local,
struct ieee80211_tx_status *st);
-void rate_control_rate_init(struct sta_info *sta);
+void rate_control_rate_init(struct link_sta_info *link_sta);
+void rate_control_rate_init_all_links(struct sta_info *sta);
void rate_control_rate_update(struct ieee80211_local *local,
struct ieee80211_supported_band *sband,
- struct sta_info *sta,
- unsigned int link_id,
+ struct link_sta_info *link_sta,
u32 changed);
static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
@@ -62,7 +62,7 @@ static inline void rate_control_add_sta_debugfs(struct sta_info *sta)
#endif
}
-extern const struct file_operations rcname_ops;
+extern const struct debugfs_short_fops rcname_ops;
static inline void rate_control_add_debugfs(struct ieee80211_local *local)
{
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 6bf3b4444a43..706cbc99f718 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -1053,7 +1053,7 @@ minstrel_ht_refill_sample_rates(struct minstrel_ht_sta *mi)
* - max_prob_rate must use only one stream, as a tradeoff between delivery
* probability and throughput during strong fluctuations
* - as long as the max prob rate has a probability of more than 75%, pick
- * higher throughput rates, even if the probablity is a bit lower
+ * higher throughput rates, even if the probability is a bit lower
*/
static void
minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 694b43091fec..2bec18fc1b03 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -508,18 +508,13 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
flags |= IEEE80211_RADIOTAP_AMPDU_IS_LAST;
if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_ERROR)
flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR;
- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
- flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN;
if (status->flag & RX_FLAG_AMPDU_EOF_BIT_KNOWN)
flags |= IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN;
if (status->flag & RX_FLAG_AMPDU_EOF_BIT)
flags |= IEEE80211_RADIOTAP_AMPDU_EOF;
put_unaligned_le16(flags, pos);
pos += 2;
- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
- *pos++ = status->ampdu_delimiter_crc;
- else
- *pos++ = 0;
+ *pos++ = 0;
*pos++ = 0;
}
@@ -767,8 +762,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
struct ieee80211_rate *rate)
{
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
- struct ieee80211_sub_if_data *sdata;
- struct sk_buff *monskb = NULL;
+ struct ieee80211_sub_if_data *sdata, *prev_sdata = NULL;
+ struct sk_buff *skb, *monskb = NULL;
int present_fcs_len = 0;
unsigned int rtap_space = 0;
struct ieee80211_sub_if_data *monitor_sdata =
@@ -842,40 +837,52 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_space);
list_for_each_entry_rcu(sdata, &local->mon_list, u.mntr.list) {
- bool last_monitor = list_is_last(&sdata->u.mntr.list,
- &local->mon_list);
+ struct cfg80211_chan_def *chandef;
+
+ chandef = &sdata->vif.bss_conf.chanreq.oper;
+ if (chandef->chan &&
+ chandef->chan->center_freq != status->freq)
+ continue;
+
+ if (!prev_sdata) {
+ prev_sdata = sdata;
+ continue;
+ }
+
+ if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
+ ieee80211_handle_mu_mimo_mon(sdata, origskb, rtap_space);
if (!monskb)
monskb = ieee80211_make_monitor_skb(local, &origskb,
rate, rtap_space,
- only_monitor &&
- last_monitor);
+ false);
+ if (!monskb)
+ continue;
- if (monskb) {
- struct sk_buff *skb;
+ skb = skb_clone(monskb, GFP_ATOMIC);
+ if (!skb)
+ continue;
- if (last_monitor) {
- skb = monskb;
- monskb = NULL;
- } else {
- skb = skb_clone(monskb, GFP_ATOMIC);
- }
+ skb->dev = prev_sdata->dev;
+ dev_sw_netstats_rx_add(skb->dev, skb->len);
+ netif_receive_skb(skb);
+ prev_sdata = sdata;
+ }
- if (skb) {
- skb->dev = sdata->dev;
- dev_sw_netstats_rx_add(skb->dev, skb->len);
- netif_receive_skb(skb);
- }
+ if (prev_sdata) {
+ if (monskb)
+ skb = monskb;
+ else
+ skb = ieee80211_make_monitor_skb(local, &origskb,
+ rate, rtap_space,
+ only_monitor);
+ if (skb) {
+ skb->dev = prev_sdata->dev;
+ dev_sw_netstats_rx_add(skb->dev, skb->len);
+ netif_receive_skb(skb);
}
-
- if (last_monitor)
- break;
}
- /* this happens if last_monitor was erroneously false */
- dev_kfree_skb(monskb);
-
- /* ditto */
if (!origskb)
return NULL;
@@ -3568,7 +3575,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
sband = rx->local->hw.wiphy->bands[status->band];
- rate_control_rate_update(local, sband, rx->sta, 0,
+ rate_control_rate_update(local, sband, rx->link_sta,
IEEE80211_RC_SMPS_CHANGED);
cfg80211_sta_opmode_change_notify(sdata->dev,
rx->sta->addr,
@@ -3605,7 +3612,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
ieee80211_sta_rx_bw_to_chan_width(rx->link_sta);
sta_opmode.changed = STA_OPMODE_MAX_BW_CHANGED;
- rate_control_rate_update(local, sband, rx->sta, 0,
+ rate_control_rate_update(local, sband, rx->link_sta,
IEEE80211_RC_BW_CHANGED);
cfg80211_sta_opmode_change_notify(sdata->dev,
rx->sta->addr,
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index adb88c06b598..cb7079071885 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -1176,14 +1176,14 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
unsigned int n_channels)
{
struct ieee80211_local *local = sdata->local;
- int ret = -EBUSY, i, n_ch = 0;
+ int i, n_ch = 0;
enum nl80211_band band;
lockdep_assert_wiphy(local->hw.wiphy);
/* busy scanning */
if (local->scan_req)
- goto unlock;
+ return -EBUSY;
/* fill internal scan request */
if (!channels) {
@@ -1200,7 +1200,9 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
&local->hw.wiphy->bands[band]->channels[i];
if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR |
- IEEE80211_CHAN_DISABLED))
+ IEEE80211_CHAN_DISABLED) ||
+ !cfg80211_wdev_channel_allowed(&sdata->wdev,
+ tmp_ch))
continue;
local->int_scan_req->channels[n_ch] = tmp_ch;
@@ -1209,21 +1211,23 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
}
if (WARN_ON_ONCE(n_ch == 0))
- goto unlock;
+ return -EINVAL;
local->int_scan_req->n_channels = n_ch;
} else {
for (i = 0; i < n_channels; i++) {
if (channels[i]->flags & (IEEE80211_CHAN_NO_IR |
- IEEE80211_CHAN_DISABLED))
+ IEEE80211_CHAN_DISABLED) ||
+ !cfg80211_wdev_channel_allowed(&sdata->wdev,
+ channels[i]))
continue;
local->int_scan_req->channels[n_ch] = channels[i];
n_ch++;
}
- if (WARN_ON_ONCE(n_ch == 0))
- goto unlock;
+ if (n_ch == 0)
+ return -EINVAL;
local->int_scan_req->n_channels = n_ch;
}
@@ -1233,9 +1237,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
local->int_scan_req->ssids[0].ssid_len = ssid_len;
- ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
- unlock:
- return ret;
+ return __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
}
void ieee80211_scan_cancel(struct ieee80211_local *local)
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 073ff9e0f397..c6015cd00372 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -377,13 +377,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
/* capture the AP chandef before (potential) downgrading */
csa_ie->chanreq.ap = new_chandef;
- if (conn->bw_limit < IEEE80211_CONN_BW_LIMIT_320 &&
- new_chandef.width == NL80211_CHAN_WIDTH_320)
- ieee80211_chandef_downgrade(&new_chandef, NULL);
-
- if (conn->bw_limit < IEEE80211_CONN_BW_LIMIT_160 &&
- (new_chandef.width == NL80211_CHAN_WIDTH_80P80 ||
- new_chandef.width == NL80211_CHAN_WIDTH_160))
+ while (conn->bw_limit <
+ ieee80211_min_bw_limit_from_chandef(&new_chandef))
ieee80211_chandef_downgrade(&new_chandef, NULL);
if (!cfg80211_chandef_compatible(&new_chandef,
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 9195d5a2de0a..9f89fb5bee37 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -169,7 +169,7 @@ struct sta_info;
* @buf_size: reorder buffer size at receiver
* @failed_bar_ssn: ssn of the last failed BAR tx attempt
* @bar_pending: BAR needs to be re-sent
- * @amsdu: support A-MSDU withing A-MDPU
+ * @amsdu: support A-MSDU within A-MDPU
* @ssn: starting sequence number of the session
*
* This structure's lifetime is managed by RCU, assignments to
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index b41b867f43b2..5f28f3633fa0 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -927,6 +927,9 @@ void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
if (!ieee80211_sdata_running(sdata))
continue;
+ if (sdata->u.mntr.flags & MONITOR_FLAG_SKIP_TX)
+ continue;
+
if ((sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) &&
!send_to_cooked)
continue;
@@ -1099,7 +1102,7 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
* This is a bit racy but we can avoid a lot of work
* with this test...
*/
- if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) {
+ if (!local->tx_mntrs && (!send_to_cooked || !local->cooked_mntrs)) {
if (status->free_list)
list_add_tail(&skb->list, status->free_list);
else
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index f07b40916485..2f92e7c7f203 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -1342,7 +1342,8 @@ static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata,
bw = min(bw, ieee80211_sta_cap_rx_bw(&sta->deflink));
if (bw != sta->sta.deflink.bandwidth) {
sta->sta.deflink.bandwidth = bw;
- rate_control_rate_update(local, sband, sta, 0,
+ rate_control_rate_update(local, sband,
+ &sta->deflink,
IEEE80211_RC_BW_CHANGED);
/*
* if a TDLS peer BW was updated, we need to
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 880a1fa8705a..94c00e71f6f8 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -313,7 +313,7 @@ int ieee80211_tkip_decrypt_data(struct arc4_ctx *ctx,
* Record previously received IV, will be copied into the
* key information after MIC verification. It is possible
* that we don't catch replays of fragments but that's ok
- * because the Michael MIC verication will then fail.
+ * because the Michael MIC verification will then fail.
*/
*out_iv32 = iv32;
*out_iv16 = iv16;
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index dc498cd8cd91..7a4985fc2b16 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -939,31 +939,34 @@ TRACE_EVENT(drv_sta_set_txpwr,
)
);
-TRACE_EVENT(drv_sta_rc_update,
+TRACE_EVENT(drv_link_sta_rc_update,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
- struct ieee80211_sta *sta,
+ struct ieee80211_link_sta *link_sta,
u32 changed),
- TP_ARGS(local, sdata, sta, changed),
+ TP_ARGS(local, sdata, link_sta, changed),
TP_STRUCT__entry(
LOCAL_ENTRY
VIF_ENTRY
STA_ENTRY
__field(u32, changed)
+ __field(u32, link_id)
),
TP_fast_assign(
LOCAL_ASSIGN;
VIF_ASSIGN;
- STA_ASSIGN;
+ STA_NAMED_ASSIGN(link_sta->sta);
__entry->changed = changed;
+ __entry->link_id = link_sta->link_id;
),
TP_printk(
- LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " changed: 0x%x",
- LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->changed
+ LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " (link %d) changed: 0x%x",
+ LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->link_id,
+ __entry->changed
)
);
@@ -3154,6 +3157,25 @@ TRACE_EVENT(drv_neg_ttlm_res,
LOCAL_PR_ARG, VIF_PR_ARG, __entry->res
)
);
+
+TRACE_EVENT(drv_prep_add_interface,
+ TP_PROTO(struct ieee80211_local *local,
+ enum nl80211_iftype type),
+
+ TP_ARGS(local, type),
+ TP_STRUCT__entry(LOCAL_ENTRY
+ __field(u32, type)
+ ),
+
+ TP_fast_assign(LOCAL_ASSIGN;
+ __entry->type = type;
+ ),
+
+ TP_printk(LOCAL_PR_FMT " type: %u\n ",
+ LOCAL_PR_ARG, __entry->type
+ )
+);
+
#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0ff8b56f5807..a24636bda679 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1763,7 +1763,8 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
switch (sdata->vif.type) {
case NL80211_IFTYPE_MONITOR:
- if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
+ if ((sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) ||
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
vif = &sdata->vif;
break;
}
@@ -3952,7 +3953,8 @@ begin:
switch (tx.sdata->vif.type) {
case NL80211_IFTYPE_MONITOR:
- if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
+ if ((tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) ||
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
vif = &tx.sdata->vif;
break;
}
@@ -6214,7 +6216,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
goto start_xmit;
/* update QoS header to prioritize control port frames if possible,
- * priorization also happens for control port frames send over
+ * prioritization also happens for control port frames send over
* AF_PACKET
*/
rcu_read_lock();
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index f94faa86ba8a..a4e1301cc999 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -756,7 +756,8 @@ static void __iterate_interfaces(struct ieee80211_local *local,
lockdep_is_held(&local->hw.wiphy->mtx)) {
switch (sdata->vif.type) {
case NL80211_IFTYPE_MONITOR:
- if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
+ if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) &&
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
continue;
break;
case NL80211_IFTYPE_AP_VLAN:
@@ -1010,7 +1011,7 @@ void ieee80211_set_wmm_default(struct ieee80211_link_data *link,
else
aCWmin = 15;
- /* Confiure old 802.11b/g medium access rules. */
+ /* Configure old 802.11b/g medium access rules. */
qparam.cw_max = aCWmax;
qparam.cw_min = aCWmin;
qparam.txop = 0;
@@ -1873,8 +1874,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
}
list_for_each_entry(sdata, &local->interfaces, list) {
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
+ continue;
if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
- sdata->vif.type != NL80211_IFTYPE_MONITOR &&
ieee80211_sdata_running(sdata)) {
res = drv_add_interface(local, sdata);
if (WARN_ON(res))
@@ -1887,11 +1890,14 @@ int ieee80211_reconfig(struct ieee80211_local *local)
*/
if (res) {
list_for_each_entry_continue_reverse(sdata, &local->interfaces,
- list)
+ list) {
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
+ continue;
if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
- sdata->vif.type != NL80211_IFTYPE_MONITOR &&
ieee80211_sdata_running(sdata))
drv_remove_interface(local, sdata);
+ }
ieee80211_handle_reconfig_failure(local);
return res;
}
@@ -2752,7 +2758,7 @@ u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
return pos + sizeof(struct ieee80211_vht_operation);
}
-u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef)
+u8 *ieee80211_ie_build_he_oper(u8 *pos, const struct cfg80211_chan_def *chandef)
{
struct ieee80211_he_operation *he_oper;
struct ieee80211_he_6ghz_oper *he_6ghz_op;
@@ -2844,7 +2850,7 @@ out:
return pos;
}
-u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef,
+u8 *ieee80211_ie_build_eht_oper(u8 *pos, const struct cfg80211_chan_def *chandef,
const struct ieee80211_sta_eht_cap *eht_cap)
{
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index bf6ef45af757..6a20fa099190 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -280,10 +280,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
/*
* This is a workaround for VHT-enabled STAs which break the spec
* and have the VHT-MCS Rx map filled in with value 3 for all eight
- * spacial streams, an example is AR9462.
+ * spatial streams, an example is AR9462.
*
* As per spec, in section 22.1.1 Introduction to the VHT PHY
- * A VHT STA shall support at least single spactial stream VHT-MCSs
+ * A VHT STA shall support at least single spatial stream VHT-MCSs
* 0 to 7 (transmit and receive) in all supported channel widths.
*/
if (vht_cap->vht_mcs.rx_mcs_map == cpu_to_le16(0xFFFF)) {
@@ -479,28 +479,6 @@ ieee80211_sta_rx_bw_to_chan_width(struct link_sta_info *link_sta)
}
}
-enum ieee80211_sta_rx_bandwidth
-ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
-{
- switch (width) {
- case NL80211_CHAN_WIDTH_20_NOHT:
- case NL80211_CHAN_WIDTH_20:
- return IEEE80211_STA_RX_BW_20;
- case NL80211_CHAN_WIDTH_40:
- return IEEE80211_STA_RX_BW_40;
- case NL80211_CHAN_WIDTH_80:
- return IEEE80211_STA_RX_BW_80;
- case NL80211_CHAN_WIDTH_160:
- case NL80211_CHAN_WIDTH_80P80:
- return IEEE80211_STA_RX_BW_160;
- case NL80211_CHAN_WIDTH_320:
- return IEEE80211_STA_RX_BW_320;
- default:
- WARN_ON_ONCE(1);
- return IEEE80211_STA_RX_BW_20;
- }
-}
-
/* FIXME: rename/move - this deals with everything not just VHT */
enum ieee80211_sta_rx_bandwidth
_ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta,
@@ -766,8 +744,7 @@ void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
if (changed > 0) {
ieee80211_recalc_min_chandef(sdata, link_sta->link_id);
- rate_control_rate_update(local, sband, link_sta->sta,
- link_sta->link_id, changed);
+ rate_control_rate_update(local, sband, link_sta, changed);
}
}
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 293afa3f57c5..40d5d9e48479 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -598,9 +598,6 @@ static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad,
memcpy(j_0, hdr->addr2, ETH_ALEN);
memcpy(&j_0[ETH_ALEN], pn, IEEE80211_GCMP_PN_LEN);
- j_0[13] = 0;
- j_0[14] = 0;
- j_0[AES_BLOCK_SIZE - 1] = 0x01;
ccmp_gcmp_aad(skb, aad, spp_amsdu);
}
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 10345388ad13..2d67b5f2010e 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -11,9 +11,6 @@ config WEXT_PROC
depends on PROC_FS
depends on WEXT_CORE
-config WEXT_SPY
- bool
-
config WEXT_PRIV
bool
@@ -188,19 +185,12 @@ config CFG80211_CRDA_SUPPORT
If unsure, say Y.
config CFG80211_WEXT
- bool "cfg80211 wireless extensions compatibility" if !CFG80211_WEXT_EXPORT
+ bool "cfg80211 wireless extensions compatibility"
select WEXT_CORE
- default y if CFG80211_WEXT_EXPORT
help
Enable this option if you need old userspace for wireless
extensions with cfg80211-based drivers.
-config CFG80211_WEXT_EXPORT
- bool
- help
- Drivers should select this option if they require cfg80211's
- wext compatibility symbols to be exported.
-
config CFG80211_KUNIT_TEST
tristate "KUnit tests for cfg80211" if !KUNIT_ALL_TESTS
depends on KUNIT
@@ -212,36 +202,3 @@ config CFG80211_KUNIT_TEST
If unsure, say N.
endif # CFG80211
-
-config LIB80211
- tristate
- default n
- help
- This options enables a library of common routines used
- by IEEE802.11 wireless LAN drivers.
-
- Drivers should select this themselves if needed.
-
-config LIB80211_CRYPT_WEP
- tristate
- select CRYPTO_LIB_ARC4
-
-config LIB80211_CRYPT_CCMP
- tristate
- select CRYPTO
- select CRYPTO_AES
- select CRYPTO_CCM
-
-config LIB80211_CRYPT_TKIP
- tristate
- select CRYPTO_LIB_ARC4
-
-config LIB80211_DEBUG
- bool "lib80211 debugging messages"
- depends on LIB80211
- default n
- help
- You can enable this if you want verbose debugging messages
- from lib80211.
-
- If unsure, say N.
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 1d49cc8b6da1..62a83faf0e07 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -1,14 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_CFG80211) += cfg80211.o
-obj-$(CONFIG_LIB80211) += lib80211.o
-obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
-obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
-obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
obj-y += tests/
obj-$(CONFIG_WEXT_CORE) += wext-core.o
obj-$(CONFIG_WEXT_PROC) += wext-proc.o
-obj-$(CONFIG_WEXT_SPY) += wext-spy.o
obj-$(CONFIG_WEXT_PRIV) += wext-priv.o
cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index e579d7e1425f..40b6375a5de4 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -289,7 +289,7 @@ static bool cfg80211_valid_center_freq(u32 center,
/*
* Valid channels are packed from lowest frequency towards higher ones.
- * So test that the lower frequency alignes with one of these steps.
+ * So test that the lower frequency aligns with one of these steps.
*/
return (center - bw / 2 - 5945) % step == 0;
}
@@ -1628,6 +1628,7 @@ bool cfg80211_reg_check_beaconing(struct wiphy *wiphy,
EXPORT_SYMBOL(cfg80211_reg_check_beaconing);
int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
struct cfg80211_chan_def *chandef)
{
if (!rdev->ops->set_monitor_channel)
@@ -1635,7 +1636,7 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
if (!cfg80211_has_monitors_only(rdev))
return -EBUSY;
- return rdev_set_monitor_channel(rdev, chandef);
+ return rdev_set_monitor_channel(rdev, dev, chandef);
}
bool cfg80211_any_usable_channels(struct wiphy *wiphy,
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 661adfc77644..93d62a1d3a45 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -603,16 +603,20 @@ use_default_name:
}
EXPORT_SYMBOL(wiphy_new_nm);
-static int wiphy_verify_combinations(struct wiphy *wiphy)
+static
+int wiphy_verify_iface_combinations(struct wiphy *wiphy,
+ const struct ieee80211_iface_combination *iface_comb,
+ int n_iface_comb,
+ bool combined_radio)
{
const struct ieee80211_iface_combination *c;
int i, j;
- for (i = 0; i < wiphy->n_iface_combinations; i++) {
+ for (i = 0; i < n_iface_comb; i++) {
u32 cnt = 0;
u16 all_iftypes = 0;
- c = &wiphy->iface_combinations[i];
+ c = &iface_comb[i];
/*
* Combinations with just one interface aren't real,
@@ -625,9 +629,13 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
if (WARN_ON(!c->num_different_channels))
return -EINVAL;
- /* DFS only works on one channel. */
- if (WARN_ON(c->radar_detect_widths &&
- (c->num_different_channels > 1)))
+ /* DFS only works on one channel. Avoid this check
+ * for multi-radio global combination, since it hold
+ * the capabilities of all radio combinations.
+ */
+ if (!combined_radio &&
+ WARN_ON(c->radar_detect_widths &&
+ c->num_different_channels > 1))
return -EINVAL;
if (WARN_ON(!c->n_limits))
@@ -648,13 +656,21 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
if (WARN_ON(wiphy->software_iftypes & types))
return -EINVAL;
- /* Only a single P2P_DEVICE can be allowed */
- if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) &&
+ /* Only a single P2P_DEVICE can be allowed, avoid this
+ * check for multi-radio global combination, since it
+ * hold the capabilities of all radio combinations.
+ */
+ if (!combined_radio &&
+ WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) &&
c->limits[j].max > 1))
return -EINVAL;
- /* Only a single NAN can be allowed */
- if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
+ /* Only a single NAN can be allowed, avoid this
+ * check for multi-radio global combination, since it
+ * hold the capabilities of all radio combinations.
+ */
+ if (!combined_radio &&
+ WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
c->limits[j].max > 1))
return -EINVAL;
@@ -693,6 +709,34 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
return 0;
}
+static int wiphy_verify_combinations(struct wiphy *wiphy)
+{
+ int i, ret;
+ bool combined_radio = false;
+
+ if (wiphy->n_radio) {
+ for (i = 0; i < wiphy->n_radio; i++) {
+ const struct wiphy_radio *radio = &wiphy->radio[i];
+
+ ret = wiphy_verify_iface_combinations(wiphy,
+ radio->iface_combinations,
+ radio->n_iface_combinations,
+ false);
+ if (ret)
+ return ret;
+ }
+
+ combined_radio = true;
+ }
+
+ ret = wiphy_verify_iface_combinations(wiphy,
+ wiphy->iface_combinations,
+ wiphy->n_iface_combinations,
+ combined_radio);
+
+ return ret;
+}
+
int wiphy_register(struct wiphy *wiphy)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
@@ -1386,6 +1430,8 @@ void cfg80211_init_wdev(struct wireless_dev *wdev)
/* allow mac80211 to determine the timeout */
wdev->ps_timeout = -1;
+ wdev->radio_mask = BIT(wdev->wiphy->n_radio) - 1;
+
if ((wdev->iftype == NL80211_IFTYPE_STATION ||
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 3b3e3cd7027a..4c45f994a8c0 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -516,6 +516,7 @@ static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
}
int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
struct cfg80211_chan_def *chandef);
int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c
deleted file mode 100644
index 64c447040786..000000000000
--- a/net/wireless/lib80211.c
+++ /dev/null
@@ -1,257 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * lib80211 -- common bits for IEEE802.11 drivers
- *
- * Copyright(c) 2008 John W. Linville <linville@tuxdriver.com>
- *
- * Portions copied from old ieee80211 component, w/ original copyright
- * notices below:
- *
- * Host AP crypto routines
- *
- * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
- * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/ctype.h>
-#include <linux/ieee80211.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#include <net/lib80211.h>
-
-#define DRV_DESCRIPTION "common routines for IEEE802.11 drivers"
-
-MODULE_DESCRIPTION(DRV_DESCRIPTION);
-MODULE_AUTHOR("John W. Linville <linville@tuxdriver.com>");
-MODULE_LICENSE("GPL");
-
-struct lib80211_crypto_alg {
- struct list_head list;
- const struct lib80211_crypto_ops *ops;
-};
-
-static LIST_HEAD(lib80211_crypto_algs);
-static DEFINE_SPINLOCK(lib80211_crypto_lock);
-
-static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info,
- int force);
-static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info);
-static void lib80211_crypt_deinit_handler(struct timer_list *t);
-
-int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name,
- spinlock_t *lock)
-{
- memset(info, 0, sizeof(*info));
-
- info->name = name;
- info->lock = lock;
-
- INIT_LIST_HEAD(&info->crypt_deinit_list);
- timer_setup(&info->crypt_deinit_timer, lib80211_crypt_deinit_handler,
- 0);
-
- return 0;
-}
-EXPORT_SYMBOL(lib80211_crypt_info_init);
-
-void lib80211_crypt_info_free(struct lib80211_crypt_info *info)
-{
- int i;
-
- lib80211_crypt_quiescing(info);
- del_timer_sync(&info->crypt_deinit_timer);
- lib80211_crypt_deinit_entries(info, 1);
-
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- struct lib80211_crypt_data *crypt = info->crypt[i];
- if (crypt) {
- if (crypt->ops) {
- crypt->ops->deinit(crypt->priv);
- module_put(crypt->ops->owner);
- }
- kfree(crypt);
- info->crypt[i] = NULL;
- }
- }
-}
-EXPORT_SYMBOL(lib80211_crypt_info_free);
-
-static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info,
- int force)
-{
- struct lib80211_crypt_data *entry, *next;
- unsigned long flags;
-
- spin_lock_irqsave(info->lock, flags);
- list_for_each_entry_safe(entry, next, &info->crypt_deinit_list, list) {
- if (atomic_read(&entry->refcnt) != 0 && !force)
- continue;
-
- list_del(&entry->list);
-
- if (entry->ops) {
- entry->ops->deinit(entry->priv);
- module_put(entry->ops->owner);
- }
- kfree(entry);
- }
- spin_unlock_irqrestore(info->lock, flags);
-}
-
-/* After this, crypt_deinit_list won't accept new members */
-static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info)
-{
- unsigned long flags;
-
- spin_lock_irqsave(info->lock, flags);
- info->crypt_quiesced = 1;
- spin_unlock_irqrestore(info->lock, flags);
-}
-
-static void lib80211_crypt_deinit_handler(struct timer_list *t)
-{
- struct lib80211_crypt_info *info = from_timer(info, t,
- crypt_deinit_timer);
- unsigned long flags;
-
- lib80211_crypt_deinit_entries(info, 0);
-
- spin_lock_irqsave(info->lock, flags);
- if (!list_empty(&info->crypt_deinit_list) && !info->crypt_quiesced) {
- printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
- "deletion list\n", info->name);
- info->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&info->crypt_deinit_timer);
- }
- spin_unlock_irqrestore(info->lock, flags);
-}
-
-void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info,
- struct lib80211_crypt_data **crypt)
-{
- struct lib80211_crypt_data *tmp;
- unsigned long flags;
-
- if (*crypt == NULL)
- return;
-
- tmp = *crypt;
- *crypt = NULL;
-
- /* must not run ops->deinit() while there may be pending encrypt or
- * decrypt operations. Use a list of delayed deinits to avoid needing
- * locking. */
-
- spin_lock_irqsave(info->lock, flags);
- if (!info->crypt_quiesced) {
- list_add(&tmp->list, &info->crypt_deinit_list);
- if (!timer_pending(&info->crypt_deinit_timer)) {
- info->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&info->crypt_deinit_timer);
- }
- }
- spin_unlock_irqrestore(info->lock, flags);
-}
-EXPORT_SYMBOL(lib80211_crypt_delayed_deinit);
-
-int lib80211_register_crypto_ops(const struct lib80211_crypto_ops *ops)
-{
- unsigned long flags;
- struct lib80211_crypto_alg *alg;
-
- alg = kzalloc(sizeof(*alg), GFP_KERNEL);
- if (alg == NULL)
- return -ENOMEM;
-
- alg->ops = ops;
-
- spin_lock_irqsave(&lib80211_crypto_lock, flags);
- list_add(&alg->list, &lib80211_crypto_algs);
- spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
-
- printk(KERN_DEBUG "lib80211_crypt: registered algorithm '%s'\n",
- ops->name);
-
- return 0;
-}
-EXPORT_SYMBOL(lib80211_register_crypto_ops);
-
-int lib80211_unregister_crypto_ops(const struct lib80211_crypto_ops *ops)
-{
- struct lib80211_crypto_alg *alg;
- unsigned long flags;
-
- spin_lock_irqsave(&lib80211_crypto_lock, flags);
- list_for_each_entry(alg, &lib80211_crypto_algs, list) {
- if (alg->ops == ops)
- goto found;
- }
- spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
- return -EINVAL;
-
- found:
- printk(KERN_DEBUG "lib80211_crypt: unregistered algorithm '%s'\n",
- ops->name);
- list_del(&alg->list);
- spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
- kfree(alg);
- return 0;
-}
-EXPORT_SYMBOL(lib80211_unregister_crypto_ops);
-
-const struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name)
-{
- struct lib80211_crypto_alg *alg;
- unsigned long flags;
-
- spin_lock_irqsave(&lib80211_crypto_lock, flags);
- list_for_each_entry(alg, &lib80211_crypto_algs, list) {
- if (strcmp(alg->ops->name, name) == 0)
- goto found;
- }
- spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
- return NULL;
-
- found:
- spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
- return alg->ops;
-}
-EXPORT_SYMBOL(lib80211_get_crypto_ops);
-
-static void *lib80211_crypt_null_init(int keyidx)
-{
- return (void *)1;
-}
-
-static void lib80211_crypt_null_deinit(void *priv)
-{
-}
-
-static const struct lib80211_crypto_ops lib80211_crypt_null = {
- .name = "NULL",
- .init = lib80211_crypt_null_init,
- .deinit = lib80211_crypt_null_deinit,
- .owner = THIS_MODULE,
-};
-
-static int __init lib80211_init(void)
-{
- pr_info(DRV_DESCRIPTION "\n");
- return lib80211_register_crypto_ops(&lib80211_crypt_null);
-}
-
-static void __exit lib80211_exit(void)
-{
- lib80211_unregister_crypto_ops(&lib80211_crypt_null);
- BUG_ON(!list_empty(&lib80211_crypto_algs));
-}
-
-module_init(lib80211_init);
-module_exit(lib80211_exit);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d7d099f7118a..1ac8a196f376 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -829,6 +829,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
[NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
[NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG },
+ [NL80211_ATTR_VIF_RADIO_MASK] = { .type = NLA_U32 },
};
/* policy for the key attributes */
@@ -2430,6 +2431,11 @@ static int nl80211_put_radio(struct wiphy *wiphy, struct sk_buff *msg, int idx)
if (nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_INDEX, idx))
goto nla_put_failure;
+ if (r->antenna_mask &&
+ nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK,
+ r->antenna_mask))
+ goto nla_put_failure;
+
for (i = 0; i < r->n_freq_range; i++) {
const struct wiphy_radio_freq_range *range = &r->freq_range[i];
@@ -3561,7 +3567,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
case NL80211_IFTYPE_MESH_POINT:
return cfg80211_set_mesh_channel(rdev, wdev, &chandef);
case NL80211_IFTYPE_MONITOR:
- return cfg80211_set_monitor_channel(rdev, &chandef);
+ return cfg80211_set_monitor_channel(rdev, dev, &chandef);
default:
break;
}
@@ -3996,7 +4002,8 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
nla_put_u32(msg, NL80211_ATTR_GENERATION,
rdev->devlist_generation ^
(cfg80211_rdev_list_generation << 2)) ||
- nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
+ nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr) ||
+ nla_put_u32(msg, NL80211_ATTR_VIF_RADIO_MASK, wdev->radio_mask))
goto nla_put_failure;
if (rdev->ops->get_channel && !wdev->valid_links) {
@@ -4199,6 +4206,7 @@ static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
[NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
[NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
[NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
+ [NL80211_MNTR_FLAG_SKIP_TX] = { .type = NLA_FLAG },
};
static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
@@ -4312,6 +4320,29 @@ static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
return -EOPNOTSUPP;
}
+static int nl80211_parse_vif_radio_mask(struct genl_info *info,
+ u32 *radio_mask)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct nlattr *attr = info->attrs[NL80211_ATTR_VIF_RADIO_MASK];
+ u32 mask, allowed;
+
+ if (!attr) {
+ *radio_mask = 0;
+ return 0;
+ }
+
+ allowed = BIT(rdev->wiphy.n_radio) - 1;
+ mask = nla_get_u32(attr);
+ if (mask & ~allowed)
+ return -EINVAL;
+ if (!mask)
+ mask = allowed;
+ *radio_mask = mask;
+
+ return 1;
+}
+
static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -4319,6 +4350,8 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
int err;
enum nl80211_iftype otype, ntype;
struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ u32 radio_mask = 0;
bool change = false;
memset(&params, 0, sizeof(params));
@@ -4332,8 +4365,6 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
}
if (info->attrs[NL80211_ATTR_MESH_ID]) {
- struct wireless_dev *wdev = dev->ieee80211_ptr;
-
if (ntype != NL80211_IFTYPE_MESH_POINT)
return -EINVAL;
if (otype != NL80211_IFTYPE_MESH_POINT)
@@ -4364,6 +4395,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
if (err > 0)
change = true;
+ err = nl80211_parse_vif_radio_mask(info, &radio_mask);
+ if (err < 0)
+ return err;
+ if (err && netif_running(dev))
+ return -EBUSY;
+
if (change)
err = cfg80211_change_iface(rdev, dev, ntype, &params);
else
@@ -4372,11 +4409,11 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
if (!err && params.use_4addr != -1)
dev->ieee80211_ptr->use_4addr = params.use_4addr;
- if (change && !err) {
- struct wireless_dev *wdev = dev->ieee80211_ptr;
+ if (radio_mask)
+ wdev->radio_mask = radio_mask;
+ if (change && !err)
nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
- }
return err;
}
@@ -4387,6 +4424,7 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
struct vif_params params;
struct wireless_dev *wdev;
struct sk_buff *msg;
+ u32 radio_mask;
int err;
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
@@ -4424,6 +4462,10 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
if (err < 0)
return err;
+ err = nl80211_parse_vif_radio_mask(info, &radio_mask);
+ if (err < 0)
+ return err;
+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -4465,6 +4507,9 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
break;
}
+ if (radio_mask)
+ wdev->radio_mask = radio_mask;
+
if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
nlmsg_free(msg);
@@ -6227,33 +6272,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
goto out;
}
- if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
- params->smps_mode =
- nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
- switch (params->smps_mode) {
- case NL80211_SMPS_OFF:
- break;
- case NL80211_SMPS_STATIC:
- if (!(rdev->wiphy.features &
- NL80211_FEATURE_STATIC_SMPS)) {
- err = -EINVAL;
- goto out;
- }
- break;
- case NL80211_SMPS_DYNAMIC:
- if (!(rdev->wiphy.features &
- NL80211_FEATURE_DYNAMIC_SMPS)) {
- err = -EINVAL;
- goto out;
- }
- break;
- default:
- err = -EINVAL;
- goto out;
- }
- } else {
- params->smps_mode = NL80211_SMPS_OFF;
- }
+ if (info->attrs[NL80211_ATTR_SMPS_MODE] &&
+ nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]) != NL80211_SMPS_OFF)
+ return -EOPNOTSUPP;
params->pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
if (params->pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
@@ -9180,6 +9201,9 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev,
lockdep_assert_wiphy(wdev->wiphy);
+ if (!cfg80211_wdev_channel_allowed(wdev, chan))
+ return false;
+
if (!cfg80211_beaconing_iface_active(wdev))
return true;
@@ -9392,7 +9416,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
}
/* ignore disabled channels */
- if (chan->flags & IEEE80211_CHAN_DISABLED)
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(wdev, chan))
continue;
request->channels[i] = chan;
@@ -9412,7 +9437,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
chan = &wiphy->bands[band]->channels[j];
- if (chan->flags & IEEE80211_CHAN_DISABLED)
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(wdev, chan))
continue;
request->channels[i] = chan;
@@ -12446,7 +12472,7 @@ static int nl80211_del_pmksa(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_MAC]) {
pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
} else if (info->attrs[NL80211_ATTR_SSID]) {
- /* SSID based pmksa flush suppported only for FILS,
+ /* SSID based pmksa flush supported only for FILS,
* OWE/SAE OFFLOAD cases
*/
if (info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
@@ -14061,8 +14087,6 @@ void cfg80211_free_coalesce(struct cfg80211_coalesce *coalesce)
for (i = 0; i < coalesce->n_rules; i++) {
rule = &coalesce->rules[i];
- if (!rule)
- continue;
for (j = 0; j < rule->n_patterns; j++)
kfree(rule->patterns[j].mask);
kfree(rule->patterns);
@@ -15498,7 +15522,7 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
/* TODO: handle 802.11 TSPEC/admission control
* need more attributes for that (e.g. BA session requirement);
- * change the WMM adminssion test above to allow both then
+ * change the WMM admission test above to allow both then
*/
return -EINVAL;
}
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index b7e3e46ec16d..326faea38ca3 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -200,7 +200,7 @@ static void find_ns(struct ieee80211_radiotap_iterator *iterator,
* present fields. @this_arg can be changed by the caller (eg,
* incremented to move inside a compound argument like
* IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in
- * little-endian format whatever the endianess of your CPU.
+ * little-endian format whatever the endianness of your CPU.
*
* Alignment Gotcha:
* You must take care when dereferencing iterator.this_arg
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index f5adbf6b5c84..adb6105bbb7d 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -445,11 +445,12 @@ rdev_libertas_set_mesh_channel(struct cfg80211_registered_device *rdev,
static inline int
rdev_set_monitor_channel(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
struct cfg80211_chan_def *chandef)
{
int ret;
- trace_rdev_set_monitor_channel(&rdev->wiphy, chandef);
- ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chandef);
+ trace_rdev_set_monitor_channel(&rdev->wiphy, dev, chandef);
+ ret = rdev->ops->set_monitor_channel(&rdev->wiphy, dev, chandef);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 6489ba943a63..1df65a5a44f7 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1147,7 +1147,7 @@ static const struct ieee80211_regdomain *reg_get_regdomain(struct wiphy *wiphy)
/*
* Follow the driver's regulatory domain, if present, unless a country
- * IE has been processed or a user wants to help complaince further
+ * IE has been processed or a user wants to help compliance further
*/
if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
lr->initiator != NL80211_REGDOM_SET_BY_USER &&
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 59a90bf3c0d6..8e3d46bf4836 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -956,7 +956,8 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev)
struct ieee80211_channel *chan =
ieee80211_get_channel(&rdev->wiphy, ap->center_freq);
- if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
+ if (!chan || chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(rdev_req->wdev, chan))
continue;
for (i = 0; i < rdev_req->n_channels; i++) {
@@ -3515,9 +3516,12 @@ int cfg80211_wext_siwscan(struct net_device *dev,
continue;
for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
+ struct ieee80211_channel *chan;
+
/* ignore disabled channels */
- if (wiphy->bands[band]->channels[j].flags &
- IEEE80211_CHAN_DISABLED)
+ chan = &wiphy->bands[band]->channels[j];
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(creq->wdev, chan))
continue;
/* If we have a wireless request structure and the
@@ -3594,7 +3598,6 @@ int cfg80211_wext_siwscan(struct net_device *dev,
kfree(creq);
return err;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_siwscan);
static char *ieee80211_scan_add_ies(struct iw_request_info *info,
const struct cfg80211_bss_ies *ies,
@@ -3966,5 +3969,4 @@ int cfg80211_wext_giwscan(struct net_device *dev,
return res;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_giwscan);
#endif
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 97c21b627791..d5c9bb614fa6 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1318,19 +1318,21 @@ TRACE_EVENT(rdev_libertas_set_mesh_channel,
);
TRACE_EVENT(rdev_set_monitor_channel,
- TP_PROTO(struct wiphy *wiphy,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_chan_def *chandef),
- TP_ARGS(wiphy, chandef),
+ TP_ARGS(wiphy, netdev, chandef),
TP_STRUCT__entry(
WIPHY_ENTRY
+ NETDEV_ENTRY
CHAN_DEF_ENTRY
),
TP_fast_assign(
WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
CHAN_DEF_ASSIGN(chandef);
),
- TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
- WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT,
+ WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
);
TRACE_EVENT(rdev_auth,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f49b55724f83..040d62051eb9 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -743,7 +743,7 @@ __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen,
return NULL;
/*
- * When reusing framents, copy some data to the head to simplify
+ * When reusing fragments, copy some data to the head to simplify
* ethernet header handling and speed up protocol header processing
* in the stack later.
*/
@@ -2923,3 +2923,32 @@ bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
return true;
}
EXPORT_SYMBOL(cfg80211_radio_chandef_valid);
+
+bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev,
+ struct ieee80211_channel *chan)
+{
+ struct wiphy *wiphy = wdev->wiphy;
+ const struct wiphy_radio *radio;
+ struct cfg80211_chan_def chandef;
+ u32 radio_mask;
+ int i;
+
+ radio_mask = wdev->radio_mask;
+ if (!wiphy->n_radio || radio_mask == BIT(wiphy->n_radio) - 1)
+ return true;
+
+ cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
+ for (i = 0; i < wiphy->n_radio; i++) {
+ if (!(radio_mask & BIT(i)))
+ continue;
+
+ radio = &wiphy->radio[i];
+ if (!cfg80211_radio_chandef_valid(radio, &chandef))
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(cfg80211_wdev_channel_allowed);
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 2371069f3c43..90d5c0592667 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -30,7 +30,6 @@ int cfg80211_wext_giwname(struct net_device *dev,
strcpy(wrqu->name, "IEEE 802.11");
return 0;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_giwname);
int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
@@ -69,7 +68,6 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
return ret;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode);
int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
@@ -105,7 +103,6 @@ int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
}
return 0;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_giwmode);
int cfg80211_wext_giwrange(struct net_device *dev,
@@ -220,7 +217,6 @@ int cfg80211_wext_giwrange(struct net_device *dev,
return 0;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_giwrange);
/**
@@ -281,7 +277,6 @@ out:
wiphy_unlock(&rdev->wiphy);
return err;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_siwrts);
int cfg80211_wext_giwrts(struct net_device *dev,
struct iw_request_info *info,
@@ -296,7 +291,6 @@ int cfg80211_wext_giwrts(struct net_device *dev,
return 0;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_giwrts);
int cfg80211_wext_siwfrag(struct net_device *dev,
struct iw_request_info *info,
@@ -327,7 +321,6 @@ out:
return err;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_siwfrag);
int cfg80211_wext_giwfrag(struct net_device *dev,
struct iw_request_info *info,
@@ -342,7 +335,6 @@ int cfg80211_wext_giwfrag(struct net_device *dev,
return 0;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_giwfrag);
static int cfg80211_wext_siwretry(struct net_device *dev,
struct iw_request_info *info,
@@ -413,7 +405,6 @@ int cfg80211_wext_giwretry(struct net_device *dev,
return 0;
}
-EXPORT_WEXT_HANDLER(cfg80211_wext_giwretry);
static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
struct net_device *dev, bool pairwise,
@@ -830,7 +821,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
ret = -EINVAL;
break;
}
- ret = cfg80211_set_monitor_channel(rdev, &chandef);
+ ret = cfg80211_set_monitor_channel(rdev, dev, &chandef);
break;
case NL80211_IFTYPE_MESH_POINT:
freq = cfg80211_wext_freq(wextfreq);
@@ -1204,7 +1195,7 @@ static int cfg80211_wext_siwpower(struct net_device *dev,
switch (wrq->flags & IW_POWER_MODE) {
case IW_POWER_ON: /* If not specified */
case IW_POWER_MODE: /* If set all mask */
- case IW_POWER_ALL_R: /* If explicitely state all */
+ case IW_POWER_ALL_R: /* If explicitly state all */
ps = true;
break;
default: /* Otherwise we ignore */
diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h
index c02eb789e676..8251ca5df8ae 100644
--- a/net/wireless/wext-compat.h
+++ b/net/wireless/wext-compat.h
@@ -5,12 +5,6 @@
#include <net/iw_handler.h>
#include <linux/wireless.h>
-#ifdef CONFIG_CFG80211_WEXT_EXPORT
-#define EXPORT_WEXT_HANDLER(h) EXPORT_SYMBOL_GPL(h)
-#else
-#define EXPORT_WEXT_HANDLER(h)
-#endif /* CONFIG_CFG80211_WEXT_EXPORT */
-
int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
struct iw_request_info *info,
struct iw_freq *wextfreq, char *extra);
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 838ad6541a17..3bb04b05c5ce 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -1159,7 +1159,7 @@ char *iwe_stream_add_event(struct iw_request_info *info, char *stream,
/* Check if it's possible */
if (likely((stream + event_len) < ends)) {
iwe->len = event_len;
- /* Beware of alignement issues on 64 bits */
+ /* Beware of alignment issues on 64 bits */
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + lcp_len, &iwe->u,
event_len - lcp_len);