Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: sys/qwz: add 802.11n with 40Mhz width
To:
tech@openbsd.org
Date:
Tue, 26 May 2026 15:42:28 +0200

Download raw body.

Thread
On Tue, May 26, 2026 at 11:50:30AM +0200, Kirill A. Korinsky wrote:
> Here clean diff. Ok to commit?

ok by me, thanks!

> Index: sys/dev/ic/qwz.c
> ===================================================================
> RCS file: /home/cvs/src/sys/dev/ic/qwz.c,v
> diff -u -p -r1.36 qwz.c
> --- sys/dev/ic/qwz.c	25 May 2026 20:33:58 -0000	1.36
> +++ sys/dev/ic/qwz.c	26 May 2026 09:48:40 -0000
> @@ -10874,6 +10874,7 @@ qwz_init_channels_world(struct qwz_softc
>  			    IEEE80211_CHAN_OFDM |
>  			    IEEE80211_CHAN_DYN |
>  			    IEEE80211_CHAN_2GHZ |
> +			    IEEE80211_CHAN_40MHZ |
>  			    IEEE80211_CHAN_HT;
>  		}
>  	}
> @@ -10884,6 +10885,7 @@ qwz_init_channels_world(struct qwz_softc
>  			chan->ic_freq = ieee80211_ieee2mhz(channels_5ghz[i],
>  			    IEEE80211_CHAN_5GHZ);
>  			chan->ic_flags = IEEE80211_CHAN_A |
> +			    IEEE80211_CHAN_40MHZ |
>  			    IEEE80211_CHAN_HT |
>  			    IEEE80211_CHAN_PASSIVE;
>  		}
> @@ -10931,6 +10933,9 @@ qwz_init_channels(struct qwz_softc *sc, 
>  				    IEEE80211_CHAN_DYN |
>  				    IEEE80211_CHAN_2GHZ |
>  				    IEEE80211_CHAN_HT;
> +				if ((rule->flags & REGULATORY_CHAN_NO_HT40) == 0)
> +					chan->ic_flags |=
> +					    IEEE80211_CHAN_40MHZ;
>  			}
>  			chnum++;
>  			freq = ieee80211_ieee2mhz(chnum, IEEE80211_CHAN_2GHZ);
> @@ -10966,6 +10971,9 @@ qwz_init_channels(struct qwz_softc *sc, 
>  				chan->ic_freq = freq;
>  				chan->ic_flags = IEEE80211_CHAN_A |
>  				    IEEE80211_CHAN_HT;
> +				if ((rule->flags & REGULATORY_CHAN_NO_HT40) == 0)
> +					chan->ic_flags |=
> +					    IEEE80211_CHAN_40MHZ;
>  				if (rule->flags & (REGULATORY_CHAN_RADAR |
>  				    REGULATORY_CHAN_NO_IR |
>  				    REGULATORY_CHAN_INDOOR_ONLY)) {
> @@ -21614,6 +21622,7 @@ qwz_mac_vdev_start_restart(struct qwz_so
>  	struct ieee80211com *ic = &sc->sc_ic;
>  	struct ieee80211_channel *chan = ic->ic_bss->ni_chan;
>  	struct wmi_vdev_start_req_arg arg = {};
> +	uint8_t sco = IEEE80211_HTOP0_SCO_SCN;
>  	int ret = 0;
>  #ifdef notyet
>  	lockdep_assert_held(&ar->conf_mutex);
> @@ -21629,7 +21638,25 @@ qwz_mac_vdev_start_restart(struct qwz_so
>  	arg.channel.band_center_freq1 = chan->ic_freq;
>  	arg.channel.band_center_freq2 = chan->ic_freq;
>  
> -	if (IEEE80211_IS_CHAN_5GHZ(chan))
> +	if (ieee80211_node_supports_ht(ic->ic_bss) &&
> +	    (chan->ic_flags & IEEE80211_CHAN_HT)) {
> +		arg.channel.allow_ht = true;
> +		if (IEEE80211_CHAN_40MHZ_ALLOWED(chan) &&
> +		    ieee80211_node_supports_ht_chan40(ic->ic_bss))
> +			sco = ic->ic_bss->ni_htop0 &
> +			    IEEE80211_HTOP0_SCO_MASK;
> +		if (sco == IEEE80211_HTOP0_SCO_SCA) {
> +			arg.channel.band_center_freq1 = chan->ic_freq + 10;
> +			arg.channel.mode = IEEE80211_IS_CHAN_5GHZ(chan) ?
> +			    MODE_11NA_HT40 : MODE_11NG_HT40;
> +		} else if (sco == IEEE80211_HTOP0_SCO_SCB) {
> +			arg.channel.band_center_freq1 = chan->ic_freq - 10;
> +			arg.channel.mode = IEEE80211_IS_CHAN_5GHZ(chan) ?
> +			    MODE_11NA_HT40 : MODE_11NG_HT40;
> +		} else
> +			arg.channel.mode = IEEE80211_IS_CHAN_5GHZ(chan) ?
> +			    MODE_11NA_HT20 : MODE_11NG_HT20;
> +	} else if (IEEE80211_IS_CHAN_5GHZ(chan))
>  		arg.channel.mode = MODE_11A;
>  	else if (ic->ic_bss->ni_flags & IEEE80211_NODE_ERP)
>  		arg.channel.mode = MODE_11G;
> @@ -24271,6 +24298,7 @@ qwz_peer_assoc_h_phymode(struct qwz_soft
>  {
>  	struct ieee80211com *ic = &sc->sc_ic;
>  	enum wmi_phy_mode phymode;
> +	uint8_t sco;
>  
>  	switch (ic->ic_curmode) {
>  	case IEEE80211_MODE_11A:
> @@ -24283,10 +24311,17 @@ qwz_peer_assoc_h_phymode(struct qwz_soft
>  		phymode = MODE_11G;
>  		break;
>  	case IEEE80211_MODE_11N:
> -		if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan))
> -			phymode = MODE_11NA_HT20;
> +		sco = IEEE80211_HTOP0_SCO_SCN;
> +		if (IEEE80211_CHAN_40MHZ_ALLOWED(ni->ni_chan) &&
> +		    ieee80211_node_supports_ht_chan40(ni))
> +			sco = ni->ni_htop0 & IEEE80211_HTOP0_SCO_MASK;
> +		if (sco == IEEE80211_HTOP0_SCO_SCA ||
> +		    sco == IEEE80211_HTOP0_SCO_SCB)
> +			phymode = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ?
> +			    MODE_11NA_HT40 : MODE_11NG_HT40;
>  		else
> -			phymode = MODE_11NG_HT20;
> +			phymode = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ?
> +			    MODE_11NA_HT20 : MODE_11NG_HT20;
>  		break;
>  	default:
>  		phymode = MODE_UNKNOWN;
> @@ -24328,7 +24363,7 @@ qwz_peer_assoc_h_ht(struct qwz_softc *sc
>  {
>  	struct ieee80211com *ic = &sc->sc_ic;
>  	int i, n;
> -	uint8_t max_nss;
> +	uint8_t max_nss, sco;
>  	uint32_t stbc, aggsize, mpdu_density;
>  #ifdef notyet
>  	lockdep_assert_held(&ar->conf_mutex);
> @@ -24336,6 +24371,11 @@ qwz_peer_assoc_h_ht(struct qwz_softc *sc
>  	if ((ni->ni_flags & IEEE80211_NODE_HT) == 0)
>  		return;
>  
> +	sco = IEEE80211_HTOP0_SCO_SCN;
> +	if (IEEE80211_CHAN_40MHZ_ALLOWED(ni->ni_chan) &&
> +	    ieee80211_node_supports_ht_chan40(ni))
> +		sco = ni->ni_htop0 & IEEE80211_HTOP0_SCO_MASK;
> +
>  	arg->ht_flag = true;
>  
>  	aggsize = (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_LE);
> @@ -24349,12 +24389,11 @@ qwz_peer_assoc_h_ht(struct qwz_softc *sc
>  
>  	if (ni->ni_htcaps & IEEE80211_HTCAP_LDPC)
>  		arg->ldpc_flag = true;
> -#if 0
> -	if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) {
> +	if (sco == IEEE80211_HTOP0_SCO_SCA ||
> +	    sco == IEEE80211_HTOP0_SCO_SCB) {
>  		arg->bw_40 = true;
>  		arg->peer_rate_caps |= WMI_HOST_RC_CW40_FLAG;
>  	}
> -#endif
>  	if (ieee80211_node_supports_ht_sgi20(ni) ||
>  	    ieee80211_node_supports_ht_sgi40(ni))
>  		arg->peer_rate_caps |= WMI_HOST_RC_SGI_FLAG;
> Index: sys/dev/ic/qwzreg.h
> ===================================================================
> RCS file: /home/cvs/src/sys/dev/ic/qwzreg.h,v
> diff -u -p -r1.15 qwzreg.h
> --- sys/dev/ic/qwzreg.h	18 May 2026 13:47:32 -0000	1.15
> +++ sys/dev/ic/qwzreg.h	26 May 2026 09:48:40 -0000
> @@ -13252,6 +13252,7 @@ struct htt_rx_full_monitor_mode_cfg_cmd 
>  } __packed;
>  
>  #define WMI_HOST_RC_DS_FLAG			0x01
> +#define WMI_HOST_RC_CW40_FLAG			0x02
>  #define WMI_HOST_RC_SGI_FLAG			0x04
>  #define WMI_HOST_RC_HT_FLAG			0x08
>  #define WMI_HOST_RC_TX_STBC_FLAG		0x20
> Index: sys/dev/pci/if_qwz_pci.c
> ===================================================================
> RCS file: /home/cvs/src/sys/dev/pci/if_qwz_pci.c,v
> diff -u -p -r1.11 if_qwz_pci.c
> --- sys/dev/pci/if_qwz_pci.c	18 May 2026 13:47:32 -0000	1.11
> +++ sys/dev/pci/if_qwz_pci.c	26 May 2026 09:48:40 -0000
> @@ -969,8 +969,8 @@ qwz_pci_attach(struct device *parent, st
>  	ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
>  	ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
>  
> -	ic->ic_htcaps = IEEE80211_HTCAP_SGI20 | IEEE80211_HTCAP_AMSDU7935;
> -	ic->ic_htcaps |=
> +	ic->ic_htcaps = IEEE80211_HTCAP_SGI20 | IEEE80211_HTCAP_SGI40 |
> +	    IEEE80211_HTCAP_CBW20_40 | IEEE80211_HTCAP_AMSDU7935 |
>  	    (IEEE80211_HTCAP_SMPS_DIS << IEEE80211_HTCAP_SMPS_SHIFT);
>  	ic->ic_htxcaps = 0;
>  	ic->ic_txbfcaps = 0;
> 
> 
> -- 
> wbr, Kirill
> 
>