This diff adds support for new iwm firmare's umac scan API.
It is required to make scanning work on -34 firmware.
Combined with the 'new ADD_STA' diff I just sent out, this is the last
change we need to get -34 firmware working.

This adds a couple of lines under #ifdef notyet for ax200 devices (which
are the post-9k generation of devices). I kept these while porting the
necessary changes from Linux, because we will eventually need them.

I really don't like that huge union of structs but that is how Linux
solved the backwards compat issue. Unless Intel starts providing newer
firmware images for old devices (unlikely) keeping track of which API
version is needed with which fimware image is only going to get more
difficult over time. So I'd prefer our approach to remain close enough to
Linux to allow code for newer devices to be ported without too much effort.

ok?
 
diff 0181db2e1507c7a303c9d89a8410f8181993d536 
7ccc2a384b9e6c567f74851744d872e72c7d91bc
blob - 73727efa2ad5d72670c6c2129ee76f4e77797652
blob + 0199163cc7f36c58992a881dd498b30ff1febc38
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -546,7 +546,9 @@ iwm_firmware_store_section(struct iwm_softc *sc, enum 
        return 0;
 }
 
-#define IWM_DEFAULT_SCAN_CHANNELS 40
+#define IWM_DEFAULT_SCAN_CHANNELS      40
+/* Newer firmware might support more channels. Raise this value if needed. */
+#define IWM_MAX_SCAN_CHANNELS          52 /* as of 8265-34 firmware image */
 
 struct iwm_tlv_calib_data {
        uint32_t ucode_type;
@@ -837,6 +839,10 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode
                        }
                        sc->sc_capa_n_scan_channels =
                          le32toh(*(uint32_t *)tlv_data);
+                       if (sc->sc_capa_n_scan_channels > 
IWM_MAX_SCAN_CHANNELS) {
+                               err = ERANGE;
+                               goto parse_out;
+                       }
                        break;
 
                case IWM_UCODE_TLV_FW_VERSION:
@@ -4939,6 +4945,24 @@ iwm_umac_scan_fill_channels(struct iwm_softc *sc,
 }
 
 int
+iwm_fill_probe_req_v1(struct iwm_softc *sc, struct iwm_scan_probe_req_v1 
*preq1)
+{
+       struct iwm_scan_probe_req preq2;
+       int err, i;
+
+       err = iwm_fill_probe_req(sc, &preq2);
+       if (err)
+               return err;
+
+       preq1->mac_header = preq2.mac_header;
+       for (i = 0; i < nitems(preq1->band_data); i++)
+               preq1->band_data[i] = preq2.band_data[i];
+       preq1->common_data = preq2.common_data;
+       memcpy(preq1->buf, preq2.buf, sizeof(preq1->buf));
+       return 0;
+}
+
+int
 iwm_fill_probe_req(struct iwm_softc *sc, struct iwm_scan_probe_req *preq)
 {
        struct ieee80211com *ic = &sc->sc_ic;
@@ -5042,12 +5066,13 @@ iwm_lmac_scan(struct iwm_softc *sc, int bgscan)
                .flags = 0,
        };
        struct iwm_scan_req_lmac *req;
+       struct iwm_scan_probe_req_v1 *preq;
        size_t req_len;
        int err, async = bgscan;
 
        req_len = sizeof(struct iwm_scan_req_lmac) +
            (sizeof(struct iwm_scan_channel_cfg_lmac) *
-           sc->sc_capa_n_scan_channels) + sizeof(struct iwm_scan_probe_req);
+           sc->sc_capa_n_scan_channels) + sizeof(struct iwm_scan_probe_req_v1);
        if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
                return ENOMEM;
        req = malloc(req_len, M_DEVBUF,
@@ -5120,10 +5145,10 @@ iwm_lmac_scan(struct iwm_softc *sc, int bgscan)
            (struct iwm_scan_channel_cfg_lmac *)req->data,
            ic->ic_des_esslen != 0, bgscan);
 
-       err = iwm_fill_probe_req(sc,
-                           (struct iwm_scan_probe_req *)(req->data +
-                           (sizeof(struct iwm_scan_channel_cfg_lmac) *
-                           sc->sc_capa_n_scan_channels)));
+       preq = (struct iwm_scan_probe_req_v1 *)(req->data +
+           (sizeof(struct iwm_scan_channel_cfg_lmac) *
+           sc->sc_capa_n_scan_channels));
+       err = iwm_fill_probe_req_v1(sc, preq);
        if (err) {
                free(req, M_DEVBUF, req_len);
                return err;
@@ -5184,9 +5209,7 @@ iwm_config_umac_scan(struct iwm_softc *sc)
        IEEE80211_ADDR_COPY(scan_config->mac_addr, sc->sc_ic.ic_myaddr);
 
        scan_config->bcast_sta_id = IWM_AUX_STA_ID;
-       scan_config->channel_flags = IWM_CHANNEL_FLAG_EBS |
-           IWM_CHANNEL_FLAG_ACCURATE_EBS | IWM_CHANNEL_FLAG_EBS_ADD |
-           IWM_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE;
+       scan_config->channel_flags = 0;
 
        for (c = &ic->ic_channels[1], nchan = 0;
            c <= &ic->ic_channels[IEEE80211_CHAN_MAX] &&
@@ -5218,6 +5241,72 @@ iwm_config_umac_scan(struct iwm_softc *sc)
 }
 
 int
+iwm_umac_scan_size(struct iwm_softc *sc)
+{
+       int base_size = IWM_SCAN_REQ_UMAC_SIZE_V1;
+       int tail_size;
+
+       if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_ADAPTIVE_DWELL_V2))
+               base_size = IWM_SCAN_REQ_UMAC_SIZE_V8;
+       else if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_ADAPTIVE_DWELL))
+               base_size = IWM_SCAN_REQ_UMAC_SIZE_V7;
+#ifdef notyet
+       else if (sc->sc_device_family >= IWM_DEVICE_FAMILY_22000)
+               base_size = IWM_SCAN_REQ_UMAC_SIZE_V6;
+#endif
+       if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_SCAN_EXT_CHAN_VER))
+               tail_size = sizeof(struct iwm_scan_req_umac_tail_v2);
+       else
+               tail_size = sizeof(struct iwm_scan_req_umac_tail_v1);
+
+       return base_size + sizeof(struct iwm_scan_channel_cfg_umac) *
+           sc->sc_capa_n_scan_channels + tail_size;
+}
+
+struct iwm_scan_umac_chan_param *
+iwm_get_scan_req_umac_chan_param(struct iwm_softc *sc,
+    struct iwm_scan_req_umac *req)
+{
+       if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_ADAPTIVE_DWELL_V2))
+               return &req->v8.channel;
+
+       if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_ADAPTIVE_DWELL))
+               return &req->v7.channel;
+#ifdef notyet
+       if (sc->sc_device_family >= IWM_DEVICE_FAMILY_22000)
+               return &req->v6.channel;
+#endif
+       return &req->v1.channel;
+}
+
+void *
+iwm_get_scan_req_umac_data(struct iwm_softc *sc, struct iwm_scan_req_umac *req)
+{
+       if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_ADAPTIVE_DWELL_V2))
+               return (void *)&req->v8.data;
+
+       if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_ADAPTIVE_DWELL))
+               return (void *)&req->v7.data;
+#ifdef notyet
+       if (sc->sc_device_family >= IWM_DEVICE_FAMILY_22000)
+               return (void *)&req->v6.data;
+#endif
+       return (void *)&req->v1.data;
+
+}
+
+/* adaptive dwell max budget time [TU] for full scan */
+#define IWM_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
+/* adaptive dwell max budget time [TU] for directed scan */
+#define IWM_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN 100
+/* adaptive dwell default high band APs number */
+#define IWM_SCAN_ADWELL_DEFAULT_HB_N_APS 8
+/* adaptive dwell default low band APs number */
+#define IWM_SCAN_ADWELL_DEFAULT_LB_N_APS 2
+/* adaptive dwell default APs number in social channels (1, 6, 11) */
+#define IWM_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10
+
+int
 iwm_umac_scan(struct iwm_softc *sc, int bgscan)
 {
        struct ieee80211com *ic = &sc->sc_ic;
@@ -5225,19 +5314,21 @@ iwm_umac_scan(struct iwm_softc *sc, int bgscan)
                .id = iwm_cmd_id(IWM_SCAN_REQ_UMAC, IWM_LONG_GROUP, 0),
                .len = { 0, },
                .data = { NULL, },
-               .flags =0,
+               .flags = 0,
        };
        struct iwm_scan_req_umac *req;
-       struct iwm_scan_req_umac_tail *tail;
+       void *cmd_data, *tail_data;
+       struct iwm_scan_req_umac_tail_v2 *tail;
+       struct iwm_scan_req_umac_tail_v1 *tailv1;
+       struct iwm_scan_umac_chan_param *chanparam;
        size_t req_len;
        int err, async = bgscan;
 
-       req_len = sizeof(struct iwm_scan_req_umac) +
-           (sizeof(struct iwm_scan_channel_cfg_umac) *
-           sc->sc_capa_n_scan_channels) +
-           sizeof(struct iwm_scan_req_umac_tail);
-       if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
-               return ENOMEM;
+       req_len = iwm_umac_scan_size(sc);
+       if ((req_len < IWM_SCAN_REQ_UMAC_SIZE_V1 +
+           sizeof(struct iwm_scan_req_umac_tail_v1)) ||
+           req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
+               return ERANGE;
        req = malloc(req_len, M_DEVBUF,
            (async ? M_NOWAIT : M_WAIT) | M_CANFAIL | M_ZERO);
        if (req == NULL)
@@ -5247,40 +5338,88 @@ iwm_umac_scan(struct iwm_softc *sc, int bgscan)
        hcmd.data[0] = (void *)req;
        hcmd.flags |= async ? IWM_CMD_ASYNC : 0;
 
-       /* These timings correspond to iwlwifi's UNASSOC scan. */
-       req->active_dwell = 10;
-       req->passive_dwell = 110;
-       req->fragmented_dwell = 44;
-       req->extended_dwell = 90;
-       if (bgscan) {
-               req->max_out_time = htole32(120);
-               req->suspend_time = htole32(120);
+       if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_ADAPTIVE_DWELL)) {
+               req->v7.adwell_default_n_aps_social =
+                       IWM_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
+               req->v7.adwell_default_n_aps =
+                       IWM_SCAN_ADWELL_DEFAULT_LB_N_APS;
+
+               if (ic->ic_des_esslen != 0)
+                       req->v7.adwell_max_budget =
+                           htole16(IWM_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
+               else
+                       req->v7.adwell_max_budget =
+                           htole16(IWM_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN);
+
+               req->v7.scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
+               req->v7.max_out_time[IWM_SCAN_LB_LMAC_IDX] = 0;
+               req->v7.suspend_time[IWM_SCAN_LB_LMAC_IDX] = 0;
+
+               if (isset(sc->sc_ucode_api,
+                   IWM_UCODE_TLV_API_ADAPTIVE_DWELL_V2)) {
+                       req->v8.active_dwell[IWM_SCAN_LB_LMAC_IDX] = 10;
+                       req->v8.passive_dwell[IWM_SCAN_LB_LMAC_IDX] = 110;
+               } else {
+                       req->v7.active_dwell = 10;
+                       req->v7.passive_dwell = 110;
+                       req->v7.fragmented_dwell = 44;
+               }
        } else {
-               req->max_out_time = htole32(0);
-               req->suspend_time = htole32(0);
+               /* These timings correspond to iwlwifi's UNASSOC scan. */
+               req->v1.active_dwell = 10;
+               req->v1.passive_dwell = 110;
+               req->v1.fragmented_dwell = 44;
+               req->v1.extended_dwell = 90;
        }
 
-       req->scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
+       if (bgscan) {
+               const uint32_t timeout = htole32(120);
+               if (isset(sc->sc_ucode_api,
+                   IWM_UCODE_TLV_API_ADAPTIVE_DWELL_V2)) {
+                       req->v8.max_out_time[IWM_SCAN_LB_LMAC_IDX] = timeout;
+                       req->v8.suspend_time[IWM_SCAN_LB_LMAC_IDX] = timeout;
+               } else if (isset(sc->sc_ucode_api,
+                   IWM_UCODE_TLV_API_ADAPTIVE_DWELL)) {
+                       req->v7.max_out_time[IWM_SCAN_LB_LMAC_IDX] = timeout;
+                       req->v7.suspend_time[IWM_SCAN_LB_LMAC_IDX] = timeout;
+               } else {
+                       req->v1.max_out_time = timeout;
+                       req->v1.suspend_time = timeout;
+               }
+       }
+
+       req->v1.scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
        req->ooc_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
 
-       req->n_channels = iwm_umac_scan_fill_channels(sc,
-           (struct iwm_scan_channel_cfg_umac *)req->data,
+       cmd_data = iwm_get_scan_req_umac_data(sc, req);
+       chanparam = iwm_get_scan_req_umac_chan_param(sc, req);
+       chanparam->count = iwm_umac_scan_fill_channels(sc,
+           (struct iwm_scan_channel_cfg_umac *)cmd_data,
            ic->ic_des_esslen != 0, bgscan);
+       chanparam->flags = 0;
 
+       tail_data = cmd_data + sizeof(struct iwm_scan_channel_cfg_umac) *
+           sc->sc_capa_n_scan_channels;
+       tail = tail_data;
+       /* tail v1 layout differs in preq and direct_scan member fields. */
+       tailv1 = tail_data;
+
        req->general_flags = htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASS_ALL |
-           IWM_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE |
-           IWM_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL);
+           IWM_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE);
 
-       tail = (void *)&req->data +
-               sizeof(struct iwm_scan_channel_cfg_umac) *
-                       sc->sc_capa_n_scan_channels;
-
        /* Check if we're doing an active directed scan. */
        if (ic->ic_des_esslen != 0) {
-               tail->direct_scan[0].id = IEEE80211_ELEMID_SSID;
-               tail->direct_scan[0].len = ic->ic_des_esslen;
-               memcpy(tail->direct_scan[0].ssid, ic->ic_des_essid,
-                   ic->ic_des_esslen);
+               if (isset(sc->sc_ucode_api, 
IWM_UCODE_TLV_API_SCAN_EXT_CHAN_VER)) {
+                       tail->direct_scan[0].id = IEEE80211_ELEMID_SSID;
+                       tail->direct_scan[0].len = ic->ic_des_esslen;
+                       memcpy(tail->direct_scan[0].ssid, ic->ic_des_essid,
+                           ic->ic_des_esslen);
+               } else {
+                       tailv1->direct_scan[0].id = IEEE80211_ELEMID_SSID;
+                       tailv1->direct_scan[0].len = ic->ic_des_esslen;
+                       memcpy(tailv1->direct_scan[0].ssid, ic->ic_des_essid,
+                           ic->ic_des_esslen);
+               }
                req->general_flags |=
                    htole32(IWM_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT);
        } else
@@ -5291,7 +5430,18 @@ iwm_umac_scan(struct iwm_softc *sc, int bgscan)
                req->general_flags |=
                    htole32(IWM_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED);
 
-       err = iwm_fill_probe_req(sc, &tail->preq);
+       if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_ADAPTIVE_DWELL)) {
+               req->general_flags |=
+                   htole32(IWM_UMAC_SCAN_GEN_FLAGS_ADAPTIVE_DWELL);
+       } else {
+               req->general_flags |=
+                   htole32(IWM_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL);
+       }
+
+       if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_SCAN_EXT_CHAN_VER))
+               err = iwm_fill_probe_req(sc, &tail->preq);
+       else
+               err = iwm_fill_probe_req_v1(sc, &tailv1->preq);
        if (err) {
                free(req, M_DEVBUF, req_len);
                return err;
blob - 8d0564aa8c5a74ad83853f409edd1845d86cae47
blob + e1f75f40b907ffdf22520dfd39a9aae28335c600
--- sys/dev/pci/if_iwmreg.h
+++ sys/dev/pci/if_iwmreg.h
@@ -639,6 +639,8 @@
 #define IWM_UCODE_TLV_API_NAN2_VER2            31
 #define IWM_UCODE_TLV_API_ADAPTIVE_DWELL       32
 #define IWM_UCODE_TLV_API_NEW_RX_STATS         35
+#define IWM_UCODE_TLV_API_ADAPTIVE_DWELL_V2    42
+#define IWM_UCODE_TLV_API_SCAN_EXT_CHAN_VER    58
 #define IWM_NUM_UCODE_TLV_API                  128
 
 #define IWM_UCODE_TLV_API_BITS \
@@ -4863,13 +4865,27 @@ struct iwm_scan_probe_segment {
  * @common_data: last (and common) part of the probe
  * @buf: raw data block
  */
-struct iwm_scan_probe_req {
+struct iwm_scan_probe_req_v1 {
        struct iwm_scan_probe_segment mac_header;
        struct iwm_scan_probe_segment band_data[2];
        struct iwm_scan_probe_segment common_data;
        uint8_t buf[IWM_SCAN_OFFLOAD_PROBE_REQ_SIZE];
 } __packed;
 
+/* iwl_scan_probe_req - PROBE_REQUEST_FRAME_API_S_VER_v2
+ * @mac_header: first (and common) part of the probe
+ * @band_data: band specific data
+ * @common_data: last (and common) part of the probe
+ * @buf: raw data block
+ */
+struct iwm_scan_probe_req {
+       struct iwm_scan_probe_segment mac_header;
+       struct iwm_scan_probe_segment band_data[3];
+       struct iwm_scan_probe_segment common_data;
+       uint8_t buf[IWM_SCAN_OFFLOAD_PROBE_REQ_SIZE];
+} __packed;
+
+
 #define IWM_SCAN_CHANNEL_FLAG_EBS              (1 << 0)
 #define IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE     (1 << 1)
 #define IWM_SCAN_CHANNEL_FLAG_CACHE_ADD                (1 << 2)
@@ -5205,6 +5221,14 @@ struct iwm_scan_config {
 #define IWM_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED    (1 << 8)
 #define IWM_UMAC_SCAN_GEN_FLAGS_MATCH          (1 << 9)
 #define IWM_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL (1 << 10)
+/* Extended dwell is obselete when adaptive dwell is used, making this
+ * bit reusable. Hence, probe request defer is used only when adaptive
+ * dwell is supported. */
+#define IWM_UMAC_SCAN_GEN_FLAGS_PROB_REQ_DEFER_SUPP    (1 << 10)
+#define IWM_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED       (1 << 11)
+#define IWM_UMAC_SCAN_GEN_FLAGS_ADAPTIVE_DWELL         (1 << 13)
+#define IWM_UMAC_SCAN_GEN_FLAGS_MAX_CHNL_TIME          (1 << 14)
+#define IWM_UMAC_SCAN_GEN_FLAGS_PROB_REQ_HIGH_TX_RATE  (1 << 15)
 
 /**
  * struct iwm_scan_channel_cfg_umac
@@ -5241,32 +5265,77 @@ struct iwm_scan_umac_schedule {
  * @preq: probe request with IEs blocks
  * @direct_scan: list of SSIDs for directed active scan
  */
-struct iwm_scan_req_umac_tail {
+struct iwm_scan_req_umac_tail_v1 {
        /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
        struct iwm_scan_umac_schedule schedule[IWM_MAX_SCHED_SCAN_PLANS];
        uint16_t delay;
        uint16_t reserved;
        /* SCAN_PROBE_PARAMS_API_S_VER_1 */
+       struct iwm_scan_probe_req_v1 preq;
+       struct iwm_ssid_ie direct_scan[IWM_PROBE_OPTION_MAX];
+} __packed;
+
+/**
+ * struct iwm_scan_req_umac_tail - the rest of the UMAC scan request command
+ *      parameters following channels configuration array.
+ * @schedule: two scheduling plans.
+ * @delay: delay in TUs before starting the first scan iteration
+ * @reserved: for future use and alignment
+ * @preq: probe request with IEs blocks
+ * @direct_scan: list of SSIDs for directed active scan
+ */
+struct iwm_scan_req_umac_tail_v2 {
+       /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
+       struct iwm_scan_umac_schedule schedule[IWM_MAX_SCHED_SCAN_PLANS];
+       uint16_t delay;
+       uint16_t reserved;
+       /* SCAN_PROBE_PARAMS_API_S_VER_2 */
        struct iwm_scan_probe_req preq;
        struct iwm_ssid_ie direct_scan[IWM_PROBE_OPTION_MAX];
 } __packed;
 
 /**
+ * struct iwm_scan_umac_chan_param
+ * @flags: channel flags &enum iwl_scan_channel_flags
+ * @count: num of channels in scan request
+ * @reserved: for future use and alignment
+ */
+struct iwm_scan_umac_chan_param {
+       uint8_t flags;
+       uint8_t count;
+       uint16_t reserved;
+} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_1 */
+
+#define IWM_SCAN_LB_LMAC_IDX 0
+#define IWM_SCAN_HB_LMAC_IDX 1
+
+/**
  * struct iwm_scan_req_umac
- * @flags: &enum iwm_umac_scan_flags
- * @uid: scan id, &enum iwm_umac_scan_uid_offsets
- * @ooc_priority: out of channel priority - &enum iwm_scan_priority
- * @general_flags: &enum iwm_umac_scan_general_flags
+ * @flags: &enum iwl_umac_scan_flags
+ * @uid: scan id, &enum iwl_umac_scan_uid_offsets
+ * @ooc_priority: out of channel priority - &enum iwl_scan_priority
+ * @general_flags: &enum iwl_umac_scan_general_flags
+ * @scan_start_mac_id: report the scan start TSF time according to this mac TSF
  * @extended_dwell: dwell time for channels 1, 6 and 11
- * @active_dwell: dwell time for active scan
- * @passive_dwell: dwell time for passive scan
+ * @active_dwell: dwell time for active scan per LMAC
+ * @passive_dwell: dwell time for passive scan per LMAC
  * @fragmented_dwell: dwell time for fragmented passive scan
- * @max_out_time: max out of serving channel time
- * @suspend_time: max suspend time
- * @scan_priority: scan internal prioritization &enum iwm_scan_priority
- * @channel_flags: &enum iwm_scan_channel_flags
- * @n_channels: num of channels in scan request
+ * @adwell_default_n_aps: for adaptive dwell the default number of APs
+ *     per channel
+ * @adwell_default_n_aps_social: for adaptive dwell the default
+ *     number of APs per social (1,6,11) channel
+ * @general_flags2: &enum iwl_umac_scan_general_flags2
+ * @adwell_max_budget: for adaptive dwell the maximal budget of TU to be added
+ *     to total scan time
+ * @max_out_time: max out of serving channel time, per LMAC - for CDB there
+ *     are 2 LMACs (high band and low band)
+ * @suspend_time: max suspend time, per LMAC - for CDB there are 2 LMACs
+ * @scan_priority: scan internal prioritization &enum iwl_scan_priority
+ * @num_of_fragments: Number of fragments needed for full coverage per band.
+ *     Relevant only for fragmented scan.
+ * @channel: &struct iwm_scan_umac_chan_param
  * @reserved: for future use and alignment
+ * @reserved3: for future use and alignment
  * @data: &struct iwm_scan_channel_cfg_umac and
  *     &struct iwm_scan_req_umac_tail
  */
@@ -5275,20 +5344,83 @@ struct iwm_scan_req_umac {
        uint32_t uid;
        uint32_t ooc_priority;
        /* SCAN_GENERAL_PARAMS_API_S_VER_1 */
-       uint32_t general_flags;
-       uint8_t extended_dwell;
-       uint8_t active_dwell;
-       uint8_t passive_dwell;
-       uint8_t fragmented_dwell;
-       uint32_t max_out_time;
-       uint32_t suspend_time;
-       uint32_t scan_priority;
-       /* SCAN_CHANNEL_PARAMS_API_S_VER_1 */
-       uint8_t channel_flags;
-       uint8_t n_channels;
-       uint16_t reserved;
-       uint8_t data[];
-} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_1 */
+       uint16_t general_flags;
+       uint8_t reserved;
+       uint8_t scan_start_mac_id;
+       union {
+               struct {
+                       uint8_t extended_dwell;
+                       uint8_t active_dwell;
+                       uint8_t passive_dwell;
+                       uint8_t fragmented_dwell;
+                       uint32_t max_out_time;
+                       uint32_t suspend_time;
+                       uint32_t scan_priority;
+                       struct iwm_scan_umac_chan_param channel;
+                       uint8_t data[];
+               } v1; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_1 */
+               struct {
+                       uint8_t extended_dwell;
+                       uint8_t active_dwell;
+                       uint8_t passive_dwell;
+                       uint8_t fragmented_dwell;
+                       uint32_t max_out_time[2];
+                       uint32_t suspend_time[2];
+                       uint32_t scan_priority;
+                       struct iwm_scan_umac_chan_param channel;
+                       uint8_t data[];
+               } v6; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_6 */
+               struct {
+                       uint8_t active_dwell;
+                       uint8_t passive_dwell;
+                       uint8_t fragmented_dwell;
+                       uint8_t adwell_default_n_aps;
+                       uint8_t adwell_default_n_aps_social;
+                       uint8_t reserved3;
+                       uint16_t adwell_max_budget;
+                       uint32_t max_out_time[2];
+                       uint32_t suspend_time[2];
+                       uint32_t scan_priority;
+                       struct iwm_scan_umac_chan_param channel;
+                       uint8_t data[];
+               } v7; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_7 */
+               struct {
+                       uint8_t active_dwell[2];
+                       uint8_t reserved2;
+                       uint8_t adwell_default_n_aps;
+                       uint8_t adwell_default_n_aps_social;
+                       uint8_t general_flags2;
+                       uint16_t adwell_max_budget;
+                       uint32_t max_out_time[2];
+                       uint32_t suspend_time[2];
+                       uint32_t scan_priority;
+                       uint8_t passive_dwell[2];
+                       uint8_t num_of_fragments[2];
+                       struct iwm_scan_umac_chan_param channel;
+                       uint8_t data[];
+               } v8; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_8 */
+               struct {
+                       uint8_t active_dwell[2];
+                       uint8_t adwell_default_hb_n_aps;
+                       uint8_t adwell_default_lb_n_aps;
+                       uint8_t adwell_default_n_aps_social;
+                       uint8_t general_flags2;
+                       uint16_t adwell_max_budget;
+                       uint32_t max_out_time[2];
+                       uint32_t suspend_time[2];
+                       uint32_t scan_priority;
+                       uint8_t passive_dwell[2];
+                       uint8_t num_of_fragments[2];
+                       struct iwm_scan_umac_chan_param channel;
+                       uint8_t data[];
+               } v9; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_9 */
+       };
+} __packed;
+
+#define IWM_SCAN_REQ_UMAC_SIZE_V8 sizeof(struct iwm_scan_req_umac)
+#define IWM_SCAN_REQ_UMAC_SIZE_V7 48
+#define IWM_SCAN_REQ_UMAC_SIZE_V6 44
+#define IWM_SCAN_REQ_UMAC_SIZE_V1 36
 
 /**
  * struct iwm_umac_scan_abort

Reply via email to