Index | Thread | Search

From:
Kevin Lo <kevlo@kevlo.org>
Subject:
Re: qwx(4) with fixed phy mode
To:
tech@openbsd.org
Date:
Wed, 5 Feb 2025 11:17:48 +0800

Download raw body.

Thread
On Tue, Feb 04, 2025 at 12:23:09PM +0100, Stefan Sperling wrote:
>
> Restrict scanned channels appropriately if qwx(4) runs in a fixed phy mode.
>
> Without this change, commands such as 'ifconfig qwx0 mode 11a' have no useful
> effect. The device would still connect to APs on 2GHz channels anyway.
>
> ok?

Confirmed that after executing 'ifconfig qwx0 mode 11a', qwx(4) could
only connect to the AP using 5GHz.

ok kevlo@

> commit - 4dc45f023929908c6b4c7456ab468885368b37b2
> commit + fb733669ec08813e3c65441276e8e7b69813e81f
> blob - 898e15e1fcbb8bc77ec314660e640fccf60a93d6
> blob + 8aef383799c69da05b7e9f1236366abfeb5ffc33
> --- sys/dev/ic/qwx.c
> +++ sys/dev/ic/qwx.c
> @@ -22182,14 +22182,31 @@ qwx_reg_update_chan_list(struct qwx_softc *sc, uint8_t
>  	int num_channels = 0;
>  	size_t params_size;
>  	int ret;
> +	int scan_2ghz = 1, scan_5ghz = 1;
>  #if 0
>  	if (ar->state == ATH11K_STATE_RESTARTING)
>  		return 0;
>  #endif
> +	/*
> +	 * Scan an appropriate subset of channels if we are running
> +	 * in a fixed, user-specified phy mode.
> +	 */
> +	if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO) {
> +		if (ic->ic_curmode == IEEE80211_MODE_11A ||
> +		    ic->ic_curmode == IEEE80211_MODE_11AC)
> +			scan_2ghz = 0;
> +		if (ic->ic_curmode == IEEE80211_MODE_11B ||
> +		    ic->ic_curmode == IEEE80211_MODE_11G)
> +			scan_5ghz = 0;
> +	}
> +
>  	lastc = &ic->ic_channels[IEEE80211_CHAN_MAX];
>  	for (channel = &ic->ic_channels[1]; channel <= lastc; channel++) {
>  		if (channel->ic_flags == 0)
>  			continue;
> +		if ((!scan_2ghz && IEEE80211_IS_CHAN_2GHZ(channel)) ||
> +		    (!scan_5ghz && IEEE80211_IS_CHAN_5GHZ(channel)))
> +			continue;
>  		num_channels++;
>  	}
>
> @@ -22215,6 +22232,9 @@ qwx_reg_update_chan_list(struct qwx_softc *sc, uint8_t
>  	for (channel = &ic->ic_channels[1]; channel <= lastc; channel++) {
>  		if (channel->ic_flags == 0)
>  			continue;
> +		if ((!scan_2ghz && IEEE80211_IS_CHAN_2GHZ(channel)) ||
> +		    (!scan_5ghz && IEEE80211_IS_CHAN_5GHZ(channel)))
> +			continue;
>  #ifdef notyet
>  		/* TODO: Set to true/false based on some condition? */
>  		ch->allow_ht = true;
> @@ -24843,6 +24863,7 @@ qwx_scan(struct qwx_softc *sc)
>  	struct ieee80211_channel *chan, *lastc;
>  	int ret = 0, num_channels, i;
>  	uint32_t scan_timeout;
> +	int scan_2ghz = 1, scan_5ghz = 1;
>
>  	if (arvif == NULL) {
>  		printf("%s: no vdev found\n", sc->sc_dev.dv_xname);
> @@ -24910,11 +24931,27 @@ qwx_scan(struct qwx_softc *sc)
>  	} else
>  		arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE;
>
> +	/*
> +	 * Scan an appropriate subset of channels if we are running
> +	 * in a fixed, user-specified phy mode.
> +	 */
> +	if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO) {
> +		if (ic->ic_curmode == IEEE80211_MODE_11A ||
> +		    ic->ic_curmode == IEEE80211_MODE_11AC)
> +			scan_2ghz = 0;
> +		if (ic->ic_curmode == IEEE80211_MODE_11B ||
> +		    ic->ic_curmode == IEEE80211_MODE_11G)
> +			scan_5ghz = 0;
> +	}
> +
>  	lastc = &ic->ic_channels[IEEE80211_CHAN_MAX];
>  	num_channels = 0;
>  	for (chan = &ic->ic_channels[1]; chan <= lastc; chan++) {
>  		if (chan->ic_flags == 0)
>  			continue;
> +		if ((!scan_2ghz && IEEE80211_IS_CHAN_2GHZ(chan)) ||
> +		    (!scan_5ghz && IEEE80211_IS_CHAN_5GHZ(chan)))
> +			continue;
>  		num_channels++;
>  	}
>  	if (num_channels) {
> @@ -24931,6 +24968,9 @@ qwx_scan(struct qwx_softc *sc)
>  		for (chan = &ic->ic_channels[1]; chan <= lastc; chan++) {
>  			if (chan->ic_flags == 0)
>  				continue;
> +			if ((!scan_2ghz && IEEE80211_IS_CHAN_2GHZ(chan)) ||
> +			    (!scan_5ghz && IEEE80211_IS_CHAN_5GHZ(chan)))
> +				continue;
>  			if (isset(sc->wmi.svc_map,
>  			    WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL)) {
>  				arg->chan_list[i++] = chan->ic_freq &
> @@ -24984,7 +25024,7 @@ qwx_scan(struct qwx_softc *sc)
>  		 * The current mode might have been fixed during association.
>  		 * Ensure all channels get scanned.
>  		 */
> -		if (IFM_SUBTYPE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
> +		if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
>  			ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
>  	}
>  #if 0
>