svn commit: r315925 - head/sys/dev/iwm
Chagin Dmitry
dchagin at freebsd.org
Sat Mar 25 10:21:55 UTC 2017
On Sat, Mar 25, 2017 at 02:49:20AM +0000, Adrian Chadd wrote:
> Author: adrian
> Date: Sat Mar 25 02:49:20 2017
> New Revision: 315925
> URL: https://svnweb.freebsd.org/changeset/base/315925
>
> Log:
> [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
>
> Modified:
> head/sys/dev/iwm/if_iwm.c
> head/sys/dev/iwm/if_iwm_scan.c
> head/sys/dev/iwm/if_iwm_scan.h
> head/sys/dev/iwm/if_iwmreg.h
> head/sys/dev/iwm/if_iwmvar.h
>
> Modified: head/sys/dev/iwm/if_iwm.c
> ==============================================================================
> --- head/sys/dev/iwm/if_iwm.c Sat Mar 25 02:44:25 2017 (r315924)
> +++ head/sys/dev/iwm/if_iwm.c Sat Mar 25 02:49:20 2017 (r315925)
> @@ -4518,6 +4518,11 @@ iwm_newstate(struct ieee80211vap *vap, e
> 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)
>
> Modified: head/sys/dev/iwm/if_iwm_scan.c
> ==============================================================================
> --- head/sys/dev/iwm/if_iwm_scan.c Sat Mar 25 02:44:25 2017 (r315924)
> +++ head/sys/dev/iwm/if_iwm_scan.c Sat Mar 25 02:49:20 2017 (r315925)
> @@ -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_sof
> 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);
> +
cc -target x86_64-unknown-freebsd12.0 --sysroot=/home/dchagin/obj/home/git/head/tmp -B/home/dchagin/obj/home/git/head/tmp/usr/bin -c -O2 -pipe -fno-strict-aliasing -g -nostdinc -I. -I/home/git/head/sys -I/home/git/head/sys/contrib/libfdt -D_KERNEL -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -MD -MF.depend.if_iwm_scan.o -MTif_iwm_scan.o -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -msoft-float -fno-asynchronous-unwind-tables -ffreestanding -fwrapv -fstack-protector -gdwarf-2 -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual -Wundef -Wno-pointer-sign -D__printf__=__freebsd_kprintf__ -Wmissing-include-dirs -fdiagnostics-show-option -Wno-unknown-pragmas -Wno-error-tautological-compare -Wno-error-empty-body -Wno-error-parentheses-equality -Wno-error-unused-function -Wno-error-pointer-sign -Wno-error-shift-negative-value -Wno-error-address-of-packed-member -mno-aes -mno-avx -std=iso9899:1999 -Werror /home/git/head/sys/dev/iwm/if_iwm_scan.c
/home/git/head/sys/dev/iwm/if_iwm_scan.c:224:12: error: unused variable 'aborted' [-Werror,-Wunused-variable]
boolean_t aborted = (scan_notif->status == IWM_SCAN_OFFLOAD_ABORTED);
^
/home/git/head/sys/dev/iwm/if_iwm_scan.c:252:12: error: unused variable 'aborted' [-Werror,-Wunused-variable]
boolean_t aborted = (notif->status == IWM_SCAN_OFFLOAD_ABORTED);
^
/home/git/head/sys/dev/iwm/if_iwm_scan.c:251:11: error: unused variable 'uid' [-Werror,-Wunused-variable]
uint32_t uid = le32toh(notif->uid);
^
3 errors generated.
> + /* 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_soft
> 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) {
>
> Modified: head/sys/dev/iwm/if_iwm_scan.h
> ==============================================================================
> --- head/sys/dev/iwm/if_iwm_scan.h Sat Mar 25 02:44:25 2017 (r315924)
> +++ head/sys/dev/iwm/if_iwm_scan.h Sat Mar 25 02:49:20 2017 (r315925)
> @@ -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__ */
>
> Modified: head/sys/dev/iwm/if_iwmreg.h
> ==============================================================================
> --- head/sys/dev/iwm/if_iwmreg.h Sat Mar 25 02:44:25 2017 (r315924)
> +++ head/sys/dev/iwm/if_iwmreg.h Sat Mar 25 02:49:20 2017 (r315925)
> @@ -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
>
> Modified: head/sys/dev/iwm/if_iwmvar.h
> ==============================================================================
> --- head/sys/dev/iwm/if_iwmvar.h Sat Mar 25 02:44:25 2017 (r315924)
> +++ head/sys/dev/iwm/if_iwmvar.h Sat Mar 25 02:49:20 2017 (r315925)
> @@ -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) \
--
More information about the svn-src-all
mailing list