On Mon, Jul 26, 2021 at 06:21:46PM +0200, Stefan Sperling wrote:
> 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.

Several people have reported messages such as:
  iwx0: unhandled firmware response 0xc2/0xc rx ring 63[255]

The 0xc2 response is a new notification from firmware (BAR_FRAME_RELEASE).
This updated version of the patch adds support for this feature.

diff 54a415eecf0903b6663209706a0fc6e2e9d40044 refs/heads/iwxfw
blob - 48bf14d7a8a421c6f1bf2b4bfc6c1792396b5400
blob + 0b97503422759e3898791e31f9999f096d6ce9cb
--- 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 *);
@@ -315,6 +318,8 @@ int iwx_ampdu_rx_start(struct ieee80211com *, struct i
 void   iwx_ampdu_rx_stop(struct ieee80211com *, struct ieee80211_node *,
            uint8_t);
 void   iwx_rx_ba_session_expired(void *);
+void   iwx_rx_bar_frame_release(struct iwx_softc *, struct iwx_rx_packet *,
+           struct iwx_rx_data *, struct mbuf_list *);
 void   iwx_reorder_timer_expired(void *);
 void   iwx_sta_rx_agg(struct iwx_softc *, struct ieee80211_node *, uint8_t,
            uint16_t, uint16_t, int, int);
@@ -356,6 +361,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 +396,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 +508,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 +957,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 +1337,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 +1352,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 +2601,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)
@@ -2810,6 +2869,41 @@ iwx_rx_ba_session_expired(void *arg)
 }
 
 void
+iwx_rx_bar_frame_release(struct iwx_softc *sc, struct iwx_rx_packet *pkt,
+    struct iwx_rx_data *data, struct mbuf_list *ml)
+{
+       struct ieee80211com *ic = &sc->sc_ic;
+       struct ieee80211_node *ni = ic->ic_bss;
+       struct iwx_bar_frame_release *release = (void *)data;
+       struct iwx_reorder_buffer *buf;
+       struct iwx_rxba_data *rxba;
+       unsigned int baid, nssn, sta_id, tid;
+
+       if (iwx_rx_packet_payload_len(pkt) < sizeof(*release))
+               return;
+
+       baid = (le32toh(release->ba_info) & IWX_BAR_FRAME_RELEASE_BAID_MASK) >>
+           IWX_BAR_FRAME_RELEASE_BAID_SHIFT;
+       if (baid == IWX_RX_REORDER_DATA_INVALID_BAID ||
+           baid >= nitems(sc->sc_rxba_data))
+               return;
+
+       rxba = &sc->sc_rxba_data[baid];
+       if (rxba == NULL || rxba->baid == IWX_RX_REORDER_DATA_INVALID_BAID)
+               return;
+
+       tid = le32toh(release->sta_tid) & IWX_BAR_FRAME_RELEASE_TID_MASK;
+       sta_id = (le32toh(release->sta_tid) &
+           IWX_BAR_FRAME_RELEASE_STA_MASK) >> IWX_BAR_FRAME_RELEASE_STA_SHIFT;
+       if (tid != rxba->tid || rxba->sta_id != IWX_STATION_ID)
+               return;
+
+       nssn = le32toh(release->ba_info) & IWX_BAR_FRAME_RELEASE_NSSN_MASK;
+       buf = &rxba->reorder_buf;
+       iwx_release_frames(sc, ni, rxba, buf, nssn, ml);
+}
+
+void
 iwx_reorder_timer_expired(void *arg)
 {
        struct mbuf_list ml = MBUF_LIST_INITIALIZER();
@@ -4416,9 +4510,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 +4522,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 +4538,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 +4635,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 +4722,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 +4772,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 +4789,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 +5063,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 +5451,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 +5502,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 +5511,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 +5660,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 +5717,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 +5830,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 +5859,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 +6014,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 +6092,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 +6644,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 +6717,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 +6753,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 +6909,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 +8497,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))
@@ -8124,6 +8561,10 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
                        break;
                }
 
+               case IWX_BAR_FRAME_RELEASE:
+                       iwx_rx_bar_frame_release(sc, pkt, data, ml);
+                       break;
+
                case IWX_TX_CMD:
                        iwx_rx_tx_cmd(sc, pkt, data);
                        break;
@@ -8137,9 +8578,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 +8622,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 +8656,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 +8757,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 +9317,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 +9335,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 +9346,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 + d7eda7cb6a3e1a7d8d3b605908a7185a8d8dd245
--- 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)
@@ -1530,6 +1580,8 @@ struct iwx_tx_queue_cfg_rsp {
 
 #define IWX_REPLY_RX_PHY_CMD   0xc0
 #define IWX_REPLY_RX_MPDU_CMD  0xc1
+#define IWX_BAR_FRAME_RELEASE  0xc2
+#define IWX_FRAME_RELEASE      0xc3
 #define IWX_BA_NOTIF           0xc5
 
 /* Location Aware Regulatory */
@@ -1605,6 +1657,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 +1978,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 +2791,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 +3010,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 +3067,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 +3081,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;
@@ -3136,7 +3319,44 @@ struct iwx_rx_mpdu_desc {
        struct iwx_rx_mpdu_desc_v1 v1;
 } __packed;
 
+struct iwx_frame_release {
+       uint8_t baid;
+       uint8_t reserved;
+       uint16_t nssn;
+};
+
 /**
+ * enum iwx_bar_frame_release_sta_tid - STA/TID information for BAR release
+ * @IWX_BAR_FRAME_RELEASE_TID_MASK: TID mask
+ * @IWX_BAR_FRAME_RELEASE_STA_MASK: STA mask
+ */
+#define IWX_BAR_FRAME_RELEASE_TID_MASK 0x0000000f
+#define IWX_BAR_FRAME_RELEASE_STA_MASK 0x000001f0
+#define IWX_BAR_FRAME_RELEASE_STA_SHIFT        4
+
+/**
+ * enum iwx_bar_frame_release_ba_info - BA information for BAR release
+ * @IWL_BAR_FRAME_RELEASE_NSSN_MASK: NSSN mask
+ * @IWL_BAR_FRAME_RELEASE_SN_MASK: SN mask (ignored by driver)
+ * @IWL_BAR_FRAME_RELEASE_BAID_MASK: BAID mask
+ */
+#define IWX_BAR_FRAME_RELEASE_NSSN_MASK                0x00000fff
+#define IWX_BAR_FRAME_RELEASE_SN_MASK          0x00fff000
+#define IWX_BAR_FRAME_RELEASE_SN_SHIFT         12
+#define IWX_BAR_FRAME_RELEASE_BAID_MASK                0x3f000000
+#define IWX_BAR_FRAME_RELEASE_BAID_SHIFT       24
+
+/**
+ * struct iwx_bar_frame_release - frame release from BAR info
+ * @sta_tid: STA & TID information, see &enum iwx_bar_frame_release_sta_tid.
+ * @ba_info: BA information, see &enum iwx_bar_frame_release_ba_info.
+ */
+struct iwx_bar_frame_release {
+       uint32_t sta_tid;
+       uint32_t ba_info;
+} __packed; /* RX_BAR_TO_FRAME_RELEASE_API_S_VER_1 */
+
+/**
  * struct iwx_radio_version_notif - information on the radio version
  * ( IWX_RADIO_VERSION_NOTIFICATION = 0x68 )
  * @radio_flavor:
@@ -4574,6 +4794,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 +4809,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 +5538,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 +5559,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 +5739,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 +5775,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 +6076,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 +6909,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