[iwm] Enable Energy Based Scan (EBS).
This can significantly reduce scan duration thus saving time and power. EBS failure reported by FW disables EBS for current connection. It is re-enabled upon new connection attempt on any WLAN interface. Obtained from: dragonflybsd.git 89f579e9823a5c446ca172cf82bbc210d6a054a4
This commit is contained in:
parent
5f00681c7d
commit
cd20383e4a
@ -4518,6 +4518,11 @@ iwm_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
||||
break;
|
||||
|
||||
case IEEE80211_S_ASSOC:
|
||||
/*
|
||||
* EBS may be disabled due to previous failures reported by FW.
|
||||
* Reset EBS status here assuming environment has been changed.
|
||||
*/
|
||||
sc->last_ebs_successful = TRUE;
|
||||
if ((error = iwm_assoc(vap, sc)) != 0) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: failed to associate: %d\n", __func__,
|
||||
@ -5525,36 +5530,27 @@ iwm_notif_intr(struct iwm_softc *sc)
|
||||
case IWM_INIT_COMPLETE_NOTIF:
|
||||
break;
|
||||
|
||||
case IWM_SCAN_OFFLOAD_COMPLETE: {
|
||||
struct iwm_periodic_scan_complete *notif;
|
||||
notif = (void *)pkt->data;
|
||||
case IWM_SCAN_OFFLOAD_COMPLETE:
|
||||
iwm_mvm_rx_lmac_scan_complete_notif(sc, pkt);
|
||||
if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) {
|
||||
sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING;
|
||||
ieee80211_runtask(ic, &sc->sc_es_task);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IWM_SCAN_ITERATION_COMPLETE: {
|
||||
struct iwm_lmac_scan_complete_notif *notif;
|
||||
notif = (void *)pkt->data;
|
||||
ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case IWM_SCAN_COMPLETE_UMAC: {
|
||||
struct iwm_umac_scan_complete *notif;
|
||||
notif = (void *)pkt->data;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"UMAC scan complete, status=0x%x\n",
|
||||
notif->status);
|
||||
case IWM_SCAN_COMPLETE_UMAC:
|
||||
iwm_mvm_rx_umac_scan_complete_notif(sc, pkt);
|
||||
if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) {
|
||||
sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING;
|
||||
ieee80211_runtask(ic, &sc->sc_es_task);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IWM_SCAN_ITERATION_COMPLETE_UMAC: {
|
||||
struct iwm_umac_scan_iter_complete_notif *notif;
|
||||
@ -5563,7 +5559,6 @@ iwm_notif_intr(struct iwm_softc *sc)
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "UMAC scan iteration "
|
||||
"complete, status=0x%x, %d channels scanned\n",
|
||||
notif->status, notif->scanned_channels);
|
||||
ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5967,6 +5962,9 @@ iwm_attach(device_t dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Set EBS as successful as long as not stated otherwise by the FW. */
|
||||
sc->last_ebs_successful = TRUE;
|
||||
|
||||
/* PCI attach */
|
||||
error = iwm_pci_attach(dev);
|
||||
if (error != 0)
|
||||
|
@ -161,6 +161,9 @@ __FBSDID("$FreeBSD$");
|
||||
* BEGIN mvm/scan.c
|
||||
*/
|
||||
|
||||
#define IWM_DENSE_EBS_SCAN_RATIO 5
|
||||
#define IWM_SPARSE_EBS_SCAN_RATIO 1
|
||||
|
||||
static uint16_t
|
||||
iwm_mvm_scan_rx_chain(struct iwm_softc *sc)
|
||||
{
|
||||
@ -198,6 +201,67 @@ iwm_mvm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
|
||||
return htole32(IWM_RATE_6M_PLCP | tx_ant);
|
||||
}
|
||||
|
||||
static const char *
|
||||
iwm_mvm_ebs_status_str(enum iwm_scan_ebs_status status)
|
||||
{
|
||||
switch (status) {
|
||||
case IWM_SCAN_EBS_SUCCESS:
|
||||
return "successful";
|
||||
case IWM_SCAN_EBS_INACTIVE:
|
||||
return "inactive";
|
||||
case IWM_SCAN_EBS_FAILED:
|
||||
case IWM_SCAN_EBS_CHAN_NOT_FOUND:
|
||||
default:
|
||||
return "failed";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iwm_mvm_rx_lmac_scan_complete_notif(struct iwm_softc *sc,
|
||||
struct iwm_rx_packet *pkt)
|
||||
{
|
||||
struct iwm_periodic_scan_complete *scan_notif = (void *)pkt->data;
|
||||
boolean_t aborted = (scan_notif->status == IWM_SCAN_OFFLOAD_ABORTED);
|
||||
|
||||
/* If this happens, the firmware has mistakenly sent an LMAC
|
||||
* notification during UMAC scans -- warn and ignore it.
|
||||
*/
|
||||
if (fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: Mistakenly got LMAC notification during UMAC scan\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Regular scan %s, EBS status %s (FW)\n",
|
||||
aborted ? "aborted" : "completed",
|
||||
iwm_mvm_ebs_status_str(scan_notif->ebs_status));
|
||||
|
||||
sc->last_ebs_successful =
|
||||
scan_notif->ebs_status == IWM_SCAN_EBS_SUCCESS ||
|
||||
scan_notif->ebs_status == IWM_SCAN_EBS_INACTIVE;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
iwm_mvm_rx_umac_scan_complete_notif(struct iwm_softc *sc,
|
||||
struct iwm_rx_packet *pkt)
|
||||
{
|
||||
struct iwm_umac_scan_complete *notif = (void *)pkt->data;
|
||||
uint32_t uid = le32toh(notif->uid);
|
||||
boolean_t aborted = (notif->status == IWM_SCAN_OFFLOAD_ABORTED);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"Scan completed, uid %u, status %s, EBS status %s\n",
|
||||
uid,
|
||||
aborted ? "aborted" : "completed",
|
||||
iwm_mvm_ebs_status_str(notif->ebs_status));
|
||||
|
||||
if (notif->ebs_status != IWM_SCAN_EBS_SUCCESS &&
|
||||
notif->ebs_status != IWM_SCAN_EBS_INACTIVE)
|
||||
sc->last_ebs_successful = FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_mvm_scan_skip_channel(struct ieee80211_channel *c)
|
||||
{
|
||||
@ -480,6 +544,21 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
iwm_mvm_scan_use_ebs(struct iwm_softc *sc)
|
||||
{
|
||||
const struct iwm_ucode_capabilities *capa = &sc->ucode_capa;
|
||||
|
||||
/* We can only use EBS if:
|
||||
* 1. the feature is supported;
|
||||
* 2. the last EBS was successful;
|
||||
* 3. if only single scan, the single scan EBS API is supported;
|
||||
* 4. it's not a p2p find operation.
|
||||
*/
|
||||
return ((capa->flags & IWM_UCODE_TLV_FLAGS_EBS_SUPPORT) &&
|
||||
sc->last_ebs_successful);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_mvm_umac_scan(struct iwm_softc *sc)
|
||||
{
|
||||
@ -549,6 +628,11 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
|
||||
} 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 (fw_has_capa(&sc->ucode_capa,
|
||||
IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT))
|
||||
req->general_flags |=
|
||||
@ -674,9 +758,20 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
|
||||
req->schedule[0].iterations = 1;
|
||||
req->schedule[0].full_scan_mul = 1;
|
||||
|
||||
/* Disable EBS. */
|
||||
req->channel_opt[0].non_ebs_ratio = 1;
|
||||
req->channel_opt[1].non_ebs_ratio = 1;
|
||||
if (iwm_mvm_scan_use_ebs(sc)) {
|
||||
req->channel_opt[0].flags =
|
||||
htole16(IWM_SCAN_CHANNEL_FLAG_EBS |
|
||||
IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
|
||||
IWM_SCAN_CHANNEL_FLAG_CACHE_ADD);
|
||||
req->channel_opt[0].non_ebs_ratio =
|
||||
htole16(IWM_DENSE_EBS_SCAN_RATIO);
|
||||
req->channel_opt[1].flags =
|
||||
htole16(IWM_SCAN_CHANNEL_FLAG_EBS |
|
||||
IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
|
||||
IWM_SCAN_CHANNEL_FLAG_CACHE_ADD);
|
||||
req->channel_opt[1].non_ebs_ratio =
|
||||
htole16(IWM_SPARSE_EBS_SCAN_RATIO);
|
||||
}
|
||||
|
||||
ret = iwm_send_cmd(sc, &hcmd);
|
||||
if (!ret) {
|
||||
|
@ -106,9 +106,13 @@
|
||||
#ifndef __IF_IWN_SCAN_H__
|
||||
#define __IF_IWN_SCAN_H__
|
||||
|
||||
extern int iwm_mvm_lmac_scan(struct iwm_softc *sc);
|
||||
extern int iwm_mvm_lmac_scan(struct iwm_softc *);
|
||||
extern int iwm_mvm_config_umac_scan(struct iwm_softc *);
|
||||
extern int iwm_mvm_umac_scan(struct iwm_softc *);
|
||||
extern int iwm_mvm_scan_stop_wait(struct iwm_softc *sc);
|
||||
extern int iwm_mvm_scan_stop_wait(struct iwm_softc *);
|
||||
extern void iwm_mvm_rx_lmac_scan_complete_notif(struct iwm_softc *,
|
||||
struct iwm_rx_packet *);
|
||||
extern void iwm_mvm_rx_umac_scan_complete_notif(struct iwm_softc *,
|
||||
struct iwm_rx_packet *);
|
||||
|
||||
#endif /* __IF_IWN_SCAN_H__ */
|
||||
|
@ -5076,6 +5076,13 @@ enum iwm_scan_offload_complete_status {
|
||||
IWM_SCAN_OFFLOAD_ABORTED = 2,
|
||||
};
|
||||
|
||||
enum iwm_scan_ebs_status {
|
||||
IWM_SCAN_EBS_SUCCESS,
|
||||
IWM_SCAN_EBS_FAILED,
|
||||
IWM_SCAN_EBS_CHAN_NOT_FOUND,
|
||||
IWM_SCAN_EBS_INACTIVE,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_lmac_scan_complete_notif - notifies end of scanning (all channels)
|
||||
* SCAN_COMPLETE_NTF_API_S_VER_3
|
||||
|
@ -536,6 +536,8 @@ struct iwm_softc {
|
||||
struct iwm_fw_paging fw_paging_db[IWM_NUM_OF_FW_PAGING_BLOCKS];
|
||||
uint16_t num_of_paging_blk;
|
||||
uint16_t num_of_pages_in_last_blk;
|
||||
|
||||
boolean_t last_ebs_successful;
|
||||
};
|
||||
|
||||
#define IWM_LOCK_INIT(_sc) \
|
||||
|
Loading…
x
Reference in New Issue
Block a user