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>