svn commit: r354515 - head/sys/dev/iwm
Mark Johnston
markj at FreeBSD.org
Thu Nov 7 23:39:05 UTC 2019
Author: markj
Date: Thu Nov 7 23:39:04 2019
New Revision: 354515
URL: https://svnweb.freebsd.org/changeset/base/354515
Log:
iwm: Implement support for scans with "adaptive" dwell time.
This is required by 9000-series firmware.
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/dev/iwm/if_iwm_scan.c
head/sys/dev/iwm/if_iwmreg.h
Modified: head/sys/dev/iwm/if_iwm_scan.c
==============================================================================
--- head/sys/dev/iwm/if_iwm_scan.c Thu Nov 7 23:38:49 2019 (r354514)
+++ head/sys/dev/iwm/if_iwm_scan.c Thu Nov 7 23:39:04 2019 (r354515)
@@ -580,6 +580,29 @@ iwm_mvm_scan_use_ebs(struct iwm_softc *sc)
sc->last_ebs_successful);
}
+static int
+iwm_mvm_scan_size(struct iwm_softc *sc)
+{
+ int base_size;
+
+ if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) {
+ if (iwm_fw_has_api(sc, IWM_UCODE_TLV_API_ADAPTIVE_DWELL))
+ base_size = IWM_SCAN_REQ_UMAC_SIZE_V7;
+ else
+ base_size = IWM_SCAN_REQ_UMAC_SIZE_V1;
+
+ return base_size +
+ sizeof(struct iwm_scan_channel_cfg_umac) *
+ sc->sc_fw.ucode_capa.n_scan_channels +
+ sizeof(struct iwm_scan_req_umac_tail);
+ } else {
+ return sizeof(struct iwm_scan_req_lmac) +
+ sizeof(struct iwm_scan_channel_cfg_lmac) *
+ sc->sc_fw.ucode_capa.n_scan_channels +
+ sizeof(struct iwm_scan_probe_req);
+ }
+}
+
int
iwm_mvm_umac_scan(struct iwm_softc *sc)
{
@@ -593,13 +616,11 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
struct iwm_scan_req_umac *req;
struct iwm_scan_req_umac_tail *tail;
size_t req_len;
- uint8_t i, nssid;
+ uint16_t general_flags;
+ uint8_t channel_flags, i, nssid;
int ret;
- req_len = sizeof(struct iwm_scan_req_umac) +
- (sizeof(struct iwm_scan_channel_cfg_umac) *
- sc->sc_fw.ucode_capa.n_scan_channels) +
- sizeof(struct iwm_scan_req_umac_tail);
+ req_len = iwm_mvm_scan_size(sc);
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
return ENOMEM;
req = malloc(req_len, M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -611,28 +632,58 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Handling ieee80211 scan request\n");
- /* These timings correspond to iwlwifi's UNASSOC scan. */
- req->active_dwell = 10;
- req->passive_dwell = 110;
- req->fragmented_dwell = 44;
- req->extended_dwell = 90;
- req->max_out_time = 0;
- req->suspend_time = 0;
+ nssid = MIN(ss->ss_nssid, IWM_PROBE_OPTION_MAX);
- req->scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
+ general_flags = IWM_UMAC_SCAN_GEN_FLAGS_PASS_ALL |
+ IWM_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
+ if (!iwm_fw_has_api(sc, IWM_UCODE_TLV_API_ADAPTIVE_DWELL))
+ general_flags |= IWM_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL;
+ if (iwm_mvm_rrm_scan_needed(sc))
+ general_flags |= IWM_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED;
+ if (nssid != 0)
+ general_flags |= IWM_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT;
+ else
+ general_flags |= IWM_UMAC_SCAN_GEN_FLAGS_PASSIVE;
+
+ channel_flags = 0;
+ if (iwm_mvm_scan_use_ebs(sc))
+ channel_flags = IWM_SCAN_CHANNEL_FLAG_EBS |
+ IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
+ IWM_SCAN_CHANNEL_FLAG_CACHE_ADD;
+
+ req->general_flags = htole16(general_flags);
req->ooc_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
- nssid = MIN(ss->ss_nssid, IWM_PROBE_OPTION_MAX);
- req->n_channels = iwm_mvm_umac_scan_fill_channels(sc,
- (struct iwm_scan_channel_cfg_umac *)req->data, nssid);
+ /* These timings correspond to iwlwifi's UNASSOC scan. */
+ if (iwm_fw_has_api(sc, IWM_UCODE_TLV_API_ADAPTIVE_DWELL)) {
+ req->v7.active_dwell = 10;
+ req->v7.passive_dwell = 110;
+ req->v7.fragmented_dwell = 44;
+ req->v7.adwell_default_n_aps_social = 10;
+ req->v7.adwell_default_n_aps = 2;
+ req->v7.adwell_max_budget = htole16(300);
+ req->v7.scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
+ req->v7.channel.flags = channel_flags;
+ req->v7.channel.count = iwm_mvm_umac_scan_fill_channels(sc,
+ (struct iwm_scan_channel_cfg_umac *)req->v7.data, nssid);
- 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 = (void *)((char *)&req->v7.data +
+ sizeof(struct iwm_scan_channel_cfg_umac) *
+ sc->sc_fw.ucode_capa.n_scan_channels);
+ } else {
+ req->v1.active_dwell = 10;
+ req->v1.passive_dwell = 110;
+ req->v1.fragmented_dwell = 44;
+ req->v1.extended_dwell = 90;
+ req->v1.scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
+ req->v1.channel.flags = channel_flags;
+ req->v1.channel.count = iwm_mvm_umac_scan_fill_channels(sc,
+ (struct iwm_scan_channel_cfg_umac *)req->v1.data, nssid);
- tail = (void *)((char *)&req->data +
- sizeof(struct iwm_scan_channel_cfg_umac) *
- sc->sc_fw.ucode_capa.n_scan_channels);
+ tail = (void *)((char *)&req->v1.data +
+ sizeof(struct iwm_scan_channel_cfg_umac) *
+ sc->sc_fw.ucode_capa.n_scan_channels);
+ }
/* Check if we're doing an active directed scan. */
for (i = 0; i < nssid; i++) {
@@ -643,21 +694,7 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
tail->direct_scan[i].len);
/* XXX debug */
}
- if (nssid != 0) {
- req->general_flags |=
- htole32(IWM_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT);
- } else
- req->general_flags |= htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASSIVE);
- if (iwm_mvm_scan_use_ebs(sc))
- req->channel_flags = IWM_SCAN_CHANNEL_FLAG_EBS |
- IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
- IWM_SCAN_CHANNEL_FLAG_CACHE_ADD;
-
- if (iwm_mvm_rrm_scan_needed(sc))
- req->general_flags |=
- htole32(IWM_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED);
-
ret = iwm_mvm_fill_probe_req(sc, &tail->preq);
if (ret) {
free(req, M_DEVBUF);
@@ -694,9 +731,7 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
"Handling ieee80211 scan request\n");
- req_len = sizeof(struct iwm_scan_req_lmac) +
- (sizeof(struct iwm_scan_channel_cfg_lmac) *
- sc->sc_fw.ucode_capa.n_scan_channels) + sizeof(struct iwm_scan_probe_req);
+ req_len = iwm_mvm_scan_size(sc);
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
return ENOMEM;
req = malloc(req_len, M_DEVBUF, M_NOWAIT | M_ZERO);
Modified: head/sys/dev/iwm/if_iwmreg.h
==============================================================================
--- head/sys/dev/iwm/if_iwmreg.h Thu Nov 7 23:38:49 2019 (r354514)
+++ head/sys/dev/iwm/if_iwmreg.h Thu Nov 7 23:39:04 2019 (r354515)
@@ -5488,21 +5488,44 @@ struct iwm_scan_req_umac_tail {
} __packed;
/**
+ * struct iwm_scan_uma_chan_param
+ * @flags: channel flags &enum iwm_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;
+
+/**
* 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
+ * @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
+ * @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 iwl_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
*/
@@ -5510,21 +5533,40 @@ struct iwm_scan_req_umac {
uint32_t flags;
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;
+ 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;
+ };
+} __packed;
+
+#define IWM_SCAN_REQ_UMAC_SIZE_V7 48
+#define IWM_SCAN_REQ_UMAC_SIZE_V1 36
/**
* struct iwm_umac_scan_abort
More information about the svn-src-all
mailing list