Re: iwm: initial 40Mhz channel support

2021-10-09 Thread Matthias Schmidt
Hi Stefan,

* Stefan Sperling wrote:
> This patch adds initial support for 40Mhz channels to the iwm driver.
> 
> There are a few changes in net80211 to support this feature in RA and
> when parsing beacons. The work for net80211 is not yet complete but
> more can be done incrementally later. What is missing in particular
> is integration with ifconfig to display the use of a 40 MHz channel.
> 
> And there is no way to force 40 MHz off at the client side yet.
> If the AP announces support for 40MHz we will always use it. Whether or
> not we'll need an override to handle some edge case remains to be seen.
> 
> Please test this on any supported iwm(4) device. Thanks!

Running this diff on

iwm0 at pci2 dev 0 function 0 "Intel Dual Band Wireless-AC 8265" rev 0x78, msi
iwm0: hw rev 0x230, fw ver 36.ca7b901d.0, address 7c:2a:31:4d:1c:b9

and noticed no regression so far.  I checked with

tcpdump -n -i iwm0 -v -y IEEE802_11_RADIO -s 4096 type mgt and subtype beacon

and I am on a 20MHz channel.  According to my Fritzbox all 2.4Ghz
clients are on 20Mhz and the 11ac clients are on 80Mhz.

Cheers

Matthias



iwm: initial 40Mhz channel support

2021-10-07 Thread Stefan Sperling
This patch adds initial support for 40Mhz channels to the iwm driver.

There are a few changes in net80211 to support this feature in RA and
when parsing beacons. The work for net80211 is not yet complete but
more can be done incrementally later. What is missing in particular
is integration with ifconfig to display the use of a 40 MHz channel.

And there is no way to force 40 MHz off at the client side yet.
If the AP announces support for 40MHz we will always use it. Whether or
not we'll need an override to handle some edge case remains to be seen.

Please test this on any supported iwm(4) device. Thanks!

diff 4056ab6b22f0b2cb4f14b2b237355717bf154e4f refs/heads/40mhz
blob - fbf2059a1571c2c55b40fce5ffd7d145ab6b1f21
blob + 3bf02ee0969978149c20498a469c1a2dcf4d7177
--- sys/dev/ic/ar5008.c
+++ sys/dev/ic/ar5008.c
@@ -1150,7 +1150,7 @@ ar5008_tx_process(struct athn_softc *sc, int qid)
/* Update rate control statistics. */
if ((ni->ni_flags & IEEE80211_NODE_HT) && ic->ic_fixed_mcs == -1) {
const struct ieee80211_ht_rateset *rs =
-   ieee80211_ra_get_ht_rateset(bf->bf_txmcs,
+   ieee80211_ra_get_ht_rateset(bf->bf_txmcs, 0 /* chan40 */,
ieee80211_node_supports_ht_sgi20(ni));
unsigned int retries = 0, i;
int mcs = bf->bf_txmcs;
blob - 6a145720d3070bd0c1eabae1bedddb5da8fb72a2
blob + 687cbf94f135f6586193b1724e52b80e7f16a529
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -335,9 +335,11 @@ void   iwm_init_channel_map(struct iwm_softc *, const 
ui
 intiwm_mimo_enabled(struct iwm_softc *);
 void   iwm_setup_ht_rates(struct iwm_softc *);
 void   iwm_mac_ctxt_task(void *);
+void   iwm_phy_ctxt_task(void *);
 void   iwm_updateprot(struct ieee80211com *);
 void   iwm_updateslot(struct ieee80211com *);
 void   iwm_updateedca(struct ieee80211com *);
+void   iwm_updatechan(struct ieee80211com *);
 void   iwm_init_reorder_buffer(struct iwm_reorder_buffer *, uint16_t,
uint16_t);
 void   iwm_clear_reorder_buffer(struct iwm_softc *, struct iwm_rxba_data *);
@@ -408,13 +410,13 @@ void  iwm_rx_bmiss(struct iwm_softc *, struct 
iwm_rx_pa
struct iwm_rx_data *);
 intiwm_binding_cmd(struct iwm_softc *, struct iwm_node *, uint32_t);
 intiwm_phy_ctxt_cmd_uhb(struct iwm_softc *, struct iwm_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint32_t);
+   uint8_t, uint32_t, uint32_t, uint8_t);
 void   iwm_phy_ctxt_cmd_hdr(struct iwm_softc *, struct iwm_phy_ctxt *,
struct iwm_phy_context_cmd *, uint32_t, uint32_t);
 void   iwm_phy_ctxt_cmd_data(struct iwm_softc *, struct iwm_phy_context_cmd *,
-   struct ieee80211_channel *, uint8_t, uint8_t);
+   struct ieee80211_channel *, uint8_t, uint8_t, uint8_t);
 intiwm_phy_ctxt_cmd(struct iwm_softc *, struct iwm_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint32_t);
+   uint8_t, uint32_t, uint32_t, uint8_t);
 intiwm_send_cmd(struct iwm_softc *, struct iwm_host_cmd *);
 intiwm_send_cmd_pdu(struct iwm_softc *, uint32_t, uint32_t, uint16_t,
const void *);
@@ -479,7 +481,7 @@ int iwm_umac_scan_abort(struct iwm_softc *);
 intiwm_lmac_scan_abort(struct iwm_softc *);
 intiwm_scan_abort(struct iwm_softc *);
 intiwm_phy_ctxt_update(struct iwm_softc *, struct iwm_phy_ctxt *,
-   struct ieee80211_channel *, uint8_t, uint8_t, uint32_t);
+   struct ieee80211_channel *, uint8_t, uint8_t, uint32_t, uint8_t);
 intiwm_auth(struct iwm_softc *);
 intiwm_deauth(struct iwm_softc *);
 intiwm_run(struct iwm_softc *);
@@ -3075,8 +3077,11 @@ iwm_init_channel_map(struct iwm_softc *sc, const uint1
if (!(ch_flags & IWM_NVM_CHANNEL_ACTIVE))
channel->ic_flags |= IEEE80211_CHAN_PASSIVE;
 
-   if (data->sku_cap_11n_enable)
+   if (data->sku_cap_11n_enable) {
channel->ic_flags |= IEEE80211_CHAN_HT;
+   if (ch_flags & IWM_NVM_CHANNEL_40MHZ)
+   channel->ic_flags |= IEEE80211_CHAN_40MHZ;
+   }
}
 }
 
@@ -3409,6 +3414,51 @@ iwm_updateedca(struct ieee80211com *ic)
iwm_add_task(sc, systq, >mac_ctxt_task);
 }
 
+void
+iwm_phy_ctxt_task(void *arg)
+{
+   struct iwm_softc *sc = arg;
+   struct ieee80211com *ic = >sc_ic;
+   struct iwm_node *in = (void *)ic->ic_bss;
+   struct ieee80211_node *ni = >in_ni;
+   uint8_t chains, sco;
+   int err, s = splnet();
+
+   if ((sc->sc_flags & IWM_FLAG_SHUTDOWN) ||
+   ic->ic_state != IEEE80211_S_RUN ||
+   in->in_phyctxt == NULL) {
+   refcnt_rele_wake(>task_refs);
+   splx(s);
+   return;
+   }
+
+   chains = iwm_mimo_enabled(sc) ? 2 : 1;
+   if (ieee80211_node_supports_ht_chan40(ni))
+   sco = (ni->ni_htop0 & IEEE80211_HTOP0_SCO_MASK);
+   else
+