Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Nov 2019 23:39:04 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354515 - head/sys/dev/iwm
Message-ID:  <201911072339.xA7Nd4bv074524@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911072339.xA7Nd4bv074524>