summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2020-06-11 08:17:33 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2020-06-11 08:17:33 +0000
commit1ddb095354c5abc7ecf8c5b2822cca659bd4f3fc (patch)
treee933789d48b305d1465af4a39a907292d832896f /sys/dev
parentd7989ebd7cbd5fec4a25f052704c65f7c98eea4d (diff)
Use the NVM_GET_INFO command in iwx(4) instead of the manual NVM data
parser inherited from iwm(4). The old parsing code is merely disabled for now and will be deleted later. Deleting the old code at the same time would result in a very untidy diff. Tested by jcs@, sven falempin, and myself.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_iwx.c206
-rw-r--r--sys/dev/pci/if_iwxreg.h133
-rw-r--r--sys/dev/pci/if_iwxvar.h7
3 files changed, 320 insertions, 26 deletions
diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c
index fab3d5624e4..4673e5fef10 100644
--- a/sys/dev/pci/if_iwx.c
+++ b/sys/dev/pci/if_iwx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwx.c,v 1.21 2020/06/10 09:29:27 stsp Exp $ */
+/* $OpenBSD: if_iwx.c,v 1.22 2020/06/11 08:17:32 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -160,6 +160,20 @@ const uint8_t iwx_nvm_channels_8000[] = {
149, 153, 157, 161, 165, 169, 173, 177, 181
};
+static const uint8_t iwx_nvm_channels_uhb[] = {
+ /* 2.4 GHz */
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ /* 5 GHz */
+ 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
+ 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
+ 149, 153, 157, 161, 165, 169, 173, 177, 181,
+ /* 6-7 GHz */
+ 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69,
+ 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129,
+ 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185,
+ 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233
+};
+
#define IWX_NUM_2GHZ_CHANNELS 14
const struct iwx_rate {
@@ -291,8 +305,7 @@ int iwx_nvm_read_chunk(struct iwx_softc *, uint16_t, uint16_t, uint16_t,
uint8_t *, uint16_t *);
int iwx_nvm_read_section(struct iwx_softc *, uint16_t, uint8_t *,
uint16_t *, size_t);
-void iwx_init_channel_map(struct iwx_softc *, const uint16_t * const,
- const uint8_t *nvm_channels, int nchan);
+void iwx_init_channel_map(struct iwx_softc *, uint16_t *, uint32_t *, int);
void iwx_setup_ht_rates(struct iwx_softc *);
int iwx_mimo_enabled(struct iwx_softc *);
void iwx_htprot_task(void *);
@@ -315,6 +328,9 @@ int iwx_parse_nvm_data(struct iwx_softc *, const uint16_t *,
const uint16_t *, const uint16_t *,
const uint16_t *, const uint16_t *,
const uint16_t *, int);
+int iwx_set_mac_addr_from_csr(struct iwx_softc *, struct iwx_nvm_data *);
+int iwx_is_valid_mac_addr(const uint8_t *);
+int iwx_nvm_get(struct iwx_softc *);
void iwx_set_hw_address_8000(struct iwx_softc *, struct iwx_nvm_data *,
const uint16_t *, const uint16_t *);
int iwx_parse_nvm_sections(struct iwx_softc *, struct iwx_nvm_section *);
@@ -2662,22 +2678,35 @@ iwx_fw_valid_rx_ant(struct iwx_softc *sc)
}
void
-iwx_init_channel_map(struct iwx_softc *sc, const uint16_t * const nvm_ch_flags,
- const uint8_t *nvm_channels, int nchan)
+iwx_init_channel_map(struct iwx_softc *sc, uint16_t *channel_profile_v3,
+ uint32_t *channel_profile_v4, int nchan_profile)
{
struct ieee80211com *ic = &sc->sc_ic;
struct iwx_nvm_data *data = &sc->sc_nvm;
int ch_idx;
struct ieee80211_channel *channel;
- uint16_t ch_flags;
+ uint32_t ch_flags;
int is_5ghz;
int flags, hw_value;
+ int nchan;
+ const uint8_t *nvm_channels;
- for (ch_idx = 0; ch_idx < nchan; ch_idx++) {
- ch_flags = le16_to_cpup(nvm_ch_flags + ch_idx);
+ if (sc->sc_uhb_supported) {
+ nchan = nitems(iwx_nvm_channels_uhb);
+ nvm_channels = iwx_nvm_channels_uhb;
+ } else {
+ nchan = nitems(iwx_nvm_channels_8000);
+ nvm_channels = iwx_nvm_channels_8000;
+ }
+
+ for (ch_idx = 0; ch_idx < nchan && ch_idx < nchan_profile; ch_idx++) {
+ if (channel_profile_v4)
+ ch_flags = le32_to_cpup(channel_profile_v4 + ch_idx);
+ else
+ ch_flags = le16_to_cpup(channel_profile_v3 + ch_idx);
- if (ch_idx >= IWX_NUM_2GHZ_CHANNELS &&
- !data->sku_cap_band_52GHz_enable)
+ is_5ghz = ch_idx >= IWX_NUM_2GHZ_CHANNELS;
+ if (is_5ghz && !data->sku_cap_band_52GHz_enable)
ch_flags &= ~IWX_NVM_CHANNEL_VALID;
if (!(ch_flags & IWX_NVM_CHANNEL_VALID))
@@ -2686,7 +2715,6 @@ iwx_init_channel_map(struct iwx_softc *sc, const uint16_t * const nvm_ch_flags,
hw_value = nvm_channels[ch_idx];
channel = &ic->ic_channels[hw_value];
- is_5ghz = ch_idx >= IWX_NUM_2GHZ_CHANNELS;
if (!is_5ghz) {
flags = IEEE80211_CHAN_2GHZ;
channel->ic_flags
@@ -2889,6 +2917,134 @@ iwx_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
iwx_add_task(sc, systq, &sc->ba_task);
}
+/* Read the mac address from WFMP registers. */
+int
+iwx_set_mac_addr_from_csr(struct iwx_softc *sc, struct iwx_nvm_data *data)
+{
+ const uint8_t *hw_addr;
+ uint32_t mac_addr0, mac_addr1;
+
+ if (!iwx_nic_lock(sc))
+ return EBUSY;
+
+ mac_addr0 = htole32(iwx_read_prph(sc, IWX_WFMP_MAC_ADDR_0));
+ mac_addr1 = htole32(iwx_read_prph(sc, IWX_WFMP_MAC_ADDR_1));
+
+ hw_addr = (const uint8_t *)&mac_addr0;
+ data->hw_addr[0] = hw_addr[3];
+ data->hw_addr[1] = hw_addr[2];
+ data->hw_addr[2] = hw_addr[1];
+ data->hw_addr[3] = hw_addr[0];
+
+ hw_addr = (const uint8_t *)&mac_addr1;
+ data->hw_addr[4] = hw_addr[1];
+ data->hw_addr[5] = hw_addr[0];
+
+ iwx_nic_unlock(sc);
+ return 0;
+}
+
+int
+iwx_is_valid_mac_addr(const uint8_t *addr)
+{
+ static const uint8_t reserved_mac[] = {
+ 0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00
+ };
+
+ return (memcmp(reserved_mac, addr, ETHER_ADDR_LEN) != 0 &&
+ memcmp(etherbroadcastaddr, addr, sizeof(etherbroadcastaddr)) != 0 &&
+ memcmp(etheranyaddr, addr, sizeof(etheranyaddr)) != 0 &&
+ !ETHER_IS_MULTICAST(addr));
+}
+
+int
+iwx_nvm_get(struct iwx_softc *sc)
+{
+ struct iwx_nvm_get_info cmd = {};
+ struct iwx_nvm_data *nvm = &sc->sc_nvm;
+ struct iwx_host_cmd hcmd = {
+ .flags = IWX_CMD_WANT_RESP | IWX_CMD_SEND_IN_RFKILL,
+ .data = { &cmd, },
+ .len = { sizeof(cmd) },
+ .id = IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
+ IWX_NVM_GET_INFO)
+ };
+ int err;
+ uint32_t mac_flags;
+ /*
+ * All the values in iwx_nvm_get_info_rsp v4 are the same as
+ * in v3, except for the channel profile part of the
+ * regulatory. So we can just access the new struct, with the
+ * exception of the latter.
+ */
+ struct iwx_nvm_get_info_rsp *rsp;
+ struct iwx_nvm_get_info_rsp_v3 *rsp_v3;
+ int v4 = isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REGULATORY_NVM_INFO);
+ size_t resp_len = v4 ? sizeof(*rsp) : sizeof(*rsp_v3);
+
+ hcmd.resp_pkt_len = sizeof(struct iwx_rx_packet) + resp_len;
+ err = iwx_send_cmd(sc, &hcmd);
+ if (err)
+ return err;
+
+ if (iwx_rx_packet_payload_len(hcmd.resp_pkt) != resp_len) {
+ err = EIO;
+ goto out;
+ }
+
+ memset(nvm, 0, sizeof(*nvm));
+
+ iwx_set_mac_addr_from_csr(sc, nvm);
+ if (!iwx_is_valid_mac_addr(nvm->hw_addr)) {
+ printf("%s: no valid mac address was found\n", DEVNAME(sc));
+ err = EINVAL;
+ goto out;
+ }
+
+ rsp = (void *)hcmd.resp_pkt->data;
+
+ /* Initialize general data */
+ nvm->nvm_version = le16toh(rsp->general.nvm_version);
+ nvm->n_hw_addrs = rsp->general.n_hw_addrs;
+
+ /* Initialize MAC sku data */
+ mac_flags = le32toh(rsp->mac_sku.mac_sku_flags);
+ nvm->sku_cap_11ac_enable =
+ !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_802_11AC_ENABLED);
+ nvm->sku_cap_11n_enable =
+ !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_802_11N_ENABLED);
+ nvm->sku_cap_11ax_enable =
+ !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_802_11AX_ENABLED);
+ nvm->sku_cap_band_24GHz_enable =
+ !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_BAND_2_4_ENABLED);
+ nvm->sku_cap_band_52GHz_enable =
+ !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_BAND_5_2_ENABLED);
+ nvm->sku_cap_mimo_disable =
+ !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_MIMO_DISABLED);
+
+ /* Initialize PHY sku data */
+ nvm->valid_tx_ant = (uint8_t)le32toh(rsp->phy_sku.tx_chains);
+ nvm->valid_rx_ant = (uint8_t)le32toh(rsp->phy_sku.rx_chains);
+
+ if (le32toh(rsp->regulatory.lar_enabled) &&
+ isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_SUPPORT)) {
+ nvm->lar_enabled = 1;
+ }
+
+ if (v4) {
+ iwx_init_channel_map(sc, NULL,
+ rsp->regulatory.channel_profile, IWX_NUM_CHANNELS);
+ } else {
+ rsp_v3 = (void *)rsp;
+ iwx_init_channel_map(sc, rsp_v3->regulatory.channel_profile,
+ NULL, IWX_NUM_CHANNELS_V1);
+ }
+out:
+ iwx_free_resp(sc, &hcmd);
+ return err;
+}
+
+#if 0
void
iwx_set_hw_address_8000(struct iwx_softc *sc, struct iwx_nvm_data *data,
const uint16_t *mac_override, const uint16_t *nvm_hw)
@@ -3085,6 +3241,7 @@ iwx_nvm_init(struct iwx_softc *sc)
return err;
}
+#endif
int
iwx_load_firmware(struct iwx_softc *sc)
@@ -3229,14 +3386,6 @@ iwx_run_init_mvm_ucode(struct iwx_softc *sc, int readnvm)
if (err)
return err;
- if (readnvm) {
- err = iwx_nvm_init(sc);
- if (err) {
- printf("%s: failed to read nvm\n", DEVNAME(sc));
- return err;
- }
- }
-
err = iwx_send_cmd_pdu(sc, IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
IWX_NVM_ACCESS_COMPLETE), 0, sizeof(nvm_complete), &nvm_complete);
if (err)
@@ -3250,9 +3399,17 @@ iwx_run_init_mvm_ucode(struct iwx_softc *sc, int readnvm)
return err;
}
- if (readnvm && IEEE80211_ADDR_EQ(etheranyaddr, sc->sc_ic.ic_myaddr))
- IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
- sc->sc_nvm.hw_addr);
+ if (readnvm) {
+ err = iwx_nvm_get(sc);
+ if (err) {
+ printf("%s: failed to read nvm\n", DEVNAME(sc));
+ return err;
+ }
+ if (IEEE80211_ADDR_EQ(etheranyaddr, sc->sc_ic.ic_myaddr))
+ IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
+ sc->sc_nvm.hw_addr);
+
+ }
return 0;
}
@@ -6425,7 +6582,7 @@ iwx_init_hw(struct iwx_softc *sc)
goto err;
}
- if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_SUPPORT)) {
+ if (sc->sc_nvm.lar_enabled) {
err = iwx_send_update_mcc_cmd(sc, "ZZ");
if (err) {
printf("%s: could not init LAR (error %d)\n",
@@ -7138,6 +7295,8 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf_list *ml)
IWX_DTS_MEASUREMENT_NOTIF_WIDE):
break;
+ case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
+ IWX_NVM_GET_INFO):
case IWX_PHY_CONFIGURATION_CMD:
case IWX_TX_ANT_CONFIGURATION_CMD:
case IWX_ADD_STA:
@@ -7718,6 +7877,7 @@ iwx_attach(struct device *parent, struct device *self, void *aux)
sc->sc_low_latency_xtal = 0;
sc->sc_xtal_latency = 0;
sc->sc_tx_with_siso_diversity = 0;
+ sc->sc_uhb_supported = 0;
break;
default:
printf("%s: unknown adapter type\n", DEVNAME(sc));
diff --git a/sys/dev/pci/if_iwxreg.h b/sys/dev/pci/if_iwxreg.h
index 305adc568db..f8e2b22fa8b 100644
--- a/sys/dev/pci/if_iwxreg.h
+++ b/sys/dev/pci/if_iwxreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwxreg.h,v 1.6 2020/05/26 11:59:48 stsp Exp $ */
+/* $OpenBSD: if_iwxreg.h,v 1.7 2020/06/11 08:17:32 stsp Exp $ */
/*-
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
@@ -910,6 +910,7 @@ enum msix_ivar_for_cause {
#define IWX_UCODE_TLV_API_NEW_RX_STATS 35
#define IWX_UCODE_TLV_API_ADAPTIVE_DWELL_V2 42
#define IWX_UCODE_TLV_API_BEACON_FILTER_V4 47
+#define IWX_UCODE_TLV_API_REGULATORY_NVM_INFO 48
#define IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG 56
#define IWX_UCODE_TLV_API_SCAN_EXT_CHAN_VER 58
#define IWX_NUM_UCODE_TLV_API 128
@@ -1735,21 +1736,28 @@ struct iwx_phy_cfg_cmd {
* @IWX_NVM_CHANNEL_IBSS: usable as an IBSS channel
* @IWX_NVM_CHANNEL_ACTIVE: active scanning allowed
* @IWX_NVM_CHANNEL_RADAR: radar detection required
+ * @IWX_NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
+ * @IWX_NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
+ * on same channel on 2.4 or same UNII band on 5.2
* @IWX_NVM_CHANNEL_DFS: dynamic freq selection candidate
* @IWX_NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
* @IWX_NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
* @IWX_NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
* @IWX_NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
+ * @IWX_NVM_CHANNEL_DC_HIGH: DC HIGH required/allowed (?)
*/
#define IWX_NVM_CHANNEL_VALID (1 << 0)
#define IWX_NVM_CHANNEL_IBSS (1 << 1)
#define IWX_NVM_CHANNEL_ACTIVE (1 << 3)
#define IWX_NVM_CHANNEL_RADAR (1 << 4)
+#define IWX_NVM_CHANNEL_INDOOR_ONLY (1 << 5)
+#define IWX_NVM_CHANNEL_GO_CONCURRENT (1 << 6)
#define IWX_NVM_CHANNEL_DFS (1 << 7)
#define IWX_NVM_CHANNEL_WIDE (1 << 8)
#define IWX_NVM_CHANNEL_40MHZ (1 << 9)
#define IWX_NVM_CHANNEL_80MHZ (1 << 10)
#define IWX_NVM_CHANNEL_160MHZ (1 << 11)
+#define IWX_NVM_CHANNEL_DC_HIGH (1 << 12)
/* Target of the IWX_NVM_ACCESS_CMD */
#define IWX_NVM_ACCESS_TARGET_CACHE 0
@@ -1823,6 +1831,129 @@ struct iwx_nvm_access_resp {
uint8_t data[];
} __packed; /* IWX_NVM_ACCESS_CMD_RESP_API_S_VER_2 */
+/*
+ * struct iwx_nvm_get_info - request to get NVM data
+ */
+struct iwx_nvm_get_info {
+ uint32_t reserved;
+} __packed; /* REGULATORY_NVM_GET_INFO_CMD_API_S_VER_1 */
+
+/**
+ * enum iwx_nvm_info_general_flags - flags in NVM_GET_INFO resp
+ * @NVM_GENERAL_FLAGS_EMPTY_OTP: 1 if OTP is empty
+ */
+#define IWX_NVM_GENERAL_FLAGS_EMPTY_OTP (1 << 0)
+
+/**
+ * struct iwx_nvm_get_info_general - general NVM data
+ * @flags: bit 0: 1 - empty, 0 - non-empty
+ * @nvm_version: nvm version
+ * @board_type: board type
+ * @n_hw_addrs: number of reserved MAC addresses
+ */
+struct iwx_nvm_get_info_general {
+ uint32_t flags;
+ uint16_t nvm_version;
+ uint8_t board_type;
+ uint8_t n_hw_addrs;
+} __packed; /* REGULATORY_NVM_GET_INFO_GENERAL_S_VER_2 */
+
+/**
+ * iwx_nvm_mac_sku_flags - flags in &iwl_nvm_get_info_sku
+ * @NVM_MAC_SKU_FLAGS_BAND_2_4_ENABLED: true if 2.4 band enabled
+ * @NVM_MAC_SKU_FLAGS_BAND_5_2_ENABLED: true if 5.2 band enabled
+ * @NVM_MAC_SKU_FLAGS_802_11N_ENABLED: true if 11n enabled
+ * @NVM_MAC_SKU_FLAGS_802_11AC_ENABLED: true if 11ac enabled
+ * @NVM_MAC_SKU_FLAGS_802_11AX_ENABLED: true if 11ax enabled
+ * @NVM_MAC_SKU_FLAGS_MIMO_DISABLED: true if MIMO disabled
+ * @NVM_MAC_SKU_FLAGS_WAPI_ENABLED: true if WAPI enabled
+ * @NVM_MAC_SKU_FLAGS_REG_CHECK_ENABLED: true if regulatory checker enabled
+ * @NVM_MAC_SKU_FLAGS_API_LOCK_ENABLED: true if API lock enabled
+ */
+#define IWX_NVM_MAC_SKU_FLAGS_BAND_2_4_ENABLED (1 << 0)
+#define IWX_NVM_MAC_SKU_FLAGS_BAND_5_2_ENABLED (1 << 1)
+#define IWX_NVM_MAC_SKU_FLAGS_802_11N_ENABLED (1 << 2)
+#define IWX_NVM_MAC_SKU_FLAGS_802_11AC_ENABLED (1 << 3)
+#define IWX_NVM_MAC_SKU_FLAGS_802_11AX_ENABLED (1 << 4)
+#define IWX_NVM_MAC_SKU_FLAGS_MIMO_DISABLED (1 << 5)
+#define IWX_NVM_MAC_SKU_FLAGS_WAPI_ENABLED (1 << 8)
+#define IWX_NVM_MAC_SKU_FLAGS_REG_CHECK_ENABLED (1 << 14)
+#define IWX_NVM_MAC_SKU_FLAGS_API_LOCK_ENABLED (1 << 15)
+
+/**
+ * struct iwx_nvm_get_info_sku - mac information
+ * @mac_sku_flags: flags for SKU, see &enum iwl_nvm_mac_sku_flags
+ */
+struct iwx_nvm_get_info_sku {
+ uint32_t mac_sku_flags;
+} __packed; /* REGULATORY_NVM_GET_INFO_MAC_SKU_SECTION_S_VER_2 */
+
+/**
+ * struct iwx_nvm_get_info_phy - phy information
+ * @tx_chains: BIT 0 chain A, BIT 1 chain B
+ * @rx_chains: BIT 0 chain A, BIT 1 chain B
+ */
+struct iwx_nvm_get_info_phy {
+ uint32_t tx_chains;
+ uint32_t rx_chains;
+} __packed; /* REGULATORY_NVM_GET_INFO_PHY_SKU_SECTION_S_VER_1 */
+
+#define IWX_NUM_CHANNELS_V1 51
+#define IWX_NUM_CHANNELS 110
+
+/**
+ * struct iwx_nvm_get_info_regulatory - regulatory information
+ * @lar_enabled: is LAR enabled
+ * @channel_profile: regulatory data of this channel
+ * @reserved: reserved
+ */
+struct iwx_nvm_get_info_regulatory_v1 {
+ uint32_t lar_enabled;
+ uint16_t channel_profile[IWX_NUM_CHANNELS_V1];
+ uint16_t reserved;
+} __packed; /* REGULATORY_NVM_GET_INFO_REGULATORY_S_VER_1 */
+
+/**
+ * struct iwx_nvm_get_info_regulatory - regulatory information
+ * @lar_enabled: is LAR enabled
+ * @n_channels: number of valid channels in the array
+ * @channel_profile: regulatory data of this channel
+ */
+struct iwx_nvm_get_info_regulatory {
+ uint32_t lar_enabled;
+ uint32_t n_channels;
+ uint32_t channel_profile[IWX_NUM_CHANNELS];
+} __packed; /* REGULATORY_NVM_GET_INFO_REGULATORY_S_VER_2 */
+
+/**
+ * struct iwx_nvm_get_info_rsp_v3 - response to get NVM data
+ * @general: general NVM data
+ * @mac_sku: data relating to MAC sku
+ * @phy_sku: data relating to PHY sku
+ * @regulatory: regulatory data
+ */
+struct iwx_nvm_get_info_rsp_v3 {
+ struct iwx_nvm_get_info_general general;
+ struct iwx_nvm_get_info_sku mac_sku;
+ struct iwx_nvm_get_info_phy phy_sku;
+ struct iwx_nvm_get_info_regulatory_v1 regulatory;
+} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_3 */
+
+/**
+ * struct iwx_nvm_get_info_rsp - response to get NVM data
+ * @general: general NVM data
+ * @mac_sku: data relating to MAC sku
+ * @phy_sku: data relating to PHY sku
+ * @regulatory: regulatory data
+ */
+struct iwx_nvm_get_info_rsp {
+ struct iwx_nvm_get_info_general general;
+ struct iwx_nvm_get_info_sku mac_sku;
+ struct iwx_nvm_get_info_phy phy_sku;
+ struct iwx_nvm_get_info_regulatory regulatory;
+} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_4 */
+
+
#define IWX_ALIVE_STATUS_ERR 0xDEAD
#define IWX_ALIVE_STATUS_OK 0xCAFE
diff --git a/sys/dev/pci/if_iwxvar.h b/sys/dev/pci/if_iwxvar.h
index 9759e0366ad..5a2d48912b4 100644
--- a/sys/dev/pci/if_iwxvar.h
+++ b/sys/dev/pci/if_iwxvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwxvar.h,v 1.7 2020/06/10 09:29:27 stsp Exp $ */
+/* $OpenBSD: if_iwxvar.h,v 1.8 2020/06/11 08:17:32 stsp Exp $ */
/*
* Copyright (c) 2014 genua mbh <info@genua.de>
@@ -192,9 +192,12 @@ struct iwx_nvm_data {
int sku_cap_band_24GHz_enable;
int sku_cap_band_52GHz_enable;
int sku_cap_11n_enable;
+ int sku_cap_11ac_enable;
+ int sku_cap_11ax_enable;
int sku_cap_amt_enable;
int sku_cap_ipan_enable;
int sku_cap_mimo_disable;
+ int lar_enabled;
uint8_t radio_cfg_type;
uint8_t radio_cfg_step;
@@ -501,7 +504,7 @@ struct iwx_softc {
int sc_ltr_delay;
int sc_xtal_latency;
int sc_low_latency_xtal;
-
+ int sc_uhb_supported;
#if NBPFILTER > 0
caddr_t sc_drvbpf;