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-head mailing list