Search Linux Wireless

[RFC v1 030/256] cl8k: add cap.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Viktor Barna <viktor.barna@xxxxxxxxxx>

(Part of the split. Please, take a look at the cover letter for more
details).

Signed-off-by: Viktor Barna <viktor.barna@xxxxxxxxxx>
---
 drivers/net/wireless/celeno/cl8k/cap.c | 928 +++++++++++++++++++++++++
 1 file changed, 928 insertions(+)
 create mode 100644 drivers/net/wireless/celeno/cl8k/cap.c

diff --git a/drivers/net/wireless/celeno/cl8k/cap.c b/drivers/net/wireless/celeno/cl8k/cap.c
new file mode 100644
index 000000000000..bfd884706aa7
--- /dev/null
+++ b/drivers/net/wireless/celeno/cl8k/cap.c
@@ -0,0 +1,928 @@
+// SPDX-License-Identifier: MIT
+/* Copyright(c) 2019-2021, Celeno Communications Ltd. */
+
+#include "cap.h"
+#include "utils/utils.h"
+#include "debug.h"
+#include "band.h"
+#include "chan_info.h"
+#include "tx/tx.h"
+#include "sta.h"
+#include "rx/rx_amsdu.h"
+
+#define CL_HT_CAPABILITIES                                              \
+{                                                                       \
+       .ht_supported = true,                                           \
+       .cap = IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU, \
+       .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,                     \
+       .ampdu_density = IEEE80211_HT_MPDU_DENSITY_1,                   \
+       .mcs = {                                                        \
+               .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0 },         \
+               .rx_highest = cpu_to_le16(65),                          \
+               .tx_params = IEEE80211_HT_MCS_TX_DEFINED,               \
+       },                                                              \
+}
+
+#define CL_VHT_CAPABILITIES                                             \
+{                                                                       \
+       .vht_supported = false,                                         \
+       .cap =                                                          \
+               IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |               \
+               IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |               \
+               IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE |               \
+               IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |               \
+               (3 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT) |    \
+               (3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT),          \
+       .vht_mcs = {                                                    \
+               .rx_mcs_map = cpu_to_le16(                              \
+                               IEEE80211_VHT_MCS_SUPPORT_0_7   << 0  | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 2  | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 4  | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 6  | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 8  | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 14), \
+               .tx_mcs_map = cpu_to_le16(                              \
+                               IEEE80211_VHT_MCS_SUPPORT_0_7   << 0  | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 2  | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 4  | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 6  | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 8  | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | \
+                               IEEE80211_VHT_MCS_NOT_SUPPORTED << 14), \
+       }                                                               \
+}
+
+#define CL_HE_CAP_ELEM_STATION                                                       \
+{                                                                                    \
+       .mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE,                             \
+       .mac_cap_info[1] = 0,                                                        \
+       .mac_cap_info[2] = 0,                                                        \
+       .mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2,            \
+       .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_BQR,                                \
+       .mac_cap_info[5] = IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX,               \
+       .phy_cap_info[0] = IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G, \
+       .phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A,                     \
+       .phy_cap_info[2] = 0,                                                        \
+       .phy_cap_info[3] = 0,                                                        \
+       .phy_cap_info[4] = 0,                                                        \
+       .phy_cap_info[5] = 0,                                                        \
+       .phy_cap_info[6] = 0,                                                        \
+       .phy_cap_info[7] = 0,                                                        \
+       .phy_cap_info[8] = IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G,       \
+       .phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US,           \
+       .phy_cap_info[10] = 0,                                                       \
+}
+
+#define CL_HE_CAP_ELEM_AP                                                       \
+{                                                                               \
+       .mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE,                        \
+       .mac_cap_info[1] = 0,                                                   \
+       .mac_cap_info[2] = 0,                                                   \
+       .mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2,       \
+       .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_BQR,                           \
+       .mac_cap_info[5] = 0,                                                   \
+       .phy_cap_info[0] = 0,                                                   \
+       .phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A,                \
+       .phy_cap_info[2] = 0,                                                   \
+       .phy_cap_info[3] = 0,                                                   \
+       .phy_cap_info[4] = 0,                                                   \
+       .phy_cap_info[5] = 0,                                                   \
+       .phy_cap_info[6] = 0,                                                   \
+       .phy_cap_info[7] = 0,                                                   \
+       .phy_cap_info[8] = 0,                                                   \
+       .phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US,      \
+       .phy_cap_info[10] = 0,                                                  \
+}
+
+#define CL_HE_CAP_ELEM_MESH_POINT                                               \
+{                                                                               \
+       .mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE,                        \
+       .mac_cap_info[1] = 0,                                                   \
+       .mac_cap_info[2] = 0,                                                   \
+       .mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2,       \
+       .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_BQR,                           \
+       .mac_cap_info[5] = 0,                                                   \
+       .phy_cap_info[0] = 0,                                                   \
+       .phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A,                \
+       .phy_cap_info[2] = 0,                                                   \
+       .phy_cap_info[3] = 0,                                                   \
+       .phy_cap_info[4] = 0,                                                   \
+       .phy_cap_info[5] = 0,                                                   \
+       .phy_cap_info[6] = 0,                                                   \
+       .phy_cap_info[7] = 0,                                                   \
+       .phy_cap_info[8] = 0,                                                   \
+       .phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US,      \
+       .phy_cap_info[10] = 0,                                                  \
+}
+
+#define CL_HE_MCS_NSS_SUPP                   \
+{                                            \
+       .rx_mcs_80 = cpu_to_le16(0xff00),    \
+       .tx_mcs_80 = cpu_to_le16(0xff00),    \
+       .rx_mcs_160 = cpu_to_le16(0xff00),   \
+       .tx_mcs_160 = cpu_to_le16(0xff00),   \
+       .rx_mcs_80p80 = cpu_to_le16(0xffff), \
+       .tx_mcs_80p80 = cpu_to_le16(0xffff), \
+}
+
+#define RATE(_bitrate, _hw_rate, _flags) { \
+       .bitrate = (_bitrate),             \
+       .flags = (_flags),                 \
+       .hw_value = (_hw_rate),            \
+}
+
+#define CHAN(_freq, _idx) {     \
+       .center_freq = (_freq), \
+       .hw_value = (_idx),     \
+       .max_power = 18,        \
+}
+
+#define CHANF(_freq, _idx, _flags) { \
+       .center_freq = (_freq),      \
+       .hw_value = (_idx),          \
+       .flags = (_flags),           \
+       .max_power = 18,             \
+}
+
+static struct ieee80211_sband_iftype_data cl_he_data[] = {
+       {
+               .types_mask = BIT(NL80211_IFTYPE_STATION),
+               .he_cap = {
+                       .has_he = true,
+                       .he_cap_elem = CL_HE_CAP_ELEM_STATION,
+                       .he_mcs_nss_supp = CL_HE_MCS_NSS_SUPP,
+               },
+       },
+       {
+               .types_mask = BIT(NL80211_IFTYPE_AP),
+               .he_cap = {
+                       .has_he = true,
+                       .he_cap_elem = CL_HE_CAP_ELEM_AP,
+                       .he_mcs_nss_supp = CL_HE_MCS_NSS_SUPP,
+               },
+       },
+       {
+               .types_mask = BIT(NL80211_IFTYPE_MESH_POINT),
+               .he_cap = {
+                       .has_he = true,
+                       .he_cap_elem = CL_HE_CAP_ELEM_MESH_POINT,
+                       .he_mcs_nss_supp = CL_HE_MCS_NSS_SUPP,
+               },
+       },
+};
+
+static struct ieee80211_rate cl_ratetable[] = {
+       RATE(10,  0x00, 0),
+       RATE(20,  0x01, IEEE80211_RATE_SHORT_PREAMBLE),
+       RATE(55,  0x02, IEEE80211_RATE_SHORT_PREAMBLE),
+       RATE(110, 0x03, IEEE80211_RATE_SHORT_PREAMBLE),
+       RATE(60,  0x04, 0),
+       RATE(90,  0x05, 0),
+       RATE(120, 0x06, 0),
+       RATE(180, 0x07, 0),
+       RATE(240, 0x08, 0),
+       RATE(360, 0x09, 0),
+       RATE(480, 0x0A, 0),
+       RATE(540, 0x0B, 0),
+};
+
+/* The channels indexes here are not used anymore */
+static struct ieee80211_channel cl_2ghz_channels[] = {
+       CHAN(2412, 0),
+       CHAN(2417, 1),
+       CHAN(2422, 2),
+       CHAN(2427, 3),
+       CHAN(2432, 4),
+       CHAN(2437, 5),
+       CHAN(2442, 6),
+       CHAN(2447, 7),
+       CHAN(2452, 8),
+       CHAN(2457, 9),
+       CHAN(2462, 10),
+       CHAN(2467, 11),
+       CHAN(2472, 12),
+       CHAN(2484, 13),
+};
+
+static struct ieee80211_channel cl_5ghz_channels[] = {
+       CHAN(5180, 0),  /* 36 -  20MHz */
+       CHAN(5200, 1),  /* 40 -  20MHz */
+       CHAN(5220, 2),  /* 44 -  20MHz */
+       CHAN(5240, 3),  /* 48 -  20MHz */
+
+       CHANF(5260, 4,  IEEE80211_CHAN_RADAR),  /* 52 -  20MHz */
+       CHANF(5280, 5,  IEEE80211_CHAN_RADAR),  /* 56 -  20MHz */
+       CHANF(5300, 6,  IEEE80211_CHAN_RADAR),  /* 60 -  20MHz */
+       CHANF(5320, 7,  IEEE80211_CHAN_RADAR),  /* 64 -  20MHz */
+       CHANF(5500, 8,  IEEE80211_CHAN_RADAR),  /* 100 - 20MHz */
+       CHANF(5520, 9,  IEEE80211_CHAN_RADAR),  /* 104 - 20MHz */
+       CHANF(5540, 10, IEEE80211_CHAN_RADAR), /* 108 - 20MHz */
+       CHANF(5560, 11, IEEE80211_CHAN_RADAR), /* 112 - 20MHz */
+       CHANF(5580, 12, IEEE80211_CHAN_RADAR), /* 116 - 20MHz */
+       CHANF(5600, 13, IEEE80211_CHAN_RADAR), /* 120 - 20MHz */
+       CHANF(5620, 14, IEEE80211_CHAN_RADAR), /* 124 - 20MHz */
+       CHANF(5640, 15, IEEE80211_CHAN_RADAR), /* 128 - 20MHz */
+       CHANF(5660, 16, IEEE80211_CHAN_RADAR), /* 132 - 20MHz */
+       CHANF(5680, 17, IEEE80211_CHAN_RADAR), /* 136 - 20MHz */
+       CHANF(5700, 18, IEEE80211_CHAN_RADAR), /* 140 - 20MHz */
+
+       CHAN(5720, 19), /* 144 - 20MHz */
+       CHAN(5745, 20), /* 149 - 20MHz */
+       CHAN(5765, 21), /* 153 - 20MHz */
+       CHAN(5785, 22), /* 157 - 20MHz */
+       CHAN(5805, 23), /* 161 - 20MHz */
+       CHAN(5825, 24), /* 165 - 20MHz */
+};
+
+static struct ieee80211_channel cl_6ghz_channels[] = {
+       CHAN(5955, 1),  /* 1 - 20MHz */
+       CHAN(5935, 2),  /* 2 - 20MHz */
+       CHAN(5975, 5),  /* 5 - 20MHz */
+       CHAN(5995, 9),  /* 9 - 20MHz */
+       CHAN(6015, 13),  /* 13 - 20MHz */
+       CHAN(6035, 17),  /* 17 - 20MHz */
+       CHAN(6055, 21),  /* 21 - 20MHz */
+       CHAN(6075, 25),  /* 25 - 20MHz */
+       CHAN(6095, 29),  /* 29 - 20MHz */
+       CHAN(6115, 33),  /* 33 - 20MHz */
+       CHAN(6135, 37),  /* 37 - 20MHz */
+       CHAN(6155, 41),  /* 41 - 20MHz */
+       CHAN(6175, 45),  /* 45 - 20MHz */
+       CHAN(6195, 49),  /* 49 - 20MHz */
+       CHAN(6215, 53),  /* 53 - 20MHz */
+       CHAN(6235, 57),  /* 57 - 20MHz */
+       CHAN(6255, 61),  /* 61 - 20MHz */
+       CHAN(6275, 65),  /* 65 - 20MHz */
+       CHAN(6295, 69),  /* 69 - 20MHz */
+       CHAN(6315, 73),  /* 73 - 20MHz */
+       CHAN(6335, 77),  /* 77 - 20MHz */
+       CHAN(6355, 81),  /* 81 - 20MHz */
+       CHAN(6375, 85),  /* 85 - 20MHz */
+       CHAN(6395, 89),  /* 89 - 20MHz */
+       CHAN(6415, 93),  /* 93 - 20MHz */
+       CHAN(6435, 97),  /* 97 - 20MHz */
+       CHAN(6455, 101),  /* 101 - 20MHz */
+       CHAN(6475, 105),  /* 105 - 20MHz */
+       CHAN(6495, 109),  /* 109 - 20MHz */
+       CHAN(6515, 113),  /* 113 - 20MHz */
+       CHAN(6535, 117),  /* 117 - 20MHz */
+       CHAN(6555, 121),  /* 121 - 20MHz */
+       CHAN(6575, 125),  /* 125 - 20MHz */
+       CHAN(6595, 129),  /* 129 - 20MHz */
+       CHAN(6615, 133),  /* 133 - 20MHz */
+       CHAN(6635, 137),  /* 137 - 20MHz */
+       CHAN(6655, 141),  /* 141 - 20MHz */
+       CHAN(6675, 145),  /* 145 - 20MHz */
+       CHAN(6695, 149),  /* 149 - 20MHz */
+       CHAN(6715, 153),  /* 153 - 20MHz */
+       CHAN(6735, 157),  /* 157 - 20MHz */
+       CHAN(6755, 161),  /* 161 - 20MHz */
+       CHAN(6775, 165),  /* 165 - 20MHz */
+       CHAN(6795, 169),  /* 169 - 20MHz */
+       CHAN(6815, 173),  /* 173 - 20MHz */
+       CHAN(6835, 177),  /* 177 - 20MHz */
+       CHAN(6855, 181),  /* 181 - 20MHz */
+       CHAN(6875, 188),  /* 185 - 20MHz */
+       CHAN(6895, 189),  /* 189 - 20MHz */
+       CHAN(6915, 193),  /* 193 - 20MHz */
+       CHAN(6935, 197),  /* 197 - 20MHz */
+       CHAN(6955, 201),  /* 201 - 20MHz */
+       CHAN(6975, 205),  /* 205 - 20MHz */
+       CHAN(6995, 209),  /* 209 - 20MHz */
+       CHAN(7015, 213),  /* 213 - 20MHz */
+       CHAN(7035, 217),  /* 217 - 20MHz */
+       CHAN(7055, 221),  /* 221 - 20MHz */
+       CHAN(7075, 225),  /* 225 - 20MHz */
+       CHAN(7095, 229),  /* 229 - 20MHz */
+       CHAN(7115, 233),  /* 233 - 20MHz */
+};
+
+static struct ieee80211_supported_band cl_band_2ghz = {
+       .channels   = cl_2ghz_channels,
+       .n_channels = ARRAY_SIZE(cl_2ghz_channels),
+       .bitrates   = cl_ratetable,
+       .n_bitrates = ARRAY_SIZE(cl_ratetable),
+       .ht_cap     = CL_HT_CAPABILITIES,
+       .vht_cap    = CL_VHT_CAPABILITIES,
+};
+
+static struct ieee80211_supported_band cl_band_5ghz = {
+       .channels   = cl_5ghz_channels,
+       .n_channels = ARRAY_SIZE(cl_5ghz_channels),
+       .bitrates   = &cl_ratetable[4],
+       .n_bitrates = ARRAY_SIZE(cl_ratetable) - 4,
+       .ht_cap     = CL_HT_CAPABILITIES,
+       .vht_cap    = CL_VHT_CAPABILITIES,
+};
+
+static struct ieee80211_supported_band cl_band_6ghz = {
+       .channels   = cl_6ghz_channels,
+       .n_channels = ARRAY_SIZE(cl_6ghz_channels),
+       .bitrates   = &cl_ratetable[4],
+       .n_bitrates = ARRAY_SIZE(cl_ratetable) - 4,
+};
+
+static const struct ieee80211_iface_limit cl_limits[] = {
+       {
+               .max   = MAX_BSS_NUM,
+               .types = BIT(NL80211_IFTYPE_AP) |
+                        BIT(NL80211_IFTYPE_STATION) |
+                        BIT(NL80211_IFTYPE_MESH_POINT),
+       },
+};
+
+static const u8 cl_if_types_ext_capa_ap[] = {
+       [0]  = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
+       [7]  = WLAN_EXT_CAPA8_OPMODE_NOTIF,
+       [10] = WLAN_EXT_CAPA11_COMPLETE_LIST_OF_NONTXBSSID_PROFILES,
+};
+
+static const struct wiphy_iftype_ext_capab cl_iftypes_ext_capa[] = {
+       {
+               .iftype = NL80211_IFTYPE_AP,
+               .extended_capabilities = cl_if_types_ext_capa_ap,
+               .extended_capabilities_mask = cl_if_types_ext_capa_ap,
+               .extended_capabilities_len = sizeof(cl_if_types_ext_capa_ap),
+       },
+};
+
+static const struct ieee80211_iface_combination cl_combinations[] = {
+       {
+               .limits = cl_limits,
+               .n_limits = ARRAY_SIZE(cl_limits),
+               .num_different_channels = 1,
+               .max_interfaces = MAX_BSS_NUM,
+               .beacon_int_min_gcd = 100,
+               .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20) |
+                                      BIT(NL80211_CHAN_WIDTH_40) |
+                                      BIT(NL80211_CHAN_WIDTH_80) |
+                                      BIT(NL80211_CHAN_WIDTH_160),
+       }
+};
+
+static u8 he_mcs_supp_tx(struct cl_hw *cl_hw, u8 nss)
+{
+       u8 mcs = cl_hw->conf->ce_he_mcs_nss_supp_tx[nss];
+
+       switch (mcs) {
+       case WRS_MCS_7:
+               return IEEE80211_HE_MCS_SUPPORT_0_7;
+       case WRS_MCS_9:
+               return IEEE80211_HE_MCS_SUPPORT_0_9;
+       case WRS_MCS_11:
+               return IEEE80211_HE_MCS_SUPPORT_0_11;
+       }
+
+       cl_dbg_err(cl_hw, "Invalid mcs %u for nss %u. Must be 7, 9 or 11!\n", mcs, nss);
+       return IEEE80211_HE_MCS_NOT_SUPPORTED;
+}
+
+static u8 he_mcs_supp_rx(struct cl_hw *cl_hw, u8 nss)
+{
+       u8 mcs = cl_hw->conf->ce_he_mcs_nss_supp_rx[nss];
+
+       switch (mcs) {
+       case WRS_MCS_7:
+               return IEEE80211_HE_MCS_SUPPORT_0_7;
+       case WRS_MCS_9:
+               return IEEE80211_HE_MCS_SUPPORT_0_9;
+       case WRS_MCS_11:
+               return IEEE80211_HE_MCS_SUPPORT_0_11;
+       }
+
+       cl_dbg_err(cl_hw, "Invalid mcs %u for nss %u. Must be 7, 9 or 11!\n", mcs, nss);
+       return IEEE80211_HE_MCS_NOT_SUPPORTED;
+}
+
+static u8 vht_mcs_supp_tx(struct cl_hw *cl_hw, u8 nss)
+{
+       u8 mcs = cl_hw->conf->ce_vht_mcs_nss_supp_tx[nss];
+
+       switch (mcs) {
+       case WRS_MCS_7:
+               return IEEE80211_VHT_MCS_SUPPORT_0_7;
+       case WRS_MCS_8:
+               return IEEE80211_VHT_MCS_SUPPORT_0_8;
+       case WRS_MCS_9:
+               return IEEE80211_VHT_MCS_SUPPORT_0_9;
+       }
+
+       cl_dbg_err(cl_hw, "Invalid mcs %u for nss %u. Must be 7-9!\n", mcs, nss);
+       return IEEE80211_VHT_MCS_NOT_SUPPORTED;
+}
+
+static u8 vht_mcs_supp_rx(struct cl_hw *cl_hw, u8 nss)
+{
+       u8 mcs = cl_hw->conf->ce_vht_mcs_nss_supp_rx[nss];
+
+       switch (mcs) {
+       case WRS_MCS_7:
+               return IEEE80211_VHT_MCS_SUPPORT_0_7;
+       case WRS_MCS_8:
+               return IEEE80211_VHT_MCS_SUPPORT_0_8;
+       case WRS_MCS_9:
+               return IEEE80211_VHT_MCS_SUPPORT_0_9;
+       }
+
+       cl_dbg_err(cl_hw, "Invalid mcs %u for nss %u. Must be 7-9!\n", mcs, nss);
+       return IEEE80211_VHT_MCS_NOT_SUPPORTED;
+}
+
+static void cl_set_he_6ghz_capab(struct cl_hw *cl_hw)
+{
+       struct ieee80211_he_6ghz_capa *he_6ghz_cap0 = &cl_hw->iftype_data[0].he_6ghz_capa;
+       struct ieee80211_he_6ghz_capa *he_6ghz_cap1 = &cl_hw->iftype_data[1].he_6ghz_capa;
+       struct ieee80211_he_6ghz_capa *he_6ghz_cap2 = &cl_hw->iftype_data[2].he_6ghz_capa;
+
+       he_6ghz_cap0->capa = cpu_to_le16(IEEE80211_HT_MPDU_DENSITY_1);
+       he_6ghz_cap0->capa |=
+               cpu_to_le16(cl_hw->conf->ha_max_mpdu_len << HE_6GHZ_CAP_MAX_MPDU_LEN_OFFSET);
+       he_6ghz_cap0->capa |=
+               cpu_to_le16(IEEE80211_VHT_MAX_AMPDU_1024K << HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP_OFFSET);
+
+       he_6ghz_cap1->capa = he_6ghz_cap0->capa;
+       he_6ghz_cap2->capa = he_6ghz_cap0->capa;
+}
+
+static void _cl_set_he_capab(struct cl_hw *cl_hw, u8 idx)
+{
+       struct ieee80211_sta_he_cap *he_cap = &cl_hw->iftype_data[idx].he_cap;
+       struct ieee80211_he_mcs_nss_supp *he_mcs_nss_supp = &he_cap->he_mcs_nss_supp;
+       struct ieee80211_he_cap_elem *he_cap_elem = &he_cap->he_cap_elem;
+       u8 rx_nss = cl_hw->conf->ce_rx_nss;
+       u8 tx_nss = cl_hw->conf->ce_tx_nss;
+       int i = 0;
+
+       if (BAND_IS_5G_6G(cl_hw)) {
+               he_cap_elem->phy_cap_info[0] |=
+                       IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
+
+               for (i = 0; i < rx_nss; i++)
+                       he_mcs_nss_supp->rx_mcs_160 |=
+                               cpu_to_le16(he_mcs_supp_rx(cl_hw, i) << (i * 2));
+
+               for (i = 0; i < tx_nss; i++)
+                       he_mcs_nss_supp->tx_mcs_160 |=
+                               cpu_to_le16(he_mcs_supp_tx(cl_hw, i) << (i * 2));
+
+               he_cap_elem->phy_cap_info[0] |=
+                       IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
+
+               for (i = 0; i < rx_nss; i++)
+                       he_mcs_nss_supp->rx_mcs_80 |=
+                               cpu_to_le16(he_mcs_supp_rx(cl_hw, i) << (i * 2));
+
+               for (i = 0; i < tx_nss; i++)
+                       he_mcs_nss_supp->tx_mcs_80 |=
+                               cpu_to_le16(he_mcs_supp_tx(cl_hw, i) << (i * 2));
+       } else {
+               he_cap_elem->phy_cap_info[0] |=
+                       IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
+
+               for (i = 0; i < rx_nss; i++)
+                       he_mcs_nss_supp->rx_mcs_80 |=
+                               cpu_to_le16(he_mcs_supp_rx(cl_hw, i) << (i * 2));
+
+               for (i = 0; i < tx_nss; i++)
+                       he_mcs_nss_supp->tx_mcs_80 |=
+                               cpu_to_le16(he_mcs_supp_tx(cl_hw, i) << (i * 2));
+       }
+
+       for (i = rx_nss; i < 8; i++) {
+               he_mcs_nss_supp->rx_mcs_80 |=
+                       cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));
+               he_mcs_nss_supp->rx_mcs_160 |=
+                       cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));
+       }
+
+       for (i = tx_nss; i < 8; i++) {
+               he_mcs_nss_supp->tx_mcs_80 |=
+                       cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));
+               he_mcs_nss_supp->tx_mcs_160 |=
+                       cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));
+       }
+
+       if (cl_hw->conf->ce_he_rxldpc_en)
+               he_cap_elem->phy_cap_info[1] |=
+                       IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;
+
+       if (cl_hw->conf->ci_rx_he_mu_ppdu)
+               he_cap_elem->phy_cap_info[3] |=
+                       IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU;
+
+       he_cap_elem->phy_cap_info[3] |=
+               IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
+       he_cap_elem->phy_cap_info[5] |=
+               IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_4;
+}
+
+static void cl_set_he_capab(struct cl_hw *cl_hw)
+{
+       struct ieee80211_sta_he_cap *he_cap0 = &cl_hw->iftype_data[0].he_cap;
+       struct ieee80211_sta_he_cap *he_cap1 = &cl_hw->iftype_data[1].he_cap;
+       struct ieee80211_he_cap_elem *he_cap_elem0 = &he_cap0->he_cap_elem;
+       struct ieee80211_he_cap_elem *he_cap_elem1 = &he_cap1->he_cap_elem;
+
+       struct cl_tcv_conf *conf = cl_hw->conf;
+       u8 tf_mac_pad_dur = conf->ci_tf_mac_pad_dur;
+
+       memcpy(&cl_hw->iftype_data, cl_he_data, sizeof(cl_hw->iftype_data));
+
+       /* TWT support */
+       if (conf->ce_twt_en) {
+               /* STA mode */
+               he_cap_elem0->mac_cap_info[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
+               /* AP mode */
+               he_cap_elem1->mac_cap_info[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;
+       }
+
+       /* OMI support */
+       if (conf->ce_omi_en) {
+               /* STA mode */
+               he_cap_elem0->mac_cap_info[3] |= IEEE80211_HE_MAC_CAP3_OMI_CONTROL;
+               /* AP mode */
+               he_cap_elem1->mac_cap_info[3] |= IEEE80211_HE_MAC_CAP3_OMI_CONTROL;
+               he_cap_elem1->mac_cap_info[5] |= IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX;
+       }
+
+       if (tf_mac_pad_dur == 1)
+               he_cap_elem0->mac_cap_info[1] |= IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_8US;
+       else if (tf_mac_pad_dur == 2)
+               he_cap_elem0->mac_cap_info[1] |= IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;
+
+       _cl_set_he_capab(cl_hw, 0);
+       _cl_set_he_capab(cl_hw, 1);
+       _cl_set_he_capab(cl_hw, 2);
+
+       if (cl_band_is_6g(cl_hw))
+               cl_set_he_6ghz_capab(cl_hw);
+
+       cl_hw->sband.n_iftype_data = ARRAY_SIZE(cl_he_data);
+       cl_hw->sband.iftype_data = cl_hw->iftype_data;
+}
+
+void cl_cap_dyn_params(struct cl_hw *cl_hw)
+{
+       struct ieee80211_hw *hw = cl_hw->hw;
+       struct wiphy *wiphy = hw->wiphy;
+       struct cl_tcv_conf *conf = cl_hw->conf;
+       u8 rx_nss = conf->ce_rx_nss;
+       u8 tx_nss = conf->ce_tx_nss;
+       u8 guard_interval = conf->ha_short_guard_interval;
+       u8 i;
+       u8 bw = cl_hw->conf->ce_channel_bandwidth;
+       struct ieee80211_supported_band *sband = &cl_hw->sband;
+       struct ieee80211_sta_ht_cap *sband_ht_cap = &sband->ht_cap;
+       struct ieee80211_sta_vht_cap *sband_vht_cap = &sband->vht_cap;
+
+       if (cl_band_is_6g(cl_hw)) {
+               memcpy(sband, &cl_band_6ghz, sizeof(struct ieee80211_supported_band));
+       } else if (cl_band_is_5g(cl_hw)) {
+               memcpy(sband, &cl_band_5ghz, sizeof(struct ieee80211_supported_band));
+               if (!conf->ci_ieee80211h) {
+                       int i;
+
+                       for (i = 0; i < sband->n_channels; i++)
+                               sband->channels[i].flags &= ~IEEE80211_CHAN_RADAR;
+               }
+       } else {
+               memcpy(sband, &cl_band_2ghz, sizeof(struct ieee80211_supported_band));
+
+               if (!conf->ci_vht_cap_24g)
+                       memset(&sband->vht_cap, 0, sizeof(struct ieee80211_sta_vht_cap));
+       }
+
+       /* 6GHz doesn't support HT/VHT */
+       if (!cl_band_is_6g(cl_hw)) {
+               if (bw > CHNL_BW_20)
+                       sband_ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+               /* Guard_interval */
+               if (guard_interval) {
+                       sband_ht_cap->cap |= IEEE80211_HT_CAP_SGI_20;
+
+                       if (bw >= CHNL_BW_40)
+                               sband_ht_cap->cap |= IEEE80211_HT_CAP_SGI_40;
+
+                       if (bw >= CHNL_BW_80)
+                               sband_vht_cap->cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
+
+                       if (bw == CHNL_BW_160)
+                               sband_vht_cap->cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
+               }
+       }
+
+       /* Amsdu */
+       cl_rx_amsdu_hw_en(hw, conf->ce_rxamsdu_en);
+       cl_hw->txamsdu_en = conf->ce_txamsdu_en;
+
+       /* Hw flags */
+       ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
+       ieee80211_hw_set(hw, SIGNAL_DBM);
+       ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
+       ieee80211_hw_set(hw, QUEUE_CONTROL);
+       ieee80211_hw_set(hw, WANT_MONITOR_VIF);
+       ieee80211_hw_set(hw, SPECTRUM_MGMT);
+       ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES);
+       ieee80211_hw_set(hw, HAS_RATE_CONTROL);
+       ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
+       ieee80211_hw_set(hw, NO_AUTO_VIF);
+
+       wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
+
+       /* Turn on "20/40 Coex Mgmt Support" bit (24g only) */
+       if (cl_band_is_24g(cl_hw)) {
+               struct ieee80211_local *local = hw_to_local(hw);
+
+               if (conf->ce_coex_en)
+                       local->ext_capa[0] |= WLAN_EXT_CAPA1_2040_BSS_COEX_MGMT_ENABLED;
+               else
+                       wiphy->features &= ~NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
+       }
+
+       if (conf->ci_fast_rx_en) {
+               ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
+               ieee80211_hw_set(hw, AP_LINK_PS);
+       }
+
+       /*
+        * To disable the dynamic PS we say to the stack that we support it in
+        * HW. This will force mac80211 rely on us to handle this.
+        */
+       ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
+
+       if (conf->ci_agg_tx)
+               ieee80211_hw_set(hw, AMPDU_AGGREGATION);
+
+       if (conf->ci_ieee80211w)
+               ieee80211_hw_set(hw, MFP_CAPABLE);
+
+       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                BIT(NL80211_IFTYPE_AP) |
+                                BIT(NL80211_IFTYPE_MESH_POINT);
+
+       wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
+                       WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+
+       if (conf->ce_uapsd_en)
+               wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
+
+       wiphy->iface_combinations = cl_combinations;
+       wiphy->n_iface_combinations = ARRAY_SIZE(cl_combinations);
+
+       hw->max_rates = IEEE80211_TX_MAX_RATES;
+       hw->max_report_rates = IEEE80211_TX_MAX_RATES;
+       hw->max_rate_tries = 1;
+
+       hw->max_tx_aggregation_subframes = conf->ce_max_agg_size_tx;
+       hw->max_rx_aggregation_subframes = conf->ce_max_agg_size_rx;
+
+       hw->vif_data_size = sizeof(struct cl_vif);
+       hw->sta_data_size = sizeof(struct cl_sta);
+
+       hw->extra_tx_headroom = 0;
+       hw->queues = IEEE80211_MAX_QUEUES;
+       hw->offchannel_tx_hw_queue = CL_HWQ_VO;
+
+       if (!cl_band_is_6g(cl_hw)) {
+               if (conf->ce_ht_rxldpc_en)
+                       sband_ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING;
+
+               sband_ht_cap->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
+               sband_vht_cap->cap |= cl_hw->conf->ha_max_mpdu_len;
+       }
+
+       if (cl_band_is_5g(cl_hw) || (cl_band_is_24g(cl_hw) && conf->ci_vht_cap_24g)) {
+               if (bw == CHNL_BW_160)
+                       sband_vht_cap->cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+
+               sband_vht_cap->cap |= (conf->ha_vht_max_ampdu_len_exp <<
+                                      IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
+
+               if (conf->ce_vht_rxldpc_en)
+                       sband_vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC;
+
+               sband_vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(0);
+               sband_vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(0);
+
+               for (i = 0; i < rx_nss; i++)
+                       sband_vht_cap->vht_mcs.rx_mcs_map |=
+                               cpu_to_le16(vht_mcs_supp_rx(cl_hw, i) << (i * 2));
+
+               for (; i < 8; i++)
+                       sband_vht_cap->vht_mcs.rx_mcs_map |=
+                               cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2));
+
+               for (i = 0; i < tx_nss; i++)
+                       sband_vht_cap->vht_mcs.tx_mcs_map |=
+                               cpu_to_le16(vht_mcs_supp_tx(cl_hw, i) << (i * 2));
+
+               for (; i < 8; i++)
+                       sband_vht_cap->vht_mcs.tx_mcs_map |=
+                               cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2));
+
+               sband_vht_cap->vht_mcs.rx_highest = cpu_to_le16(390 * rx_nss);
+               sband_vht_cap->vht_mcs.tx_highest = cpu_to_le16(390 * tx_nss);
+               sband_vht_cap->vht_supported = true;
+       }
+
+       /* 6GHz band supports HE only */
+       if (!cl_band_is_6g(cl_hw)) {
+               for (i = 0; i < rx_nss; i++)
+                       sband_ht_cap->mcs.rx_mask[i] = U8_MAX;
+
+               if (bw == CHNL_BW_20)
+                       sband_ht_cap->mcs.rx_highest = guard_interval ?
+                               cpu_to_le16(72 * rx_nss) : cpu_to_le16(65 * rx_nss);
+               else
+                       sband_ht_cap->mcs.rx_highest = guard_interval ?
+                               cpu_to_le16(150 * rx_nss) : cpu_to_le16(135 * rx_nss);
+       }
+
+       if (cl_hw->conf->ce_wireless_mode > WIRELESS_MODE_HT_VHT)
+               cl_set_he_capab(cl_hw);
+
+       /* Get channels and power limitations information from ChannelInfo file */
+       cl_chan_info_init(cl_hw);
+
+       if (cl_band_is_6g(cl_hw)) {
+               wiphy->bands[NL80211_BAND_2GHZ] = NULL;
+               wiphy->bands[NL80211_BAND_5GHZ] = NULL;
+               wiphy->bands[NL80211_BAND_6GHZ] = sband;
+       } else if (cl_band_is_5g(cl_hw)) {
+               wiphy->bands[NL80211_BAND_2GHZ] = NULL;
+               wiphy->bands[NL80211_BAND_5GHZ] = sband;
+               wiphy->bands[NL80211_BAND_6GHZ] = NULL;
+       } else {
+               wiphy->bands[NL80211_BAND_2GHZ] = sband;
+               wiphy->bands[NL80211_BAND_5GHZ] = NULL;
+               wiphy->bands[NL80211_BAND_6GHZ] = NULL;
+       }
+
+       wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
+}
+
+enum he_pkt_ext_constellations {
+       HE_PKT_EXT_BPSK = 0,
+       HE_PKT_EXT_QPSK,
+       HE_PKT_EXT_16QAM,
+       HE_PKT_EXT_64QAM,
+       HE_PKT_EXT_256QAM,
+       HE_PKT_EXT_1024QAM,
+       HE_PKT_EXT_RESERVED,
+       HE_PKT_EXT_NONE,
+};
+
+static u8 mcs_to_constellation[WRS_MCS_MAX_HE] = {
+       HE_PKT_EXT_BPSK,
+       HE_PKT_EXT_QPSK,
+       HE_PKT_EXT_QPSK,
+       HE_PKT_EXT_16QAM,
+       HE_PKT_EXT_16QAM,
+       HE_PKT_EXT_64QAM,
+       HE_PKT_EXT_64QAM,
+       HE_PKT_EXT_64QAM,
+       HE_PKT_EXT_256QAM,
+       HE_PKT_EXT_256QAM,
+       HE_PKT_EXT_1024QAM,
+       HE_PKT_EXT_1024QAM
+};
+
+#define QAM_THR_1 0
+#define QAM_THR_2 1
+#define QAM_THR_MAX 2
+
+static u8 get_ppe_val(u8 *ppe, u8 ppe_pos_bit)
+{
+       u8 byte_num = ppe_pos_bit / 8;
+       u8 bit_num = ppe_pos_bit % 8;
+       u8 residue_bits;
+       u8 res;
+
+       if (bit_num <= 5)
+               return (ppe[byte_num] >> bit_num) &
+                      (BIT(IEEE80211_PPE_THRES_INFO_PPET_SIZE) - 1);
+
+       /*
+        * If bit_num > 5, we have to combine bits with next byte.
+        * Calculate how many bits we need to take from current byte (called
+        * here "residue_bits"), and add them to bits from next byte.
+        */
+       residue_bits = 8 - bit_num;
+
+       res = (ppe[byte_num + 1] &
+              (BIT(IEEE80211_PPE_THRES_INFO_PPET_SIZE - residue_bits) - 1)) <<
+             residue_bits;
+       res += (ppe[byte_num] >> bit_num) & (BIT(residue_bits) - 1);
+
+       return res;
+}
+
+static void set_fixed_ppe_val(u8 pe_dur[CHNL_BW_MAX][WRS_MCS_MAX_HE], u8 dur)
+{
+       u8 val = ((dur << 6) | (dur << 4) | (dur << 2) | dur);
+
+       memset(pe_dur, val, CHNL_BW_MAX * WRS_MCS_MAX_HE);
+}
+
+void cl_cap_ppe_duration(struct cl_hw *cl_hw, struct ieee80211_sta *sta,
+                        u8 pe_dur[CHNL_BW_MAX][WRS_MCS_MAX_HE])
+{
+       /* Force NVRAM parameter */
+       if (cl_hw->conf->ci_pe_duration <= PPE_16US) {
+               set_fixed_ppe_val(pe_dur, cl_hw->conf->ci_pe_duration);
+               return;
+       }
+
+       /*
+        * If STA sets the PPE Threshold Present subfield to 0,
+        * the value should be set according to the Nominal Packet Padding subfield
+        */
+       if ((sta->he_cap.he_cap_elem.phy_cap_info[6] &
+            IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) == 0) {
+               switch (sta->he_cap.he_cap_elem.phy_cap_info[9] &
+                       IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_MASK) {
+               case IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_0US:
+                       set_fixed_ppe_val(pe_dur, PPE_0US);
+                       break;
+               case IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_8US:
+                       set_fixed_ppe_val(pe_dur, PPE_8US);
+                       break;
+               case IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US:
+               default:
+                       set_fixed_ppe_val(pe_dur, PPE_16US);
+                       break;
+               }
+
+               return;
+       }
+
+       /*
+        * struct iwl_he_pkt_ext - QAM thresholds
+        * The required PPE is set via HE Capabilities IE, per Nss x BW x MCS
+        * The IE is organized in the following way:
+        * Support for Nss x BW (or RU) matrix:
+        *      (0=SISO, 1=MIMO2) x (0-20MHz, 1-40MHz, 2-80MHz, 3-160MHz)
+        * Each entry contains 2 QAM thresholds for 8us and 16us:
+        *      0=BPSK, 1=QPSK, 2=16QAM, 3=64QAM, 4=256QAM, 5=1024QAM, 6=RES, 7=NONE
+        * i.e. QAM_th1 < QAM_th2 such if TX uses QAM_tx:
+        *      QAM_tx < QAM_th1            --> PPE=0us
+        *      QAM_th1 <= QAM_tx < QAM_th2 --> PPE=8us
+        *      QAM_th2 <= QAM_tx           --> PPE=16us
+        * @pkt_ext_qam_th: QAM thresholds
+        *      For each Nss/Bw define 2 QAM thrsholds (0..5)
+        *      For rates below the low_th, no need for PPE
+        *      For rates between low_th and high_th, need 8us PPE
+        *      For rates equal or higher then the high_th, need 16us PPE
+        *      Nss (0-siso, 1-mimo2) x BW (0-20MHz, 1-40MHz, 2-80MHz, 3-160MHz) x
+        *              (0-low_th, 1-high_th)
+        */
+       u8 pkt_ext_qam_th[WRS_SS_MAX][CHNL_BW_MAX][QAM_THR_MAX];
+
+       /* If PPE Thresholds exist, parse them into a FW-familiar format. */
+       u8 nss = (sta->he_cap.ppe_thres[0] & IEEE80211_PPE_THRES_NSS_MASK) + 1;
+       u8 ru_index_bitmap = u32_get_bits(sta->he_cap.ppe_thres[0],
+                                         IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK);
+       u8 *ppe = &sta->he_cap.ppe_thres[0];
+       u8 ppe_pos_bit = 7; /* Starting after PPE header */
+       u8 bw, ss, mcs, constellation;
+
+       if (nss > WRS_SS_MAX)
+               nss = WRS_SS_MAX;
+
+       for (ss = 0; ss < nss; ss++) {
+               u8 ru_index_tmp = ru_index_bitmap << 1;
+
+               for (bw = 0; bw <= cl_hw->bw; bw++) {
+                       ru_index_tmp >>= 1;
+                       if (!(ru_index_tmp & 1))
+                               continue;
+
+                       pkt_ext_qam_th[ss][bw][QAM_THR_2] = get_ppe_val(ppe, ppe_pos_bit);
+                       ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
+                       pkt_ext_qam_th[ss][bw][QAM_THR_1] = get_ppe_val(ppe, ppe_pos_bit);
+                       ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
+               }
+       }
+
+       /* Reset PE duration before filling it */
+       memset(pe_dur, 0, CHNL_BW_MAX * WRS_MCS_MAX_HE);
+
+       for (ss = 0; ss < nss; ss++) {
+               for (bw = 0; bw <= cl_hw->bw; bw++) {
+                       for (mcs = 0; mcs < WRS_MCS_MAX_HE; mcs++) {
+                               constellation = mcs_to_constellation[mcs];
+
+                               if (constellation < pkt_ext_qam_th[ss][bw][QAM_THR_1])
+                                       pe_dur[bw][mcs] |= (PPE_0US << (ss * 2));
+                               else if (constellation < pkt_ext_qam_th[ss][bw][QAM_THR_2])
+                                       pe_dur[bw][mcs] |= (PPE_8US << (ss * 2));
+                               else
+                                       pe_dur[bw][mcs] |= (PPE_16US << (ss * 2));
+                       }
+               }
+       }
+}
--
2.30.0

________________________________
The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any retransmission, dissemination, copying or other use of, or taking of any action in reliance upon this information is prohibited. If you received this in error, please contact the sender and delete the material from any computer. Nothing contained herein shall be deemed as a representation, warranty or a commitment by Celeno. No warranties are expressed or implied, including, but not limited to, any implied warranties of non-infringement, merchantability and fitness for a particular purpose.
________________________________





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux