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
This commit is contained in:
parent
c513f15bf0
commit
666c8655f2
@ -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,20 +694,6 @@ 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) {
|
||||
@ -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);
|
||||
|
@ -5487,22 +5487,45 @@ struct iwm_scan_req_umac_tail {
|
||||
struct iwm_ssid_ie direct_scan[IWM_PROBE_OPTION_MAX];
|
||||
} __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
|
||||
|
Loading…
Reference in New Issue
Block a user