summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2019-11-08 16:42:12 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2019-11-08 16:42:12 +0000
commit47a3d9093cddc470ff7af3784a92ae2acacc64cb (patch)
tree4dcedfae5943df04a6a8d0c5c1c6efd47d18d6a3
parent2500f9f7e01ddcb2e853e073281dec28d71e4646 (diff)
Add support to iwm(4) for new umac scan API in newer firmware versions.
Tested by phessler@, Tracey Emery, and myself on 8260 and 8265.
-rw-r--r--sys/dev/pci/if_iwm.c234
-rw-r--r--sys/dev/pci/if_iwmreg.h188
2 files changed, 352 insertions, 70 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
index 8398ffed599..2250acb0afe 100644
--- a/sys/dev/pci/if_iwm.c
+++ b/sys/dev/pci/if_iwm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwm.c,v 1.278 2019/11/08 16:41:14 stsp Exp $ */
+/* $OpenBSD: if_iwm.c,v 1.279 2019/11/08 16:42:11 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -546,7 +546,9 @@ iwm_firmware_store_section(struct iwm_softc *sc, enum iwm_ucode_type type,
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_type ucode_type)
}
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:
@@ -4943,6 +4949,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;
@@ -5046,12 +5070,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,
@@ -5124,10 +5149,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;
@@ -5188,9 +5213,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] &&
@@ -5222,6 +5245,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;
@@ -5229,19 +5318,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)
@@ -5251,40 +5342,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;
- 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);
+ 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;
- tail = (void *)&req->data +
- sizeof(struct iwm_scan_channel_cfg_umac) *
- sc->sc_capa_n_scan_channels;
+ req->general_flags = htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASS_ALL |
+ IWM_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE);
/* 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
@@ -5295,7 +5434,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;
diff --git a/sys/dev/pci/if_iwmreg.h b/sys/dev/pci/if_iwmreg.h
index 30f25f2f149..ebdbb2114ca 100644
--- a/sys/dev/pci/if_iwmreg.h
+++ b/sys/dev/pci/if_iwmreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwmreg.h,v 1.41 2019/11/08 16:41:15 stsp Exp $ */
+/* $OpenBSD: if_iwmreg.h,v 1.42 2019/11/08 16:42:11 stsp Exp $ */
/******************************************************************************
*
@@ -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