This patch implements support for new iwx(4) -63 firmware images
available in the iwx-firmware-20210512 package (via fw_update).

Please test this patch and report back. If testing works out well
then I will commit these changes to CVS incrementally. Thanks!

For those testing my iwx Tx agg patch: Please remove that patch first.
Tx agg will come back later. Getting new firmware images to work is more
important right now because these images contain fixes for fragattacks.

diff 54a415eecf0903b6663209706a0fc6e2e9d40044 refs/heads/iwxfw
blob - 48bf14d7a8a421c6f1bf2b4bfc6c1792396b5400
blob + 91be6f7f188e6d6754571b7dc1f4fb38c72546da
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -232,6 +232,7 @@ const int iwx_mcs2ridx[] = {
 };
 
 uint8_t        iwx_lookup_cmd_ver(struct iwx_softc *, uint8_t, uint8_t);
+uint8_t        iwx_lookup_notif_ver(struct iwx_softc *, uint8_t, uint8_t);
 int    iwx_is_mimo_ht_plcp(uint8_t);
 int    iwx_is_mimo_mcs(int);
 int    iwx_store_cscheme(struct iwx_softc *, uint8_t *, size_t);
@@ -297,6 +298,8 @@ int iwx_nic_rx_init(struct iwx_softc *);
 int    iwx_nic_init(struct iwx_softc *);
 int    iwx_enable_txq(struct iwx_softc *, int, int, int, int);
 void   iwx_post_alive(struct iwx_softc *);
+int    iwx_schedule_session_protection(struct iwx_softc *, struct iwx_node *,
+           uint32_t);
 void   iwx_protect_session(struct iwx_softc *, struct iwx_node *, uint32_t,
            uint32_t);
 void   iwx_unprotect_session(struct iwx_softc *, struct iwx_node *);
@@ -356,6 +359,10 @@ void       iwx_rx_tx_cmd(struct iwx_softc *, struct 
iwx_rx_p
 void   iwx_rx_bmiss(struct iwx_softc *, struct iwx_rx_packet *,
            struct iwx_rx_data *);
 int    iwx_binding_cmd(struct iwx_softc *, struct iwx_node *, uint32_t);
+int    iwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *, struct iwx_phy_ctxt *, 
uint8_t,
+           uint8_t, uint32_t);
+int    iwx_phy_ctxt_cmd_v3(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
+           uint8_t, uint32_t);
 int    iwx_phy_ctxt_cmd_uhb(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
            uint8_t, uint32_t, uint32_t);
 int    iwx_phy_ctxt_cmd(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
@@ -387,7 +394,16 @@ int        iwx_add_sta_cmd(struct iwx_softc *, struct 
iwx_nod
 int    iwx_add_aux_sta(struct iwx_softc *);
 int    iwx_rm_sta_cmd(struct iwx_softc *, struct iwx_node *);
 int    iwx_fill_probe_req(struct iwx_softc *, struct iwx_scan_probe_req *);
+int    iwx_config_umac_scan_reduced(struct iwx_softc *);
 int    iwx_config_umac_scan(struct iwx_softc *);
+uint16_t iwx_scan_umac_flags_v2(struct iwx_softc *, int);
+void   iwx_scan_umac_dwell_v10(struct iwx_softc *,
+           struct iwx_scan_general_params_v10 *, int);
+void   iwx_scan_umac_fill_general_p_v10(struct iwx_softc *,
+           struct iwx_scan_general_params_v10 *, uint16_t, int);
+void   iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *,
+           struct iwx_scan_channel_params_v6 *, uint32_t, int, int);
+int    iwx_umac_scan_v14(struct iwx_softc *, int);
 int    iwx_umac_scan(struct iwx_softc *, int);
 void   iwx_mcc_update(struct iwx_softc *, struct iwx_mcc_chub_notif *);
 uint8_t        iwx_ridx2rate(struct ieee80211_rateset *, int);
@@ -490,6 +506,21 @@ iwx_lookup_cmd_ver(struct iwx_softc *sc, uint8_t grp, 
        return IWX_FW_CMD_VER_UNKNOWN;
 }
 
+uint8_t
+iwx_lookup_notif_ver(struct iwx_softc *sc, uint8_t grp, uint8_t cmd)
+{
+       const struct iwx_fw_cmd_version *entry;
+       int i;
+
+       for (i = 0; i < sc->n_cmd_versions; i++) {
+               entry = &sc->cmd_versions[i];
+               if (entry->group == grp && entry->cmd == cmd)
+                       return entry->notif_ver;
+       }
+
+       return IWX_FW_CMD_VER_UNKNOWN;
+}
+
 int
 iwx_is_mimo_ht_plcp(uint8_t ht_plcp)
 {
@@ -924,7 +955,7 @@ iwx_firmware_store_section(struct iwx_softc *sc, enum 
 
 #define IWX_DEFAULT_SCAN_CHANNELS      40
 /* Newer firmware might support more channels. Raise this value if needed. */
-#define IWX_MAX_SCAN_CHANNELS          52 /* as of 8265-34 firmware image */
+#define IWX_MAX_SCAN_CHANNELS          67 /* as of iwx-cc-a0-62 firmware */
 
 struct iwx_tlv_calib_data {
        uint32_t ucode_type;
@@ -1304,6 +1335,8 @@ iwx_read_firmware(struct iwx_softc *sc)
                        break;
 
                case IWX_UCODE_TLV_FW_FSEQ_VERSION:
+               case IWX_UCODE_TLV_PHY_INTEGRATION_VERSION:
+               case IWX_UCODE_TLV_FW_NUM_STATIONS:
                        break;
 
                /* undocumented TLVs found in iwx-cc-a0-46 image */
@@ -1317,6 +1350,13 @@ iwx_read_firmware(struct iwx_softc *sc)
                case 0x1000002:
                        break;
 
+               case IWX_UCODE_TLV_TYPE_DEBUG_INFO:
+               case IWX_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
+               case IWX_UCODE_TLV_TYPE_HCMD:
+               case IWX_UCODE_TLV_TYPE_REGIONS:
+               case IWX_UCODE_TLV_TYPE_TRIGGERS:
+                       break;
+
                default:
                        err = EINVAL;
                        goto parse_out;
@@ -2559,6 +2599,23 @@ out:
        return err;
 }
 
+int
+iwx_schedule_session_protection(struct iwx_softc *sc, struct iwx_node *in,
+    uint32_t duration)
+{
+       struct iwx_session_prot_cmd cmd = {
+               .id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id,
+                   in->in_color)),
+               .action = htole32(IWX_FW_CTXT_ACTION_ADD),
+               .conf_id = htole32(IWX_SESSION_PROTECT_CONF_ASSOC),
+               .duration_tu = htole32(duration * IEEE80211_DUR_TU),
+       };
+       uint32_t cmd_id;
+
+       cmd_id = iwx_cmd_id(IWX_SESSION_PROTECTION_CMD, IWX_MAC_CONF_GROUP, 0);
+       return iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd);
+}
+
 void
 iwx_protect_session(struct iwx_softc *sc, struct iwx_node *in,
     uint32_t duration, uint32_t max_delay)
@@ -4416,9 +4473,8 @@ iwx_binding_cmd(struct iwx_softc *sc, struct iwx_node 
 }
 
 int
-iwx_phy_ctxt_cmd_uhb(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
-    uint8_t chains_static, uint8_t chains_dynamic, uint32_t action,
-    uint32_t apply_time)
+iwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
+    uint8_t chains_static, uint8_t chains_dynamic, uint32_t action)
 {
        struct ieee80211com *ic = &sc->sc_ic;
        struct iwx_phy_context_cmd_uhb cmd;
@@ -4429,8 +4485,13 @@ iwx_phy_ctxt_cmd_uhb(struct iwx_softc *sc, struct iwx_
        cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id,
            ctxt->color));
        cmd.action = htole32(action);
-       cmd.apply_time = htole32(apply_time);
 
+       if (IEEE80211_IS_CHAN_2GHZ(ctxt->channel) ||
+           !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT))
+               cmd.lmac_id = htole32(IWX_LMAC_24G_INDEX);
+       else
+               cmd.lmac_id = htole32(IWX_LMAC_5G_INDEX);
+
        cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
            IWX_PHY_BAND_24 : IWX_PHY_BAND_5;
        cmd.ci.channel = htole32(ieee80211_chan2ieee(ic, chan));
@@ -4440,25 +4501,96 @@ iwx_phy_ctxt_cmd_uhb(struct iwx_softc *sc, struct iwx_
        idle_cnt = chains_static;
        active_cnt = chains_dynamic;
        cmd.rxchain_info = htole32(iwx_fw_valid_rx_ant(sc) <<
-                                       IWX_PHY_RX_CHAIN_VALID_POS);
+           IWX_PHY_RX_CHAIN_VALID_POS);
        cmd.rxchain_info |= htole32(idle_cnt << IWX_PHY_RX_CHAIN_CNT_POS);
        cmd.rxchain_info |= htole32(active_cnt <<
            IWX_PHY_RX_CHAIN_MIMO_CNT_POS);
-       cmd.txchain_info = htole32(iwx_fw_valid_tx_ant(sc));
 
        return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
 }
 
 int
-iwx_phy_ctxt_cmd(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
-    uint8_t chains_static, uint8_t chains_dynamic, uint32_t action,
-    uint32_t apply_time)
+iwx_phy_ctxt_cmd_v3(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
+    uint8_t chains_static, uint8_t chains_dynamic, uint32_t action)
 {
        struct ieee80211com *ic = &sc->sc_ic;
        struct iwx_phy_context_cmd cmd;
        uint8_t active_cnt, idle_cnt;
        struct ieee80211_channel *chan = ctxt->channel;
 
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id,
+           ctxt->color));
+       cmd.action = htole32(action);
+
+       if (IEEE80211_IS_CHAN_2GHZ(ctxt->channel) ||
+           !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT))
+               cmd.lmac_id = htole32(IWX_LMAC_24G_INDEX);
+       else
+               cmd.lmac_id = htole32(IWX_LMAC_5G_INDEX);
+
+       cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
+           IWX_PHY_BAND_24 : IWX_PHY_BAND_5;
+       cmd.ci.channel = ieee80211_chan2ieee(ic, chan);
+       cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE20;
+       cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
+
+       idle_cnt = chains_static;
+       active_cnt = chains_dynamic;
+       cmd.rxchain_info = htole32(iwx_fw_valid_rx_ant(sc) <<
+           IWX_PHY_RX_CHAIN_VALID_POS);
+       cmd.rxchain_info |= htole32(idle_cnt << IWX_PHY_RX_CHAIN_CNT_POS);
+       cmd.rxchain_info |= htole32(active_cnt <<
+           IWX_PHY_RX_CHAIN_MIMO_CNT_POS);
+
+       return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
+}
+
+int
+iwx_phy_ctxt_cmd_uhb(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
+    uint8_t chains_static, uint8_t chains_dynamic, uint32_t action,
+    uint32_t apply_time)
+{
+       struct ieee80211com *ic = &sc->sc_ic;
+       struct iwx_phy_context_cmd_uhb_v1 cmd;
+       uint8_t active_cnt, idle_cnt;
+       struct ieee80211_channel *chan = ctxt->channel;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id,
+           ctxt->color));
+       cmd.action = htole32(action);
+       cmd.apply_time = htole32(apply_time);
+
+       cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
+           IWX_PHY_BAND_24 : IWX_PHY_BAND_5;
+       cmd.ci.channel = htole32(ieee80211_chan2ieee(ic, chan));
+       cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE20;
+       cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
+
+       idle_cnt = chains_static;
+       active_cnt = chains_dynamic;
+       cmd.rxchain_info = htole32(iwx_fw_valid_rx_ant(sc) <<
+                                       IWX_PHY_RX_CHAIN_VALID_POS);
+       cmd.rxchain_info |= htole32(idle_cnt << IWX_PHY_RX_CHAIN_CNT_POS);
+       cmd.rxchain_info |= htole32(active_cnt <<
+           IWX_PHY_RX_CHAIN_MIMO_CNT_POS);
+       cmd.txchain_info = htole32(iwx_fw_valid_tx_ant(sc));
+
+       return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
+}
+
+int
+iwx_phy_ctxt_cmd(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
+    uint8_t chains_static, uint8_t chains_dynamic, uint32_t action,
+    uint32_t apply_time)
+{
+       struct ieee80211com *ic = &sc->sc_ic;
+       struct iwx_phy_context_cmd_v1 cmd;
+       uint8_t active_cnt, idle_cnt;
+       struct ieee80211_channel *chan = ctxt->channel;
+       int cmdver;
+
        /*
         * Intel increased the size of the fw_channel_info struct and neglected
         * to bump the phy_context_cmd struct, which contains an fw_channel_info
@@ -4466,6 +4598,17 @@ iwx_phy_ctxt_cmd(struct iwx_softc *sc, struct iwx_phy_
         * To keep things simple we use a separate function to handle the larger
         * variant of the phy context command.
         */
+       cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_PHY_CONTEXT_CMD);
+       if (cmdver == 3) {
+               /* Version 3 differs in the "data" portion of the command. */
+               if (isset(sc->sc_enabled_capa,
+                   IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS)) {
+                       return iwx_phy_ctxt_cmd_uhb_v3(sc, ctxt, chains_static,
+                           chains_dynamic, action);
+               }
+               return iwx_phy_ctxt_cmd_v3(sc, ctxt, chains_static,
+                   chains_dynamic, action);
+       }
        if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS))
                return iwx_phy_ctxt_cmd_uhb(sc, ctxt, chains_static,
                    chains_dynamic, action, apply_time);
@@ -4542,15 +4685,24 @@ iwx_send_cmd(struct iwx_softc *sc, struct iwx_host_cmd
        desc = &ring->desc[idx];
        txdata = &ring->data[idx];
 
+       /*
+        * XXX Intel inside (tm)
+        * Firmware API versions >= 50 reject old-style commands in
+        * group 0 with a "BAD_COMMAND" firmware error. We must pretend
+        * that such commands were in the LONG_GROUP instead in order
+        * for firmware to accept them.
+        */
+       if (iwx_cmd_groupid(code) == 0) {
+               code = IWX_WIDE_ID(IWX_LONG_GROUP, code);
+               txdata->flags |= IWX_TXDATA_FLAG_CMD_IS_NARROW;
+       } else
+               txdata->flags &= ~IWX_TXDATA_FLAG_CMD_IS_NARROW;
+
        group_id = iwx_cmd_groupid(code);
-       if (group_id != 0) {
-               hdrlen = sizeof(cmd->hdr_wide);
-               datasz = sizeof(cmd->data_wide);
-       } else {
-               hdrlen = sizeof(cmd->hdr);
-               datasz = sizeof(cmd->data);
-       }
 
+       hdrlen = sizeof(cmd->hdr_wide);
+       datasz = sizeof(cmd->data_wide);
+
        if (paylen > datasz) {
                /* Command is too large to fit in pre-allocated space. */
                size_t totlen = hdrlen + paylen;
@@ -4583,21 +4735,14 @@ iwx_send_cmd(struct iwx_softc *sc, struct iwx_host_cmd
                paddr = txdata->cmd_paddr;
        }
 
-       if (group_id != 0) {
-               cmd->hdr_wide.opcode = iwx_cmd_opcode(code);
-               cmd->hdr_wide.group_id = group_id;
-               cmd->hdr_wide.qid = ring->qid;
-               cmd->hdr_wide.idx = idx;
-               cmd->hdr_wide.length = htole16(paylen);
-               cmd->hdr_wide.version = iwx_cmd_version(code);
-               data = cmd->data_wide;
-       } else {
-               cmd->hdr.code = code;
-               cmd->hdr.flags = 0;
-               cmd->hdr.qid = ring->qid;
-               cmd->hdr.idx = idx;
-               data = cmd->data;
-       }
+       memset(cmd, 0, sizeof(*cmd));
+       cmd->hdr_wide.opcode = iwx_cmd_opcode(code);
+       cmd->hdr_wide.group_id = group_id;
+       cmd->hdr_wide.qid = ring->qid;
+       cmd->hdr_wide.idx = idx;
+       cmd->hdr_wide.length = htole16(paylen);
+       cmd->hdr_wide.version = iwx_cmd_version(code);
+       data = cmd->data_wide;
 
        for (i = 0, off = 0; i < nitems(hcmd->data); i++) {
                if (hcmd->len[i] == 0)
@@ -4607,10 +4752,17 @@ iwx_send_cmd(struct iwx_softc *sc, struct iwx_host_cmd
        }
        KASSERT(off == paylen);
 
-       desc->tbs[0].tb_len = htole16(hdrlen + paylen);
-       addr = htole64((uint64_t)paddr);
+       desc->tbs[0].tb_len = htole16(MIN(hdrlen + paylen, IWX_FIRST_TB_SIZE));
+       addr = htole64(paddr);
        memcpy(&desc->tbs[0].addr, &addr, sizeof(addr));
-       desc->num_tbs = 1;
+       if (hdrlen + paylen > IWX_FIRST_TB_SIZE) {
+               desc->tbs[1].tb_len = htole16(hdrlen + paylen -
+                   IWX_FIRST_TB_SIZE);
+               addr = htole64(paddr + IWX_FIRST_TB_SIZE);
+               memcpy(&desc->tbs[1].addr, &addr, sizeof(addr));
+               desc->num_tbs = htole16(2);
+       } else
+               desc->num_tbs = htole16(1);
 
        if (paylen > datasz) {
                bus_dmamap_sync(sc->sc_dmat, txdata->map, 0,
@@ -4874,7 +5026,7 @@ iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ie
         * Tx aggregation will require additional queues (one queue per TID
         * for which aggregation is enabled) but we do not implement this yet.
         */
-       ring = &sc->txq[ac + IWX_DQA_AUX_QUEUE + 1];
+       ring = &sc->txq[ac + sc->first_data_qid];
        desc = &ring->desc[ring->cur];
        memset(desc, 0, sizeof(*desc));
        data = &ring->data[ring->cur];
@@ -5262,7 +5414,16 @@ iwx_add_aux_sta(struct iwx_softc *sc)
        struct iwx_add_sta_cmd cmd;
        int err, qid = IWX_DQA_AUX_QUEUE;
        uint32_t status;
+       uint8_t cmdver;
 
+       /*
+        * ADD_STA command version >= 12 implies that firmware uses
+        * an internal AUX station for scanning.
+        */
+       cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_ADD_STA);
+       if (cmdver != IWX_FW_CMD_VER_UNKNOWN && cmdver >= 12)
+               return 0;
+
        memset(&cmd, 0, sizeof(cmd));
        cmd.sta_id = IWX_AUX_STA_ID;
        cmd.station_type = IWX_STA_AUX_ACTIVITY;
@@ -5304,7 +5465,8 @@ iwx_rm_sta_cmd(struct iwx_softc *sc, struct iwx_node *
 
 uint8_t
 iwx_umac_scan_fill_channels(struct iwx_softc *sc,
-    struct iwx_scan_channel_cfg_umac *chan, int n_ssids, int bgscan)
+    struct iwx_scan_channel_cfg_umac *chan, size_t chan_nitems,
+    int n_ssids, int bgscan)
 {
        struct ieee80211com *ic = &sc->sc_ic;
        struct ieee80211_channel *c;
@@ -5312,6 +5474,7 @@ iwx_umac_scan_fill_channels(struct iwx_softc *sc,
 
        for (nchan = 0, c = &ic->ic_channels[1];
            c <= &ic->ic_channels[IEEE80211_CHAN_MAX] &&
+           nchan < chan_nitems &&
            nchan < sc->sc_capa_n_scan_channels;
            c++) {
                uint8_t channel_num;
@@ -5460,10 +5623,48 @@ iwx_fill_probe_req(struct iwx_softc *sc, struct iwx_sc
 }
 
 int
+iwx_config_umac_scan_reduced(struct iwx_softc *sc)
+{
+       struct iwx_scan_config scan_cfg;
+       struct iwx_host_cmd hcmd = {
+               .id = iwx_cmd_id(IWX_SCAN_CFG_CMD, IWX_LONG_GROUP, 0),
+               .len[0] = sizeof(scan_cfg),
+               .data[0] = &scan_cfg,
+               .flags = 0,
+       };
+       int cmdver;
+
+       memset(&scan_cfg, 0, sizeof(scan_cfg));
+
+       /*
+        * ADD_STA command version >= 12 implies that firmware uses
+        * an internal AUX station for scanning.
+        */
+       cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_ADD_STA);
+       if (cmdver == IWX_FW_CMD_VER_UNKNOWN || cmdver < 12)
+               scan_cfg.bcast_sta_id = IWX_AUX_STA_ID;
+       else {
+               /*
+                * SCAN_CFG version >= 5 implies that the broadcast
+                * STA ID field is deprecated.
+                */
+               cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP,
+                   IWX_SCAN_CFG_CMD);
+               if (cmdver == IWX_FW_CMD_VER_UNKNOWN || cmdver < 5)
+                       scan_cfg.bcast_sta_id = 0xff;
+       }
+
+       scan_cfg.tx_chains = htole32(iwx_fw_valid_tx_ant(sc));
+       scan_cfg.rx_chains = htole32(iwx_fw_valid_rx_ant(sc));
+
+       return iwx_send_cmd(sc, &hcmd);
+}
+
+int
 iwx_config_umac_scan(struct iwx_softc *sc)
 {
        struct ieee80211com *ic = &sc->sc_ic;
-       struct iwx_scan_config *scan_config;
+       struct iwx_scan_config_v2 *scan_config;
        int err, nchan;
        size_t cmd_size;
        struct ieee80211_channel *c;
@@ -5479,6 +5680,9 @@ iwx_config_umac_scan(struct iwx_softc *sc)
            IWX_SCAN_CONFIG_RATE_36M | IWX_SCAN_CONFIG_RATE_48M |
            IWX_SCAN_CONFIG_RATE_54M);
 
+       if (isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG))
+               return iwx_config_umac_scan_reduced(sc);
+
        cmd_size = sizeof(*scan_config) + sc->sc_capa_n_scan_channels;
 
        scan_config = malloc(cmd_size, M_DEVBUF, M_WAIT | M_CANFAIL | M_ZERO);
@@ -5589,6 +5793,25 @@ iwx_get_scan_req_umac_data(struct iwx_softc *sc, struc
 
 }
 
+uint16_t
+iwx_scan_umac_flags_v2(struct iwx_softc *sc, int bgscan)
+{
+       struct ieee80211com *ic = &sc->sc_ic;
+       uint16_t flags = 0;
+
+       if (ic->ic_des_esslen == 0)
+               flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE;
+
+       flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_PASS_ALL;
+       flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_NTFY_ITER_COMPLETE;
+       flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_ADAPTIVE_DWELL;
+
+       return flags;
+}
+
+#define IWX_SCAN_DWELL_ACTIVE          10
+#define IWX_SCAN_DWELL_PASSIVE         110
+
 /* adaptive dwell max budget time [TU] for full scan */
 #define IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
 /* adaptive dwell max budget time [TU] for directed scan */
@@ -5599,8 +5822,145 @@ iwx_get_scan_req_umac_data(struct iwx_softc *sc, struc
 #define IWX_SCAN_ADWELL_DEFAULT_LB_N_APS 2
 /* adaptive dwell default APs number in social channels (1, 6, 11) */
 #define IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10
+/* adaptive dwell number of APs override for p2p friendly GO channels */
+#define IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY 10
+/* adaptive dwell number of APs override for social channels */
+#define IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS 2
 
+void
+iwx_scan_umac_dwell_v10(struct iwx_softc *sc,
+    struct iwx_scan_general_params_v10 *general_params, int bgscan)
+{
+       uint32_t suspend_time, max_out_time;
+       uint8_t active_dwell, passive_dwell;
+
+       active_dwell = IWX_SCAN_DWELL_ACTIVE;
+       passive_dwell = IWX_SCAN_DWELL_PASSIVE;
+
+       general_params->adwell_default_social_chn =
+               IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
+       general_params->adwell_default_2g = IWX_SCAN_ADWELL_DEFAULT_LB_N_APS;
+       general_params->adwell_default_5g = IWX_SCAN_ADWELL_DEFAULT_HB_N_APS;
+
+       if (bgscan)
+               general_params->adwell_max_budget =
+                       htole16(IWX_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
+       else
+               general_params->adwell_max_budget =
+                       htole16(IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN);
+
+       general_params->scan_priority = htole32(IWX_SCAN_PRIORITY_EXT_6);
+       if (bgscan) {
+               max_out_time = htole32(120);
+               suspend_time = htole32(120);
+       } else {
+               max_out_time = htole32(0);
+               suspend_time = htole32(0);
+       }
+       general_params->max_out_of_time[IWX_SCAN_LB_LMAC_IDX] =
+               htole32(max_out_time);
+       general_params->suspend_time[IWX_SCAN_LB_LMAC_IDX] =
+               htole32(suspend_time);
+       general_params->max_out_of_time[IWX_SCAN_HB_LMAC_IDX] =
+               htole32(max_out_time);
+       general_params->suspend_time[IWX_SCAN_HB_LMAC_IDX] =
+               htole32(suspend_time);
+
+       general_params->active_dwell[IWX_SCAN_LB_LMAC_IDX] = active_dwell;
+       general_params->passive_dwell[IWX_SCAN_LB_LMAC_IDX] = passive_dwell;
+       general_params->active_dwell[IWX_SCAN_HB_LMAC_IDX] = active_dwell;
+       general_params->passive_dwell[IWX_SCAN_HB_LMAC_IDX] = passive_dwell;
+}
+
+void
+iwx_scan_umac_fill_general_p_v10(struct iwx_softc *sc,
+    struct iwx_scan_general_params_v10 *gp, uint16_t gen_flags, int bgscan)
+{
+       iwx_scan_umac_dwell_v10(sc, gp, bgscan);
+
+       gp->flags = htole16(gen_flags);
+
+       if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1)
+               gp->num_of_fragments[IWX_SCAN_LB_LMAC_IDX] = 3;
+       if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2)
+               gp->num_of_fragments[IWX_SCAN_HB_LMAC_IDX] = 3;
+
+       gp->scan_start_mac_id = 0;
+}
+
+void
+iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *sc,
+    struct iwx_scan_channel_params_v6 *cp, uint32_t channel_cfg_flags,
+    int n_ssid, int bgscan)
+{
+       cp->flags = IWX_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER;
+
+       cp->count = iwx_umac_scan_fill_channels(sc, cp->channel_config,
+           nitems(cp->channel_config), n_ssid, bgscan);
+
+       cp->n_aps_override[0] = IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY;
+       cp->n_aps_override[1] = IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS;
+}
+
 int
+iwx_umac_scan_v14(struct iwx_softc *sc, int bgscan)
+{
+       struct ieee80211com *ic = &sc->sc_ic;
+       struct iwx_host_cmd hcmd = {
+               .id = iwx_cmd_id(IWX_SCAN_REQ_UMAC, IWX_LONG_GROUP, 0),
+               .len = { 0, },
+               .data = { NULL, },
+               .flags = 0,
+       };
+       struct iwx_scan_req_umac_v14 *cmd;
+       struct iwx_scan_req_params_v14 *scan_p;
+       int err, async = bgscan, n_ssid = 0;
+       uint16_t gen_flags;
+       uint32_t bitmap_ssid = 0;
+
+       cmd = malloc(sizeof(*cmd), M_DEVBUF,
+           (async ? M_NOWAIT : M_WAIT) | M_CANFAIL | M_ZERO);
+       if (cmd == NULL)
+               return ENOMEM;
+
+       scan_p = &cmd->scan_params;
+
+       cmd->ooc_priority = htole32(IWX_SCAN_PRIORITY_EXT_6);
+       cmd->uid = htole32(0);
+
+       gen_flags = iwx_scan_umac_flags_v2(sc, bgscan);
+       iwx_scan_umac_fill_general_p_v10(sc, &scan_p->general_params,
+           gen_flags, bgscan);
+
+       scan_p->periodic_params.schedule[0].interval = htole16(0);
+       scan_p->periodic_params.schedule[0].iter_count = 1;
+
+       err = iwx_fill_probe_req(sc, &scan_p->probe_params.preq);
+       if (err)
+               return err;
+
+       if (ic->ic_des_esslen != 0) {
+               scan_p->probe_params.direct_scan[0].id = IEEE80211_ELEMID_SSID;
+               scan_p->probe_params.direct_scan[0].len = ic->ic_des_esslen;
+               memcpy(scan_p->probe_params.direct_scan[0].ssid,
+                   ic->ic_des_essid, ic->ic_des_esslen);
+               bitmap_ssid |= (1 << 0);
+               n_ssid = 1;
+       }
+
+       iwx_scan_umac_fill_ch_p_v6(sc, &scan_p->channel_params, bitmap_ssid,
+           n_ssid, bgscan);
+
+       hcmd.len[0] = sizeof(*cmd);
+       hcmd.data[0] = (void *)cmd;
+       hcmd.flags |= async ? IWX_CMD_ASYNC : 0;
+
+       err = iwx_send_cmd(sc, &hcmd);
+       free(cmd, M_DEVBUF, sizeof(*cmd));
+       return err;
+}
+
+int
 iwx_umac_scan(struct iwx_softc *sc, int bgscan)
 {
        struct ieee80211com *ic = &sc->sc_ic;
@@ -5617,7 +5977,12 @@ iwx_umac_scan(struct iwx_softc *sc, int bgscan)
        struct iwx_scan_umac_chan_param *chanparam;
        size_t req_len;
        int err, async = bgscan;
+       int cmdver;
 
+       cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_SCAN_REQ_UMAC);
+       if (cmdver == 14)
+               return iwx_umac_scan_v14(sc, bgscan);
+
        req_len = iwx_umac_scan_size(sc);
        if ((req_len < IWX_SCAN_REQ_UMAC_SIZE_V1 +
            sizeof(struct iwx_scan_req_umac_tail_v1)) ||
@@ -5690,6 +6055,7 @@ iwx_umac_scan(struct iwx_softc *sc, int bgscan)
        chanparam = iwx_get_scan_req_umac_chan_param(sc, req);
        chanparam->count = iwx_umac_scan_fill_channels(sc,
            (struct iwx_scan_channel_cfg_umac *)cmd_data,
+           sc->sc_capa_n_scan_channels,
            ic->ic_des_esslen != 0, bgscan);
        chanparam->flags = 0;
 
@@ -6241,19 +6607,31 @@ iwx_scan_abort(struct iwx_softc *sc)
 int
 iwx_enable_data_tx_queues(struct iwx_softc *sc)
 {
-       int err, ac;
+       int err, ac, cmdver;
 
+       /*
+        * ADD_STA command version >= 12 implies that firmware uses
+        * an internal AUX station for scanning. We do not configure
+        * an AUX Tx queue in this case and data queue indices assigned
+        * by firmware shift upwards accordingly.
+        */
+       cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_ADD_STA);
+       if (cmdver != IWX_FW_CMD_VER_UNKNOWN && cmdver >= 12)
+               sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1;
+       else
+               sc->first_data_qid = IWX_DQA_AUX_QUEUE + 1;
+
        for (ac = 0; ac < EDCA_NUM_AC; ac++) {
-               int qid = ac + IWX_DQA_AUX_QUEUE + 1;
+               int qid = ac + sc->first_data_qid;
                /*
                 * Regular data frames use the "MGMT" TID and queue.
                 * Other TIDs and queues are reserved for frame aggregation.
                 */
-               err = iwx_enable_txq(sc, IWX_STATION_ID, qid, IWX_TID_NON_QOS,
+               err = iwx_enable_txq(sc, IWX_STATION_ID, qid, IWX_MGMT_TID,
                    IWX_TX_RING_COUNT);
                if (err) {
                        printf("%s: could not enable Tx queue %d (error %d)\n",
-                           DEVNAME(sc), ac, err);
+                           DEVNAME(sc), qid, err);
                        return err;
                }
        }
@@ -6302,10 +6680,17 @@ iwx_rs_init(struct iwx_softc *sc, struct iwx_node *in)
        struct ieee80211_rateset *rs = &ni->ni_rates;
        struct iwx_tlc_config_cmd cfg_cmd;
        uint32_t cmd_id;
-       int i;
+       int i, cmdver;
+       size_t cmd_size = sizeof(cfg_cmd);
 
        memset(&cfg_cmd, 0, sizeof(cfg_cmd));
 
+       /* In old versions of the API the struct is 4 bytes smaller */
+       cmdver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
+           IWX_TLC_MNG_CONFIG_CMD);
+       if (cmdver == IWX_FW_CMD_VER_UNKNOWN || cmdver < 3)
+               cmd_size -= sizeof(uint32_t);
+
        for (i = 0; i < rs->rs_nrates; i++) {
                uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL;
                int idx = iwx_rs_rval2idx(rval);
@@ -6331,8 +6716,7 @@ iwx_rs_init(struct iwx_softc *sc, struct iwx_node *in)
                cfg_cmd.sgi_ch_width_supp = (1 << IWX_TLC_MNG_CH_WIDTH_20MHZ);
 
        cmd_id = iwx_cmd_id(IWX_TLC_MNG_CONFIG_CMD, IWX_DATA_PATH_GROUP, 0);
-       return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, sizeof(cfg_cmd),
-           &cfg_cmd);
+       return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, cmd_size, &cfg_cmd);
 }
 
 void
@@ -6488,9 +6872,12 @@ iwx_auth(struct iwx_softc *sc)
                duration = in->in_ni.ni_intval * 2;
        else
                duration = IEEE80211_DUR_TU; 
-       iwx_protect_session(sc, in, duration, in->in_ni.ni_intval / 2);
+       if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_SESSION_PROT_CMD))
+               err = iwx_schedule_session_protection(sc, in, duration);
+       else
+               iwx_protect_session(sc, in, duration, in->in_ni.ni_intval / 2);
 
-       return 0;
+       return err;
 
 rm_sta:
        if (generation == sc->sc_generation) {
@@ -8073,6 +8460,19 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
                if (!iwx_rx_pkt_valid(pkt))
                        break;
 
+               /*
+                * XXX Intel inside (tm)
+                * Any commands in the LONG_GROUP could actually be in the
+                * LEGACY group. Firmware API versions >= 50 reject commands
+                * in group 0, forcing us to use this hack.
+                */
+               if (iwx_cmd_groupid(code) == IWX_LONG_GROUP) {
+                       struct iwx_tx_ring *ring = &sc->txq[qid];
+                       struct iwx_tx_data *txdata = &ring->data[idx];
+                       if (txdata->flags & IWX_TXDATA_FLAG_CMD_IS_NARROW)
+                               code = iwx_cmd_opcode(code);
+               }
+
                len = sizeof(pkt->len_n_flags) + iwx_rx_packet_len(pkt);
                if (len < sizeof(pkt->hdr) ||
                    len > (IWX_RBUF_SIZE - offset - minsz))
@@ -8137,9 +8537,37 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
 
                case IWX_ALIVE: {
                        struct iwx_alive_resp_v4 *resp4;
+                       struct iwx_alive_resp_v5 *resp5;
 
                        DPRINTF(("%s: firmware alive\n", __func__));
-                       if (iwx_rx_packet_payload_len(pkt) == sizeof(*resp4)) {
+                       sc->sc_uc.uc_ok = 0;
+
+                       /*
+                        * For v5 and above, we can check the version, for older
+                        * versions we need to check the size.
+                        */
+                        if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP,
+                           IWX_ALIVE) == 5) {
+                               SYNC_RESP_STRUCT(resp5, pkt);
+                               if (iwx_rx_packet_payload_len(pkt) !=
+                                   sizeof(*resp5)) {
+                                       sc->sc_uc.uc_intr = 1;
+                                       wakeup(&sc->sc_uc);
+                                       break;
+                               }
+                               sc->sc_uc.uc_lmac_error_event_table[0] = 
le32toh(
+                                   
resp5->lmac_data[0].dbg_ptrs.error_event_table_ptr);
+                               sc->sc_uc.uc_lmac_error_event_table[1] = 
le32toh(
+                                   
resp5->lmac_data[1].dbg_ptrs.error_event_table_ptr);
+                               sc->sc_uc.uc_log_event_table = le32toh(
+                                   
resp5->lmac_data[0].dbg_ptrs.log_event_table_ptr);
+                               sc->sched_base = le32toh(
+                                   resp5->lmac_data[0].dbg_ptrs.scd_base_ptr);
+                               sc->sc_uc.uc_umac_error_event_table = le32toh(
+                                   resp5->umac_data.dbg_ptrs.error_info_addr);
+                               if (resp5->status == IWX_ALIVE_STATUS_OK)
+                                       sc->sc_uc.uc_ok = 1;
+                       } else if (iwx_rx_packet_payload_len(pkt) == 
sizeof(*resp4)) {
                                SYNC_RESP_STRUCT(resp4, pkt);
                                sc->sc_uc.uc_lmac_error_event_table[0] = 
le32toh(
                                    
resp4->lmac_data[0].dbg_ptrs.error_event_table_ptr);
@@ -8153,8 +8581,6 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
                                    resp4->umac_data.dbg_ptrs.error_info_addr);
                                if (resp4->status == IWX_ALIVE_STATUS_OK)
                                        sc->sc_uc.uc_ok = 1;
-                               else
-                                       sc->sc_uc.uc_ok = 0;
                        }
 
                        sc->sc_uc.uc_intr = 1;
@@ -8189,6 +8615,8 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
                        break;
                }
 
+               case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
+                   IWX_SESSION_PROTECTION_CMD):
                case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
                    IWX_NVM_GET_INFO):
                case IWX_ADD_STA_KEY:
@@ -8288,6 +8716,10 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
                        break;
                }
 
+               case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
+                   IWX_SESSION_PROTECTION_NOTIF):
+                       break;
+
                case IWX_WIDE_ID(IWX_SYSTEM_GROUP,
                    IWX_FSEQ_VER_MISMATCH_NOTIFICATION):
                    break;
@@ -8844,7 +9276,7 @@ iwx_attach(struct device *parent, struct device *self,
 
        switch (PCI_PRODUCT(pa->pa_id)) {
        case PCI_PRODUCT_INTEL_WL_22500_1:
-               sc->sc_fwname = "iwx-cc-a0-48";
+               sc->sc_fwname = "iwx-cc-a0-63";
                sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
                sc->sc_fwdmasegsz = IWX_FWDMASEGSZ_8000;
                sc->sc_integrated = 1;
@@ -8862,7 +9294,7 @@ iwx_attach(struct device *parent, struct device *self,
                        return;
                }
 
-               sc->sc_fwname = "iwx-QuZ-a0-hr-b0-48";
+               sc->sc_fwname = "iwx-QuZ-a0-hr-b0-63";
                sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
                sc->sc_fwdmasegsz = IWX_FWDMASEGSZ_8000;
                sc->sc_integrated = 1;
@@ -8873,7 +9305,7 @@ iwx_attach(struct device *parent, struct device *self,
                sc->sc_uhb_supported = 0;
                break;
        case PCI_PRODUCT_INTEL_WL_22500_4:
-           sc->sc_fwname = "iwx-Qu-c0-hr-b0-48";
+           sc->sc_fwname = "iwx-Qu-c0-hr-b0-63";
            sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
            sc->sc_fwdmasegsz = IWX_FWDMASEGSZ_8000;
            sc->sc_integrated = 1;
blob - 55422b8d6961837cf9281b56c8671b1aea163b57
blob + b4e46bb72ee5c37cfa03fcd5e1f1b7f6bd28954a
--- sys/dev/pci/if_iwxreg.h
+++ sys/dev/pci/if_iwxreg.h
@@ -918,11 +918,27 @@ enum msix_ivar_for_cause {
 #define IWX_UCODE_TLV_API_NAN2_VER2            31
 #define IWX_UCODE_TLV_API_ADAPTIVE_DWELL       32
 #define IWX_UCODE_TLV_API_NEW_RX_STATS         35
+#define IWX_UCODE_TLV_API_WOWLAN_KEY_MATERIAL  36
+#define IWX_UCODE_TLV_API_QUOTA_LOW_LATENCY    38
+#define IWX_UCODE_TLV_API_DEPRECATE_TTAK       41
 #define IWX_UCODE_TLV_API_ADAPTIVE_DWELL_V2    42
+#define IWX_UCODE_TLV_API_NAN_NOTIF_V2         43
+#define IWX_UCODE_TLV_API_FRAG_EBS             44
+#define IWX_UCODE_TLV_API_REDUCE_TX_POWER      45
+#define IWX_UCODE_TLV_API_SHORT_BEACON_NOTIF   46
 #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_REGULATORY_NVM_INFO  48
+#define IWX_UCODE_TLV_API_FTM_NEW_RANGE_REQ    49
+#define IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG  56
+#define IWX_UCODE_TLV_API_SCAN_OFFLOAD_CHANS   50
+#define IWX_UCODE_TLV_API_MBSSID_HE            52
+#define IWX_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE  53
+#define IWX_UCODE_TLV_API_FTM_RTT_ACCURACY     54
+#define IWX_UCODE_TLV_API_SAR_TABLE_VER                55
+#define IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG  56
+#define IWX_UCODE_TLV_API_ADWELL_HB_DEF_N_AP   57
 #define IWX_UCODE_TLV_API_SCAN_EXT_CHAN_VER    58
+#define IWX_UCODE_TLV_API_BAND_IN_RX_DATA      59
 #define IWX_NUM_UCODE_TLV_API                  128
 
 #define IWX_UCODE_TLV_API_BITS \
@@ -1013,18 +1029,36 @@ enum msix_ivar_for_cause {
 #define IWX_UCODE_TLV_CAPA_GSCAN_SUPPORT               31
 #define IWX_UCODE_TLV_CAPA_NAN_SUPPORT                 34
 #define IWX_UCODE_TLV_CAPA_UMAC_UPLOAD                 35
+#define IWM_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT         37
+#define IWX_UCODE_TLV_CAPA_STA_PM_NOTIF                        38
 #define IWX_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT         39
 #define IWX_UCODE_TLV_CAPA_CDB_SUPPORT                 40
-#define IWX_UCODE_TLV_CAPA_TLC_OFFLOAD                  43
-#define IWX_UCODE_TLV_CAPA_DYNAMIC_QUOTA                44
+#define IWX_UCODE_TLV_CAPA_D0I3_END_FIRST              41
+#define IWX_UCODE_TLV_CAPA_TLC_OFFLOAD                 43
+#define IWX_UCODE_TLV_CAPA_DYNAMIC_QUOTA               44
+#define IWX_UCODE_TLV_CAPA_COEX_SCHEMA_2               45
+#define IWX_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD          46
+#define IWX_UCODE_TLV_CAPA_FTM_CALIBRATED              47
 #define IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS           48
+#define IWX_UCODE_TLV_CAPA_CS_MODIFY                   49
+#define IWX_UCODE_TLV_CAPA_SET_LTR_GEN2                        50
+#define IWX_UCODE_TLV_CAPA_SET_PPAG                    52
+#define IWX_UCODE_TLV_CAPA_TAS_CFG                     53
+#define IWX_UCODE_TLV_CAPA_SESSION_PROT_CMD            54
+#define IWX_UCODE_TLV_CAPA_PROTECTED_TWT               56
+#define IWX_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE          57
+#define IWX_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN           58
+#define IWX_UCODE_TLV_CAPA_PROTECTED_TWT               56
+#define IWX_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE          57
+#define IWX_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN           58
 #define IWX_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE                64
 #define IWX_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS           65
 #define IWX_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT            67
 #define IWX_UCODE_TLV_CAPA_MULTI_QUEUE_RX_SUPPORT      68
+#define IWX_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD                70
 #define IWX_UCODE_TLV_CAPA_BEACON_ANT_SELECTION                71
 #define IWX_UCODE_TLV_CAPA_BEACON_STORING              72
-#define IWX_UCODE_TLV_CAPA_LAR_SUPPORT_V2              73
+#define IWX_UCODE_TLV_CAPA_LAR_SUPPORT_V3              73
 #define IWX_UCODE_TLV_CAPA_CT_KILL_BY_FW               74
 #define IWX_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT     75
 #define IWX_UCODE_TLV_CAPA_CTDP_SUPPORT                        76
@@ -1032,7 +1066,17 @@ enum msix_ivar_for_cause {
 #define IWX_UCODE_TLV_CAPA_LMAC_UPLOAD                 79
 #define IWX_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG       80
 #define IWX_UCODE_TLV_CAPA_LQM_SUPPORT                 81
+#define IWX_UCODE_TLV_CAPA_TX_POWER_ACK                        84
+#define IWX_UCODE_TLV_CAPA_D3_DEBUG                    87
 #define IWX_UCODE_TLV_CAPA_LED_CMD_SUPPORT             88
+#define IWX_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT     89
+#define IWX_UCODE_TLV_CAPA_CSI_REPORTING               90
+#define IWX_UCODE_TLV_CAPA_CSI_REPORTING_V2            91
+#define IWX_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP 92
+#define IWX_UCODE_TLV_CAPA_DBG_BUF_ALLOC_CMD_SUPP      93
+#define IWX_UCODE_TLV_CAPA_MLME_OFFLOAD                        96
+#define IWX_UCODE_TLV_CAPA_BIGTK_SUPPORT               100
+#define IWX_UCODE_TLV_CAPA_RFIM_SUPPORT                        102
 
 #define IWX_NUM_UCODE_TLV_CAPA 128
 
@@ -1189,7 +1233,13 @@ struct iwx_ucode_header {
 #define IWX_UCODE_TLV_FW_RECOVERY_INFO 57
 #define IWX_UCODE_TLV_FW_FMAC_RECOVERY_INFO 59
 #define IWX_UCODE_TLV_FW_FSEQ_VERSION  60
+#define IWX_UCODE_TLV_PHY_INTEGRATION_VERSION  61
+#define IWX_UCODE_TLV_PNVM_VERSION             62
+#define IWX_UCODE_TLV_PNVM_SKU                 64
 
+#define IWX_UCODE_TLV_CONST_BASE               0x100
+#define IWX_UCODE_TLV_FW_NUM_STATIONS          (IWX_UCODE_TLV_CONST_BASE + 0)
+
 #define IWX_UCODE_TLV_DEBUG_BASE       0x1000005
 #define IWX_UCODE_TLV_TYPE_DEBUG_INFO          (IWX_UCODE_TLV_DEBUG_BASE + 0)
 #define IWX_UCODE_TLV_TYPE_BUFFER_ALLOCATION   (IWX_UCODE_TLV_DEBUG_BASE + 1)
@@ -1605,6 +1655,10 @@ struct iwx_tx_queue_cfg_rsp {
 #define IWX_INIT_EXTENDED_CFG_CMD      0x03
 #define IWX_FW_ERROR_RECOVERY_CMD      0x07
 
+/* MAC_CONF group subcommand IDs */
+#define IWX_SESSION_PROTECTION_CMD     0x05
+#define IWX_SESSION_PROTECTION_NOTIF   0xfb
+
 /* DATA_PATH group subcommand IDs */
 #define IWX_DQA_ENABLE_CMD     0x00
 #define IWX_TLC_MNG_CONFIG_CMD 0x0f
@@ -1922,6 +1976,19 @@ struct iwx_alive_resp_v4 {
        struct iwx_umac_alive umac_data;
 } __packed; /* ALIVE_RES_API_S_VER_4 */
 
+struct iwx_sku_id {
+       uint32_t data[3];
+} __packed; /* SKU_ID_API_S_VER_1 */
+
+struct iwx_alive_resp_v5 {
+       uint16_t status;
+       uint16_t flags;
+       struct iwx_lmac_alive lmac_data[2];
+       struct iwx_umac_alive umac_data;
+       struct iwx_sku_id sku_id;
+} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_5 */
+
+
 #define IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE      (1 << 0)
 #define IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY   (1 << 1)
 
@@ -2722,7 +2789,87 @@ struct iwx_time_event_notif {
        uint32_t status;
 } __packed; /* IWX_MAC_TIME_EVENT_NTFY_API_S_VER_1 */
 
+/**
+ * enum iwx_session_prot_conf_id - session protection's configurations
+ * @SESSION_PROTECT_CONF_ASSOC: Start a session protection for association.
+ *     The firmware will allocate two events.
+ *     Valid for BSS_STA and P2P_STA.
+ *     * A rather short event that can't be fragmented and with a very
+ *     high priority. If every goes well (99% of the cases) the
+ *     association should complete within this first event. During
+ *     that event, no other activity will happen in the firmware,
+ *     which is why it can't be too long.
+ *     The length of this event is hard-coded in the firmware: 300TUs.
+ *     * Another event which can be much longer (it's duration is
+ *     configurable by the driver) which has a slightly lower
+ *     priority and that can be fragmented allowing other activities
+ *     to run while this event is running.
+ *     The firmware will automatically remove both events once the driver sets
+ *     the BSS MAC as associated. Neither of the events will be removed
+ *     for the P2P_STA MAC.
+ *     Only the duration is configurable for this protection.
+ * @SESSION_PROTECT_CONF_GO_CLIENT_ASSOC: not used
+ * @SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV: Schedule the P2P Device to be in
+ *     listen mode. Will be fragmented. Valid only on the P2P Device MAC.
+ *     Valid only on the P2P Device MAC. The firmware will take into account
+ *     the duration, the interval and the repetition count.
+ * @SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION: Schedule the P2P Device to be be
+ *     able to run the GO Negotiation. Will not be fragmented and not
+ *     repetitive. Valid only on the P2P Device MAC. Only the duration will
+ *     be taken into account.
+ * @SESSION_PROTECT_CONF_MAX_ID: not used
+ */
+enum iwx_session_prot_conf_id {
+       IWX_SESSION_PROTECT_CONF_ASSOC,
+       IWX_SESSION_PROTECT_CONF_GO_CLIENT_ASSOC,
+       IWX_SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV,
+       IWX_SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION,
+       IWX_SESSION_PROTECT_CONF_MAX_ID,
+}; /* SESSION_PROTECTION_CONF_ID_E_VER_1 */
 
+/**
+ * struct iwx_session_prot_cmd - configure a session protection
+ * @id_and_color: the id and color of the mac for which this session protection
+ *     is sent
+ * @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE
+ * @conf_id: see &enum iwx_mvm_session_prot_conf_id
+ * @duration_tu: the duration of the whole protection in TUs.
+ * @repetition_count: not used
+ * @interval: not used
+ *
+ * Note: the session protection will always be scheduled to start as
+ * early as possible, but the maximum delay is configuration dependent.
+ * The firmware supports only one concurrent session protection per vif.
+ * Adding a new session protection will remove any currently running session.
+ */
+struct iwx_session_prot_cmd {
+       /* COMMON_INDEX_HDR_API_S_VER_1 hdr */
+       uint32_t id_and_color;
+       uint32_t action;
+       uint32_t conf_id;
+       uint32_t duration_tu;
+       uint32_t repetition_count;
+       uint32_t interval;
+} __packed; /* SESSION_PROTECTION_CMD_API_S_VER_1 */
+
+/**
+ * struct iwx_session_prot_notif - session protection started / ended
+ * @mac_id: the mac id for which the session protection started / ended
+ * @status: 1 means success, 0 means failure
+ * @start: 1 means the session protection started, 0 means it ended
+ * @conf_id: see &enum iwx_mvm_session_prot_conf_id
+ *
+ * Note that any session protection will always get two notifications: start
+ * and end even the firmware could not schedule it.
+ */
+struct iwx_session_prot_notif {
+       uint32_t mac_id;
+       uint32_t status;
+       uint32_t start;
+       uint32_t conf_id;
+} __packed; /* SESSION_PROTECTION_NOTIFICATION_API_S_VER_2 */
+
+
 /* Bindings and Time Quota */
 
 /**
@@ -2861,6 +3008,40 @@ struct iwx_fw_channel_info {
 /* TODO: fix the value, make it depend on firmware at runtime? */
 #define IWX_NUM_PHY_CTX        3
 
+/**
+ * struct iwl_phy_context_cmd - config of the PHY context
+ * ( IWX_PHY_CONTEXT_CMD = 0x8 )
+ * @id_and_color: ID and color of the relevant Binding
+ * @action: action to perform, one of IWX_FW_CTXT_ACTION_*
+ * @lmac_id: the lmac id the phy context belongs to
+ * @ci: channel info
+ * @rxchain_info: ???
+ * @dsp_cfg_flags: set to 0
+ * @reserved: reserved to align to 64 bit
+ */
+struct iwx_phy_context_cmd_uhb {
+       /* COMMON_INDEX_HDR_API_S_VER_1 */
+       uint32_t id_and_color;
+       uint32_t action;
+       /* PHY_CONTEXT_DATA_API_S_VER_3 */
+       struct iwx_fw_channel_info ci;
+       uint32_t lmac_id;
+       uint32_t rxchain_info;
+       uint32_t dsp_cfg_flags;
+       uint32_t reserved;
+} __packed; /* PHY_CONTEXT_CMD_API_VER_3 */
+struct iwx_phy_context_cmd {
+       /* COMMON_INDEX_HDR_API_S_VER_1 */
+       uint32_t id_and_color;
+       uint32_t action;
+       /* PHY_CONTEXT_DATA_API_S_VER_3 */
+       struct iwx_fw_channel_info_v1 ci;
+       uint32_t lmac_id;
+       uint32_t rxchain_info;
+       uint32_t dsp_cfg_flags;
+       uint32_t reserved;
+} __packed; /* PHY_CONTEXT_CMD_API_VER_3 */
+
 /* TODO: complete missing documentation */
 /**
  * struct iwx_phy_context_cmd - config of the PHY context
@@ -2884,7 +3065,7 @@ struct iwx_fw_channel_info {
  * magic with pointers to struct members instead.)
  */
 /* This version must be used if IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS is set: */
-struct iwx_phy_context_cmd_uhb {
+struct iwx_phy_context_cmd_uhb_v1 {
        /* COMMON_INDEX_HDR_API_S_VER_1 */
        uint32_t id_and_color;
        uint32_t action;
@@ -2898,7 +3079,7 @@ struct iwx_phy_context_cmd_uhb {
        uint32_t dsp_cfg_flags;
 } __packed; /* IWX_PHY_CONTEXT_CMD_API_VER_1 */
 /* This version must be used otherwise: */
-struct iwx_phy_context_cmd {
+struct iwx_phy_context_cmd_v1 {
        /* COMMON_INDEX_HDR_API_S_VER_1 */
        uint32_t id_and_color;
        uint32_t action;
@@ -4574,6 +4755,8 @@ enum iwx_tlc_mng_ht_rates {
  * @sgi_ch_width_supp: bitmap of SGI support per channel width
  *                    use (1 << @enum iwx_tlc_mng_cfg_cw)
  * @reserved2: reserved
+ * @max_tx_op: max TXOP in uSecs for all AC (BK, BE, VO, VI),
+ *            set zero for no limit.
  */
 struct iwx_tlc_config_cmd {
        uint8_t sta_id;
@@ -4587,8 +4770,9 @@ struct iwx_tlc_config_cmd {
        uint16_t ht_rates[IWX_TLC_NSS_MAX][2];
        uint16_t max_mpdu_len;
        uint8_t sgi_ch_width_supp;
-       uint8_t reserved2[1];
-} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_2 */
+       uint8_t reserved2;
+       uint32_t max_tx_op;
+} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_3 */
 
 /**
  * @IWX_TLC_NOTIF_FLAG_RATE: last initial rate update
@@ -5315,6 +5499,10 @@ struct iwx_scan_probe_req {
 #define IWX_SCAN_CHANNEL_FLAG_EBS              (1 << 0)
 #define IWX_SCAN_CHANNEL_FLAG_EBS_ACCURATE     (1 << 1)
 #define IWX_SCAN_CHANNEL_FLAG_CACHE_ADD                (1 << 2)
+#define IWX_SCAN_CHANNEL_FLAG_EBS_FRAG         (1 << 3)
+#define IWX_SCAN_CHANNEL_FLAG_FORCE_EBS                (1 << 4)
+#define IWX_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER        (1 << 5)
+#define IWX_SCAN_CHANNEL_FLAG_6G_PSC_NO_FILTER (1 << 6)
 
 /* iwx_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S
  * @flags: enum iwx_scan_channel_flags
@@ -5332,6 +5520,17 @@ struct iwx_scan_channel_opt {
 #define IWX_SCAN_PRIORITY_MEDIUM       1
 #define IWX_SCAN_PRIORITY_HIGH         2
 
+enum iwx_scan_priority_ext {
+       IWX_SCAN_PRIORITY_EXT_0_LOWEST,
+       IWX_SCAN_PRIORITY_EXT_1,
+       IWX_SCAN_PRIORITY_EXT_2,
+       IWX_SCAN_PRIORITY_EXT_3,
+       IWX_SCAN_PRIORITY_EXT_4,
+       IWX_SCAN_PRIORITY_EXT_5,
+       IWX_SCAN_PRIORITY_EXT_6,
+       IWX_SCAN_PRIORITY_EXT_7_HIGHEST,
+};
+
 /**
  * iwx_scan_offload_complete - PERIODIC_SCAN_COMPLETE_NTF_API_S_VER_2
  * @last_schedule_line: last schedule line executed (fast or regular)
@@ -5501,7 +5700,26 @@ struct iwx_scan_dwell {
 #define IWX_SCAN_HB_LMAC_IDX 1 /* high-band */
 
 /**
- * struct iwx_scan_config
+ * struct iwl_scan_config
+ * @enable_cam_mode: whether to enable CAM mode.
+ * @enable_promiscouos_mode: whether to enable promiscouos mode
+ * @bcast_sta_id: the index of the station in the fw. Deprecated starting with
+ *     API version 5.
+ * @reserved: reserved
+ * @tx_chains: valid_tx antenna - ANT_* definitions
+ * @rx_chains: valid_rx antenna - ANT_* definitions
+ */
+struct iwx_scan_config {
+       uint8_t enable_cam_mode;
+       uint8_t enable_promiscouos_mode;
+       uint8_t bcast_sta_id;
+       uint8_t reserved;
+       uint32_t tx_chains;
+       uint32_t rx_chains;
+} __packed; /* SCAN_CONFIG_DB_CMD_API_S_5 */
+
+/**
+ * struct iwx_scan_config_v2
  * @flags:                     enum scan_config_flags
  * @tx_chains:                 valid_tx antenna - ANT_* definitions
  * @rx_chains:                 valid_rx antenna - ANT_* definitions
@@ -5518,7 +5736,7 @@ struct iwx_scan_dwell {
  *                             scan_config_channel_flag
  * @channel_array:             default supported channels
  */
-struct iwx_scan_config {
+struct iwx_scan_config_v2 {
        uint32_t flags;
        uint32_t tx_chains;
        uint32_t rx_chains;
@@ -5819,6 +6037,125 @@ struct iwx_scan_req_umac {
 #define IWX_SCAN_REQ_UMAC_SIZE_V1 36
 
 /**
+ * struct iwx_scan_general_params_v10
+ * @flags: &enum iwx_umac_scan_flags
+ * @reserved: reserved for future
+ * @scan_start_mac_id: report the scan start TSF time according to this mac TSF
+ * @active_dwell: dwell time for active scan per LMAC
+ * @adwell_default_2g: adaptive dwell default number of APs
+ *                        for 2.4GHz channel
+ * @adwell_default_5g: adaptive dwell default number of APs
+ *                        for 5GHz channels
+ * @adwell_default_social_chn: adaptive dwell default number of
+ *                             APs per social channel
+ * @reserved1: reserved for future
+ * @adwell_max_budget: the maximal number of TUs that adaptive dwell
+ *                     can add to the total scan time
+ * @max_out_of_time: max out of serving channel time, per LMAC
+ * @suspend_time: max suspend time, per LMAC
+ * @scan_priority: priority of the request
+ * @passive_dwell: continues dwell time for passive channel
+ *                 (without adaptive dwell)
+ * @num_of_fragments: number of fragments needed for full fragmented
+ *                    scan coverage.
+ */
+struct iwx_scan_general_params_v10 {
+       uint16_t flags;
+       uint8_t reserved;
+       uint8_t scan_start_mac_id;
+       uint8_t active_dwell[IWX_SCAN_TWO_LMACS];
+       uint8_t adwell_default_2g;
+       uint8_t adwell_default_5g;
+       uint8_t adwell_default_social_chn;
+       uint8_t reserved1;
+       uint16_t adwell_max_budget;
+       uint32_t max_out_of_time[IWX_SCAN_TWO_LMACS];
+       uint32_t suspend_time[IWX_SCAN_TWO_LMACS];
+       uint32_t scan_priority;
+       uint8_t passive_dwell[IWX_SCAN_TWO_LMACS];
+       uint8_t num_of_fragments[IWX_SCAN_TWO_LMACS];
+} __packed; /* SCAN_GENERAL_PARAMS_API_S_VER_10 */
+
+/**
+ * struct iwx_scan_channel_params_v6
+ * @flags: channel flags &enum iwl_scan_channel_flags
+ * @count: num of channels in scan request
+ * @n_aps_override: override the number of APs the FW uses to calculate dwell
+ *     time when adaptive dwell is used.
+ *     Channel k will use n_aps_override[i] when BIT(20 + i) is set in
+ *     channel_config[k].flags
+ * @channel_config: array of explicit channel configurations
+ *                  for 2.4Ghz and 5.2Ghz bands
+ */
+struct iwx_scan_channel_params_v6 {
+       uint8_t flags;
+       uint8_t count;
+       uint8_t n_aps_override[2];
+       struct iwx_scan_channel_cfg_umac channel_config[67];
+} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_6 */
+
+/**
+ * struct iwx_scan_periodic_parms_v1
+ * @schedule: can scheduling parameter
+ * @delay: initial delay of the periodic scan in seconds
+ * @reserved: reserved for future
+ */
+struct iwx_scan_periodic_parms_v1 {
+       struct iwx_scan_umac_schedule schedule[IWX_MAX_SCHED_SCAN_PLANS];
+       uint16_t delay;
+       uint16_t reserved;
+} __packed; /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
+
+#define IWX_SCAN_SHORT_SSID_MAX_SIZE        8
+#define IWX_SCAN_BSSID_MAX_SIZE             16
+
+/**
+ * struct iwx_scan_probe_params_v4
+ * @preq: scan probe request params
+ * @short_ssid_num: number of valid short SSIDs in short ssid array
+ * @bssid_num: number of valid bssid in bssids array
+ * @reserved: reserved
+ * @direct_scan: list of ssids
+ * @short_ssid: array of short ssids
+ * @bssid_array: array of bssids
+ */
+struct iwx_scan_probe_params_v4 {
+       struct iwx_scan_probe_req preq;
+       uint8_t short_ssid_num;
+       uint8_t bssid_num;
+       uint16_t reserved;
+       struct iwx_ssid_ie direct_scan[IWX_PROBE_OPTION_MAX];
+       uint32_t short_ssid[IWX_SCAN_SHORT_SSID_MAX_SIZE];
+       uint8_t bssid_array[IWX_SCAN_BSSID_MAX_SIZE][ETHER_ADDR_LEN];
+} __packed; /* SCAN_PROBE_PARAMS_API_S_VER_4 */
+
+/**
+ * struct iwx_scan_req_params_v14
+ * @general_params: &struct iwx_scan_general_params_v10
+ * @channel_params: &struct iwx_scan_channel_params_v6
+ * @periodic_params: &struct iwx_scan_periodic_parms_v1
+ * @probe_params: &struct iwx_scan_probe_params_v4
+ */
+struct iwx_scan_req_params_v14 {
+       struct iwx_scan_general_params_v10 general_params;
+       struct iwx_scan_channel_params_v6 channel_params;
+       struct iwx_scan_periodic_parms_v1 periodic_params;
+       struct iwx_scan_probe_params_v4 probe_params;
+} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_14 */
+
+/**
+ * struct iwx_scan_req_umac_v14
+ * @uid: scan id, &enum iwl_umac_scan_uid_offsets
+ * @ooc_priority: out of channel priority - &enum iwx_scan_priority
+ * @scan_params: scan parameters
+ */
+struct iwx_scan_req_umac_v14 {
+       uint32_t uid;
+       uint32_t ooc_priority;
+       struct iwx_scan_req_params_v14 scan_params;
+} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_14 */
+
+/**
  * struct iwx_umac_scan_abort
  * @uid: scan id, &enum iwx_umac_scan_uid_offsets
  * @flags: reserved
@@ -6533,7 +6870,7 @@ struct iwx_cmd_header_wide {
 #define IWX_POWER_SCHEME_LP    3
 
 #define IWX_DEF_CMD_PAYLOAD_SIZE 320
-#define IWX_MAX_CMD_PAYLOAD_SIZE ((4096 - 4) - sizeof(struct iwx_cmd_header))
+#define IWX_MAX_CMD_PAYLOAD_SIZE (4096 - sizeof(struct iwx_cmd_header_wide))
 #define IWX_CMD_FAILED_MSK 0x40
 
 /**
blob - 928b4d9ec79fed1937e4e147b905cf0da7c36750
blob + 4d297250743b79e9f6bd250041b7ff3b51f43cea
--- sys/dev/pci/if_iwxvar.h
+++ sys/dev/pci/if_iwxvar.h
@@ -123,7 +123,7 @@ struct iwx_tx_radiotap_header {
         (1 << IEEE80211_RADIOTAP_RATE) |                               \
         (1 << IEEE80211_RADIOTAP_CHANNEL))
 
-#define IWX_UCODE_SECT_MAX 42
+#define IWX_UCODE_SECT_MAX 47
 #define IWX_FWDMASEGSZ (192*1024)
 #define IWX_FWDMASEGSZ_8000 (320*1024)
 /* sanity check value */
@@ -236,6 +236,8 @@ struct iwx_tx_data {
        bus_addr_t      cmd_paddr;
        struct mbuf     *m;
        struct iwx_node *in;
+       int flags;
+#define IWX_TXDATA_FLAG_CMD_IS_NARROW  0x01
 };
 
 struct iwx_tx_ring {
@@ -501,6 +503,7 @@ struct iwx_softc {
        struct iwx_tx_ring txq[IWX_MAX_QUEUES];
        struct iwx_rx_ring rxq;
        int qfullmsk;
+       int first_data_qid;
 
        int sc_sf_state;
 
@@ -536,7 +539,7 @@ struct iwx_softc {
        int sc_capa_n_scan_channels;
        uint8_t sc_ucode_api[howmany(IWX_NUM_UCODE_TLV_API, NBBY)];
        uint8_t sc_enabled_capa[howmany(IWX_NUM_UCODE_TLV_CAPA, NBBY)];
-#define IWX_MAX_FW_CMD_VERSIONS        64
+#define IWX_MAX_FW_CMD_VERSIONS        167
        struct iwx_fw_cmd_version cmd_versions[IWX_MAX_FW_CMD_VERSIONS];
        int n_cmd_versions;
 

Reply via email to