The branch main has been updated by bz:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=10f91d9ff7b827aac6035e224e6ddc2c79f3a0cd

commit 10f91d9ff7b827aac6035e224e6ddc2c79f3a0cd
Merge: bf603dbbb2c9 f5eb24d531de
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2025-12-05 20:48:02 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
CommitDate: 2026-02-10 08:35:34 +0000

    rtw89: update Realtek's rtw89 driver
    
    This version is based on
    git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
    24d479d26b25bce5faea3ddd9fa8f3a6c3129ea7 ( tag: v6.19-rc6 ).
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
    PR:             285228

 sys/contrib/dev/rtw89/Kconfig           |  22 +
 sys/contrib/dev/rtw89/Makefile          |   6 +
 sys/contrib/dev/rtw89/cam.c             | 173 +++---
 sys/contrib/dev/rtw89/cam.h             | 446 ++++------------
 sys/contrib/dev/rtw89/chan.c            |  11 +-
 sys/contrib/dev/rtw89/chan.h            |  10 +-
 sys/contrib/dev/rtw89/coex.c            |   5 +-
 sys/contrib/dev/rtw89/core.c            | 911 ++++++++++++++++++++++++++++----
 sys/contrib/dev/rtw89/core.h            | 242 ++++++++-
 sys/contrib/dev/rtw89/debug.c           | 424 ++++++++++++++-
 sys/contrib/dev/rtw89/debug.h           |   1 +
 sys/contrib/dev/rtw89/fw.c              | 353 ++++++++++---
 sys/contrib/dev/rtw89/fw.h              | 144 ++++-
 sys/contrib/dev/rtw89/mac.c             | 270 ++++++++--
 sys/contrib/dev/rtw89/mac.h             | 115 +++-
 sys/contrib/dev/rtw89/mac80211.c        | 124 ++++-
 sys/contrib/dev/rtw89/mac_be.c          |  10 +-
 sys/contrib/dev/rtw89/pci.c             | 486 +++++++++++++----
 sys/contrib/dev/rtw89/pci.h             | 132 ++++-
 sys/contrib/dev/rtw89/pci_be.c          |  18 +-
 sys/contrib/dev/rtw89/phy.c             | 541 +++++++++++++++++--
 sys/contrib/dev/rtw89/phy.h             |  24 +-
 sys/contrib/dev/rtw89/phy_be.c          |  13 +
 sys/contrib/dev/rtw89/ps.c              |  26 +-
 sys/contrib/dev/rtw89/reg.h             |  80 ++-
 sys/contrib/dev/rtw89/regd.c            |  22 +-
 sys/contrib/dev/rtw89/rtw8851b.c        |   7 +
 sys/contrib/dev/rtw89/rtw8851b_rfk.c    | 167 +++---
 sys/contrib/dev/rtw89/rtw8851be.c       |   4 +
 sys/contrib/dev/rtw89/rtw8851bu.c       |  27 +
 sys/contrib/dev/rtw89/rtw8852a.c        | 129 ++++-
 sys/contrib/dev/rtw89/rtw8852a_rfk.c    |  16 +-
 sys/contrib/dev/rtw89/rtw8852ae.c       |   4 +
 sys/contrib/dev/rtw89/rtw8852au.c       |  79 +++
 sys/contrib/dev/rtw89/rtw8852b.c        |   7 +
 sys/contrib/dev/rtw89/rtw8852b_common.c |   6 +-
 sys/contrib/dev/rtw89/rtw8852b_rfk.c    |   6 +-
 sys/contrib/dev/rtw89/rtw8852be.c       |   4 +
 sys/contrib/dev/rtw89/rtw8852bt.c       |   4 +
 sys/contrib/dev/rtw89/rtw8852bt_rfk.c   |  14 +-
 sys/contrib/dev/rtw89/rtw8852bte.c      |   4 +
 sys/contrib/dev/rtw89/rtw8852bu.c       |  26 +
 sys/contrib/dev/rtw89/rtw8852c.c        | 172 +++++-
 sys/contrib/dev/rtw89/rtw8852c.h        |   2 +-
 sys/contrib/dev/rtw89/rtw8852c_rfk.c    |  69 ++-
 sys/contrib/dev/rtw89/rtw8852ce.c       |   4 +
 sys/contrib/dev/rtw89/rtw8852cu.c       |  69 +++
 sys/contrib/dev/rtw89/rtw8922a.c        |  26 +-
 sys/contrib/dev/rtw89/rtw8922ae.c       |   4 +
 sys/contrib/dev/rtw89/sar.c             |  15 +
 sys/contrib/dev/rtw89/sar.h             |   1 +
 sys/contrib/dev/rtw89/ser.c             |   5 +-
 sys/contrib/dev/rtw89/txrx.h            |  45 +-
 sys/contrib/dev/rtw89/usb.c             | 115 ++--
 sys/contrib/dev/rtw89/usb.h             |  12 +
 sys/contrib/dev/rtw89/wow.c             |  87 ++-
 sys/contrib/dev/rtw89/wow.h             |   6 +
 sys/modules/rtw89/Makefile              |   7 +-
 58 files changed, 4651 insertions(+), 1101 deletions(-)

diff --cc sys/contrib/dev/rtw89/Makefile
index 23e43c444f69,000000000000..1be81f254fca
mode 100644,000000..100644
--- a/sys/contrib/dev/rtw89/Makefile
+++ b/sys/contrib/dev/rtw89/Makefile
@@@ -1,92 -1,0 +1,98 @@@
 +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 +
 +obj-$(CONFIG_RTW89_CORE) += rtw89_core.o
 +rtw89_core-y += core.o \
 +              mac80211.o \
 +              mac.o \
 +              mac_be.o \
 +              phy.o \
 +              phy_be.o \
 +              fw.o \
 +              cam.o \
 +              efuse.o \
 +              efuse_be.o \
 +              regd.o \
 +              sar.o \
 +              coex.o \
 +              ps.o \
 +              chan.o \
 +              ser.o \
 +              acpi.o \
 +              util.o
 +
 +rtw89_core-$(CONFIG_PM) += wow.o
 +
 +obj-$(CONFIG_RTW89_8851B) += rtw89_8851b.o
 +rtw89_8851b-objs := rtw8851b.o \
 +                  rtw8851b_table.o \
 +                  rtw8851b_rfk.o \
 +                  rtw8851b_rfk_table.o
 +
 +obj-$(CONFIG_RTW89_8851BE) += rtw89_8851be.o
 +rtw89_8851be-objs := rtw8851be.o
 +
 +obj-$(CONFIG_RTW89_8851BU) += rtw89_8851bu.o
 +rtw89_8851bu-objs := rtw8851bu.o
 +
 +obj-$(CONFIG_RTW89_8852A) += rtw89_8852a.o
 +rtw89_8852a-objs := rtw8852a.o \
 +                  rtw8852a_table.o \
 +                  rtw8852a_rfk.o \
 +                  rtw8852a_rfk_table.o
 +
 +obj-$(CONFIG_RTW89_8852AE) += rtw89_8852ae.o
 +rtw89_8852ae-objs := rtw8852ae.o
 +
++obj-$(CONFIG_RTW89_8852AU) += rtw89_8852au.o
++rtw89_8852au-objs := rtw8852au.o
++
 +obj-$(CONFIG_RTW89_8852B_COMMON) += rtw89_8852b_common.o
 +rtw89_8852b_common-objs := rtw8852b_common.o
 +
 +obj-$(CONFIG_RTW89_8852B) += rtw89_8852b.o
 +rtw89_8852b-objs := rtw8852b.o \
 +                  rtw8852b_table.o \
 +                  rtw8852b_rfk.o \
 +                  rtw8852b_rfk_table.o
 +
 +obj-$(CONFIG_RTW89_8852BE) += rtw89_8852be.o
 +rtw89_8852be-objs := rtw8852be.o
 +
 +obj-$(CONFIG_RTW89_8852BU) += rtw89_8852bu.o
 +rtw89_8852bu-objs := rtw8852bu.o
 +
 +obj-$(CONFIG_RTW89_8852BT) += rtw89_8852bt.o
 +rtw89_8852bt-objs := rtw8852bt.o \
 +                  rtw8852bt_rfk.o \
 +                  rtw8852bt_rfk_table.o
 +
 +obj-$(CONFIG_RTW89_8852BTE) += rtw89_8852bte.o
 +rtw89_8852bte-objs := rtw8852bte.o
 +
 +obj-$(CONFIG_RTW89_8852C) += rtw89_8852c.o
 +rtw89_8852c-objs := rtw8852c.o \
 +                  rtw8852c_table.o \
 +                  rtw8852c_rfk.o \
 +                  rtw8852c_rfk_table.o
 +
 +obj-$(CONFIG_RTW89_8852CE) += rtw89_8852ce.o
 +rtw89_8852ce-objs := rtw8852ce.o
 +
++obj-$(CONFIG_RTW89_8852CU) += rtw89_8852cu.o
++rtw89_8852cu-objs := rtw8852cu.o
++
 +obj-$(CONFIG_RTW89_8922A) += rtw89_8922a.o
 +rtw89_8922a-objs := rtw8922a.o \
 +                  rtw8922a_rfk.o
 +
 +obj-$(CONFIG_RTW89_8922AE) += rtw89_8922ae.o
 +rtw89_8922ae-objs := rtw8922ae.o
 +
 +rtw89_core-$(CONFIG_RTW89_DEBUG) += debug.o
 +
 +obj-$(CONFIG_RTW89_PCI) += rtw89_pci.o
 +rtw89_pci-y := pci.o pci_be.o
 +
 +obj-$(CONFIG_RTW89_USB) += rtw89_usb.o
 +rtw89_usb-y := usb.o
 +
diff --cc sys/contrib/dev/rtw89/core.c
index 1220378d08cf,000000000000..b1b16dda3304
mode 100644,000000..100644
--- a/sys/contrib/dev/rtw89/core.c
+++ b/sys/contrib/dev/rtw89/core.c
@@@ -1,5998 -1,0 +1,6725 @@@
 +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 +/* Copyright(c) 2019-2020  Realtek Corporation
 + */
 +
 +#if defined(__FreeBSD__)
 +#define       LINUXKPI_PARAM_PREFIX   rtw89_
 +#endif
 +
 +#include <linux/ip.h>
++#include <linux/sort.h>
 +#include <linux/udp.h>
 +
 +#include "cam.h"
 +#include "chan.h"
 +#include "coex.h"
 +#include "core.h"
 +#include "efuse.h"
 +#include "fw.h"
 +#include "mac.h"
 +#include "phy.h"
 +#include "ps.h"
 +#include "reg.h"
 +#include "sar.h"
 +#include "ser.h"
 +#include "txrx.h"
 +#include "util.h"
 +#include "wow.h"
 +
 +static bool rtw89_disable_ps_mode;
 +module_param_named(disable_ps_mode, rtw89_disable_ps_mode, bool, 0644);
 +MODULE_PARM_DESC(disable_ps_mode, "Set Y to disable low power mode");
 +
 +#if defined(__FreeBSD__)
 +static bool rtw_ht_support = false;
 +module_param_named(support_ht, rtw_ht_support, bool, 0644);
 +MODULE_PARM_DESC(support_ht, "Set to Y to enable HT support");
 +
 +static bool rtw_vht_support = false;
 +module_param_named(support_vht, rtw_vht_support, bool, 0644);
 +MODULE_PARM_DESC(support_vht, "Set to Y to enable VHT support");
 +
 +static bool rtw_eht_support = false;
 +module_param_named(support_eht, rtw_eht_support, bool, 0644);
 +MODULE_PARM_DESC(support_eht, "Set to Y to enable EHT support");
 +#endif
 +
 +
 +#define RTW89_DEF_CHAN(_freq, _hw_val, _flags, _band) \
 +      { .center_freq = _freq, .hw_value = _hw_val, .flags = _flags, .band = 
_band, }
 +#define RTW89_DEF_CHAN_2G(_freq, _hw_val)     \
 +      RTW89_DEF_CHAN(_freq, _hw_val, 0, NL80211_BAND_2GHZ)
 +#define RTW89_DEF_CHAN_5G(_freq, _hw_val)     \
 +      RTW89_DEF_CHAN(_freq, _hw_val, 0, NL80211_BAND_5GHZ)
 +#define RTW89_DEF_CHAN_5G_NO_HT40MINUS(_freq, _hw_val)        \
 +      RTW89_DEF_CHAN(_freq, _hw_val, IEEE80211_CHAN_NO_HT40MINUS, 
NL80211_BAND_5GHZ)
 +#define RTW89_DEF_CHAN_6G(_freq, _hw_val)     \
 +      RTW89_DEF_CHAN(_freq, _hw_val, 0, NL80211_BAND_6GHZ)
 +
 +static struct ieee80211_channel rtw89_channels_2ghz[] = {
 +      RTW89_DEF_CHAN_2G(2412, 1),
 +      RTW89_DEF_CHAN_2G(2417, 2),
 +      RTW89_DEF_CHAN_2G(2422, 3),
 +      RTW89_DEF_CHAN_2G(2427, 4),
 +      RTW89_DEF_CHAN_2G(2432, 5),
 +      RTW89_DEF_CHAN_2G(2437, 6),
 +      RTW89_DEF_CHAN_2G(2442, 7),
 +      RTW89_DEF_CHAN_2G(2447, 8),
 +      RTW89_DEF_CHAN_2G(2452, 9),
 +      RTW89_DEF_CHAN_2G(2457, 10),
 +      RTW89_DEF_CHAN_2G(2462, 11),
 +      RTW89_DEF_CHAN_2G(2467, 12),
 +      RTW89_DEF_CHAN_2G(2472, 13),
 +      RTW89_DEF_CHAN_2G(2484, 14),
 +};
 +
 +static struct ieee80211_channel rtw89_channels_5ghz[] = {
 +      RTW89_DEF_CHAN_5G(5180, 36),
 +      RTW89_DEF_CHAN_5G(5200, 40),
 +      RTW89_DEF_CHAN_5G(5220, 44),
 +      RTW89_DEF_CHAN_5G(5240, 48),
 +      RTW89_DEF_CHAN_5G(5260, 52),
 +      RTW89_DEF_CHAN_5G(5280, 56),
 +      RTW89_DEF_CHAN_5G(5300, 60),
 +      RTW89_DEF_CHAN_5G(5320, 64),
 +      RTW89_DEF_CHAN_5G(5500, 100),
 +      RTW89_DEF_CHAN_5G(5520, 104),
 +      RTW89_DEF_CHAN_5G(5540, 108),
 +      RTW89_DEF_CHAN_5G(5560, 112),
 +      RTW89_DEF_CHAN_5G(5580, 116),
 +      RTW89_DEF_CHAN_5G(5600, 120),
 +      RTW89_DEF_CHAN_5G(5620, 124),
 +      RTW89_DEF_CHAN_5G(5640, 128),
 +      RTW89_DEF_CHAN_5G(5660, 132),
 +      RTW89_DEF_CHAN_5G(5680, 136),
 +      RTW89_DEF_CHAN_5G(5700, 140),
 +      RTW89_DEF_CHAN_5G(5720, 144),
 +      RTW89_DEF_CHAN_5G(5745, 149),
 +      RTW89_DEF_CHAN_5G(5765, 153),
 +      RTW89_DEF_CHAN_5G(5785, 157),
 +      RTW89_DEF_CHAN_5G(5805, 161),
 +      RTW89_DEF_CHAN_5G_NO_HT40MINUS(5825, 165),
 +      RTW89_DEF_CHAN_5G(5845, 169),
 +      RTW89_DEF_CHAN_5G(5865, 173),
 +      RTW89_DEF_CHAN_5G(5885, 177),
 +};
 +
 +static_assert(RTW89_5GHZ_UNII4_START_INDEX + RTW89_5GHZ_UNII4_CHANNEL_NUM ==
 +            ARRAY_SIZE(rtw89_channels_5ghz));
 +
 +static struct ieee80211_channel rtw89_channels_6ghz[] = {
 +      RTW89_DEF_CHAN_6G(5955, 1),
 +      RTW89_DEF_CHAN_6G(5975, 5),
 +      RTW89_DEF_CHAN_6G(5995, 9),
 +      RTW89_DEF_CHAN_6G(6015, 13),
 +      RTW89_DEF_CHAN_6G(6035, 17),
 +      RTW89_DEF_CHAN_6G(6055, 21),
 +      RTW89_DEF_CHAN_6G(6075, 25),
 +      RTW89_DEF_CHAN_6G(6095, 29),
 +      RTW89_DEF_CHAN_6G(6115, 33),
 +      RTW89_DEF_CHAN_6G(6135, 37),
 +      RTW89_DEF_CHAN_6G(6155, 41),
 +      RTW89_DEF_CHAN_6G(6175, 45),
 +      RTW89_DEF_CHAN_6G(6195, 49),
 +      RTW89_DEF_CHAN_6G(6215, 53),
 +      RTW89_DEF_CHAN_6G(6235, 57),
 +      RTW89_DEF_CHAN_6G(6255, 61),
 +      RTW89_DEF_CHAN_6G(6275, 65),
 +      RTW89_DEF_CHAN_6G(6295, 69),
 +      RTW89_DEF_CHAN_6G(6315, 73),
 +      RTW89_DEF_CHAN_6G(6335, 77),
 +      RTW89_DEF_CHAN_6G(6355, 81),
 +      RTW89_DEF_CHAN_6G(6375, 85),
 +      RTW89_DEF_CHAN_6G(6395, 89),
 +      RTW89_DEF_CHAN_6G(6415, 93),
 +      RTW89_DEF_CHAN_6G(6435, 97),
 +      RTW89_DEF_CHAN_6G(6455, 101),
 +      RTW89_DEF_CHAN_6G(6475, 105),
 +      RTW89_DEF_CHAN_6G(6495, 109),
 +      RTW89_DEF_CHAN_6G(6515, 113),
 +      RTW89_DEF_CHAN_6G(6535, 117),
 +      RTW89_DEF_CHAN_6G(6555, 121),
 +      RTW89_DEF_CHAN_6G(6575, 125),
 +      RTW89_DEF_CHAN_6G(6595, 129),
 +      RTW89_DEF_CHAN_6G(6615, 133),
 +      RTW89_DEF_CHAN_6G(6635, 137),
 +      RTW89_DEF_CHAN_6G(6655, 141),
 +      RTW89_DEF_CHAN_6G(6675, 145),
 +      RTW89_DEF_CHAN_6G(6695, 149),
 +      RTW89_DEF_CHAN_6G(6715, 153),
 +      RTW89_DEF_CHAN_6G(6735, 157),
 +      RTW89_DEF_CHAN_6G(6755, 161),
 +      RTW89_DEF_CHAN_6G(6775, 165),
 +      RTW89_DEF_CHAN_6G(6795, 169),
 +      RTW89_DEF_CHAN_6G(6815, 173),
 +      RTW89_DEF_CHAN_6G(6835, 177),
 +      RTW89_DEF_CHAN_6G(6855, 181),
 +      RTW89_DEF_CHAN_6G(6875, 185),
 +      RTW89_DEF_CHAN_6G(6895, 189),
 +      RTW89_DEF_CHAN_6G(6915, 193),
 +      RTW89_DEF_CHAN_6G(6935, 197),
 +      RTW89_DEF_CHAN_6G(6955, 201),
 +      RTW89_DEF_CHAN_6G(6975, 205),
 +      RTW89_DEF_CHAN_6G(6995, 209),
 +      RTW89_DEF_CHAN_6G(7015, 213),
 +      RTW89_DEF_CHAN_6G(7035, 217),
 +      RTW89_DEF_CHAN_6G(7055, 221),
 +      RTW89_DEF_CHAN_6G(7075, 225),
 +      RTW89_DEF_CHAN_6G(7095, 229),
 +      RTW89_DEF_CHAN_6G(7115, 233),
 +};
 +
 +static struct ieee80211_rate rtw89_bitrates[] = {
 +      { .bitrate = 10,  .hw_value = 0x00, },
 +      { .bitrate = 20,  .hw_value = 0x01, },
 +      { .bitrate = 55,  .hw_value = 0x02, },
 +      { .bitrate = 110, .hw_value = 0x03, },
 +      { .bitrate = 60,  .hw_value = 0x04, },
 +      { .bitrate = 90,  .hw_value = 0x05, },
 +      { .bitrate = 120, .hw_value = 0x06, },
 +      { .bitrate = 180, .hw_value = 0x07, },
 +      { .bitrate = 240, .hw_value = 0x08, },
 +      { .bitrate = 360, .hw_value = 0x09, },
 +      { .bitrate = 480, .hw_value = 0x0a, },
 +      { .bitrate = 540, .hw_value = 0x0b, },
 +};
 +
 +static const struct ieee80211_iface_limit rtw89_iface_limits[] = {
 +      {
 +              .max = 1,
 +              .types = BIT(NL80211_IFTYPE_STATION),
 +      },
 +      {
 +              .max = 1,
 +              .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
 +                       BIT(NL80211_IFTYPE_P2P_GO) |
 +                       BIT(NL80211_IFTYPE_AP),
 +      },
 +};
 +
 +static const struct ieee80211_iface_limit rtw89_iface_limits_mcc[] = {
 +      {
 +              .max = 1,
 +              .types = BIT(NL80211_IFTYPE_STATION),
 +      },
 +      {
 +              .max = 1,
 +              .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
 +                       BIT(NL80211_IFTYPE_P2P_GO),
 +      },
 +};
 +
 +static const struct ieee80211_iface_combination rtw89_iface_combs[] = {
 +      {
 +              .limits = rtw89_iface_limits,
 +              .n_limits = ARRAY_SIZE(rtw89_iface_limits),
 +              .max_interfaces = RTW89_MAX_INTERFACE_NUM,
 +              .num_different_channels = 1,
 +      },
 +      {
 +              .limits = rtw89_iface_limits_mcc,
 +              .n_limits = ARRAY_SIZE(rtw89_iface_limits_mcc),
 +              .max_interfaces = RTW89_MAX_INTERFACE_NUM,
 +              .num_different_channels = 2,
 +      },
 +};
 +
 +static const u8 rtw89_ext_capa_sta[] = {
 +      [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
 +      [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
 +      [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
 +};
 +
 +static const struct wiphy_iftype_ext_capab rtw89_iftypes_ext_capa[] = {
 +      {
 +              .iftype = NL80211_IFTYPE_STATION,
 +              .extended_capabilities = rtw89_ext_capa_sta,
 +              .extended_capabilities_mask = rtw89_ext_capa_sta,
 +              .extended_capabilities_len = sizeof(rtw89_ext_capa_sta),
 +              /* relevant only if EHT is supported */
 +              .eml_capabilities = 0,
 +              .mld_capa_and_ops = 0,
 +      },
 +};
 +
 +#define RTW89_6GHZ_SPAN_HEAD 6145
 +#define RTW89_6GHZ_SPAN_IDX(center_freq) \
 +      ((((int)(center_freq) - RTW89_6GHZ_SPAN_HEAD) / 5) / 2)
 +
 +#define RTW89_DECL_6GHZ_SPAN(center_freq, subband_l, subband_h) \
 +      [RTW89_6GHZ_SPAN_IDX(center_freq)] = { \
 +              .sar_subband_low = RTW89_SAR_6GHZ_ ## subband_l, \
 +              .sar_subband_high = RTW89_SAR_6GHZ_ ## subband_h, \
 +              .acpi_sar_subband_low = RTW89_ACPI_SAR_6GHZ_ ## subband_l, \
 +              .acpi_sar_subband_high = RTW89_ACPI_SAR_6GHZ_ ## subband_h, \
 +              .ant_gain_subband_low = RTW89_ANT_GAIN_6GHZ_ ## subband_l, \
 +              .ant_gain_subband_high = RTW89_ANT_GAIN_6GHZ_ ## subband_h, \
 +      }
 +
 +/* Since 6GHz subbands are not edge aligned, some cases span two subbands.
 + * In the following, we describe each of them with rtw89_6ghz_span.
 + */
 +static const struct rtw89_6ghz_span rtw89_overlapping_6ghz[] = {
 +      RTW89_DECL_6GHZ_SPAN(6145, SUBBAND_5_L, SUBBAND_5_H),
 +      RTW89_DECL_6GHZ_SPAN(6165, SUBBAND_5_L, SUBBAND_5_H),
 +      RTW89_DECL_6GHZ_SPAN(6185, SUBBAND_5_L, SUBBAND_5_H),
 +      RTW89_DECL_6GHZ_SPAN(6505, SUBBAND_6, SUBBAND_7_L),
 +      RTW89_DECL_6GHZ_SPAN(6525, SUBBAND_6, SUBBAND_7_L),
 +      RTW89_DECL_6GHZ_SPAN(6545, SUBBAND_6, SUBBAND_7_L),
 +      RTW89_DECL_6GHZ_SPAN(6665, SUBBAND_7_L, SUBBAND_7_H),
 +      RTW89_DECL_6GHZ_SPAN(6705, SUBBAND_7_L, SUBBAND_7_H),
 +      RTW89_DECL_6GHZ_SPAN(6825, SUBBAND_7_H, SUBBAND_8),
 +      RTW89_DECL_6GHZ_SPAN(6865, SUBBAND_7_H, SUBBAND_8),
 +      RTW89_DECL_6GHZ_SPAN(6875, SUBBAND_7_H, SUBBAND_8),
 +      RTW89_DECL_6GHZ_SPAN(6885, SUBBAND_7_H, SUBBAND_8),
 +};
 +
 +const struct rtw89_6ghz_span *
 +rtw89_get_6ghz_span(struct rtw89_dev *rtwdev, u32 center_freq)
 +{
 +      int idx;
 +
 +      if (center_freq >= RTW89_6GHZ_SPAN_HEAD) {
 +              idx = RTW89_6GHZ_SPAN_IDX(center_freq);
 +              /* To decrease size of rtw89_overlapping_6ghz[],
 +               * RTW89_6GHZ_SPAN_IDX() truncates the leading NULLs
 +               * to make first span as index 0 of the table. So, if center
 +               * frequency is less than the first one, it will get netative.
 +               */
 +              if (idx >= 0 && idx < ARRAY_SIZE(rtw89_overlapping_6ghz))
 +                      return &rtw89_overlapping_6ghz[idx];
 +      }
 +
 +      return NULL;
 +}
 +
- bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 
*bitrate)
++bool rtw89_legacy_rate_to_bitrate(struct rtw89_dev *rtwdev, u8 legacy_rate, 
u16 *bitrate)
 +{
-       struct ieee80211_rate rate;
++      const struct ieee80211_rate *rate;
 +
-       if (unlikely(rpt_rate >= ARRAY_SIZE(rtw89_bitrates))) {
-               rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "invalid rpt rate %d\n", 
rpt_rate);
++      if (unlikely(legacy_rate >= ARRAY_SIZE(rtw89_bitrates))) {
++              rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
++                          "invalid legacy rate %d\n", legacy_rate);
 +              return false;
 +      }
 +
-       rate = rtw89_bitrates[rpt_rate];
-       *bitrate = rate.bitrate;
++      rate = &rtw89_bitrates[legacy_rate];
++      *bitrate = rate->bitrate;
 +
 +      return true;
 +}
 +
 +static const struct ieee80211_supported_band rtw89_sband_2ghz = {
 +      .band           = NL80211_BAND_2GHZ,
 +      .channels       = rtw89_channels_2ghz,
 +      .n_channels     = ARRAY_SIZE(rtw89_channels_2ghz),
 +      .bitrates       = rtw89_bitrates,
 +      .n_bitrates     = ARRAY_SIZE(rtw89_bitrates),
 +      .ht_cap         = {0},
 +      .vht_cap        = {0},
 +};
 +
 +static const struct ieee80211_supported_band rtw89_sband_5ghz = {
 +      .band           = NL80211_BAND_5GHZ,
 +      .channels       = rtw89_channels_5ghz,
 +      .n_channels     = ARRAY_SIZE(rtw89_channels_5ghz),
 +
 +      /* 5G has no CCK rates, 1M/2M/5.5M/11M */
 +      .bitrates       = rtw89_bitrates + 4,
 +      .n_bitrates     = ARRAY_SIZE(rtw89_bitrates) - 4,
 +      .ht_cap         = {0},
 +      .vht_cap        = {0},
 +};
 +
 +static const struct ieee80211_supported_band rtw89_sband_6ghz = {
 +      .band           = NL80211_BAND_6GHZ,
 +      .channels       = rtw89_channels_6ghz,
 +      .n_channels     = ARRAY_SIZE(rtw89_channels_6ghz),
 +
 +      /* 6G has no CCK rates, 1M/2M/5.5M/11M */
 +      .bitrates       = rtw89_bitrates + 4,
 +      .n_bitrates     = ARRAY_SIZE(rtw89_bitrates) - 4,
 +};
 +
++static const struct rtw89_hw_rate_def {
++      enum rtw89_hw_rate ht;
++      enum rtw89_hw_rate vht[RTW89_NSS_NUM];
++} rtw89_hw_rate[RTW89_CHIP_GEN_NUM] = {
++      [RTW89_CHIP_AX] = {
++              .ht = RTW89_HW_RATE_MCS0,
++              .vht = {RTW89_HW_RATE_VHT_NSS1_MCS0,
++                      RTW89_HW_RATE_VHT_NSS2_MCS0,
++                      RTW89_HW_RATE_VHT_NSS3_MCS0,
++                      RTW89_HW_RATE_VHT_NSS4_MCS0},
++      },
++      [RTW89_CHIP_BE] = {
++              .ht = RTW89_HW_RATE_V1_MCS0,
++              .vht = {RTW89_HW_RATE_V1_VHT_NSS1_MCS0,
++                      RTW89_HW_RATE_V1_VHT_NSS2_MCS0,
++                      RTW89_HW_RATE_V1_VHT_NSS3_MCS0,
++                      RTW89_HW_RATE_V1_VHT_NSS4_MCS0},
++      },
++};
++
 +static void __rtw89_traffic_stats_accu(struct rtw89_traffic_stats *stats,
 +                                     struct sk_buff *skb, bool tx)
 +{
 +      if (tx) {
 +              stats->tx_cnt++;
 +              stats->tx_unicast += skb->len;
 +      } else {
 +              stats->rx_cnt++;
 +              stats->rx_unicast += skb->len;
 +      }
 +}
 +
 +static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev,
 +                                   struct rtw89_vif *rtwvif,
 +                                   struct sk_buff *skb,
 +                                   bool accu_dev, bool tx)
 +{
 +      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 +
 +      if (!ieee80211_is_data(hdr->frame_control))
 +              return;
 +
 +      if (is_broadcast_ether_addr(hdr->addr1) ||
 +          is_multicast_ether_addr(hdr->addr1))
 +              return;
 +
 +      if (accu_dev)
 +              __rtw89_traffic_stats_accu(&rtwdev->stats, skb, tx);
 +
 +      if (rtwvif) {
 +              __rtw89_traffic_stats_accu(&rtwvif->stats, skb, tx);
 +              __rtw89_traffic_stats_accu(&rtwvif->stats_ps, skb, tx);
 +      }
 +}
 +
 +void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef)
 +{
 +      cfg80211_chandef_create(chandef, &rtw89_channels_2ghz[0],
 +                              NL80211_CHAN_NO_HT);
 +}
 +
 +void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
 +                            struct rtw89_chan *chan)
 +{
 +      struct ieee80211_channel *channel = chandef->chan;
 +      enum nl80211_chan_width width = chandef->width;
 +      u32 primary_freq, center_freq;
 +      u8 center_chan;
 +      u8 bandwidth = RTW89_CHANNEL_WIDTH_20;
 +      u32 offset;
 +      u8 band;
 +
 +      center_chan = channel->hw_value;
 +      primary_freq = channel->center_freq;
 +      center_freq = chandef->center_freq1;
 +
 +      switch (width) {
 +      case NL80211_CHAN_WIDTH_20_NOHT:
 +      case NL80211_CHAN_WIDTH_20:
 +              bandwidth = RTW89_CHANNEL_WIDTH_20;
 +              break;
 +      case NL80211_CHAN_WIDTH_40:
 +              bandwidth = RTW89_CHANNEL_WIDTH_40;
 +              if (primary_freq > center_freq) {
 +                      center_chan -= 2;
 +              } else {
 +                      center_chan += 2;
 +              }
 +              break;
 +      case NL80211_CHAN_WIDTH_80:
 +      case NL80211_CHAN_WIDTH_160:
 +              bandwidth = nl_to_rtw89_bandwidth(width);
 +              if (primary_freq > center_freq) {
 +                      offset = (primary_freq - center_freq - 10) / 20;
 +                      center_chan -= 2 + offset * 4;
 +              } else {
 +                      offset = (center_freq - primary_freq - 10) / 20;
 +                      center_chan += 2 + offset * 4;
 +              }
 +              break;
 +      default:
 +              center_chan = 0;
 +              break;
 +      }
 +
 +      switch (channel->band) {
 +      default:
 +      case NL80211_BAND_2GHZ:
 +              band = RTW89_BAND_2G;
 +              break;
 +      case NL80211_BAND_5GHZ:
 +              band = RTW89_BAND_5G;
 +              break;
 +      case NL80211_BAND_6GHZ:
 +              band = RTW89_BAND_6G;
 +              break;
 +      }
 +
 +      rtw89_chan_create(chan, center_chan, channel->hw_value, band, 
bandwidth);
 +}
 +
 +static void __rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev,
 +                                      const struct rtw89_chan *chan,
 +                                      enum rtw89_phy_idx phy_idx)
 +{
 +      const struct rtw89_chip_info *chip = rtwdev->chip;
 +      bool entity_active;
 +
 +      entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
 +      if (!entity_active)
 +              return;
 +
 +      chip->ops->set_txpwr(rtwdev, chan, phy_idx);
 +}
 +
 +void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
 +{
 +      const struct rtw89_chan *chan;
 +
 +      chan = rtw89_mgnt_chan_get(rtwdev, 0);
 +      __rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_0);
 +
 +      if (!rtwdev->support_mlo)
 +              return;
 +
 +      chan = rtw89_mgnt_chan_get(rtwdev, 1);
 +      __rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_1);
 +}
 +
++static void rtw89_chip_rfk_channel_for_pure_mon_vif(struct rtw89_dev *rtwdev,
++                                                  enum rtw89_phy_idx phy_idx)
++{
++      struct rtw89_vif *rtwvif = rtwdev->pure_monitor_mode_vif;
++      struct rtw89_vif_link *rtwvif_link;
++
++      if (!rtwvif)
++              return;
++
++      rtwvif_link = rtw89_vif_get_link_inst(rtwvif, phy_idx);
++      if (!rtwvif_link)
++              return;
++
++      rtw89_chip_rfk_channel(rtwdev, rtwvif_link);
++}
++
 +static void __rtw89_set_channel(struct rtw89_dev *rtwdev,
 +                              const struct rtw89_chan *chan,
 +                              enum rtw89_mac_idx mac_idx,
 +                              enum rtw89_phy_idx phy_idx)
 +{
 +      const struct rtw89_chip_info *chip = rtwdev->chip;
 +      const struct rtw89_chan_rcd *chan_rcd;
 +      struct rtw89_channel_help_params bak;
 +      bool entity_active;
 +
 +      entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
 +
 +      chan_rcd = rtw89_chan_rcd_get_by_chan(chan);
 +
 +      rtw89_chip_set_channel_prepare(rtwdev, &bak, chan, mac_idx, phy_idx);
 +
 +      chip->ops->set_channel(rtwdev, chan, mac_idx, phy_idx);
 +
 +      chip->ops->set_txpwr(rtwdev, chan, phy_idx);
 +
 +      rtw89_chip_set_channel_done(rtwdev, &bak, chan, mac_idx, phy_idx);
 +
 +      if (!entity_active || chan_rcd->band_changed) {
 +              rtw89_btc_ntfy_switch_band(rtwdev, phy_idx, chan->band_type);
 +              rtw89_chip_rfk_band_changed(rtwdev, phy_idx, chan);
 +      }
 +
 +      rtw89_set_entity_state(rtwdev, phy_idx, true);
++
++      rtw89_chip_rfk_channel_for_pure_mon_vif(rtwdev, phy_idx);
 +}
 +
 +int rtw89_set_channel(struct rtw89_dev *rtwdev)
 +{
 +      const struct rtw89_chan *chan;
 +      enum rtw89_entity_mode mode;
 +
 +      mode = rtw89_entity_recalc(rtwdev);
 +      if (mode < 0 || mode >= NUM_OF_RTW89_ENTITY_MODE) {
 +              WARN(1, "Invalid ent mode: %d\n", mode);
 +              return -EINVAL;
 +      }
 +
 +      chan = rtw89_mgnt_chan_get(rtwdev, 0);
 +      __rtw89_set_channel(rtwdev, chan, RTW89_MAC_0, RTW89_PHY_0);
 +
 +      if (!rtwdev->support_mlo)
 +              return 0;
 +
 +      chan = rtw89_mgnt_chan_get(rtwdev, 1);
 +      __rtw89_set_channel(rtwdev, chan, RTW89_MAC_1, RTW89_PHY_1);
 +
 +      return 0;
 +}
 +
 +static enum rtw89_core_tx_type
 +rtw89_core_get_tx_type(struct rtw89_dev *rtwdev,
 +                     struct sk_buff *skb)
 +{
 +      struct ieee80211_hdr *hdr = (void *)skb->data;
 +      __le16 fc = hdr->frame_control;
 +
 +      if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc))
 +              return RTW89_CORE_TX_TYPE_MGMT;
 +
 +      return RTW89_CORE_TX_TYPE_DATA;
 +}
 +
 +static void
 +rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev,
 +                              struct rtw89_core_tx_request *tx_req,
 +                              enum btc_pkt_type pkt_type)
 +{
 +      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;
 +      u8 tid;
 +
 +      if (pkt_type == PACKET_EAPOL) {
 +              desc_info->bk = true;
 +              return;
 +      }
 +
 +      if (!(IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU))
 +              return;
 +
 +      if (!rtwsta_link) {
 +              rtw89_warn(rtwdev, "cannot set ampdu info without sta\n");
 +              return;
 +      }
 +
 +      tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
 +      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 << link_sta->ht_cap.ampdu_factor) - 1);
 +
 +      desc_info->agg_en = true;
 +      desc_info->ampdu_density = link_sta->ht_cap.ampdu_density;
 +      desc_info->ampdu_num = ampdu_num;
 +
 +      rcu_read_unlock();
 +}
 +
 +static void
 +rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev,
 +                           struct rtw89_core_tx_request *tx_req)
 +{
 +      struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
 +      const struct rtw89_chip_info *chip = rtwdev->chip;
 +      const struct rtw89_sec_cam_entry *sec_cam;
 +      struct ieee80211_tx_info *info;
 +      struct ieee80211_key_conf *key;
 +      struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
 +      struct sk_buff *skb = tx_req->skb;
 +      u8 sec_type = RTW89_SEC_KEY_TYPE_NONE;
 +      u8 sec_cam_idx;
 +      u64 pn64;
 +
 +      info = IEEE80211_SKB_CB(skb);
 +      key = info->control.hw_key;
 +      sec_cam_idx = key->hw_key_idx;
 +      sec_cam = cam_info->sec_entries[sec_cam_idx];
 +      if (!sec_cam) {
 +              rtw89_warn(rtwdev, "sec cam entry is empty\n");
 +              return;
 +      }
 +
 +      switch (key->cipher) {
 +      case WLAN_CIPHER_SUITE_WEP40:
 +              sec_type = RTW89_SEC_KEY_TYPE_WEP40;
 +              break;
 +      case WLAN_CIPHER_SUITE_WEP104:
 +              sec_type = RTW89_SEC_KEY_TYPE_WEP104;
 +              break;
 +      case WLAN_CIPHER_SUITE_TKIP:
 +              sec_type = RTW89_SEC_KEY_TYPE_TKIP;
 +              break;
 +      case WLAN_CIPHER_SUITE_CCMP:
 +              sec_type = RTW89_SEC_KEY_TYPE_CCMP128;
 +              break;
 +      case WLAN_CIPHER_SUITE_CCMP_256:
 +              sec_type = RTW89_SEC_KEY_TYPE_CCMP256;
 +              break;
 +      case WLAN_CIPHER_SUITE_GCMP:
 +              sec_type = RTW89_SEC_KEY_TYPE_GCMP128;
 +              break;
 +      case WLAN_CIPHER_SUITE_GCMP_256:
 +              sec_type = RTW89_SEC_KEY_TYPE_GCMP256;
 +              break;
 +      default:
 +              rtw89_warn(rtwdev, "key cipher not supported %d\n", 
key->cipher);
 +              return;
 +      }
 +
 +      desc_info->sec_en = true;
 +      desc_info->sec_keyid = key->keyidx;
 +      desc_info->sec_type = sec_type;
 +      desc_info->sec_cam_idx = sec_cam->sec_cam_idx;
 +
 +      if (!chip->hw_sec_hdr)
 +              return;
 +
 +      pn64 = atomic64_inc_return(&key->tx_pn);
 +      desc_info->sec_seq[0] = pn64;
 +      desc_info->sec_seq[1] = pn64 >> 8;
 +      desc_info->sec_seq[2] = pn64 >> 16;
 +      desc_info->sec_seq[3] = pn64 >> 24;
 +      desc_info->sec_seq[4] = pn64 >> 32;
 +      desc_info->sec_seq[5] = pn64 >> 40;
 +      desc_info->wp_offset = 1; /* in unit of 8 bytes for security header */
 +}
 +
 +static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
 +                                  struct rtw89_core_tx_request *tx_req,
 +                                  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))
 +              lowest_rate = RTW89_HW_RATE_OFDM6;
 +      else if (chan->band_type == RTW89_BAND_2G)
 +              lowest_rate = RTW89_HW_RATE_CCK1;
 +      else
 +              lowest_rate = RTW89_HW_RATE_OFDM6;
 +
 +      if (!rtwvif_link)
 +              return 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 rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
 +      struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
 +      struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
 +
 +      if (desc_info->mlo && !desc_info->sw_mld) {
 +              if (rtwsta_link)
 +                      return rtw89_sta_get_main_macid(rtwsta_link->rtwsta);
 +              else
 +                      return rtw89_vif_get_main_macid(rtwvif_link->rtwvif);
 +      }
 +
 +      if (!rtwsta_link)
 +              return rtwvif_link->mac_id;
 +
 +      return rtwsta_link->mac_id;
 +}
 +
 +static void rtw89_core_tx_update_llc_hdr(struct rtw89_dev *rtwdev,
 +                                       struct rtw89_tx_desc_info *desc_info,
 +                                       struct sk_buff *skb)
 +{
 +      struct ieee80211_hdr *hdr = (void *)skb->data;
 +      __le16 fc = hdr->frame_control;
 +
 +      desc_info->hdr_llc_len = ieee80211_hdrlen(fc);
 +      desc_info->hdr_llc_len >>= 1; /* in unit of 2 bytes */
 +}
 +
++u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel)
++{
++      switch (qsel) {
++      default:
++              rtw89_warn(rtwdev, "Cannot map qsel to dma: %d\n", qsel);
++              fallthrough;
++      case RTW89_TX_QSEL_BE_0:
++      case RTW89_TX_QSEL_BE_1:
++      case RTW89_TX_QSEL_BE_2:
++      case RTW89_TX_QSEL_BE_3:
++              return RTW89_TXCH_ACH0;
++      case RTW89_TX_QSEL_BK_0:
++      case RTW89_TX_QSEL_BK_1:
++      case RTW89_TX_QSEL_BK_2:
++      case RTW89_TX_QSEL_BK_3:
++              return RTW89_TXCH_ACH1;
++      case RTW89_TX_QSEL_VI_0:
++      case RTW89_TX_QSEL_VI_1:
++      case RTW89_TX_QSEL_VI_2:
++      case RTW89_TX_QSEL_VI_3:
++              return RTW89_TXCH_ACH2;
++      case RTW89_TX_QSEL_VO_0:
++      case RTW89_TX_QSEL_VO_1:
++      case RTW89_TX_QSEL_VO_2:
++      case RTW89_TX_QSEL_VO_3:
++              return RTW89_TXCH_ACH3;
++      case RTW89_TX_QSEL_B0_MGMT:
++              return RTW89_TXCH_CH8;
++      case RTW89_TX_QSEL_B0_HI:
++              return RTW89_TXCH_CH9;
++      case RTW89_TX_QSEL_B1_MGMT:
*** 59787 LINES SKIPPED ***

Reply via email to