Re: initial Intel Elkhart Lake Ethernet support / dwqe(4) at pci

2023-10-11 Thread Stefan Sperling
On Wed, Oct 11, 2023 at 02:05:52PM +0200, Stefan Sperling wrote:
> Anyway, here is an eephy(4) diff to enable/disable delays on the 88E1512.

That diff wasn't quite right. The register offset should be 0x21,
and Linux configures delays every time after link auto-negotiation.

I am still unsure if this change really makes sense, and I cannot
easily verify it as it makes no apparent difference to dwqe(4).
Maybe this change should wait until we really need it?

---
 add support for Tx/Rx delay settings on 881E512 to eephy(4)
 
diff 0292379527460b61efdf8c49732814a6faa13cc0 
1b3f658f3c2db79931a12fb835f5c11f8e7b170c
commit - 0292379527460b61efdf8c49732814a6faa13cc0
commit + 1b3f658f3c2db79931a12fb835f5c11f8e7b170c
blob - e33abe384313e9301fb6c3292c05ce577ffc890e
blob + c4e39265405869cc631da7120e6c8b501c59aa15
--- sys/dev/mii/eephy.c
+++ sys/dev/mii/eephy.c
@@ -303,6 +303,11 @@ eephy_service(struct mii_softc *sc, struct mii_data *m
 {
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
int bmcr;
+   /*
+* If autonegotiation is not enabled, we need a
+* software reset for the settings to take effect.
+*/
+   int sw_reset = (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO);
 
if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0)
return (ENXIO);
@@ -335,11 +340,24 @@ eephy_service(struct mii_softc *sc, struct mii_data *m
 
mii_phy_setmedia(sc);
 
-   /*
-* If autonegotiation is not enabled, we need a
-* software reset for the settings to take effect.
-*/
-   if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
+   if (sc->mii_model == MII_MODEL_MARVELL_E1512 &&
+   (sc->mii_flags & MIIF_SETDELAY)) {
+   int page, reg;
+   printf("%s: configuring Rx/Tx delay\n", __func__);
+   page = PHY_READ(sc, E1000_EADR);
+   PHY_WRITE(sc, E1000_EADR, 2);
+   reg = PHY_READ(sc, E1000_MSCR2);
+   reg &= ~E1000_MSCR2_DELAY_MASK;
+   if (sc->mii_flags & MIIF_RXID)
+   reg |= E1000_MSCR2_RXDELAY;
+   if (sc->mii_flags & MIIF_TXID)
+   reg |= E1000_MSCR2_TXDELAY;
+   PHY_WRITE(sc, E1000_MSCR2, reg);
+   PHY_WRITE(sc, E1000_EADR, page);
+   sw_reset = 1;
+   }
+
+   if (sw_reset) {
bmcr = PHY_READ(sc, E1000_CR);
PHY_WRITE(sc, E1000_CR, bmcr | E1000_CR_RESET);
}
blob - 59c6c5678987cecde898f44c77b6046a9b7b672f
blob + 41ec501cca74c9a719213c9db1c1bc23ffc31047
--- sys/dev/mii/eephyreg.h
+++ sys/dev/mii/eephyreg.h
@@ -331,3 +331,10 @@
 #define E1000_GCR1_RESET   0x8000
 #define E1000_GCR1_MODE_MASK   0x0007
 #define E1000_GCR1_MODE_SGMII  0x0001
+
+/* The following register is found only on the 88E151x Alaska PHY */
+/* Page 2 */
+#define E1000_MSCR20x21/* MAC-Specific Control Register 2 */
+#define E1000_MSCR2_RXDELAY0x20
+#define E1000_MSCR2_TXDELAY0x10
+#define E1000_MSCR2_DELAY_MASK 0x30



Re: initial Intel Elkhart Lake Ethernet support / dwqe(4) at pci

2023-10-11 Thread Stefan Sperling
On Wed, Oct 11, 2023 at 10:27:24AM +0200, Stefan Sperling wrote:
> On Tue, Oct 10, 2023 at 09:06:59PM +0200, Mark Kettenis wrote:
> > > OK for your diff. Please put it in and I'll rebase on top.
> > 
> > done
> 
> Thanks. Here is a rebased version. Re-tested with the same results.

Turns out I made a mistake when setting up the PHY type because I
misunderstood the Linux driver code.
The phy mode needs to be: sc->sc_phy_mode = DWQE_PHY_MODE_RGMII_ID;
Which means Tx/Rx delays must be enabled (which they are by default).

Anyway, here is an eephy(4) diff to enable/disable delays on the 88E1512.
We might need this eventually in any case.

See Table 110 in the Alaska 88E1510/88E1518/88E1512/88E1514 datasheet
from January 6 2022, page 106/107.

diff /usr/src
commit - 08f2ab0930d2d7a77214a2b9b2623266a5f343ac
path + /usr/src
blob - e33abe384313e9301fb6c3292c05ce577ffc890e
file + sys/dev/mii/eephy.c
--- sys/dev/mii/eephy.c
+++ sys/dev/mii/eephy.c
@@ -200,6 +200,20 @@ eephy_attach(struct device *parent, struct device *sel
PHY_WRITE(sc, E1000_GCR1, reg);
PHY_WRITE(sc, E1000_EADR, page);
}
+   
+   if (sc->mii_model == MII_MODEL_MARVELL_E1512 &&
+   (sc->mii_flags & MIIF_SETDELAY)) {
+   page = PHY_READ(sc, E1000_EADR);
+   PHY_WRITE(sc, E1000_EADR, 2);
+   reg = PHY_READ(sc, E1000_MSCR2);
+   reg &= ~E1000_MSCR2_DELAY_MASK;
+   if (sc->mii_flags & MIIF_RXID)
+   reg |= E1000_MSCR2_RXDELAY;
+   if (sc->mii_flags & MIIF_TXID)
+   reg |= E1000_MSCR2_TXDELAY;
+   PHY_WRITE(sc, E1000_MSCR2, reg);
+   PHY_WRITE(sc, E1000_EADR, page);
+   }
 
PHY_RESET(sc);
 
blob - 59c6c5678987cecde898f44c77b6046a9b7b672f
file + sys/dev/mii/eephyreg.h
--- sys/dev/mii/eephyreg.h
+++ sys/dev/mii/eephyreg.h
@@ -331,3 +331,10 @@
 #define E1000_GCR1_RESET   0x8000
 #define E1000_GCR1_MODE_MASK   0x0007
 #define E1000_GCR1_MODE_SGMII  0x0001
+
+/* The following register is found only on the 88E151x Alaska PHY */
+/* Page 2 */
+#define E1000_MSCR20x15/* MAC-Specific Control Register 2 */
+#define E1000_MSCR2_RXDELAY0x20
+#define E1000_MSCR2_TXDELAY0x10
+#define E1000_MSCR2_DELAY_MASK 0x30



Re: initial Intel Elkhart Lake Ethernet support / dwqe(4) at pci

2023-10-11 Thread Stefan Sperling
On Tue, Oct 10, 2023 at 09:06:59PM +0200, Mark Kettenis wrote:
> > OK for your diff. Please put it in and I'll rebase on top.
> 
> done

Thanks. Here is a rebased version. Re-tested with the same results.

diff refs/heads/master refs/heads/dwqe
commit - 8af2f04850cda85ea291bfaddc0e4d58c40f2935
commit + 539534a1060039a11b4c3faca5385beb016c34de
blob - c6094ca5a57d964784f56124b8d923393b1abb66
blob + cf64e8ff2018fb0ee1e7e59b29b2bc2dd281aa99
--- sys/arch/amd64/conf/GENERIC
+++ sys/arch/amd64/conf/GENERIC
@@ -556,6 +556,7 @@ lii*at pci? # Attansic L2 
Ethernet
 jme*   at pci? # JMicron JMC250/JMC260 Ethernet
 bnxt*  at pci? # Broadcom BCM573xx, BCM574xx
 ixl*   at pci? # Intel Ethernet 700 Series
+dwqe*  at pci? # Intel Elkhart Lake Ethernet
 mcx*   at pci? # Mellanox ConnectX-4
 iavf*  at pci? # Intel Ethernet Adaptive VF
 aq*at pci? # Aquantia aQtion Ethernet
blob - 7d260ef46054d6566ef2f81f6cf96dc8de5a5893
blob + 3d01c4f2665c86b8fe4cbb18379afaccf8ca65ac
--- sys/dev/ic/dwqe.c
+++ sys/dev/ic/dwqe.c
@@ -705,7 +705,7 @@ dwqe_up(struct dwqe_softc *sc)
 {
struct ifnet *ifp = >sc_ac.ac_if;
struct dwqe_buf *txb, *rxb;
-   uint32_t mode, reg, tqs, rqs;
+   uint32_t mode, reg, fifosz, tqs, rqs;
int i;
 
/* Allocate Tx descriptor ring. */
@@ -793,9 +793,21 @@ dwqe_up(struct dwqe_softc *sc)
mode |= GMAC_MTL_CHAN_RX_OP_MODE_RSF;
}
mode &= ~GMAC_MTL_CHAN_RX_OP_MODE_RQS_MASK;
-   rqs = (128 << GMAC_MAC_HW_FEATURE1_RXFIFOSIZE(sc->sc_hw_feature[1]) /
-   256) - 1;
-   mode |= rqs << GMAC_MTL_CHAN_RX_OP_MODE_RQS_SHIFT;
+   if (sc->sc_rxfifo_size)
+   fifosz = sc->sc_rxfifo_size;
+   else
+   fifosz = (128 <<
+   GMAC_MAC_HW_FEATURE1_RXFIFOSIZE(sc->sc_hw_feature[1]));
+   rqs = fifosz / 256 - 1;
+   mode |= (rqs << GMAC_MTL_CHAN_RX_OP_MODE_RQS_SHIFT) &
+  GMAC_MTL_CHAN_RX_OP_MODE_RQS_MASK;
+   if (fifosz >= 4096) {
+   mode |= GMAC_MTL_CHAN_RX_OP_MODE_EHFC; 
+   mode &= ~GMAC_MTL_CHAN_RX_OP_MODE_RFD_MASK;
+   mode |= 0x3 << GMAC_MTL_CHAN_RX_OP_MODE_RFD_SHIFT;
+   mode &= ~GMAC_MTL_CHAN_RX_OP_MODE_RFA_MASK;
+   mode |= 0x1 << GMAC_MTL_CHAN_RX_OP_MODE_RFA_SHIFT;
+   }
dwqe_write(sc, GMAC_MTL_CHAN_RX_OP_MODE(0), mode);
 
mode = dwqe_read(sc, GMAC_MTL_CHAN_TX_OP_MODE(0));
@@ -809,9 +821,14 @@ dwqe_up(struct dwqe_softc *sc)
mode &= ~GMAC_MTL_CHAN_TX_OP_MODE_TXQEN_MASK;
mode |= GMAC_MTL_CHAN_TX_OP_MODE_TXQEN;
mode &= ~GMAC_MTL_CHAN_TX_OP_MODE_TQS_MASK;
-   tqs = (128 << GMAC_MAC_HW_FEATURE1_TXFIFOSIZE(sc->sc_hw_feature[1]) /
-   256) - 1;
-   mode |= tqs << GMAC_MTL_CHAN_TX_OP_MODE_TQS_SHIFT;
+   if (sc->sc_txfifo_size)
+   fifosz = sc->sc_txfifo_size;
+   else
+   fifosz = (128 <<
+   GMAC_MAC_HW_FEATURE1_TXFIFOSIZE(sc->sc_hw_feature[1]));
+   tqs = (fifosz / 256) - 1;
+   mode |= (tqs << GMAC_MTL_CHAN_TX_OP_MODE_TQS_SHIFT) &
+   GMAC_MTL_CHAN_TX_OP_MODE_TQS_MASK;
dwqe_write(sc, GMAC_MTL_CHAN_TX_OP_MODE(0), mode);
 
reg = dwqe_read(sc, GMAC_QX_TX_FLOW_CTRL(0));
blob - 68d698a50beef00f002d986d7d24f8984c3efe0c
blob + d5ba09b005c469eec48b17dcbda6c76f277380e7
--- sys/dev/ic/dwqevar.h
+++ sys/dev/ic/dwqevar.h
@@ -97,6 +97,8 @@ struct dwqe_softc {
int sc_pbl;
int sc_txpbl;
int sc_rxpbl;
+   int sc_txfifo_size;
+   int sc_rxfifo_size;
int sc_axi_config;
int sc_lpi_en;
int sc_xit_frm;
blob - 101ed502e76987c27878712b4921cc49f7eb7f59
blob + 6868eb3591995804dbc332308c9d9629f73c269f
--- sys/dev/pci/files.pci
+++ sys/dev/pci/files.pci
@@ -363,6 +363,10 @@ device ixl: ether, ifnet, ifmedia, intrmap, stoeplitz
 attach ixl at pci
 file   dev/pci/if_ixl.cixl
 
+# Intel Elkhart Lake Ethernet
+attach dwqe at pci with dwqe_pci
+file   dev/pci/if_dwqe_pci.c   dwqe_pci
+
 # Neterion Xframe 10 Gigabit ethernet
 device xge: ether, ifnet, ifmedia
 attach xge  at pci
blob - /dev/null
blob + d157f116c025d882f1ec8df84b4c3deca3ca340f (mode 644)
--- /dev/null
+++ sys/dev/pci/if_dwqe_pci.c
@@ -0,0 +1,154 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2023 Stefan Sperling 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice

Re: bwfm(4): support scan v3

2023-10-11 Thread Stefan Sperling
On Tue, Oct 10, 2023 at 11:41:39PM +0200, Mark Kettenis wrote:
> The firmware for the BCM4388 has yet another version of the "escan"
> command.  But we can treat it the same as v2 since it just added a new
> parameter in place of some padding.  We just set that new parameter to
> zero, which doesn't change anything.
> 
> As a bonus this adds some missing htole16() calls.
> 
> This is the equivalent of:
> 
> https://github.com/AsahiLinux/linux/commit/399ef7b1cb9094c1c64e0f9ad6caa5c4d114009f
> 
> ok?

> @@ -274,8 +275,10 @@ bwfm_preinit(struct bwfm_softc *sc)
>   nmode = 0;
>   if (bwfm_fwvar_var_get_int(sc, "vhtmode", ))
>   vhtmode = 0;
> - if (bwfm_fwvar_var_get_int(sc, "scan_ver", >sc_scan_ver))
> - sc->sc_scan_ver = 0;
> + if (bwfm_fwvar_var_get_data(sc, "scan_ver", _ver,
> + sizeof(scan_ver)))
> + scan_ver.scan_ver_major = 0;
> + sc->sc_scan_ver = letoh16(scan_ver.scan_ver_major);

Perhaps check whether firmware reports a supported scan command version,
and fail or print a warning when it doesn't?
That might make future firmware upgrades a bit easier in case the vendor
changes this again.

Either way, ok by me.



Re: initial Intel Elkhart Lake Ethernet support / dwqe(4) at pci

2023-10-10 Thread Stefan Sperling
On Tue, Oct 10, 2023 at 08:41:37PM +0200, Mark Kettenis wrote:
> So the GMAC_VERSION #define is simply wrong.  We should commit the
> diff attached and drop the sc_core stuff you added below.

That means all our supported chips are GMAC4 and later? Good to know.
 
> > +   switch (PCI_PRODUCT(pa->pa_id)) {
> > +   case PCI_PRODUCT_INTEL_EHL_PSE0_RGMII_1G:
> > +   sc->sc_phy_mode = DWQE_PHY_MODE_RGMII;
> 
> This suggests that the PHY must be programmed to disable its internal
> delays.  Our eephy(4) driver doesn't do this.  That may explain the
> poor performance.  See how MIIF_SETDELAY, MIIF_RXID and MIIF_TXID are
> used in rgephy(4).
> 
> Anyway, that is a different driver, so a separate diff that can go in
> after this one.

Thanks for the hint. I will take a look.

> > +   sc->sc_txfifo_size = 4096 * 8;
> > +   sc->sc_rxfifo_size = 4096 * 8;
> 
> Makes more sense to simply use 32768 here.  Intel's data sheet says 32KB.

I will fix this and send a follow-up version soon.

OK for your diff. Please put it in and I'll rebase on top.

> Index: dev/ic/dwqereg.h
> ===
> RCS file: /cvs/src/sys/dev/ic/dwqereg.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 dwqereg.h
> --- dev/ic/dwqereg.h  16 Feb 2023 14:43:53 -  1.2
> +++ dev/ic/dwqereg.h  10 Oct 2023 18:40:19 -
> @@ -39,8 +39,6 @@
>  #define  GMAC_MAC_PACKET_FILTER_PR   (1 << 0)
>  #define GMAC_MAC_HASH_TAB_REG0   0x0010
>  #define GMAC_MAC_HASH_TAB_REG1   0x0014
> -#define GMAC_VERSION 0x0020
> -#define  GMAC_VERSION_SNPS_MASK  0xff
>  #define GMAC_INT_MASK0x003c
>  #define  GMAC_INT_MASK_LPIIM (1 << 10)
>  #define  GMAC_INT_MASK_PIM   (1 << 3)
> @@ -60,6 +58,8 @@
>  #define GMAC_INT_STATUS  0x00b0
>  #define GMAC_INT_EN  0x00b4
>  #define GMAC_MAC_1US_TIC_CTR 0x00dc
> +#define GMAC_VERSION 0x0110
> +#define  GMAC_VERSION_SNPS_MASK  0xff
>  #define GMAC_MAC_HW_FEATURE(x)   (0x011c + (x) * 0x4)
>  #define  GMAC_MAC_HW_FEATURE1_TXFIFOSIZE(x) (((x) >> 6) & 0x1f)
>  #define  GMAC_MAC_HW_FEATURE1_RXFIFOSIZE(x) (((x) >> 0) & 0x3f)
> 
> 



initial Intel Elkhart Lake Ethernet support / dwqe(4) at pci

2023-10-10 Thread Stefan Sperling
_RX_OP_MODE(0), mode);
 
mode = dwqe_read(sc, GMAC_MTL_CHAN_TX_OP_MODE(0));
@@ -809,9 +828,14 @@ dwqe_up(struct dwqe_softc *sc)
mode &= ~GMAC_MTL_CHAN_TX_OP_MODE_TXQEN_MASK;
mode |= GMAC_MTL_CHAN_TX_OP_MODE_TXQEN;
mode &= ~GMAC_MTL_CHAN_TX_OP_MODE_TQS_MASK;
-   tqs = (128 << GMAC_MAC_HW_FEATURE1_TXFIFOSIZE(sc->sc_hw_feature[1]) /
-   256) - 1;
-   mode |= tqs << GMAC_MTL_CHAN_TX_OP_MODE_TQS_SHIFT;
+   if (sc->sc_txfifo_size)
+   fifosz = sc->sc_txfifo_size;
+   else
+   fifosz = (128 <<
+   GMAC_MAC_HW_FEATURE1_TXFIFOSIZE(sc->sc_hw_feature[1]));
+   tqs = (fifosz / 256) - 1;
+   mode |= (tqs << GMAC_MTL_CHAN_TX_OP_MODE_TQS_SHIFT) &
+   GMAC_MTL_CHAN_TX_OP_MODE_TQS_MASK;
dwqe_write(sc, GMAC_MTL_CHAN_TX_OP_MODE(0), mode);
 
reg = dwqe_read(sc, GMAC_QX_TX_FLOW_CTRL(0));
blob - d35a811571a16d98ca672d17ec188111d4d92132
blob + d43c9d12b27b2f871fb7105f99a1fe99a32ec9d9
--- sys/dev/ic/dwqereg.h
+++ sys/dev/ic/dwqereg.h
@@ -41,6 +41,7 @@
 #define GMAC_MAC_HASH_TAB_REG1 0x0014
 #define GMAC_VERSION   0x0020
 #define  GMAC_VERSION_SNPS_MASK0xff
+#define GMAC4_VERSION  0x0110
 #define GMAC_INT_MASK  0x003c
 #define  GMAC_INT_MASK_LPIIM   (1 << 10)
 #define  GMAC_INT_MASK_PIM (1 << 3)
blob - 68d698a50beef00f002d986d7d24f8984c3efe0c
blob + 8d2c534793f9bfa5f2895ef5a44ec8e927d4fc00
--- sys/dev/ic/dwqevar.h
+++ sys/dev/ic/dwqevar.h
@@ -24,6 +24,11 @@ enum dwqe_phy_mode {
DWQE_PHY_MODE_RGMII_RXID,
 };
 
+enum dwqe_core {
+   DWQE_CORE_GMAC,
+   DWQE_CORE_GMAC4
+};
+
 struct dwqe_buf {
bus_dmamap_ttb_map;
struct mbuf *tb_m;
@@ -60,6 +65,7 @@ struct dwqe_softc {
int sc_link;
int sc_phyloc;
enum dwqe_phy_mode  sc_phy_mode;
+   enum dwqe_core  sc_core;
struct timeout  sc_phy_tick;
int sc_fixed_link;
 
@@ -97,6 +103,8 @@ struct dwqe_softc {
int sc_pbl;
int sc_txpbl;
int sc_rxpbl;
+   int sc_txfifo_size;
+   int sc_rxfifo_size;
int sc_axi_config;
int sc_lpi_en;
int sc_xit_frm;
blob - 101ed502e76987c27878712b4921cc49f7eb7f59
blob + 6868eb3591995804dbc332308c9d9629f73c269f
--- sys/dev/pci/files.pci
+++ sys/dev/pci/files.pci
@@ -363,6 +363,10 @@ device ixl: ether, ifnet, ifmedia, intrmap, stoeplitz
 attach ixl at pci
 file   dev/pci/if_ixl.cixl
 
+# Intel Elkhart Lake Ethernet
+attach dwqe at pci with dwqe_pci
+file   dev/pci/if_dwqe_pci.c   dwqe_pci
+
 # Neterion Xframe 10 Gigabit ethernet
 device xge: ether, ifnet, ifmedia
 attach xge  at pci
blob - /dev/null
blob + 101b5670451611858f70b95a1082442b47056600 (mode 644)
--- /dev/null
+++ sys/dev/pci/if_dwqe_pci.c
@@ -0,0 +1,155 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2023 Stefan Sperling 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Driver for the Intel Elkhart Lake ethernet controller.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#if NBPFILTER > 0
+#include 
+#endif
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+
+static const struct pci_matchid dwqe_pci_devices[] = {
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE0_RGMII_1G },
+#if 0
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE0_SGMII_1G },
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE0_SGMII_2G },
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE1_RGMII_1G },
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE1_SGMII_1G },
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE1_SGMII_2G },
+#endif
+};
+
+struct dwqe_pci_softc {
+   struct dwqe_softc   sc_sc;
+   pci_chipset_tag_t   sc_pct;
+   pcitag_tsc_pcitag;
+   bu

Re: Send international text with mail(1) - proposal and patches

2023-09-24 Thread Stefan Sperling
On Sun, Sep 24, 2023 at 07:06:35AM +0200, Walter Alejandro Iglesias wrote:
> Hi Ingo,
> 
> On Thu, Sep 21, 2023 at 03:04:24PM +0200, Ingo Schwarze wrote:
> > In general, the tool for checking the validity of UTF-8 strings
> > is a simple loop around mblen(3) if you want to report the precise
> > positions of errors found, or simply mbstowcs(3) with a NULL pwcs
> > argument if you are content with a one-bit "valid" or "invalid" answer.
> 
> Acording to mbstowcs(3):
> 
> RETURN VALUES
>   mbstowcs() returns:
> 
>   0 or positive
> The value returned is the number of elements stored in the array
> pointed to by pwcs, except for a terminating null wide character
> (if any).  If pwcs is not null and the value returned is equal
> to n, the wide-character string pointed to by pwcs is not null
> terminated.  If pwcs is a null pointer, the value returned is
> the number of elements to contain the whole string converted,
> except for a terminating null wide character.
> 
>   (size_t)-1  The array indirectly pointed to by s contains a byte
>   sequence forming invalid character.  In this case,
>   mbstowcs() sets errno to indicate the error.
> 
> ERRORS
>  mbstowcs() may cause an error in the following cases:
> 
>  [EILSEQ]  s points to the string containing invalid or
>incomplete multibyte character.
> 
> 
> To understand what mbstowcs(3) does I wrote the little test.c program
> pasted at bottom.  In the following example [a] is UTF-8 aaculte and (a)
> iso-latin aacute.
> 
> Using setlocale(LC_CTYPE, "en_US.UTF-8");
> 
>   $ cc -g -Wall test.c
>   $ echo -n arbol | a.out
>   ulen: 5
>   $ echo -n [a]rbol | a.out
>   ulen: 5
>   $ echo -n (a)rbol | a.out
>   ulen: 5

In the UTF-8 locale I can trigger an error message with your program
by sending the latin1 code for a-acute to stdin. I suppose your test
command didn't actually send latin1 to stdin for some reason?

  $ perl -e 'printf "\xe1rbol\n"' | ./a.out
  error: Illegal byte sequence

> Using setlocale(LC_CTYPE, "C");
> 
>   $ cc -g -Wall test.c
>   $ echo -n arbol | a.out
>   ulen: 5
>   $ echo -n [a]rbol | a.out
>   ulen: 6
>   $ echo -n (a)rbol | a.out
>   ulen: 7
> 
> And no error message in any case.  I don't understand in which way those
> return values let me know that the third string is invalid UTF-8.  Am I
> doing something wrong?

There is no concept of byte sequences in the C locale, bytes are bytes.
It is not possible to detect invalid UTF-8 via libc while running in the
C locale since the citrus code in libc won't even run. However, the various
ctype tests like isascii(unsigned char)c); isprint((unsigned char)c); and so
on can be used to filter or stub out non-ASCII characters, which is what
users running in the C locale would want.



Re: Send international text with mail(1) - proposal and patches

2023-09-21 Thread Stefan Sperling
On Thu, Sep 21, 2023 at 01:25:01PM +0200, Walter Alejandro Iglesias wrote:
> I corrected many of the things you pointed me, but not all.  The
> function I use to check utf8 is mine, I use it in a pair of little
> programs which I've *hardly* checked for memory leacks.  I know my
> function looks BIG :-), but I know for sure that it does the job.

We already have code in libc that does this, see the function
_citrus_utf8_ctype_mbrtowc in lib/libc/citrus/citrus_utf8.c.
Please use the libc interface if at all possible, it is best to
have just one place to fix when a UTF-8 parser bug is found.

There is also utf8_isvalid() in tmux utf8.c though you would
have to trim tmux UTF-8 code down for your narrow use case.

Your implementation lacks proper bounds checking. It accesses
s[i + 3] based purely on the contents of the input string, without
checking whether len < i + 3. Entering the while (i != len) loop with
i == len-1 and a specially crafted input string can be problematic.



Re: vmd/vmm: remove an ioctl from the vcpu hotpath, go brrr

2023-09-02 Thread Stefan Sperling
On Sat, Sep 02, 2023 at 12:59:51PM +0200, Peter Hessler wrote:
> I just upgraded to -current and didn't have this patch in for a little
> bit, and woof that was super noticable.  Still works for my big VM host.
> 
> OK

No issues here either with just one VM running for testing some
software, so mostly idle.



Re: iwx background scan fix

2023-08-30 Thread Stefan Sperling
On Wed, Aug 30, 2023 at 11:07:17PM +, Peter Stuge wrote:
> Stefan Sperling wrote:
> > "Active scan" means the device will send probe requests containing a
> > desired SSID, soliciting immediate probe responses from APs which
> > announce the desired SSID.
> 
> Does this broadcast many known SSIDs or only a single desired one?

Only the one which is displayed by ifconfig iwx0 on the ieee80211: line.



iwx background scan fix

2023-08-23 Thread Stefan Sperling
When I updated iwx to -77 firmware I made a mistake in setting up
the new version of the scan command, in the particular case of
starting a background scan.

One part of the command says that active scan should be used.
"Active scan" means the device will send probe requests containing a
desired SSID, soliciting immediate probe responses from APs which
announce the desired SSID. This avoids having to wait for the usual
periodically transmitted beacons on every scanned channel across the
supported 2GHz and 5GHz ranges, and thus saves time during the scan.

In another part of the same command we are supposed to tell the
device which SSID to scan for. The bug I spotted is that during a
background scan we do not set any of the bits which select an SSID
from the list of SSIDs the device may scan for (we only ever populate
this list with one entry, thus always set the first bit).

This patch sets the missing bit in the scan command. The device now
seems to be using probe requests during background scans as intended.
With iwx0 in debug mode I am now seeing a shorter list of APs in
/var/log/messages, which always includes APs for the desired SSID
and usually omits any unrelated APs. Roaming between APs seems to work
well in my testing and background scans seem to complete faster than
before.

There is a known fatal firmware error with SYSASSERT 0x20002806 which
sometimes triggers during background scans. I cannot tell whether this
change fixes that issue because I could never trigger the error reliably.
Today it didn't show up at all during my testing even without this fix.
But this particular firmware error is likely related.

Any additional tests? Ok?
 
diff eb1b93f95d68c8a362dbd50b0d6814511573e654 
72a06ec90bd2b911539c1fefdd1ae60a844d884e
commit - eb1b93f95d68c8a362dbd50b0d6814511573e654
commit + 72a06ec90bd2b911539c1fefdd1ae60a844d884e
blob - 26b002045aafdd90cfdfb10d3edd4ea96030ecbc
blob + 7c6e8f9620011e7cf11c41a55fce56af24fccb9d
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -425,7 +425,7 @@ voidiwx_scan_umac_fill_ch_p_v6(struct iwx_softc *,
 void   iwx_scan_umac_fill_general_p_v10(struct iwx_softc *,
struct iwx_scan_general_params_v10 *, uint16_t, int);
 void   iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *,
-   struct iwx_scan_channel_params_v6 *, uint32_t, int, int);
+   struct iwx_scan_channel_params_v6 *, uint32_t, int);
 intiwx_umac_scan_v14(struct iwx_softc *, int);
 void   iwx_mcc_update(struct iwx_softc *, struct iwx_mcc_chub_notif *);
 uint8_tiwx_ridx2rate(struct ieee80211_rateset *, int);
@@ -6855,7 +6855,7 @@ iwx_umac_scan_fill_channels(struct iwx_softc *sc,
 uint8_t
 iwx_umac_scan_fill_channels(struct iwx_softc *sc,
 struct iwx_scan_channel_cfg_umac *chan, size_t chan_nitems,
-int n_ssids, int bgscan)
+int n_ssids, uint32_t channel_cfg_flags)
 {
struct ieee80211com *ic = >sc_ic;
struct ieee80211_channel *c;
@@ -6886,8 +6886,8 @@ iwx_umac_scan_fill_channels(struct iwx_softc *sc,
chan->v1.iter_count = 1;
chan->v1.iter_interval = htole16(0);
}
-   if (n_ssids != 0 && !bgscan)
-   chan->flags = htole32(1 << 0); /* select SSID 0 */
+
+   chan->flags = htole32(channel_cfg_flags);
chan++;
nchan++;
}
@@ -7128,12 +7128,12 @@ iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *sc,
 void
 iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *sc,
 struct iwx_scan_channel_params_v6 *cp, uint32_t channel_cfg_flags,
-int n_ssid, int bgscan)
+int n_ssid)
 {
cp->flags = IWX_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER;
 
cp->count = iwx_umac_scan_fill_channels(sc, cp->channel_config,
-   nitems(cp->channel_config), n_ssid, bgscan);
+   nitems(cp->channel_config), n_ssid, channel_cfg_flags);
 
cp->n_aps_override[0] = IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY;
cp->n_aps_override[1] = IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS;
@@ -7188,7 +7188,7 @@ iwx_umac_scan_v14(struct iwx_softc *sc, int bgscan)
}
 
iwx_scan_umac_fill_ch_p_v6(sc, _p->channel_params, bitmap_ssid,
-   n_ssid, bgscan);
+   n_ssid);
 
hcmd.len[0] = sizeof(*cmd);
hcmd.data[0] = (void *)cmd;



Re: rtwn: R92C_RXDW0_OWN -> R92C_TXDW0_OWN

2023-07-14 Thread Stefan Sperling
On Fri, Jul 14, 2023 at 02:45:09PM +0800, Kevin Lo wrote:
> In rtwn_tx(), check if the OWN bit of Tx instead of Rx is set.
> Luckily, definitions of R92C_TXDW0_OWN and R92C_RXDW0_OWN are the same.
> 
> ok?

ok stsp

> Index: sys/dev/pci/if_rtwn.c
> ===
> RCS file: /cvs/src/sys/dev/pci/if_rtwn.c,v
> retrieving revision 1.40
> diff -u -p -u -p -r1.40 if_rtwn.c
> --- sys/dev/pci/if_rtwn.c 21 Apr 2022 21:03:03 -  1.40
> +++ sys/dev/pci/if_rtwn.c 14 Jul 2023 06:43:06 -
> @@ -1022,7 +1022,7 @@ rtwn_tx(void *cookie, struct mbuf *m, st
>  
>   /* Fill Tx descriptor. */
>   txd = _ring->desc[tx_ring->cur];
> - if (htole32(txd->txdw0) & R92C_RXDW0_OWN) {
> + if (htole32(txd->txdw0) & R92C_TXDW0_OWN) {
>   m_freem(m);
>   return (ENOBUFS);
>   }
> 
> 



Re: gitignore: got + cvs coexistence

2023-07-07 Thread Stefan Sperling
On Fri, Jul 07, 2023 at 12:26:16PM +0200, Tobias Heider wrote:
> For bigger changesets I have started experimenting with using got.
> I don't like to have the whole tree on disk twice so I keep my got and CVS
> checkouts in the same directory.

Curious. I am not sure how well that will work in practice but
if it works for you then why not. I usually keep them separate,
using temporary CVS checkouts for commits to CVS.

> A downside of this approach is of course that got always lists all the unknown
> CVS dirs in got status. Does anything speak against ignoring them via 
> gitignore?

In any case, I doubt anyone would ever want to check their CVS directories
into Git. So ok by me.

> diff 7efd0ea99b79bbbda1539b1ae5c635ebfa688970 
> 99115307e40554b41e9d62708e81599b0337da96
> commit - 7efd0ea99b79bbbda1539b1ae5c635ebfa688970
> commit + 99115307e40554b41e9d62708e81599b0337da96
> blob - 3fdff78bcab1fcf6493998cb99b64ff5a5da4f63
> blob + f07392d0d0015dac869ec1d55affd353aafba670
> --- .gitignore
> +++ .gitignore
> @@ -1,2 +1,3 @@
>  **/obj
>  **/tags
> +**/CVS
> 
> 



Re: Add Intel Wi-Fi 6 AX211 0x51f1 device

2023-06-27 Thread Stefan Sperling
On Tue, Jun 27, 2023 at 10:55:04AM +0200, Reyk Floeter wrote:
> Hi,
> 
> the following diff adds the Intel Wi-Fi 6 0x51f1 device, found in a
> new Thinkpad X1 Carbon Gen 11.
> 
> iwx0 at pci0 dev 20 function 3 "Intel Wi-Fi 6 AX211" rev 0x01, msix
> iwx0: hw rev 0x370, fw 77.f92b5fed.0, pnvm e4a49534, address ...
> 
> I looked at the Linux code for the values for 0x51f1 and 0x7a70:
> https://github.com/torvalds/linux/commit/1c4db7613f35b248ff05b8bfb3a4580a3d11d75c

Thanks, your diff looks correct to me. ok stsp@

> This works fine with my 11ac setup and performance seems OK (around
> 200Mbps - what can I expect on OpenBSD these days?).  I don't know if
> the device supports UHB channels.

This speed matches what I see in my environment, more or less.
Apparently it goes up to 300 Mbit/s for some people, but I have never
seen it go that far up myself.

We are capped to 80 MHz channels at the moment. I do have a 160MHz AP now
but would need to find spare time to make that work (as things look right
now, me finding time for this soon is rather unlikely).

And the size we advertise for aggregates on Rx in VHT capabilities is
the smallest possible value we can advertise in 11ac (3895 octets).
Increasing this frame size limit should result in a performance boost.
We might have to increase the size of our Rx buffers accordingly, unless
the hardware handles de-aggregation into a cluster of our 4k-sized Rx
buffers, which may well be the case but I don't know for sure.
It would not be an entirely trivial diff, but likely less coding work
and more widely applicable than 160 MHz channel support.



Re: urtwn: support new chip RTL8188FTV

2023-04-27 Thread Stefan Sperling
On Thu, Apr 27, 2023 at 01:38:04PM +0800, Kevin Lo wrote:
> Hi,
> 
> The diff below adds initial support for RTL8188FTV adapters.
> RTL8188FTV is an 802.11b/g/n, 1T1R chipset.
> The firmware file comes from Linux's rtl8188fufw.bin [1].
> 
> Tested with Comfast CF-WU710N v4 on amd64.
> 
> Test reports and OKs are welcome.

OK stsp@
I don't have hardware to test this. I have verified that
'make release' is still passing on amd64 with this patch.



Re: AX88179A fallback to cdce(4)

2023-04-24 Thread Stefan Sperling
On Mon, Apr 24, 2023 at 05:32:28AM -0600, bent...@openbsd.org wrote:
> Hi,
> 
> The AX88179A, which has the same product ID as AX88179, shows up as axen(4),
> but doesn't work:
> 
> "axen0: invalid buffer(pkt#1), continue"
> https://marc.info/?l=openbsd-bugs=164832882524713=2
> 
> gerhard@ sent a diff in that thread that checks the revision and makes
> this device fall back to cdce(4). It's gotten a couple of positive test
> reports, and works on my device as well (Steam Deck Dock). A downside is
> that cdce(4) leaves performance on the table. A CDC/NCM interface could
> be better, but there's no driver for it.
> 
> In their current state, these devices have zero performance. Given that,
> does it make sense to commit this diff?

I am fine with this approach, ok by me.

There is public GPL source code for a Linux driver on the vendor page:
https://www.asix.com.tw/en/product/USBEthernet/Super-Speed_USB_Ethernet/AX88179A
Click the link under "Linux kernel 5.x/4.x/3.x/2.6.x Driver" and you should get
a file called ASIX_USB_NIC_Linux_Driver_Source_v1.1.0.tar.bz2 which contains
the equivalent of our axen(4) driver with extra code to support your device
in ax88179a_772d.{c,h}. If someone eventually adds support to our axen(4)
and then we can flip this device back from cdce(4) to axen(4).



fix iwm/iwx updatechan callbacks

2023-04-12 Thread Stefan Sperling
The iwm_updatechan and iwx_updatechan callbacks are not reachable
because they were never wired up. Only the iwn driver already has
this callback pointer set as intended.

With the patch below iwm/iwx should get triggered when an AP switches
between 20MHz and 40/80MHz channel width, as indicated by the
11n HT-operation information element in beacons.

Tests for regressions on any iwm/iwx devices would be welcome.

diff /usr/src
commit - d5650cee3563531d216bf9be18275aff4dec8349
path + /usr/src
blob - 437a2b9f3722bb3684750a56a51535ef9b8b59ca
file + sys/dev/pci/if_iwm.c
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -12009,6 +12009,7 @@ iwm_attach(struct device *parent, struct device *self,
ic->ic_updateprot = iwm_updateprot;
ic->ic_updateslot = iwm_updateslot;
ic->ic_updateedca = iwm_updateedca;
+   ic->ic_updatechan = iwm_updatechan;
ic->ic_updatedtim = iwm_updatedtim;
ic->ic_ampdu_rx_start = iwm_ampdu_rx_start;
ic->ic_ampdu_rx_stop = iwm_ampdu_rx_stop;
blob - a61031f47f65c1778069b2205a21ce0ce30a6f83
file + sys/dev/pci/if_iwx.c
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -11330,6 +11330,7 @@ iwx_attach(struct device *parent, struct device *self,
/* Override 802.11 state transition machine. */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = iwx_newstate;
+   ic->ic_updatechan = iwx_updatechan;
ic->ic_updateprot = iwx_updateprot;
ic->ic_updateslot = iwx_updateslot;
ic->ic_updateedca = iwx_updateedca;



Re: unifdef ath(4)

2023-03-26 Thread Stefan Sperling
On Sun, Mar 26, 2023 at 05:17:36PM +1100, Jonathan Gray wrote:
> there is no need to sync with FreeBSD

ok stsp

> Index: sys/dev/ic/ath.c
> ===
> RCS file: /cvs/src/sys/dev/ic/ath.c,v
> retrieving revision 1.123
> diff -u -p -r1.123 ath.c
> --- sys/dev/ic/ath.c  21 Apr 2022 21:03:02 -  1.123
> +++ sys/dev/ic/ath.c  26 Mar 2023 06:00:43 -
> @@ -308,11 +308,6 @@ ath_attach(u_int16_t devid, struct ath_s
>   timeout_set(>sc_cal_to, ath_calibrate, sc);
>   timeout_set(>sc_rssadapt_to, ath_rssadapt_updatestats, sc);
>  
> -#ifdef __FreeBSD__
> - ATH_TXBUF_LOCK_INIT(sc);
> - ATH_TXQ_LOCK_INIT(sc);
> -#endif
> -
>   ATH_TASK_INIT(>sc_txtask, ath_tx_proc, sc);
>   ATH_TASK_INIT(>sc_rxtask, ath_rx_proc, sc);
>   ATH_TASK_INIT(>sc_rxorntask, ath_rxorn_proc, sc);
> @@ -352,9 +347,6 @@ ath_attach(u_int16_t devid, struct ath_s
>   ifp->if_start = ath_start;
>   ifp->if_watchdog = ath_watchdog;
>   ifp->if_ioctl = ath_ioctl;
> -#ifndef __OpenBSD__
> - ifp->if_stop = ath_stop;/* XXX */
> -#endif
>   ifq_set_maxlen(>if_snd, ATH_TXBUF * ATH_TXDESC);
>  
>   ic->ic_softc = sc;
> @@ -472,10 +464,6 @@ ath_detach(struct ath_softc *sc, int fla
>   if_detach(ifp);
>  
>   splx(s);
> -#ifdef __FreeBSD__
> - ATH_TXBUF_LOCK_DESTROY(sc);
> - ATH_TXQ_LOCK_DESTROY(sc);
> -#endif
>  
>   return 0;
>  }
> @@ -983,15 +971,6 @@ ath_ioctl(struct ifnet *ifp, u_long cmd,
>   break;
>   case SIOCADDMULTI:
>   case SIOCDELMULTI:
> -#ifdef __FreeBSD__
> - /*
> -  * The upper layer has already installed/removed
> -  * the multicast address(es), just recalculate the
> -  * multicast filter for the card.
> -  */
> - if (ifp->if_flags & IFF_RUNNING)
> - ath_mode_init(sc);
> -#endif
>   error = (cmd == SIOCADDMULTI) ?
>   ether_addmulti(ifr, >sc_ic.ic_ac) :
>   ether_delmulti(ifr, >sc_ic.ic_ac);
> @@ -1189,13 +1168,6 @@ ath_getmbuf(int flags, int type, u_int p
>   struct mbuf *m;
>  
>   KASSERT(pktlen <= MCLBYTES, ("802.11 packet too large: %u", pktlen));
> -#ifdef __FreeBSD__
> - if (pktlen <= MHLEN) {
> - MGETHDR(m, flags, type);
> - } else {
> - m = m_getcl(flags, type, M_PKTHDR);
> - }
> -#else
>   MGETHDR(m, flags, type);
>   if (m != NULL && pktlen > MHLEN) {
>   MCLGET(m, flags);
> @@ -1204,7 +1176,6 @@ ath_getmbuf(int flags, int type, u_int p
>   m = NULL;
>   }
>   }
> -#endif
>   return m;
>  }
>  
> Index: sys/dev/ic/athvar.h
> ===
> RCS file: /cvs/src/sys/dev/ic/athvar.h,v
> retrieving revision 1.35
> diff -u -p -r1.35 athvar.h
> --- sys/dev/ic/athvar.h   11 Oct 2020 07:05:28 -  1.35
> +++ sys/dev/ic/athvar.h   26 Mar 2023 05:19:55 -
> @@ -194,15 +194,11 @@ typedef struct ath_task {
>  } ath_task_t;
>  
>  struct ath_softc {
> -#ifndef __FreeBSD__
>   struct device   sc_dev;
> -#endif
>   struct ieee80211com sc_ic;  /* IEEE 802.11 common */
> -#ifndef __FreeBSD__
>   int (*sc_enable)(struct ath_softc *);
>   void(*sc_disable)(struct ath_softc *);
>   void(*sc_power)(struct ath_softc *, int);
> -#endif
>   int (*sc_newstate)(struct ieee80211com *,
>   enum ieee80211_state, int);
>   void(*sc_node_free)(struct ieee80211com *,
> @@ -213,16 +209,10 @@ struct ath_softc {
>   void(*sc_recv_mgmt)(struct ieee80211com *,
>   struct mbuf *, struct ieee80211_node *,
>   struct ieee80211_rxinfo *, int);
> -#ifdef __FreeBSD__
> - device_tsc_dev;
> -#endif
>   bus_space_tag_t sc_st;  /* bus space tag */
>   bus_space_handle_t  sc_sh;  /* bus space handle */
>   bus_size_t  sc_ss;  /* bus space size */
>   bus_dma_tag_t   sc_dmat;/* bus DMA tag */
> -#ifdef __FreeBSD__
> - struct mtx  sc_mtx; /* master lock (recursive) */
> -#endif
>   struct ath_hal  *sc_ah; /* Atheros HAL */
>   unsigned intsc_invalid : 1, /* disable hardware accesses */
>   sc_doani : 1,   /* dynamic noise immunity */
> @@ -274,13 +264,7 @@ struct ath_softc {
>   u_int32_t   *sc_txlink; /* link ptr in last TX desc */
>   int sc_tx_timer;/* transmit timeout */
>   TAILQ_HEAD(, ath_buf)   sc_txbuf;   /* transmit buffer */
> -#ifdef __FreeBSD__
> - struct mtx  

Re: installer: handle WEP failure (bwfm)

2023-03-15 Thread Stefan Sperling
On Thu, Mar 16, 2023 at 08:51:30AM +1100, Jonathan Gray wrote:
> It will be a day or two until I can set everything up again.
> If this works for you I think you should commit it. ok jsg@

Done, thanks!



Re: installer: handle WEP failure (bwfm)

2023-03-15 Thread Stefan Sperling
On Wed, Mar 15, 2023 at 09:18:25AM +1100, Jonathan Gray wrote:
> On Tue, Mar 14, 2023 at 01:37:28PM +0100, Stefan Sperling wrote:
> > On Tue, Mar 14, 2023 at 12:19:10PM +, Klemens Nanni wrote:
> > > Here is an yet untested WEP removal diff based on 'grep WEP' in case we go
> > > this way rather than fixing WEP.
> > 
> > Did you test wether adding the WEP capability flag to the driver is
> > sufficient? If you have a hostap-capable interface like athn(4) and
> > a bwfm(4) client it is trvial to create a test setup for this. Just
> > use static IPs on AP and client and try get to a ping through.
> > 
> > I would encourage you to at least try to fix WEP instead of axing
> > things that would need to be reinstated once it's been fixed.
> > Maybe one day you will be traveling and depend on bwfm(4) to connect
> > to some WEP-only hotspot and then you will be happy to have fixed it ;)
> 
> It isn't enough.
> 
> panic'd without 'if (cmd->ni != NULL)'

Yes, that is needed because intially net80211 sets all the WEP keys
while passing NULL for the 'ni' argument.

> I started on this, but didn't get to a point where it could
> pass traffic to another machine running hostap.

Huh. But your diff is in fact working for me...?!?

Did you use athn(4) hostap to test this?  I noticed mine comes up
in 'mode 11n' by default even if WEP is configured, which is a
misconfigured state because 11n requires WPA.

With your diff I can ping an athn(4) WEP hostap in 11g (not n) mode using
a USB bwfm device (vendor/product 0a5c:bd1e, Raspberry Pi 2 wifi dongle):
bwfm0 at uhub1 port 1 configuration 1 interface 0 "Broadcom Remote Download 
Wireless Adapter" rev 2.00/0.01 addr 5

> Perhaps it would be easier to do software WEP.

Software crypto is impossible on this device because it expects
Ethernet frames from the kernel, rather than 802.11 frames... :-/ 

We should probably avoid asking the device to do wpa and wep at the
same time. The old code was inherited from Linux as-is but not clearing
the other crypto mode flags when we change the mode seems wrong to me.
I have tweaked the driver accordingly, see below. Though this tweak doesn't
make a difference during testing, even while flipping between WEP and WPA.
Presumably the internal device state is always getting reset somehow before
we read it out and change it.

If WEP still doesn't work on your device then we may need to set
the authmode to SHARED_KEY on some devices:

bwfm_fwvar_var_set_int(sc, "auth", BWFM_AUTH_SHARED_KEY);

My device requires OPEN auth and does not work if SHARED_KEY is set.
But maybe this differs between device/firmware versions as hinted at
by the comments in my slightly tweaked diff below, based on yours.

OK stsp@ for your diff if you want to commit it.
I can layer my cosmetic tweaks on top.
 
diff d5650cee3563531d216bf9be18275aff4dec8349 
9ed7f223411e76981d3f306085bf471975800ad3
commit - d5650cee3563531d216bf9be18275aff4dec8349
commit + 9ed7f223411e76981d3f306085bf471975800ad3
blob - 56c8e2365b5aadb2f9f32bcc99a0a73f4b2ded0f
blob + f3ab1d1bb3bdf51986512481edb5d274a61dd9d9
--- sys/dev/ic/bwfm.c
+++ sys/dev/ic/bwfm.c
@@ -199,6 +199,7 @@ bwfm_attach(struct bwfm_softc *sc)
ic->ic_state = IEEE80211_S_INIT;
 
ic->ic_caps =
+   IEEE80211_C_WEP |
 #ifndef IEEE80211_STA_ONLY
IEEE80211_C_HOSTAP |/* Access Point */
 #endif
@@ -2001,8 +2002,7 @@ bwfm_connect(struct bwfm_softc *sc)
uint8_t *frm;
 
/*
-* OPEN: Open or WPA/WPA2 on newer Chips/Firmware.
-* SHARED KEY: WEP.
+* OPEN: Open or WEP or WPA/WPA2 on newer Chips/Firmware.
 * AUTO: Automatic, probably for older Chips/Firmware.
 */
if (ic->ic_flags & IEEE80211_F_RSNON) {
@@ -2041,6 +2041,9 @@ bwfm_connect(struct bwfm_softc *sc)
 
bwfm_fwvar_var_set_int(sc, "wpa_auth", wpa);
bwfm_fwvar_var_set_int(sc, "wsec", wsec);
+   } else if (ic->ic_flags & IEEE80211_F_WEPON) {
+   bwfm_fwvar_var_set_int(sc, "wpa_auth", BWFM_WPA_AUTH_DISABLED);
+   bwfm_fwvar_var_set_int(sc, "wsec", BWFM_WSEC_WEP);
} else {
bwfm_fwvar_var_set_int(sc, "wpa_auth", BWFM_WPA_AUTH_DISABLED);
bwfm_fwvar_var_set_int(sc, "wsec", BWFM_WSEC_NONE);
@@ -2083,8 +2086,7 @@ bwfm_hostap(struct bwfm_softc *sc)
struct bwfm_join_params join;
 
/*
-* OPEN: Open or WPA/WPA2 on newer Chips/Firmware.
-* SHARED KEY: WEP.
+* OPEN: Open or WEP or WPA/WPA2 on newer Chips/Firmware.
 * AUTO: Automatic, probably for older Chips/Firmware.
 */
if (ic->ic_flags & IEEE80211_F_RSNON) {
@@ -2883,10 +2885,12 @@ bwfm_set_key_cb(struct bwfm_softc *sc, void *arg)
 
bwfm_fwvar_var_set_d

Re: installer: handle WEP failure (bwfm)

2023-03-14 Thread Stefan Sperling
On Tue, Mar 14, 2023 at 12:19:10PM +, Klemens Nanni wrote:
> Here is an yet untested WEP removal diff based on 'grep WEP' in case we go
> this way rather than fixing WEP.

Did you test wether adding the WEP capability flag to the driver is
sufficient? If you have a hostap-capable interface like athn(4) and
a bwfm(4) client it is trvial to create a test setup for this. Just
use static IPs on AP and client and try get to a ping through.

I would encourage you to at least try to fix WEP instead of axing
things that would need to be reinstated once it's been fixed.
Maybe one day you will be traveling and depend on bwfm(4) to connect
to some WEP-only hotspot and then you will be happy to have fixed it ;)



Re: iwx(4) -77 firmware diff for testing

2023-03-02 Thread Stefan Sperling
On Wed, Feb 22, 2023 at 03:31:28PM +0100, Stefan Sperling wrote:
> Below is my work-in-progress diff to update iwx(4) to latest firmware.
> Every system tracking -current should already have the new -77 firmware 
> images.
> 
> The new images contain security fixes of (to me) unknown severity.
> Unfortunately there have been quite a number of firmware API changes since
> our last upgrade and it took me quite some time to get all the required new
> bits in place and arrive at an operational state.
> 
> While testing please enable additional debug output with:
>   ifconfig iwx0 debug
> To activate it at boot time: echo debug >> /etc/hostname.iwx0
> 
> There are some known issue with occasional firmware errors.
> My devices eventually manage to connect and work regardless. If you see a
> firmware error in dmesg please include the extra information shown in dmesg
> after enabling the debugging mode as above. This information is hidden by
> default and the driver will only print "fatal firmware error" to dmesg
> without more context, but the extra context is needed for debugging.
> 
> If you hit an error which looks like this:
> 
>iwx0: firmware parse error 22, section type 19
>iwx0: failed to load init firmware
> 
> Then you will need to increase this constant in if_iwxvar.h until you
> get past the error:
> 
> #define IWX_UCODE_SECT_MAX 56

This new version of the patch fixes two issues:

IWX_UCODE_SECT_MAX was bumped to 57 to accommodate some AX211 devices.

Fixed iwx0: 0x211A | ADVANCED_SYSASSERT
with helpful hints from Johannes Berg at Linux/Intel.
This was an annoying issue since it made connecting to an access point
fail quite often. Root cause were changes in the mac context command,
where the firmware now expects beacon-related info to be initialized
early, already before we attempt to associate.

The only remaining known issue is:
iwx0: 0x20002806 | ADVANCED_SYSASSERT, as seen by jmc@
This seems related to background scans. I could not yet reproduce the error,
roaming seems to work as expected for me, but this might depend on the RF
environment. Since roaming is evidently not completely broken by this I will
not treat this as a blocker for moving development into the tree.

Patch test reports are still welcome but please be fast if there is an issue
you are seeing that I am not aware of. I will start splitting/committing this
soon.

diff refs/heads/master refs/heads/iwxfw
commit - 50b5a752f56b56e236653f0da2264f2ec83f9fde
commit + 0e6ef712fc262423d483ba4cdeab9f957d41e71e
blob - a91a0d85b3877e13d7798e7f90f21fd601eac1e5
blob + b4f90c6d74e76f1b5a4658cde4af19f2fe76a42a
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -235,7 +235,6 @@ int iwx_is_mimo_mcs(int);
 uint8_tiwx_lookup_cmd_ver(struct iwx_softc *, uint8_t, uint8_t);
 uint8_tiwx_lookup_notif_ver(struct iwx_softc *, uint8_t, uint8_t);
 intiwx_is_mimo_ht_plcp(uint8_t);
-intiwx_is_mimo_mcs(int);
 intiwx_store_cscheme(struct iwx_softc *, uint8_t *, size_t);
 intiwx_alloc_fw_monitor_block(struct iwx_softc *, uint8_t, uint8_t);
 intiwx_alloc_fw_monitor(struct iwx_softc *, uint8_t);
@@ -380,10 +379,10 @@ int   iwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *, 
struct
struct iwx_rx_data *);
 intiwx_binding_cmd(struct iwx_softc *, struct iwx_node *, uint32_t);
 uint8_tiwx_get_vht_ctrl_pos(struct ieee80211com *, struct 
ieee80211_channel *);
-intiwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *, struct iwx_phy_ctxt *, 
uint8_t,
-   uint8_t, uint32_t, uint8_t, uint8_t);
-intiwx_phy_ctxt_cmd_v3(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint8_t, uint8_t);
+intiwx_phy_ctxt_cmd_uhb_v3_v4(struct iwx_softc *, struct iwx_phy_ctxt *,
+   uint8_t, uint8_t, uint32_t, uint8_t, uint8_t, int);
+intiwx_phy_ctxt_cmd_v3_v4(struct iwx_softc *, struct iwx_phy_ctxt *,
+   uint8_t, uint8_t, uint32_t, uint8_t, uint8_t, int);
 intiwx_phy_ctxt_cmd(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
uint8_t, uint32_t, uint32_t, uint8_t, uint8_t);
 intiwx_send_cmd(struct iwx_softc *, struct iwx_host_cmd *);
@@ -395,6 +394,8 @@ const struct iwx_rate *iwx_tx_fill_cmd(struct iwx_soft
const void *, uint32_t *);
 void   iwx_free_resp(struct iwx_softc *, struct iwx_host_cmd *);
 void   iwx_cmd_done(struct iwx_softc *, int, int, int);
+uint32_t iwx_fw_rateidx_ofdm(uint8_t);
+uint32_t iwx_fw_rateidx_cck(uint8_t);
 const struct iwx_rate *iwx_tx_fill_cmd(struct iwx_softc *, struct iwx_node *,
struct ieee80211_frame *, uint16_t *, uint32_t *);
 void   iwx_tx_update_byte_tbl(struct iwx_softc *, struct iwx_tx_ring *, int,
@@ -446,11 +447,16 @@ int   iwx_rs_rval2idx(uint8_t);
 intiwx_umac_scan_abort(struct iwx_softc *);
 intiwx_scan_abort(struct iwx_softc *);
 intiwx_enable_mgmt_queue(s

iwx(4) -77 firmware diff for testing

2023-02-22 Thread Stefan Sperling
Below is my work-in-progress diff to update iwx(4) to latest firmware.
Every system tracking -current should already have the new -77 firmware images.

The new images contain security fixes of (to me) unknown severity.
Unfortunately there have been quite a number of firmware API changes since
our last upgrade and it took me quite some time to get all the required new
bits in place and arrive at an operational state.

While testing please enable additional debug output with:
  ifconfig iwx0 debug
To activate it at boot time: echo debug >> /etc/hostname.iwx0

There are some known issue with occasional firmware errors.
My devices eventually manage to connect and work regardless. If you see a
firmware error in dmesg please include the extra information shown in dmesg
after enabling the debugging mode as above. This information is hidden by
default and the driver will only print "fatal firmware error" to dmesg
without more context, but the extra context is needed for debugging.

If you hit an error which looks like this:

   iwx0: firmware parse error 22, section type 19
   iwx0: failed to load init firmware

Then you will need to increase this constant in if_iwxvar.h until you
get past the error:

#define IWX_UCODE_SECT_MAX 56

It will probably just need a +1 or +2.
It is possible to find the required maximum by parsing all the
firmware files, but I haven't gotten around to that yet.

Tested and known to work with occasional firmware errors on:

iwx0 at pci2 dev 0 function 0 "Intel Wi-Fi 6 AX200" rev 0x1a, msix
iwx0: hw rev 0x340, fw 77.f92b5fed.0

iwx0 at pci0 dev 20 function 3 "Intel Wi-Fi 6 AX201" rev 0x00, msix
iwx0: hw rev 0x350, fw 77.f92b5fed.0,

iwx0 at pci4 dev 0 function 0 "Intel Wi-Fi 6 AX210" rev 0x1a, msix
iwx0: hw rev 0x420, fw 77.f92b5fed.0, pnvm dbd9582f,

diff refs/heads/master refs/heads/iwxfw
commit - 1c92691b7a84f0421db1f337820c9101754737fe
commit + babe10bea47ca36edb28f4dc8ead5853424475dc
blob - a91a0d85b3877e13d7798e7f90f21fd601eac1e5
blob + 0959f986a912ab36ebe8e9ec705973c1de83fbfe
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -235,7 +235,6 @@ int iwx_is_mimo_mcs(int);
 uint8_tiwx_lookup_cmd_ver(struct iwx_softc *, uint8_t, uint8_t);
 uint8_tiwx_lookup_notif_ver(struct iwx_softc *, uint8_t, uint8_t);
 intiwx_is_mimo_ht_plcp(uint8_t);
-intiwx_is_mimo_mcs(int);
 intiwx_store_cscheme(struct iwx_softc *, uint8_t *, size_t);
 intiwx_alloc_fw_monitor_block(struct iwx_softc *, uint8_t, uint8_t);
 intiwx_alloc_fw_monitor(struct iwx_softc *, uint8_t);
@@ -380,10 +379,10 @@ int   iwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *, 
struct
struct iwx_rx_data *);
 intiwx_binding_cmd(struct iwx_softc *, struct iwx_node *, uint32_t);
 uint8_tiwx_get_vht_ctrl_pos(struct ieee80211com *, struct 
ieee80211_channel *);
-intiwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *, struct iwx_phy_ctxt *, 
uint8_t,
-   uint8_t, uint32_t, uint8_t, uint8_t);
-intiwx_phy_ctxt_cmd_v3(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint8_t, uint8_t);
+intiwx_phy_ctxt_cmd_uhb_v3_v4(struct iwx_softc *, struct iwx_phy_ctxt *,
+   uint8_t, uint8_t, uint32_t, uint8_t, uint8_t, int);
+intiwx_phy_ctxt_cmd_v3_v4(struct iwx_softc *, struct iwx_phy_ctxt *,
+   uint8_t, uint8_t, uint32_t, uint8_t, uint8_t, int);
 intiwx_phy_ctxt_cmd(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
uint8_t, uint32_t, uint32_t, uint8_t, uint8_t);
 intiwx_send_cmd(struct iwx_softc *, struct iwx_host_cmd *);
@@ -395,6 +394,8 @@ const struct iwx_rate *iwx_tx_fill_cmd(struct iwx_soft
const void *, uint32_t *);
 void   iwx_free_resp(struct iwx_softc *, struct iwx_host_cmd *);
 void   iwx_cmd_done(struct iwx_softc *, int, int, int);
+uint32_t iwx_fw_rateidx_ofdm(uint8_t);
+uint32_t iwx_fw_rateidx_cck(uint8_t);
 const struct iwx_rate *iwx_tx_fill_cmd(struct iwx_softc *, struct iwx_node *,
struct ieee80211_frame *, uint16_t *, uint32_t *);
 void   iwx_tx_update_byte_tbl(struct iwx_softc *, struct iwx_tx_ring *, int,
@@ -446,11 +447,16 @@ int   iwx_rs_rval2idx(uint8_t);
 intiwx_umac_scan_abort(struct iwx_softc *);
 intiwx_scan_abort(struct iwx_softc *);
 intiwx_enable_mgmt_queue(struct iwx_softc *);
+intiwx_disable_mgmt_queue(struct iwx_softc *);
 intiwx_rs_rval2idx(uint8_t);
 uint16_t iwx_rs_ht_rates(struct iwx_softc *, struct ieee80211_node *, int);
 uint16_t iwx_rs_vht_rates(struct iwx_softc *, struct ieee80211_node *, int);
+intiwx_rs_init_v3(struct iwx_softc *, struct iwx_node *);
+intiwx_rs_init_v4(struct iwx_softc *, struct iwx_node *);
 intiwx_rs_init(struct iwx_softc *, struct iwx_node *);
 intiwx_enable_data_tx_queues(struct iwx_softc *);
+intiwx_phy_send_rlc(struct iwx_softc *, struct iwx_phy_ctxt *,
+   uint8_t, uint8_t);
 intiwx_phy_ctxt_update(struct iwx_softc *, struct iwx_phy_ctxt *,
struct 

Re: ifconfig.c redundancy the second

2023-01-18 Thread Stefan Sperling
On Fri, Jan 13, 2023 at 09:18:30PM +0100, Mathias Koehler wrote:
> Ehm well it should look like this, sorry:

This code duplication has now been removed. Thanks!

> ===
> RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
> retrieving revision 1.460
> diff -u -p -u -p -r1.460 ifconfig.c
> --- ifconfig.c  18 Dec 2022 18:56:38 -  1.460
> +++ ifconfig.c  13 Jan 2023 18:52:48 -
> @@ -1907,12 +1907,14 @@ delifjoinlist(const char *val, int d)
> memset(, 0, sizeof(join));
> join.i_flags |= (IEEE80211_JOIN_DEL | IEEE80211_JOIN_DEL_ALL);
> 
> +   /*
> if (d == -1) {
> ifr.ifr_data = (caddr_t)
> if (ioctl(sock, SIOCS80211JOIN, (caddr_t)) == -1)
> err(1, "SIOCS80211JOIN");
> return;
> }
> +   */
> 
> ifr.ifr_data = (caddr_t)
> 
> 



Re: athn auto media type (Was: Re: Explicit NULL assignment after free)

2023-01-02 Thread Stefan Sperling
On Sun, Jan 01, 2023 at 10:37:44PM +, Ali Farzanrad wrote:
> OK, I started in a working state where I was connected to my Android
> phone:

OK, let's untangle this... see below...

> # cat /etc/hostname.athn0
> nwid [..name..] wpakey [..pass..]
> inet autoconf

Before you get to "status: active" the interface was scanning for APs.
While scanning, it did already behave just as you describe below...

> # ifconfig athn0
> athn0: flags=808843 mtu 1500
>   lladdr [..lladdr..]
>   index 1 priority 4 llprio 3
>   groups: wlan egress
>   media: IEEE802.11 autoselect (HT-MCS7 mode 11n)
>   status: active
>   ieee80211: nwid [..name..] chan 9 bssid [..bssid..] -45dBm wpakey 
> wpaprotos wpa2 wpaakms psk wpaciphers ccmp wpagroupcipher ccmp
>   inet 192.168.131.83 netmask 0xff00 broadcast 192.168.131.255
> 
> then I simply re-run netstart:
> 
> # sh /etc/netstart athn0
> # ifconfig athn0
> athn0: flags=808843 mtu 1500
>   lladdr [..lladdr..]
>   index 1 priority 4 llprio 3
>   groups: wlan egress
>   media: IEEE802.11 autoselect (DS1 mode 11b)
>   status: no network

... here.

The interface is not connected to any AP (status: no network) so it will
keep scanning. While scanning, the interface will switch between modes,
because the 11b/g and 11a bands require separate sets of channels to
be scanned. To implement switching between channel sets the net80211 stack
will keep switching modes internally. This shows up on the ifconfig media
line as a side-effect. But this unrelated to Tx rates used for data frames
because no data frames will even be sent before the interface is associated.

So now, you are in 11b mode and scanning...

>   ieee80211: nwid [..name..] wpakey wpaprotos wpa2 wpaakms psk wpaciphers 
> ccmp wpagroupcipher ccmp
>   inet 192.168.131.83 netmask 0xff00 broadcast 192.168.131.255
> 
> [..after some time..]
> 
> # ifconfig athn0
> athn0: flags=808843 mtu 1500
>   lladdr [..lladdr..]
>   index 1 priority 4 llprio 3
>   groups: wlan egress
>   media: IEEE802.11 autoselect (DS1 mode 11g)
>   status: no network

... and here, you are in 11g mode, but still not associated, sill scanning.

The real problem is that your AP seems to be disappearing.
Your phone might be switching between WLAN channels, or it might be
turning the AP off for some reason. In either case the AP will have
disappeared from the client's point of view.

You could try:
ifconfig athn0 debug
tail -f /var/log/messages

Hopefully the additional debug info now written to /var/log/messages will
help you figure out why the AP is not being seen anymore.

>   ieee80211: nwid [..name..] chan 9 bssid [..bssid..] -100dBm wpakey 
> wpaprotos wpa2 wpaakms psk wpaciphers ccmp wpagroupcipher ccmp
>   inet 192.168.131.83 netmask 0xff00 broadcast 192.168.131.255
> 
> [..after some time..]
> 
> # ifconfig athn0
> athn0: flags=808843 mtu 1500
>   lladdr [..lladdr..]
>   index 1 priority 4 llprio 3
>   groups: wlan egress
>   media: IEEE802.11 autoselect (DS1)
>   status: no network
>   ieee80211: nwid [..name..] wpakey wpaprotos wpa2 wpaakms psk wpaciphers 
> ccmp wpagroupcipher ccmp
>   inet 192.168.131.83 netmask 0xff00 broadcast 192.168.131.255
> 
> and it repeats showing different modes but always in DS1 media type.
> 2 days ago I waited for hours, but it didn't find correct media type.
> This time even after reboot it didn't find correct media type, so I
> forced to turn my phone's Internet sharing off and on.
> 
> I wanted to find the problem by myself but unfortunately I don't know
> how :(
> 



Re: Explicit NULL assignment after free

2023-01-01 Thread Stefan Sperling
On Sun, Jan 01, 2023 at 09:00:30PM +, Ali Farzanrad wrote:
> Hi Stefan,
> 
> Stefan Sperling  wrote:
> > On Sun, Jan 01, 2023 at 05:00:35PM +, Ali Farzanrad wrote:
> > > Hi tech@,
> > > 
> > > Happy new year!
> > > I have some weird problems with my athn interface which drives me crazy.
> > > 
> > > 1. Whenever I configure my athn as `media auto' for the first time it
> > > correctly detects correct media subclass, but as soon as I select exact
> > > same media subclass manually, it diverts to DS1 media subclass and after
> > > that auto will not work again (I need to reboot system or my WiFi
> > > provider aka my Android phone).
> > 
> > You are not supposed to force a specific Tx rate, unless you are
> > debugging a Tx-specific problem in the code. The driver will
> > adjust the Tx rate on demand, based on packet loss statistics.
> > If you force a specific Tx rate then associated devices will either see
> > a lot of packet loss (if the rate is too high and the device is too far
> > away) or very low speed (if the Tx rate is forced to a low rate).
> 
> OK, but the point is DS1 is not a correst config for my Android WiFi.
> Normally it should be HT-MCS0 or HT-MCS7 in 11n mode.

Given your android phone is the AP which athn(4) connects to, indeed,
the driver should use HT-MCS0 up to HT-MCS7 while connected in 11n mode
(retried frames will use legacy rates if HT-MCS0 doesn't work, but this
won't be displayed by ifconfig; you would have to capture frames from
the air with a separate wifi device in monitor mode to see this).

Because there is no support for Tx aggregation and 40Mhz channels in
our athn driver yet, running athn in 11n mode does not provide a
significant performance advantage over 11a/11g modes. The driver does
support Rx aggregation though, so at least traffic sent from the AP to
the athn client may be a bit faster than in 11a/11g modes.

> > On 2Ghz channels the driver will start out in DS1 and adjust upwards,
> > and adjust the rate upwards if packet loss remains low while doing so.
> 
> So it might be my Android phone problem which caused my system think DS1
> is the correct config, right?

I don't know why ifconfig would show DS1 if 11n mode is active.
I believe it is possible for DS1 to show up somewhere in ifconfig output
If you forced it to use DS1 earlier and produced a non-default media
config as a result. In such cases the media info shown by ifconfig might
be incorrect and confusing. No polish has gone into that part of the
user-facing display because it is not really intended for users. AFAIK the
commands which force a particular Tx rate aren't even documented anymore.
We removed the docs at some point because regular users should not need
to fiddle with wifi Tx rate selection.

You might simply not be switching back into auto-selection mode with
the commands you are running. Try rebooting with a hostnname.athn0
that does not contain any 'media' and 'mode' commands and it should
be reset to defaults (that is the foolproof way to reset things; there
are other ways but I'd rather avoid talking about those without a solid
understanding of what you were doing).



Re: Explicit NULL assignment after free

2023-01-01 Thread Stefan Sperling
On Sun, Jan 01, 2023 at 05:00:35PM +, Ali Farzanrad wrote:
> Hi tech@,
> 
> Happy new year!
> I have some weird problems with my athn interface which drives me crazy.
> 
> 1. Whenever I configure my athn as `media auto' for the first time it
> correctly detects correct media subclass, but as soon as I select exact
> same media subclass manually, it diverts to DS1 media subclass and after
> that auto will not work again (I need to reboot system or my WiFi
> provider aka my Android phone).

You are not supposed to force a specific Tx rate, unless you are
debugging a Tx-specific problem in the code. The driver will
adjust the Tx rate on demand, based on packet loss statistics.
If you force a specific Tx rate then associated devices will either see
a lot of packet loss (if the rate is too high and the device is too far
away) or very low speed (if the Tx rate is forced to a low rate).

> 2. Sometimes my athn interface will reset all of a sudden and after
> reset it diverts to DS1 media subclass again.

On 2Ghz channels the driver will start out in DS1 and adjust upwards,
and adjust the rate upwards if packet loss remains low while doing so.

> Anyway I decided to read athn related files, but I rarely understand the
> code.  My primary suspect was bad dynamic allocation usage, and I found
> this:
> 
> /usr/src/sys/dev/ic/ar5008.c:676: free(rxq->bf, M_DEVBUF, 0);
> /usr/src/sys/dev/ic/ar5008.c:677:
> /usr/src/sys/dev/ic/ar5008.c:678: /* Free Rx descriptors. */
> 
> In this file almost after every free there is an explicit NULL
> assignment but why there is no NULL assignment after this line?
> 
> ===
> RCS file: /home/cvs/src/sys/dev/ic/ar5008.c,v
> retrieving revision 1.71
> diff -u -p -r1.71 ar5008.c
> --- ar5008.c  27 Dec 2022 20:13:03 -  1.71
> +++ ar5008.c  1 Jan 2023 16:57:54 -
> @@ -674,6 +674,7 @@ ar5008_rx_free(struct athn_softc *sc)
>   m_freem(bf->bf_m);
>   }
>   free(rxq->bf, M_DEVBUF, 0);
> + rxq->bf = NULL;
>  
>   /* Free Rx descriptors. */
>   if (rxq->map != NULL) {

There is no reason to NULL out this pointer.
ar5008_rx_free() is called from either athn_detach() (via sc->ops.dma_free)
or if device attachment fails in athn_attach() (via sc->osp.dma_alloc).
In either case we're not going to be using this allocation ever again.



net80211: ignore beacons on secondary HT/VHT channels

2022-12-31 Thread Stefan Sperling
One of my 80MHz 11ac APs transmits beacons on several channels,
while indicating its actual primary channel in the HT operation
information element (HT OP IE). We currently ignore the primary
channel given in the HT OP IE, and this leads to a problem.

(We do read the AP's idea of its primary channel from the DSSS
parameter IE, but this IE will only be sent on 2GHz channels so
it won't be present in 11ac mode.)

(The HT OP IE is used in both HT/11n and VHT/11ac modes; There is
an 11ac-specific VHT OP IE as well but this only elaborates on
information provided by the HT OP IE, and therefore lacks the
primary channel number.)

In my case, the HTOP primary channel is always 104, and as expected
we see a beacon on channel 104. But we also see beacons from this AP
on channels 118 and 140. Because higher channel numbers are scanned
later and we use the channel number of the most recently received
beacon, ni->ni_chan will be set to 140. As a result, the AP shows up
with channel 140 in the ifconfig scan list, which is wrong.

When the iwm(4) driver later asks firmware to use an 80MHz wide channel,
the firmware triggers a fatal firmware error and the interface fails to
associate with these messages:

  iwm0: fatal firmware error
  iwm0: could not update PHY context (error 35)
  iwm0: failed to update PHY

This happens because the 80MHz channel configuration calculated based
on the value 140 is nonsense. The VHT OP IE says we should be using center
channel 106, which the driver asks the firmware to use.
This center channel works with the actual primary channel 104. But it
makes no sense with the wrong primary channel number 140, and the
firmware detects this and complains.

We can fix this problem by ignoring beacons sent on secondary channels.
With the patch below, I now see:

$ netstat -W iwm0 | grep mismatched\ chan
2 input packets with mismatched channel
$

And the interface associates successfully.

There is a related potential issue where an AP could try to deliberately
trigger this firmware error by sending a nonsense channel configuration.
The driver should be smarter and avoid sending a bogus PHY context command
to the device. But that can be fixed separately.

ok?

diff /usr/src
commit - 40e30772d6fb1f63ba9da196c5948e7546cd6cb9
path + /usr/src
blob - 220fe94908abfd078618b64a45e652cd6adf98f1
file + sys/net80211/ieee80211_input.c
--- sys/net80211/ieee80211_input.c
+++ sys/net80211/ieee80211_input.c
@@ -1693,7 +1693,12 @@ ieee80211_recv_probe_resp(struct ieee80211com *ic, str
htcaps = frm;
break;
case IEEE80211_ELEMID_HTOP:
+   if (frm[1] < 22) {
+   ic->ic_stats.is_rx_elem_toosmall++;
+   break;
+   }
htop = frm;
+   chan = frm[2];
break;
case IEEE80211_ELEMID_VHTCAPS:
vhtcaps = frm;



iwx(4): fix firmware error upon authentication timeout

2022-12-19 Thread Stefan Sperling
If authentication to the AP times out iwx(4) currently triggers a
fatal firmware error while resetting the device.

As part of configuring the device for operation, we create a "binding"
between a MAC config and a PHY config in firmware.
And before we start to associate, firmware is given a "time event"
which "protects the seession" (meaning it prevents firmware from
moving off-channel while we are trying to talk to our new AP).

If we fail to associate we try to reset the device configuration.
But if we attempt to remove the "binding" while the time event
is still active, the firmware will crash (trace shown below).

This patch below fills in missing bits of time-event management.
Code was lifted from iwm(4) and adapted to iwx(4) data structures.

We now stop the time-event as soon as we realize that authentication has
failed. While here, remove iwx_send_time_event_cmd() which is unused.

ok?

iwx0: SCAN -> AUTH
iwx0: sending auth to xx:xx:xx:xx:xx:xx on channel 64 mode 11a
iwx0: authentication timed out for xx:xx:xx:xx:xx:xx
iwx_send_cmd: sending command 0x118
iwx_cmd_done: command 0x18 done
iwx_send_cmd: sending command 0x11e
iwx_cmd_done: command 0x1e done
iwx_send_cmd: sending command 0x118
iwx_cmd_done: command 0x18 done
iwx_send_cmd: sending command 0x119
iwx_cmd_done: command 0x19 done
iwx_send_cmd: sending command 0x12b
iwx0: dumping device error log
iwx0: Start Error Log Dump:
iwx0: Status: 0x19, count: 6
iwx0: 0x0071 | NMI_INTERRUPT_UMAC_FATAL
iwx0: 0080A210 | trm_hw_status0
iwx0:  | trm_hw_status1
iwx0: 004FB322 | branchlink2
iwx0: 004F1B86 | interruptlink1
iwx0: 004F1B86 | interruptlink2
iwx0: 00013622 | data1
iwx0: 1000 | data2
iwx0:  | data3
iwx0:  | beacon time
iwx0: B289E195 | tsf low
iwx0: 007D | tsf hi
iwx0:  | time gp1
iwx0: 008AB03C | time gp2
iwx0: 0001 | uCode revision type
iwx0: 0044 | uCode version major
iwx0: 01D30B0C | uCode version minor
iwx0: 0340 | hw version
iwx0: 18889000 | board version
iwx0: 80F9FC3B | hcmd
iwx0: 2402 | isr0
iwx0: 0100 | isr1
iwx0: 08F2 | isr2
iwx0: 00C3000C | isr3
iwx0:  | isr4
iwx0: 011C | last cmd Id
iwx0: 00013622 | wait_event
iwx0: 0080 | l2p_control
iwx0: 00010034 | l2p_duration
iwx0: 003F | l2p_mhvalid
iwx0: 0080 | l2p_addr_match
iwx0: 0009 | lmpm_pmg_sel
iwx0:  | timestamp
iwx0: 80A4 | flow_handler
iwx0: Start UMAC Error Log Dump:
iwx0: Status: 0x19, count: 7
iwx0: 0x2000320F | ADVANCED_SYSASSERT
iwx0: 0x | umac branchlink1
iwx0: 0x80455D20 | umac branchlink2
iwx0: 0x010771CE | umac interruptlink1
iwx0: 0x | umac interruptlink2
iwx0: 0x | umac data1
iwx0: 0xDEADBEEF | umac data2
iwx0: 0xDEADBEEF | umac data3
iwx0: 0x0044 | umac major
iwx0: 0x01D30B0C | umac minor
iwx0: 0x008AB036 | frame pointer
iwx0: 0xC0885E68 | stack pointer
iwx0: 0x001C012B | last host cmd
iwx0: 0x | isr status reg
driver status:
  tx ring  0: qid=0  cur=29  cur_hw=29  queued=1  
  tx ring  1: qid=1  cur=1   cur_hw=1   queued=0  
  tx ring  2: qid=2  cur=0   cur_hw=0   queued=0  
  tx ring  3: qid=3  cur=0   cur_hw=0   queued=0  
  tx ring  4: qid=4  cur=0   cur_hw=0   queued=0  
  tx ring  5: qid=5  cur=0   cur_hw=0   queued=0  
  tx ring  6: qid=6  cur=0   cur_hw=0   queued=0  
  tx ring  7: qid=7  cur=0   cur_hw=0   queued=0  
  tx ring  8: qid=8  cur=0   cur_hw=0   queued=0  
  tx ring  9: qid=9  cur=0   cur_hw=0   queued=0  
  rx ring: cur=136
  802.11 state AUTH
iwx0: fatal firmware error

diff /usr/src
commit - 36ea8d761cea6a70e9e97003c06b13843e25
path + /usr/src
blob - f4dc3de32d8cc36a18e016b789f7374f34b4b4fd
file + sys/dev/pci/if_iwx.c
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -311,6 +311,7 @@ voidiwx_init_channel_map(struct iwx_softc *, 
uint16_t
 void   iwx_post_alive(struct iwx_softc *);
 intiwx_schedule_session_protection(struct iwx_softc *, struct iwx_node *,
uint32_t);
+void   iwx_unprotect_session(struct iwx_softc *, struct iwx_node *);
 void   iwx_init_channel_map(struct iwx_softc *, uint16_t *, uint32_t *, int);
 void   iwx_setup_ht_rates(struct iwx_softc *);
 void   iwx_setup_vht_rates(struct iwx_softc *);
@@ -2910,56 +2911,7 @@ iwx_post_alive(struct iwx_softc *sc)
iwx_ict_reset(sc);
 }
 
-/*
- * For the high priority TE use a time event type that has similar priority to
- * the FW's action scan priority.
- */
-#define IWX_ROC_TE_TYPE_NORMAL IWX_TE_P2P_DEVICE_DISCOVERABLE
-#define IWX_ROC_TE_TYPE_MGMT_TX IWX_TE_P2P_CLIENT_ASSOC
-
 int
-iwx_send_time_event_cmd(struct iwx_softc *sc,
-const struct iwx_time_event_cmd *cmd)
-{
-   struct iwx_rx_packet *pkt;
-   struct iwx_time_event_resp *resp;
-   struct iwx_host_cmd hcmd = {
-   .id = IWX_TIME_EVENT_CMD,
-   .flags = IWX_CMD_WANT_RESP,
-   .resp_pkt_len = sizeof(*pkt) + sizeof(*resp),
-   };
-   uint32_t resp_len;
-   int err;
-
-   hcmd.data[0] = cmd;

iwm: fix KASSERT if firmware cannot be loaded

2022-12-15 Thread Stefan Sperling
iwm(4) can panic if the firmware image is missing or corrupt:

starting network
iwm1: firmware parse error 22, section type 0
iwm1: failed to load init firmware
ifconfig: SIOCSIFXFLAGS: Invalid argument
panic: kernel diagnostic assertion "sc->task_refs.r_refs == 0" failed: file "/u
sr/src/sys/dev/pci/if_iwm.c", line 10361
Stopped at  db_enter+0x10:  popq%rbp
TIDPIDUID PRFLAGS PFLAGS0 0x3  01K 
ifconfig
db_enter() at db_enter+0x10
panic(81f3341f) at panic+0xbf
__assert(81fa36d6,81f9df76,2879,81f4cb41) at __assert+0
x25
iwm_init(805eb048) at iwm_init+0x2c4
iwm_ioctl(805eb048,8020690c,80bc2400) at iwm_ioctl+0xf9
in6_ifinit(805eb048,80bc2400,1) at in6_ifinit+0xbb
in6_update_ifa(805eb048,8000227473b0,0) at in6_update_ifa+0x774
in6_ifattach_linklocal(805eb048,0) at in6_ifattach_linklocal+0x1ff
in6_ifattach(805eb048) at in6_ifattach+0xef
ifioctl(fd810ec50ac0,801169ab,800022747570,800022782a80) at ifioctl
+0xd97
sys_ioctl(800022782a80,800022747680,8000227476e0) at sys_ioctl+0x2c
4
syscall(800022747750) at syscall+0x384
Xsyscall() at Xsyscall+0x128
end of kernel
end trace frame: 0x7f7e1490, count: 2
https://www.openbsd.org/ddb.html describes the minimum info required in bug
reports.  Insufficient info makes it difficult to find and fix bugs.
ddb{1}>

This issue has already been fixed for iwx(4) in r1.113 of if_iwx.c.
Equivalent fix for iwm(4) below.

ok?

diff /usr/src
commit - 36ea8d761cea6a70e9e97003c06b13843e25
path + /usr/src
blob - b7d37d7182e12521452a6d0ee178001ce2f9ba14
file + sys/dev/pci/if_iwm.c
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -10358,9 +10358,6 @@ iwm_init(struct ifnet *ifp)
 
generation = ++sc->sc_generation;
 
-   KASSERT(sc->task_refs.r_refs == 0);
-   refcnt_init(>task_refs);
-
err = iwm_preinit(sc);
if (err)
return err;
@@ -10374,7 +10371,7 @@ iwm_init(struct ifnet *ifp)
err = iwm_init_hw(sc);
if (err) {
if (generation == sc->sc_generation)
-   iwm_stop(ifp);
+   iwm_stop_device(sc);
return err;
}
 
@@ -10383,6 +10380,8 @@ iwm_init(struct ifnet *ifp)
if (sc->sc_nvm.sku_cap_11ac_enable)
iwm_setup_vht_rates(sc);
 
+   KASSERT(sc->task_refs.r_refs == 0);
+   refcnt_init(>task_refs);
ifq_clr_oactive(>if_snd);
ifp->if_flags |= IFF_RUNNING;
 



Re: ZZZ and extra mountpoints

2022-10-21 Thread Stefan Sperling
On Fri, Oct 21, 2022 at 06:46:14PM +0100, Jason McIntyre wrote:
> pluggable?

It really is a very machine-specific question. It depends
on how the manufaturer decided to connect devices to the
mainboard, which is not always possible to tell from the
perspective of software which runs on the machine.

There can be flash disks soldered into laptops which are
connected via an sdmmc bus, which will be detached because
they look just like a pluggable SD card.

There are machines with internal USB disks, e.g. the Edge
Router lite, which, granted, is not an amd64 machine and
does not suspend/resume. But a similar embedded amd64 with
a USB slot for internal disk could exist. Perhaps as a custom
build where someone plugged a USB stick into a USB header on
the motherboard. Certainly feasible.

Several laptops I own have internal webcams on the USB bus.
Which will be detached because there isn't a generic way to
tell whether they are on an internal or external USB port.
And perhaps the entire USB bus will be powered down when
the host controller goes to sleep, and all connected devices
will lose power.

I tend to agree that the complexity of this is out of scope for
man pages. Understanding this properly requires reading books
about computer architecture first.



Re: sparc64: ofwboot: support booting from softraid 1C

2022-09-02 Thread Stefan Sperling
On Thu, Sep 01, 2022 at 08:31:04PM +, Klemens Nanni wrote:
> This is practically the same diff we already landed for arm64.
> 
> The kernel already supports booting off 1C and with tech@'s
> "installboot: sparc64: fix -r on multi-chunk softraid chunk" diff the
> install process will no longer fail when installing bootstraps onto any
> softraid volume which requires at least two chunks by design.
> 
> Feedback? OK?

ok by me, diff looks fine.

> Index: boot.c
> ===
> RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/boot.c,v
> retrieving revision 1.39
> diff -u -p -r1.39 boot.c
> --- boot.c4 Aug 2022 09:16:53 -   1.39
> +++ boot.c1 Sep 2022 20:10:55 -
> @@ -366,7 +366,8 @@ srbootdev(const char *bootline)
>   return ENODEV;
>   }
>  
> - if (bv->sbv_level == 'C' && bv->sbv_keys == NULL)
> + if ((bv->sbv_level == 'C' || bv->sbv_level == 0x1C) &&
> + bv->sbv_keys == NULL)
>   if (sr_crypto_unlock_volume(bv) != 0)
>   return EPERM;
>  
> Index: softraid_sparc64.c
> ===
> RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/softraid_sparc64.c,v
> retrieving revision 1.5
> diff -u -p -r1.5 softraid_sparc64.c
> --- softraid_sparc64.c9 Dec 2020 18:10:19 -   1.5
> +++ softraid_sparc64.c1 Sep 2022 20:08:03 -
> @@ -290,6 +290,7 @@ srprobe(void)
>   break;
>  
>   case 1:
> + case 0x1C:
>   if (bv->sbv_chunk_no == bv->sbv_chunks_found)
>   bv->sbv_state = BIOC_SVONLINE;
>   else if (bv->sbv_chunks_found > 0)
> @@ -312,7 +313,8 @@ sr_vol_boot_chunk(struct sr_boot_volume 
>  {
>   struct sr_boot_chunk *bc = NULL;
>  
> - if (bv->sbv_level == 1 || bv->sbv_level == 'C' ) { /* RAID1 or CRYPTO */
> + if (bv->sbv_level == 1 || bv->sbv_level == 'C' ||
> + bv->sbv_level == 0x1C) {
>   /* Select first online chunk. */
>   SLIST_FOREACH(bc, >sbv_chunks, sbc_link)
>   if (bc->sbc_state == BIOC_SDONLINE)
> @@ -368,7 +370,7 @@ sr_strategy(struct sr_boot_volume *bv, i
>   err = strategy(, rw, blk, size, buf, rsize);
>   return err;
>  
> - } else if (bv->sbv_level == 'C') {
> + } else if (bv->sbv_level == 'C' || bv->sbv_level == 0x1C) {
>   /* XXX - select correct key. */
>   aes_xts_setkey(, (u_char *)bv->sbv_keys, 64);
>  
> Index: vers.c
> ===
> RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/vers.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 vers.c
> --- vers.c4 Aug 2022 09:16:53 -   1.24
> +++ vers.c20 Aug 2022 03:59:47 -
> @@ -1 +1 @@
> -const char version[] = "1.23";
> +const char version[] = "1.24";
> 



softraid raid1c keydisk cosmetic fix

2022-08-12 Thread Stefan Sperling
Use raid1c-specific meta-data while looking for a key disk that
belongs to a RAID 1C volume.

By dumb luck this is only a cosmetic issue, because struct layout
happens to put the field in the same place.

ok?
 
diff a87e94ce1617958c99b63ed0a056e46650a27375 
ba39970f6365aeeb1b486101f6573c60b7f88573
commit - a87e94ce1617958c99b63ed0a056e46650a27375
commit + ba39970f6365aeeb1b486101f6573c60b7f88573
blob - 762f6ee57d5e7902c097d71830fea6e63080e7b5
blob + 737fafbaad517c55293c69f0a6ddcb8fbb720c83
--- sys/dev/softraid.c
+++ sys/dev/softraid.c
@@ -2593,10 +2593,13 @@ sr_ioctl_vol(struct sr_softc *sc, struct bioc_vol *bv)
bv->bv_nodisk = sd->sd_meta->ssdi.ssd_chunk_no;
 
 #ifdef CRYPTO
-   if ((sd->sd_meta->ssdi.ssd_level == 'C' ||
-   sd->sd_meta->ssdi.ssd_level == 0x1C) &&
+   if (sd->sd_meta->ssdi.ssd_level == 'C' &&
sd->mds.mdd_crypto.key_disk != NULL)
bv->bv_nodisk++;
+
+   if (sd->sd_meta->ssdi.ssd_level == 0x1C &&
+   sd->mds.mdd_raid1c.sr1c_crypto.key_disk != NULL)
+   bv->bv_nodisk++;
 #endif
if (bv->bv_status == BIOC_SVREBUILD)
bv->bv_percent = sr_rebuild_percent(sd);
@@ -2650,10 +2653,13 @@ sr_ioctl_disk(struct sr_softc *sc, struct bioc_disk *b
src = sd->sd_vol.sv_chunks[bd->bd_diskid];
 #ifdef CRYPTO
else if (bd->bd_diskid == sd->sd_meta->ssdi.ssd_chunk_no &&
-   (sd->sd_meta->ssdi.ssd_level == 'C' ||
-   sd->sd_meta->ssdi.ssd_level == 0x1C) &&
+   sd->sd_meta->ssdi.ssd_level == 'C' &&
sd->mds.mdd_crypto.key_disk != NULL)
src = sd->mds.mdd_crypto.key_disk;
+   else if (bd->bd_diskid == sd->sd_meta->ssdi.ssd_chunk_no &&
+   sd->sd_meta->ssdi.ssd_level == 0x1C &&
+   sd->mds.mdd_raid1c.sr1c_crypto.key_disk != NULL)
+   src = sd->mds.mdd_crypto.key_disk;
 #endif
else
break;



Re: softraid(4) RAID 1C boot support on arm64

2022-08-12 Thread Stefan Sperling
On Fri, Aug 12, 2022 at 09:41:59AM +, Klemens Nanni wrote:
> Here's the adapted diff for arm64 minus manual bits to avoid churn for
> now.
> 
> installboot(8) needs softraid(4) support (see my diff on tech@), but
> besides that, root on passphrase 1C softraid on arm64 works as expected:
> 
>   # df /
>   Filesystem  512-blocks  Used Avail Capacity  Mounted on
>   /dev/sd4a  2331356161952   2052840 7%/
>   # bioctl sd4
>   Volume  Status   Size Device
>   softraid0 0 Online10741585920 sd4 RAID1C
> 0 Online10741585920 0:0.0   noencl 
> 1 Online10741585920 0:1.0   noencl 

Great! Thank you for covering additional platforms.

ok stsp@

> Index: conf.c
> ===
> RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/conf.c,v
> retrieving revision 1.39
> diff -u -p -r1.39 conf.c
> --- conf.c30 Jul 2022 21:06:54 -  1.39
> +++ conf.c11 Aug 2022 14:42:01 -
> @@ -46,7 +46,7 @@
>  #include "efipxe.h"
>  #include "softraid_arm64.h"
>  
> -const char version[] = "1.11";
> +const char version[] = "1.12";
>  int  debug = 0;
>  
>  struct fs_ops file_system[] = {
> Index: softraid_arm64.c
> ===
> RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/softraid_arm64.c,v
> retrieving revision 1.3
> diff -u -p -r1.3 softraid_arm64.c
> --- softraid_arm64.c  2 Jun 2021 22:44:27 -   1.3
> +++ softraid_arm64.c  11 Aug 2022 14:43:52 -
> @@ -285,6 +285,7 @@ srprobe(void)
>   break;
>  
>   case 1:
> + case 0x1C:
>   if (bv->sbv_chunk_no == bv->sbv_chunks_found)
>   bv->sbv_state = BIOC_SVONLINE;
>   else if (bv->sbv_chunks_found > 0)
> @@ -341,7 +342,7 @@ sr_strategy(struct sr_boot_volume *bv, i
>   /* XXX - If I/O failed we should try another chunk... */
>   return dip->strategy(dip, rw, blk, size, buf, rsize);
>  
> - } else if (bv->sbv_level == 'C') {
> + } else if (bv->sbv_level == 'C' || bv->sbv_level == 0x1C) {
>  
>   /* Select first online chunk. */
>   SLIST_FOREACH(bc, >sbv_chunks, sbc_link)
> @@ -604,7 +605,8 @@ sropen(struct open_file *f, ...)
>   return EADAPT;
>   }
>  
> - if (bv->sbv_level == 'C' && bv->sbv_keys == NULL)
> + if ((bv->sbv_level == 'C' || bv->sbv_level == 0x1C)
> + && bv->sbv_keys == NULL)
>   if (sr_crypto_unlock_volume(bv) != 0)
>   return EPERM;
>  
> 
> 



Re: arm64: installboot: support softraid

2022-08-12 Thread Stefan Sperling
On Thu, Aug 11, 2022 at 03:51:17PM +, Klemens Nanni wrote:
> Booting off softraid on arm64 is supported but installboot(8) has no
> softraid(4) support on arm64.
> 
> This means installboot always copies the single bootstrap efiboot on the
> root volume and completely ignores softraid chunks, so root on softraid
> on arm64 is unable to boot unless one manually drops into the installer
> shell and runs `installboot -r/mnt ...' on each chunk before reboot.
> 
> Add support for this by copying over sparc64's softraid stage-1 code
> as-is and making stage-2 a NOOP.
> 
>   # ./obj/installboot -v sd4 /root/BOOTAA64.EFI
>   Using / as root
>   installing bootstrap on /dev/rsd4c
>   using first-stage /root/BOOTAA64.EFI
>   sd4: softraid volume with 1 disk(s)
>   sd0a: installing boot blocks on /dev/rsd0c
>   copying /root/BOOTAA64.EFI to 
> /tmp/installboot.KuBD4zkfpM/efi/boot/bootaa64.efi
>   writing /tmp/installboot.KuBD4zkfpM/efi/boot/startup.nsh
> 
> I have not yet tested this through install media builds, but
> 1. nuking all EFI partitions,
> 2. recreating EFI partitions on softraid chunks with installboot and
> 3. reinstalling efiboot with new installboot on the softraid volume
> results in bootable root on softraid on arm64:
> 
>   # bioctl sd4
>  
>   Volume  Status   Size Device
>   softraid0 0 Online   107380400640 sd4 CRYPTO
> 0 Online   107380400640 0:0.0   noencl 
> 
>   # dd if=/dev/zero of=/dev/sd4i bs=1m count=1 
>   1+0 records in
>   1+0 records out
>   1048576 bytes transferred in 0.073 secs (14181527 bytes/sec)
> 
>   # dd if=/dev/zero of=/dev/sd0i bs=1m count=1
>   1+0 records in
>   1+0 records out
>   1048576 bytes transferred in 0.028 secs (37360833 bytes/sec)
> 
>   # ./obj/installboot -p sd0
> 
>   # ./installboot -v sd4 /root/BOOTAA64.EFI   
>  <
>   Using / as root
>   installing bootstrap on /dev/rsd4c
>   using first-stage /root/BOOTAA64.EFI
>   sd4: softraid volume with 1 disk(s)
>   sd0a: installing boot blocks on /dev/rsd0c
>   copying /root/BOOTAA64.EFI to 
> /tmp/installboot.NnXAhE7JwW/efi/boot/bootaa64.efi
>   writing /tmp/installboot.NnXAhE7JwW/efi/boot/startup.nsh
> 
> Feedback? OK (once I've build a miniroot and tested a fresh install)?

Looks fine to me. ok stsp@

> Index: Makefile
> ===
> RCS file: /cvs/src/usr.sbin/installboot/Makefile,v
> retrieving revision 1.24
> diff -u -p -r1.24 Makefile
> --- Makefile  3 Feb 2022 10:21:13 -   1.24
> +++ Makefile  10 Aug 2022 20:52:46 -
> @@ -16,6 +16,10 @@ SRCS += i386_installboot.c
>  SRCS += i386_nlist.c
>  SRCS += i386_softraid.c
>  .elif ${MACHINE} == "armv7" || ${MACHINE} == "arm64" || ${MACHINE} == 
> "riscv64"
> +.  if ${MACHINE} == "arm64"
> +CFLAGS += -DSOFTRAID
> +SRCS += efi_softraid.c
> +.  endif
>  SRCS += efi_installboot.c
>  .elif ${MACHINE} == "hppa"
>  CFLAGS += -DBOOTSTRAP
> Index: efi_softraid.c
> ===
> RCS file: efi_softraid.c
> diff -N efi_softraid.c
> --- /dev/null 1 Jan 1970 00:00:00 -
> +++ efi_softraid.c10 Aug 2022 21:59:34 -
> @@ -0,0 +1,87 @@
> +/*   $OpenBSD: sparc64_softraid.c,v 1.5 2020/06/08 19:17:12 kn Exp $ */
> +/*
> + * Copyright (c) 2012 Joel Sing 
> + * Copyright (c) 2022 Klemens Nanni 
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "installboot.h"
> +
> +void
> +sr_install_bootblk(int devfd, int vol, int disk)
> +{
> + struct bioc_disk bd;
> + char *realdev;
> + int diskfd;
> + char part;
> +
> + /* Get device name for this disk/chunk. */
> + memset(, 0, sizeof(bd));
> + bd.bd_volid = vol;
> + bd.bd_diskid = disk;
> + if (ioctl(devfd, BIOCDISK, ) == -1)
> + err(1, "BIOCDISK");
> +
> + /* Check disk status. */
> + if (bd.bd_status != BIOC_SDONLINE && 

Re: softraid(4) RAID 1C boot support on amd64

2022-08-12 Thread Stefan Sperling
On Fri, Aug 12, 2022 at 07:28:57PM +0200, Stefan Sperling wrote:
> On Fri, Aug 12, 2022 at 03:20:40PM +0200, Stefan Sperling wrote:
> > I am currently trying to find time in order to test my patch on
> > real hardware. Any additional testing would be very welcome.
> 
> I found time :)
> 
> Tested on real hardware with 4 disks.
> Both biosboot and UEFI boot are working as expected.

I have committed my changes, so just try an upcoming snapshot.
Boot loader versions 3.55 (biosboot) and 3.54/3.62 (efiboot)
and 3.55 (pxeboot) should support RAID 1C.



Re: softraid(4) RAID 1C boot support on amd64

2022-08-12 Thread Stefan Sperling
On Fri, Aug 12, 2022 at 03:20:40PM +0200, Stefan Sperling wrote:
> I am currently trying to find time in order to test my patch on
> real hardware. Any additional testing would be very welcome.

I found time :)

Tested on real hardware with 4 disks.
Both biosboot and UEFI boot are working as expected.

I kept rebooting and pulling disks from the system until only
one disk was left, and the result was fine:

Volume  Status   Size Device  
softraid0 0 Online  1000204074496 sd4 RAID1C 
  0 Online  1000204074496 0:0.0   noencl 
  1 Online  1000204074496 0:1.0   noencl 
  2 Online  1000204074496 0:2.0   noencl 
  3 Online  1000204074496 0:3.0   noencl 

Volume  Status   Size Device  
softraid0 0 Degraded1000204074496 sd3 RAID1C 
  0 Offline 0 0:0.0   noencl <>
  1 Online  1000204074496 0:1.0   noencl 
  2 Online  1000204074496 0:2.0   noencl 
  3 Online  1000204074496 0:3.0   noencl 

Volume  Status   Size Device  
softraid0 0 Degraded1000204074496 sd2 RAID1C 
  0 Offline 0 0:0.0   noencl <>
  1 Offline 0 0:1.0   noencl <>
  2 Online  1000204074496 0:2.0   noencl 
  3 Online  1000204074496 0:3.0   noencl 

Volume  Status   Size Device  
softraid0 0 Degraded1000204074496 sd1 RAID1C 
  0 Offline 0 0:0.0   noencl <>
  1 Offline 0 0:1.0   noencl <>
  2 Offline 0 0:2.0   noencl <>
  3 Online  1000204074496 0:3.0   noencl 



Re: softraid(4) RAID 1C boot support on amd64

2022-08-12 Thread Stefan Sperling
On Fri, Aug 12, 2022 at 02:28:30PM +0200, Erling Westenvik wrote:
> On Thu, Aug 04, 2022 at 07:26:23PM +0200, Stefan Sperling wrote:
> > This adds support for booting from RAID 1C volumes on amd64.
> 
> This is so cool and I can't wait to get a chance to try it out!
> 
> > Only boot-loader changes are needed. Both installboot(8) and
> > the kernel already do what is required to make this work.
> > 
> > I have tested with biosboot in vmm. The changes involved are trivial,
> > and I am modifying copies of the same code across all bootloaders.
> > So I would assume that all boot methods work with this patch.
> > Additional testing to verify this would be welcome, of course.
> > 
> > In my testing, a fresh install onto a RAID 1C volume succeeds and
> > the resulting system can be booted as usual. I have tried this on
> > a volume locked with a keydisk, and a volume locked with a passphrase.
> > 
> > I have also tested booting with one of two disks missing and as
> > expected the system came up with a degraded volume:
> 
> OpenBSD's RAID 1 implementation supports more than two disks. Would
> there be a need to test such a setup as well?

Yes, sure, that would not hurt.

I am currently trying to find time in order to test my patch on
real hardware. Any additional testing would be very welcome.

Manually compiling and updating the boot loader is sufficient to test
this patch. But building a custom snapshot of the full system is easier
if the boot loader build + upgrade steps aren't already clear to you.
The full-system build procedure is documented in the release(8) man page.

Alternatively, I could share my own amd64 snapshots which I am using
for testing. Contact me off-list if you are interested and I will
respond with a link.



softraid(4) RAID 1C boot support on amd64

2022-08-04 Thread Stefan Sperling
This adds support for booting from RAID 1C volumes on amd64.
Only boot-loader changes are needed. Both installboot(8) and
the kernel already do what is required to make this work.

I have tested with biosboot in vmm. The changes involved are trivial,
and I am modifying copies of the same code across all bootloaders.
So I would assume that all boot methods work with this patch.
Additional testing to verify this would be welcome, of course.

In my testing, a fresh install onto a RAID 1C volume succeeds and
the resulting system can be booted as usual. I have tried this on
a volume locked with a keydisk, and a volume locked with a passphrase.

I have also tested booting with one of two disks missing and as
expected the system came up with a degraded volume:

softraid0: not all chunks were provided; attempting to bring volume 0 online
softraid0: trying to bring up sd3 degraded
sd2 at scsibus4 targ 1 lun 0: 
sd2: 8191MB, 512 bytes/sector, 16776624 sectors
softraid0: volume sd2 is roaming, it used to be sd3, updating metadata
softraid0: roaming device sd1a -> sd0a
root on sd2a (3ee0bf348da5ea75.a) swap on sd2b dump on sd2b

The volume could successfully be rebuilt with bioctl -R, once the
missing disk was added back in.

ok?

diff 43cbe5bff6629c463463325cebb7e87b291b4a73 
20d3307dd4ffcb7fd9baece3386a59b24bbcc8e0
commit - 43cbe5bff6629c463463325cebb7e87b291b4a73
commit + 20d3307dd4ffcb7fd9baece3386a59b24bbcc8e0
blob - c00d17a6628822b649ad4391a3af7c69801631f0
blob + e320f3d143c2d2023f83743be4ef31e82eabe2af
--- share/man/man4/softraid.4
+++ share/man/man4/softraid.4
@@ -118,7 +118,8 @@ may be used to install
 in the boot storage area of the
 .Nm
 volume.
-Boot support is currently limited to the CRYPTO and RAID 1 disciplines
+Boot support is currently limited to the RAID 1C discipline on the
+amd64 platform, and the CRYPTO and RAID 1 disciplines
 on amd64, arm64, i386, and sparc64 platforms.
 On sparc64, bootable chunks must be RAID partitions using the letter
 .Sq a .
blob - 543d9b404ed39512ed693e96d60958d8d467c3e8
blob + bda7e562558bc1cfad1800dac3f93e03439b48f7
--- sys/arch/amd64/stand/boot/conf.c
+++ sys/arch/amd64/stand/boot/conf.c
@@ -41,7 +41,7 @@
 #include 
 #include 
 
-const char version[] = "3.54";
+const char version[] = "3.55";
 intdebug = 1;
 
 
blob - 5b4e78c86c4ea1a1d3491ca2a8f973588a38e7ba
blob + a53be08f763dd8a2069f5646bf266d747f3346a7
--- sys/arch/amd64/stand/cdboot/conf.c
+++ sys/arch/amd64/stand/cdboot/conf.c
@@ -42,7 +42,7 @@
 #include 
 #include 
 
-const char version[] = "3.54";
+const char version[] = "3.55";
 intdebug = 1;
 
 
blob - dcf19e147de5c7c2e8b2e75fc0c47bf97421dd97
blob + ca83d39d7e22d24f86fc328e1a8703c4de8ce056
--- sys/arch/amd64/stand/efi32/conf.c
+++ sys/arch/amd64/stand/efi32/conf.c
@@ -40,7 +40,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "3.53";
+const char version[] = "3.54";
 
 #ifdef EFI_DEBUG
 intdebug = 0;
blob - e55f63529858ee9b98014f1cb1e0105db8e5d7a9
blob + 33b15ed229b1895c04047026193f36deb649866a
--- sys/arch/amd64/stand/efi32/efidev.c
+++ sys/arch/amd64/stand/efi32/efidev.c
@@ -599,9 +599,11 @@ efiopen(struct open_file *f, ...)
return EADAPT;
}
 
-   if (bv->sbv_level == 'C' && bv->sbv_keys == NULL)
+   if ((bv->sbv_level == 'C' || bv->sbv_level == 0x1C) &&
+   bv->sbv_keys == NULL) {
if (sr_crypto_unlock_volume(bv) != 0)
return EPERM;
+   }
 
if (bv->sbv_diskinfo == NULL) {
dip = alloc(sizeof(struct diskinfo));
blob - 4eac75be43a98df370691f543dd172b8885dc0a4
blob + 8ef9e04e890c237994cdcacc98b8d78de43d4e37
--- sys/arch/amd64/stand/efi64/conf.c
+++ sys/arch/amd64/stand/efi64/conf.c
@@ -40,7 +40,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "3.53";
+const char version[] = "3.54";
 
 #ifdef EFI_DEBUG
 intdebug = 0;
blob - e55f63529858ee9b98014f1cb1e0105db8e5d7a9
blob + 33b15ed229b1895c04047026193f36deb649866a
--- sys/arch/amd64/stand/efi64/efidev.c
+++ sys/arch/amd64/stand/efi64/efidev.c
@@ -599,9 +599,11 @@ efiopen(struct open_file *f, ...)
return EADAPT;
}
 
-   if (bv->sbv_level == 'C' && bv->sbv_keys == NULL)
+   if ((bv->sbv_level == 'C' || bv->sbv_level == 0x1C) &&
+   bv->sbv_keys == NULL) {
if (sr_crypto_unlock_volume(bv) != 0)
return EPERM;
+   }
 
if (bv->sbv_diskinfo == NULL) {
dip = alloc(sizeof(struct diskinfo));
blob - 2096ee66f3d2908bf2b462211f8ba7aa5b6a83a0
blob + b202cb05372802682f84d370c1e33dee21259938
--- sys/arch/amd64/stand/efiboot/conf.c
+++ sys/arch/amd64/stand/efiboot/conf.c
@@ -40,7 +40,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "3.61";
+const char version[] = "3.62";
 
 

Re: patch(1): fix locate_hunk for empty files

2022-08-02 Thread Stefan Sperling
On Mon, Aug 01, 2022 at 03:38:59PM +0200, Omar Polo wrote:
> there's an edge case in locate_hunk with empty files; if `first_guess'
> is zero then main() assumes that locate_hunk has failed and aborts the
> patch operation.  Instead, make sure to return 1 (the line number) so
> that the patch operation can continue.
> 
> this issue was found by Neels Hofmeyr (I presume) in the diff
> implementation for got.  The regress suite for diff.git expects that
> `patch && patch -R' is an identity and so currently fails with base
> patch(1).
> 
> (while here i've also added a comment about t19 that was missing.)
> 
> ok?

ok stsp@

Unrelated to the problem you are fixing, but worth mentioning anyway:

Both 'got patch' and Larry's patch(1) fail to create t20.in during
the application of your diff. This can be trivially worked around
by running "touch t20.in".

I am unsure how a new empty file should be represented in unidiff.
I would expect to see at least a hunk header of the form @@ -0,0 +0,0 @@
but none of 'cvs diff', 'svn diff', and 'git diff' produce any hunk
headers for added empty files. They just produce their own custom
meta-data lines. ('hg diff' is even worse and doesn't print anything).
Which probably means patch(1) would need to be tought about lines such
as "Index" or similar, which are usually treated as noise? Horrible.

Testing the above hunk header idea, this unidiff successfully tricks
Larry patch(1) into creating an empty file:

--- /dev/null
+++ regress/usr.bin/patch/t20.in
@@ -0,0 +0,0 @@

So I suppose this issue should be fixed in diff tooling rather than
trying to work around it in patch(1).



Re: patch(1) fix dwim for reversed patch

2022-08-02 Thread Stefan Sperling
On Mon, Aug 01, 2022 at 12:48:16PM +0200, Omar Polo wrote:
> i was looking for a different issue in patch when i found this.
> patch(1) fails to recognize the reversal application of a patch that
> creates a file (this is test t3).
> 
> since an empty context always matches, the idea is to run the dwim code
> also when locate_hunk succeeds, but only if the patch would create a
> file (pch_ptrn_lines() == 0) and the match is on the first line.
> 
> regress now passes completely.
> 
> ok?

ok stsp@

> diff /usr/src
> commit - faf550173e173cd2ef8642601dc48202a09fd44f
> path + /usr/src
> blob - 73781e33724010ac3ce470e6c079eaa17c3d6365
> file + regress/usr.bin/patch/Makefile
> --- regress/usr.bin/patch/Makefile
> +++ regress/usr.bin/patch/Makefile
> @@ -7,10 +7,6 @@ CLEANFILES=  *.copy *.orig *.rej t5 d19/*
>  REGRESS_TARGETS= t1  t2  t3  t4  t5  t6  t7  t8  t9 \
>   t10 t11 t12 t13 t14 t15 t16 t17 t18 t19
>  
> -t3:
> - @echo ${*} currently fails
> - @echo DISABLED
> -
>  # .in: input file
>  # .diff: patch
>  # .out: desired result after patching
> @@ -18,7 +14,7 @@ t3:
>  # t1: diff contains invalid line number 0.
>  # t2: diff contains invalid line numbers beyond end of input file.
>  # t3: a case where patch should detect a previously applied patch.
> -# Diff transform an empty file into a single line one. Currently fails.
> +# Diff transform an empty file into a single line one.
>  # t4: a case where patch has to detect a previously applied patch.
>  # Diff transform a file with a single line with an eol into a single
>  # line without eol.
> @@ -47,6 +43,7 @@ t3:
>   @(! ${PATCH} ${PATCHFLAGS} ${*}.copy ${.CURDIR}/${*}.diff)
>   @cmp -s ${*}.copy ${.CURDIR}/${*}.out || \
>   (echo "XXX ${*} failed" && false)
> +
>  t4:
>   @echo ${*}
>   @cp ${.CURDIR}/${*}.in ${*}.copy
> blob - 1d9070b01842d982b3b3ce6d5f810913a739813e
> file + usr.bin/patch/patch.c
> --- usr.bin/patch/patch.c
> +++ usr.bin/patch/patch.c
> @@ -260,7 +260,8 @@ main(int argc, char *argv[])
>   if (!skip_rest_of_patch) {
>   do {
>   where = locate_hunk(fuzz);
> - if (hunk == 1 && where == 0 && !force) {
> + if ((hunk == 1 && where == 0 && !force) 
> ||
> + (where == 1 && pch_ptrn_lines() == 
> 0 && !force)) {
>   /* dwim for reversed patch? */
>   if (!pch_swap()) {
>   if (fuzz == 0)
> @@ -276,6 +277,10 @@ main(int argc, char *argv[])
>   /* put it back 
> to normal */
>   fatal("lost 
> hunk on alloc error!\n");
>   reverse = !reverse;
> +
> + /* restore position if 
> this patch creates a file */
> + if (pch_ptrn_lines() == 
> 0)
> + where = 1;
>   } else if (noreverse) {
>   if (!pch_swap())
>   /* put it back 
> to normal */
> 
> 



Re: Fix cursor jumps for elantech trackpoint v4

2022-07-16 Thread Stefan Sperling
On Sat, Jul 16, 2022 at 08:26:49AM +0200, Stefan Hagen wrote:
> Hi,
> 
> This is a workaround taken from Linux to mitigate sporadic cursor jumps
> due to a firmware bug. Known affected laptops are:
> 
> - Lenovo Thinkpad X13 Gen1 (AMD version)
> - Lenovo Thinkpad T14s (AMD version)
> - Lenovo A475
> 
> The trackpoint device is a touchpad/trackpoint combination that shows up
> in dmesg as "Elantech Clickpad, version 4".
> 
> The faulty packets are reporting relative movements greater than 127 and
> cause the mouse cursor to jump into a corner of the screen. It only 
> happens when the trackpoint is used. The touchpad is not affected.
> 
> The bug report leading up to the fix:
> https://bugzilla.kernel.org/show_bug.cgi?id=209167
> 
> The packet layout is described here:
> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/input/mouse/elantech.c?h=v5.18.9#n492
> 
> I'm running with this diff since r2k22 and haven't had a cursor jump or 
> other negative side effects.
> 
> Thanks to stsp@ for helping.
> 
> Comments? OK?

ok stsp@, but I would remove the entire #ifdef DIAGNOSTIC printf block
before commit. Documenting the issue via the comment is good enough.

In general, printing messages in interrupt handlers is bad. And usually
done only under #ifdef DEBUG (code under DIAGNOSTIC is compiled in by
default). If a device ends up triggering this very often then a lot of
messages on the console could render the system unsuable.

> Index: sys/dev/pckbc/pms.c
> ===
> RCS file: /home/cvs/src/sys/dev/pckbc/pms.c,v
> retrieving revision 1.96
> diff -u -p -u -p -r1.96 pms.c
> --- sys/dev/pckbc/pms.c   6 Apr 2022 18:59:30 -   1.96
> +++ sys/dev/pckbc/pms.c   2 Jul 2022 20:23:45 -
> @@ -2610,6 +2610,22 @@ pms_proc_elantech_v4(struct pms_softc *s
>  
>   case ELANTECH_PKT_TRACKPOINT:
>   if (sc->sc_dev_enable & PMS_DEV_SECONDARY) {
> + /*
> + * This firmware misreport coordinates for trackpoint
> + * occasionally. Discard packets outside of [-127, 127] 
> range
> + * to prevent cursor jumps.
> + */
> + if (sc->packet[4] == 0x80 || sc->packet[5] == 0x80 ||
> + sc->packet[1] >> 7 == sc->packet[4] >> 7 ||
> + sc->packet[2] >> 7 == sc->packet[5] >> 7) {
> +#ifdef DIAGNOSTIC
> + printf("%s: discard faulty packet (elantech 
> bug) "
> + "(state = %d,", DEVNAME(sc), 
> sc->inputstate);
> + pms_print_packet(sc);
> + printf(")\n");
> +#endif
> + return;
> + }
>   x = sc->packet[4] - 0x100 + (sc->packet[1] << 1);
>   y = sc->packet[5] - 0x100 + (sc->packet[2] << 1);
>   buttons = butmap[sc->packet[0] & 7];
> 
> 



Re: ifconfig description for wireguard peers

2022-07-14 Thread Stefan Sperling
On Thu, Jul 14, 2022 at 10:57:51AM +0200, Claudio Jeker wrote:
> On Thu, Jul 14, 2022 at 10:51:42AM +0200, Stefan Sperling wrote:
> > Perhaps also consider moving counters to netstat -s instead of ifconfig.
> 
> I don't think netstat -s is a good place for per peer stats (neither is
> ifconfig though). netstat -s shows global per protocol counters.

Ah yes, indeed. netstat only makes sense for global counters. Thanks.



Re: ifconfig description for wireguard peers

2022-07-14 Thread Stefan Sperling
On Wed, Jul 13, 2022 at 05:13:49PM +, Mikolaj Kucharski wrote:
> On Wed, Jul 13, 2022 at 05:43:59PM +0100, Stuart Henderson wrote:
> > > 
> > > Not sure how to handle long output in different way. If you don't
> > > specify wgdesc to the ifconfig, the diff doesn't change anything and
> > > ifconfig(8) output is exactly the same. If you don't find this feature
> > > useful, by not using it, nothing changes for you. Isn't that fair?
> > 
> > It might be better if wgpeer details would be skipped from plain
> > "ifconfig" and only listed if "ifconfig wg0" is used, much like
> > IPv4 aliases are skipped from "ifconfig" and only listed when
> > you use either "ifconfig -A" or "ifconfig em0" etc.
> > 
> 
> Ah, that helps. Thank you! Will look into it. Indeed this makes more
> sense. I was aware of -A, but was not aware of ifconfig  behaviour.

Perhaps also consider moving counters to netstat -s instead of ifconfig.



Re: Race in disk_attach_callback?

2022-07-13 Thread Stefan Sperling
On Wed, Jul 13, 2022 at 02:18:53PM +0200, Otto Moerbeek wrote:
> Hi,
> 
> after a prompt from stsp@ and florian@, reporting that newfs_msdos
> fails when given an $duid.i argument, I set down to see what could be
> going on. My test using an USB stick failed to reprdouce the problem.
> Then I started using a vnd, and that shows the issue (once in a
> while). The feeling is that any disk devcied created on the fly might
> show this issue.

Just as an additional detail: This also affects softraid volumes,
which is how I ran into the issue. Installing a laptop with
softraid full disk encryption on top of an EFI/GPT disk can result
in a failure to format the MSDOS partition required for installing
the EFI boot loader. When this happens the installer reports that
it could not install a boot loader.
A manual invocation of newfs_msdos with the correct /dev/sdxi device,
and a subsequent invocation of installboot, can be used as a workaround.



Re: What is ieee80211com.ic_max_nnodes?

2022-07-12 Thread Stefan Sperling
On Mon, Jul 11, 2022 at 03:13:58PM -0400, Farhan Khan wrote:
> On Mon, Jul 11, 2022, at 2:24 PM, Stefan Sperling wrote:
> Thank you so much for your prompt reply!
> 
> > In AP mode, max nodes effectively sets a limit on how many clients can
> > be connected concurrently. Because athn(4) USB firmware has an internal
> > limit of 8 stations in its station table, and one entry is reserved for
> > other use, the USB device can only serve 7 clients at a time.
> 
> Can you please show me where that limit is set to 7 or 8?

Sorry, my memories of what happened here were flaky.

There used to be a limit on max_nnodes as described above. But this was
lifted because it was also enforced in client mode (so the driver could
not scan for more than 8 APs at a time).
See this commit:
https://github.com/openbsd/src/commit/dd463f29c687b46f3b8f379c8ee269693223931a

> > In the line of code you linked to, a similar cap is applied based on the
> > number of pairwise WPA key slots available in hardware. This should be
> > larger than the USB device limit, since the driver queries the device for
> > this limit and caps it at 128.
> > 
> 
> As this paragraph says, rather than 7 or 8, sc->kc_entries is 128.
> And lastly, how is ic_max_nnodes used by the net80211 stack?

It limits the amount of new allocations in ieee80211_alloc_node_helper().



Re: What is ieee80211com.ic_max_nnodes?

2022-07-11 Thread Stefan Sperling
On Mon, Jul 11, 2022 at 11:32:12AM -0400, Farhan Khan wrote:
> Hi all,
> 
> I am reading through the athn(4) driver and see a reference to 
> ieee80211com.ic_max_nnodes here 
> (http://bxr.su/OpenBSD/sys/dev/ic/athn.c#294). What is this variable? The 
> comment immediately above says "In HostAP mode, the number of STAs that we 
> can handle...". What does "handle" this mean in this context? What is it used 
> for?
> 
> Broader question: I am trying to identify what the FreeBSD equivalent of this 
> is, but that exact question might be out of scope of this email list.
> 
> Preliminary Research:
> * Looking through the code, I see that it is used only by athn(4) and rtwn(4).
> * The ieee80211 subsystem assigns it to ieee80211_cache_size aka 
> IEEE80211_CACHE_SIZE (512) by default. So does the athn driver.
> * The variable is consumed in sys/net80211/ieee80211_node.c in the functions 
> ieee80211_alloc_node_helper ieee80211_clean_nodes, but I do not these 
> functions (yet).
> * NetBSD seems to call the the variable ic_max_aid, but I could be mistaken. 
> Their wi(4), rtwn(4) and rt(4) drivers uses it.
> 
> Thanks!

It is the maximum allowed number of entries in ic_tree.

struct ieee80211_tree   ic_tree;
int ic_nnodes;  /* length of ic_nnodes */
int ic_max_nnodes;  /* max length of ic_nnodes */

This tree represents our view of all other the wlan devices we can see
and potentially interact with.
(The comments say 'length' because at some point in time, ic_tree was a
list instead of a tree; someone forgot to update/remove these comments
when that change was made.)

Nodes in this tree are keyed on MAC address, and correspond to a "station"
in 802.11 standard terminology.

In client mode, max nodes says how many APs can show up in scan results.

In AP mode, max nodes effectively sets a limit on how many clients can
be connected concurrently. Because athn(4) USB firmware has an internal
limit of 8 stations in its station table, and one entry is reserved for
other use, the USB device can only serve 7 clients at a time.
In the line of code you linked to, a similar cap is applied based on the
number of pairwise WPA key slots available in hardware. This should be
larger than the USB device limit, since the driver queries the device for
this limit and caps it at 128.



Re: bwfm: fix ifconfig media display on rpi2 usb wifi dongle

2022-06-26 Thread Stefan Sperling
On Sun, Jun 26, 2022 at 07:48:46PM +1000, Jonathan Gray wrote:
> sta.rssi is later used which is 'Fields valid for ver >= 4'
> but it seems with the earlier zeroing the use here should be fine?

Thanks! I missed that.

Testing suggests it makes more sense to keep the RSSI value which
was discovered during the scan phase.

With the new patch below ifconfig shows -51dBm.
With the previous patch ifconfig showed -70dBm for the same AP (with
client/AP location unchanged).

diff /usr/src
commit - 9badb9ad8932c12f4ece484255eb2703a2518c17
path + /usr/src
blob - 0c9c948115a0c115a43bd365ad4e389ba694c4a8
file + sys/dev/ic/bwfm.c
--- sys/dev/ic/bwfm.c
+++ sys/dev/ic/bwfm.c
@@ -703,22 +703,24 @@ bwfm_update_node(void *arg, struct ieee80211_node *ni)
if (!IEEE80211_ADDR_EQ(ni->ni_macaddr, sta.ea))
return;
 
-   if (le16toh(sta.ver) < 4)
+   if (le16toh(sta.ver) < 3)
return;
 
flags = le32toh(sta.flags);
if ((flags & BWFM_STA_SCBSTATS) == 0)
return;
 
-   rssi = 0;
-   for (i = 0; i < BWFM_ANT_MAX; i++) {
-   if (sta.rssi[i] >= 0)
-   continue;
-   if (rssi == 0 || sta.rssi[i] > rssi)
-   rssi = sta.rssi[i];
+   if (le16toh(sta.ver) >= 4) {
+   rssi = 0;
+   for (i = 0; i < BWFM_ANT_MAX; i++) {
+   if (sta.rssi[i] >= 0)
+   continue;
+   if (rssi == 0 || sta.rssi[i] > rssi)
+   rssi = sta.rssi[i];
+   }
+   if (rssi)
+   ni->ni_rssi = rssi;
}
-   if (rssi)
-   ni->ni_rssi = rssi;
 
txrate = le32toh(sta.tx_rate); /* in kbit/s */
if (txrate == 0x) /* Seen this happening during association. */



bwfm: fix ifconfig media display on rpi2 usb wifi dongle

2022-06-25 Thread Stefan Sperling
There is an off-by-one in bwfm_update_node(). This function reads
the tx_rate field from station information returned by firmware.

According to a comment in the Linux driver, this field is valid
for sta_info command versions >= 3.

linux/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
struct brcmf_sta_info_le {
__le16 ver; /* version of this struct */
[...]
/* Fields valid for ver >= 3 */
[...]
__le32 tx_rate; /* Rate of last successful tx frame */

However, our driver only reads Tx rate info if the version is >= 4.

On the rpi2 usb wifi adapter (WLU6331) this breaks media mode display.
Firmware on this device uses command version 3, and the media mode
displayed is always "DS1 11g". Diff below fixes this. ifconfig will
now display 11n mode while associated to an 11n AP.

ok?

diff /usr/src
commit - 9badb9ad8932c12f4ece484255eb2703a2518c17
path + /usr/src
blob - 0c9c948115a0c115a43bd365ad4e389ba694c4a8
file + sys/dev/ic/bwfm.c
--- sys/dev/ic/bwfm.c
+++ sys/dev/ic/bwfm.c
@@ -703,7 +703,7 @@ bwfm_update_node(void *arg, struct ieee80211_node *ni)
if (!IEEE80211_ADDR_EQ(ni->ni_macaddr, sta.ea))
return;
 
-   if (le16toh(sta.ver) < 4)
+   if (le16toh(sta.ver) < 3)
return;
 
flags = le32toh(sta.flags);



Re: I got the RALINK RT5372 usb wifi adapter working

2022-05-10 Thread Stefan Sperling
On Mon, May 09, 2022 at 08:17:35PM +, molotov31337 wrote:
> I recently picked up a Panda Wireless PAU06 and got it working, can this be 
> committed?
> Here is the cvs diff

Committed, thanks!

> Index: usbdevs
> ===
> RCS file: /cvs/src/sys/dev/usb/usbdevs,v
> retrieving revision 1.745
> diff -u -p -u -r1.745 usbdevs
> --- usbdevs 24 Dec 2021 06:18:11 - 1.745
> +++ usbdevs 9 May 2022 20:12:42 -
> @@ -3731,6 +3731,7 @@ product RALINK RT3370 0x3370 RT3370
> product RALINK RT3572 0x3572 RT3572
> product RALINK RT3573 0x3573 RT3573
> product RALINK RT5370 0x5370 RT5370
> +product RALINK RT5372 0x5372 RT5372
> product RALINK RT5572 0x5572 RT5572
> product RALINK MT7601 0x7601 MT7601
> product RALINK MT7601_2 0x760a MT7601
> Index: if_run.c
> ===
> RCS file: /cvs/src/sys/dev/usb/if_run.c,v
> retrieving revision 1.135
> diff -u -p -u -r1.135 if_run.c
> --- if_run.c 22 Nov 2021 10:17:14 - 1.135
> +++ if_run.c 9 May 2022 20:12:43 -
> @@ -259,6 +259,7 @@ static const struct usb_devno run_devs[]
> USB_ID(RALINK, RT3572),
> USB_ID(RALINK, RT3573),
> USB_ID(RALINK, RT5370),
> + USB_ID(RALINK, RT5372),
> USB_ID(RALINK, RT5572),
> USB_ID(RALINK, RT8070), USB_ID(SAMSUNG, WIS09ABGN),
> 
> And the device shows up in dmesg as
> run0 at uhub0 port 4 configuration 1 interface 0 "Ralink 802.11 n WLAN" rev 
> 2.00/1.01 addr 2
> run0: MAC/BBP RT5392 (rev 0x0223), RF RT5372 (MIMO 2T2R), address 
> 9c:ef:d5:fa:4b:15
> 
> Sent with [ProtonMail](https://protonmail.com/) secure email.



fix mac address on iwx(4) AX210

2022-05-10 Thread Stefan Sperling
As noticed by jsg@ and kevlo@ we use a bad MAC address on AX210 devices.
Patch below fixes the issue on AX210, and still works on AX200.

The old way of reading the MAC no longer works on AX210; apparently this
new way of reading the MAC was introduced in the 9k hw generation but the
old way was still working until now.

ok?

diff 04382ee86a01509dce834178b7ab1460d3539207 
37ed6bbfb5c966e24cc7dbbe8dd40222aac69407
blob - b3ea3675ae9dc65b56a1c90ab7f92c1c0a4f3a8f
blob + 9e94f17a9fc41ca7c3ce1096497ccc478f958197
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -341,8 +341,9 @@ voidiwx_sta_tx_agg_start(struct iwx_softc *, struct 
i
uint8_t);
 void   iwx_ba_task(void *);
 
-intiwx_set_mac_addr_from_csr(struct iwx_softc *, struct iwx_nvm_data *);
+void   iwx_set_mac_addr_from_csr(struct iwx_softc *, struct iwx_nvm_data *);
 intiwx_is_valid_mac_addr(const uint8_t *);
+void   iwx_flip_hw_address(uint32_t, uint32_t, uint8_t *);
 intiwx_nvm_get(struct iwx_softc *);
 intiwx_load_firmware(struct iwx_softc *);
 intiwx_start_fw(struct iwx_softc *);
@@ -3688,31 +3689,33 @@ iwx_ampdu_tx_start(struct ieee80211com *ic, struct iee
return EBUSY;
 }
 
-/* Read the mac address from WFMP registers. */
-int
+void
 iwx_set_mac_addr_from_csr(struct iwx_softc *sc, struct iwx_nvm_data *data)
 {
-   const uint8_t *hw_addr;
uint32_t mac_addr0, mac_addr1;
 
+   memset(data->hw_addr, 0, sizeof(data->hw_addr));
+
if (!iwx_nic_lock(sc))
-   return EBUSY;
+   return;
 
-   mac_addr0 = htole32(iwx_read_prph(sc, IWX_WFMP_MAC_ADDR_0));
-   mac_addr1 = htole32(iwx_read_prph(sc, IWX_WFMP_MAC_ADDR_1));
+   mac_addr0 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR0_STRAP(sc)));
+   mac_addr1 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR1_STRAP(sc)));
 
-   hw_addr = (const uint8_t *)_addr0;
-   data->hw_addr[0] = hw_addr[3];
-   data->hw_addr[1] = hw_addr[2];
-   data->hw_addr[2] = hw_addr[1];
-   data->hw_addr[3] = hw_addr[0];
+   iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
 
-   hw_addr = (const uint8_t *)_addr1;
-   data->hw_addr[4] = hw_addr[1];
-   data->hw_addr[5] = hw_addr[0];
+   /* If OEM fused a valid address, use it instead of the one in OTP. */
+   if (iwx_is_valid_mac_addr(data->hw_addr)) {
+   iwx_nic_unlock(sc);
+   return;
+   }
 
+   mac_addr0 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR0_OTP(sc)));
+   mac_addr1 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR1_OTP(sc)));
+
+   iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
+
iwx_nic_unlock(sc);
-   return 0;
 }
 
 int
@@ -3728,6 +3731,22 @@ iwx_is_valid_mac_addr(const uint8_t *addr)
!ETHER_IS_MULTICAST(addr));
 }
 
+void
+iwx_flip_hw_address(uint32_t mac_addr0, uint32_t mac_addr1, uint8_t *dest)
+{
+   const uint8_t *hw_addr;
+
+   hw_addr = (const uint8_t *)_addr0;
+   dest[0] = hw_addr[3];
+   dest[1] = hw_addr[2];
+   dest[2] = hw_addr[1];
+   dest[3] = hw_addr[0];
+
+   hw_addr = (const uint8_t *)_addr1;
+   dest[4] = hw_addr[1];
+   dest[5] = hw_addr[0];
+}
+
 int
 iwx_nvm_get(struct iwx_softc *sc)
 {
@@ -10654,6 +10673,8 @@ iwx_attach(struct device *parent, struct device *self,
}
}
 
+   sc->mac_addr_from_csr = 0x380; /* differs on BZ hw generation */
+
if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
sc->sc_umac_prph_offset = 0x30;
sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX_GEN3;
blob - 6ddfb14e5eb9240cc82ea07d12a6e5c846167586
blob + 0f1948913a39bee6956603e3e322b9961615f038
--- sys/dev/pci/if_iwxreg.h
+++ sys/dev/pci/if_iwxreg.h
@@ -1160,6 +1160,12 @@ enum msix_ivar_for_cause {
 #define IWX_MSIX_AUTO_CLEAR_CAUSE  (0 << 7)
 #define IWX_MSIX_NON_AUTO_CLEAR_CAUSE  (1 << 7)
 
+#define IWX_CSR_ADDR_BASE(sc)  ((sc)->mac_addr_from_csr)
+#define IWX_CSR_MAC_ADDR0_OTP(sc)  (IWX_CSR_ADDR_BASE(sc) + 0x00)
+#define IWX_CSR_MAC_ADDR1_OTP(sc)  (IWX_CSR_ADDR_BASE(sc) + 0x04)
+#define IWX_CSR_MAC_ADDR0_STRAP(sc)(IWX_CSR_ADDR_BASE(sc) + 0x08)
+#define IWX_CSR_MAC_ADDR1_STRAP(sc)(IWX_CSR_ADDR_BASE(sc) + 0x0c)
+
 /**
  * uCode API flags
  * @IWX_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
blob - bec0758d890fb5939a291ed794a610f9e5ac37df
blob + 19f9a333d1a1e479845512439daaef8adc164ca4
--- sys/dev/pci/if_iwxvar.h
+++ sys/dev/pci/if_iwxvar.h
@@ -681,6 +681,7 @@ struct iwx_softc {
 #define IWX_DEVICE_FAMILY_220001
 #define IWX_DEVICE_FAMILY_AX2102
uint32_t sc_sku_id[3];
+   uint32_t mac_addr_from_csr;
 
struct iwx_dma_info ctxt_info_dma;
struct iwx_self_init_dram init_dram;



add support for AX210/AX211 devices to iwx(4)

2022-05-09 Thread Stefan Sperling
This patch adds support for AX210/AX211 devices to iwx(4).

While this patch attempts to make a couple of devices work which
are part of this device family, so far only one specific AX210
device has been tested:

iwx0 at pci4 dev 0 function 0 "Intel Wi-Fi 6 AX210" rev 0x1a, msix
iwx0: hw rev 0x420, fw 67.8f59b80b.0, pnvm dda57f4f, address ba:d0:f1:95:2b:a0

Problems are not entirely unexpected when testing on other devices.
Hopefully, any AX210/AX211 devices will work. But since several variants
of firmware are involved and each firmware variant requires a specific
device, I cannot test everything by myself.
If your device is not working please enable 'ifconfig iwx0 debug' and
include the additional information this prints to /var/log/messages
in your test report.

I have tested this patch on AX200 and AX201 devices as well. I do not
see any regressions but additional testing would be welcome.

AX210 device firmware is already available via fw_update.
The required firmware package version is iwx-firmware-20220110.

Please update your tree before applying this patch. I made a commit
to sys/dev/pci/pcidevs earlier today which this patch depends on.
It will fail to compile otherwise.

diff 9d011d1bb76b879a432878d921f2f89e1153b973 refs/heads/ax210
blob - ba8e3352346b081628ac1b4999fc7681b48eb695
blob + cad4b806a5bb3626af3b395da4ab8bd55f8cd17f
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -175,6 +175,7 @@ static const uint8_t iwx_nvm_channels_uhb[] = {
 };
 
 #define IWX_NUM_2GHZ_CHANNELS  14
+#define IWX_NUM_5GHZ_CHANNELS  37
 
 const struct iwx_rate {
uint16_t rate;
@@ -239,7 +240,10 @@ intiwx_store_cscheme(struct iwx_softc *, uint8_t 
*, s
 intiwx_alloc_fw_monitor_block(struct iwx_softc *, uint8_t, uint8_t);
 intiwx_alloc_fw_monitor(struct iwx_softc *, uint8_t);
 intiwx_apply_debug_destination(struct iwx_softc *);
+void   iwx_set_ltr(struct iwx_softc *);
 intiwx_ctxt_info_init(struct iwx_softc *, const struct iwx_fw_sects *);
+intiwx_ctxt_info_gen3_init(struct iwx_softc *,
+   const struct iwx_fw_sects *);
 void   iwx_ctxt_info_free_fw_img(struct iwx_softc *);
 void   iwx_ctxt_info_free_paging(struct iwx_softc *);
 intiwx_init_fw_sec(struct iwx_softc *, const struct iwx_fw_sects *,
@@ -250,10 +254,15 @@ int   iwx_firmware_store_section(struct iwx_softc *, 
enu
 intiwx_set_default_calib(struct iwx_softc *, const void *);
 void   iwx_fw_info_free(struct iwx_fw_info *);
 intiwx_read_firmware(struct iwx_softc *);
+uint32_t iwx_prph_addr_mask(struct iwx_softc *);
 uint32_t iwx_read_prph_unlocked(struct iwx_softc *, uint32_t);
 uint32_t iwx_read_prph(struct iwx_softc *, uint32_t);
 void   iwx_write_prph_unlocked(struct iwx_softc *, uint32_t, uint32_t);
 void   iwx_write_prph(struct iwx_softc *, uint32_t, uint32_t);
+uint32_t iwx_read_umac_prph_unlocked(struct iwx_softc *, uint32_t);
+uint32_t iwx_read_umac_prph(struct iwx_softc *, uint32_t);
+void   iwx_write_umac_prph_unlocked(struct iwx_softc *, uint32_t, uint32_t);
+void   iwx_write_umac_prph(struct iwx_softc *, uint32_t, uint32_t);
 intiwx_read_mem(struct iwx_softc *, uint32_t, void *, int);
 intiwx_write_mem(struct iwx_softc *, uint32_t, const void *, int);
 intiwx_write_mem32(struct iwx_softc *, uint32_t, uint32_t);
@@ -337,6 +346,10 @@ intiwx_is_valid_mac_addr(const uint8_t *);
 intiwx_nvm_get(struct iwx_softc *);
 intiwx_load_firmware(struct iwx_softc *);
 intiwx_start_fw(struct iwx_softc *);
+intiwx_pnvm_handle_section(struct iwx_softc *, const uint8_t *, size_t);
+intiwx_pnvm_parse(struct iwx_softc *, const uint8_t *, size_t);
+void   iwx_ctxt_info_gen3_set_pnvm(struct iwx_softc *);
+intiwx_load_pnvm(struct iwx_softc *);
 intiwx_send_tx_ant_cfg(struct iwx_softc *, uint8_t);
 intiwx_send_phy_cfg_cmd(struct iwx_softc *);
 intiwx_load_ucode_wait_alive(struct iwx_softc *);
@@ -357,7 +370,7 @@ voidiwx_rx_frame(struct iwx_softc *, struct mbuf *, 
i
uint32_t, struct ieee80211_rxinfo *, struct mbuf_list *);
 void   iwx_clear_tx_desc(struct iwx_softc *, struct iwx_tx_ring *, int);
 void   iwx_txd_done(struct iwx_softc *, struct iwx_tx_data *);
-void   iwx_txq_advance(struct iwx_softc *, struct iwx_tx_ring *, int);
+void   iwx_txq_advance(struct iwx_softc *, struct iwx_tx_ring *, uint16_t);
 void   iwx_rx_tx_cmd(struct iwx_softc *, struct iwx_rx_packet *,
struct iwx_rx_data *);
 void   iwx_clear_oactive(struct iwx_softc *, struct iwx_tx_ring *);
@@ -381,8 +394,9 @@ int iwx_send_cmd_pdu_status(struct iwx_softc *, uint32
 void   iwx_free_resp(struct iwx_softc *, struct iwx_host_cmd *);
 void   iwx_cmd_done(struct iwx_softc *, int, int, int);
 const struct iwx_rate *iwx_tx_fill_cmd(struct iwx_softc *, struct iwx_node *,
-   struct ieee80211_frame *, struct iwx_tx_cmd_gen2 *);
-void   iwx_tx_update_byte_tbl(struct iwx_tx_ring *, int, uint16_t, uint16_t);
+   struct ieee80211_frame *, uint16_t *, 

Re: athn(4) USB question: Where is Tx interrupt handler?

2022-05-08 Thread Stefan Sperling
On Sun, May 08, 2022 at 12:29:57AM -0400, Farhan Khan wrote:
> On May 6, 2022 4:37:48 AM EDT, Stefan Sperling  wrote:
> >On Thu, May 05, 2022 at 01:19:08PM -0400, Farhan Khan wrote:
> >> Hi all,
> >> 
> >> Summary Question:
> >> 
> >> Broadly, I am trying to understand where a interrupt callback is specified 
> >> if 
> >> not already specified by usbd_open_pipe_intr(9). Specifically, for the 
> >> athn(4) 
> >> driver, I am trying to understand if/how athn_usb_intr() is executed for 
> >> Tx 
> >> interrupts. This seems necessary yet I do not see a callback specified by 
> >> usbd_setup_xfer(9) or by usbd_open_pipe_intr(9).
> >> 
> >> All code is located in sys/dev/usb/if_athn_usb.c.
> >> 
> >> Question Walk-through:
> >> 
> >> >From reading the code, it seems that the athn_usb_intr() function is 
> >> >called 
> >> whenever a Tx interrupt is triggered. The reason I think this is because 
> >> there 
> >> is a tsleep_nsec(9) for a Tx interrupt that awaits for a wakeup(9) that 
> >> only 
> >> happens in athn_usb_intr().
> >> 
> >> The 3 relevant steps are listed below in athn_usb_htc_setup() under the 
> >> comment "Set credits for WLAN Tx pipe":
> >> 
> >> 1. athn_usb_htc_msg(), which runs usbd_setup_xfer(9) and usbd_transfer(9) 
> >> for 
> >> a Tx interrupt. The callback is set to NULL.
> >> 2. usc->wait_msg_id is set to AR_HTC_MSG_CONF_PIPE_RSP.
> >> 3. A tsleep_nsec() on >wait_msg_id
> >> 
> >> The only place I see a wakeup(9) on >wait_msg_id is within 
> >> athn_usb_intr(), on condition that usc->wait_msg_id is set to 
> >> AR_HTC_MSG_CONF_PIPE_RSP. Seems like a perfect match. Additionally, I do 
> >> not 
> >> see an Rx interrupt anywhere else. But even if it does happen somewhere 
> >> and I 
> >> am just missing it, the only place AR_HTC_MSG_CONF_PIPE_RSP is used is 
> >> step 2.
> >> 
> >> Rx interrupt callbacks to athn_usb_intr() are specified by the 
> >> usbd_open_pipe_intr(9) call in athn_usb_open_pipes(). That seems explicit. 
> >> But 
> >> for the Tx interrupt, I do not see where the mapping to athn_usb_intr() is.
> >> 
> >> Please assist, thank you.
> >
> >Everything related to Tx is happening in athn_usb_tx() and athn_usb_txoef().
> >
> >usbd_setup_xfer() gets a function pointer to call when the USB transfer
> >has completed. This function pointer is athn_usb_txeof():
> >
> > usbd_setup_xfer(data->xfer, usc->tx_data_pipe, data, data->buf,
> > xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT,
> > athn_usb_txeof);
> >
> >athn_usb_txeof() puts the buffer associated with the Tx attempt back onto
> >the list of free buffers, and schedules more Tx attempts if needed by
> >calling if_start().
> >
> >The associated mbuf is freed quite early, before the Tx attempt is even made,
> >because the entire packet gets copied into the Tx command sent to the device:
> >
> > /* Copy payload. */
> > m_copydata(m, 0, m->m_pkthdr.len, frm);
> > frm += m->m_pkthdr.len;
> > m_freem(m);
> 
> 
> Hi Stefan!
> Reading through athn_usb_txeof, I don't see where it triggers an Rx interrupt 
> such that the wakeup(9) is done. Additionally, that seems to be a periodic 
> function whereas I suspect thr interrupt I am looking for is only during 
> initial of the device, not if-up. But perhaps I am mistaken? I do kot 
> understand where or how the wakeup(9) occurs.
> 
> Thanks!
 
athn_usb_intr() is not used for Tx interrupts.
athn_usb_intr() is only used to process HTC message responses, not for
processing packets. The driver sleeps on >wait_msg_id when it must
wait for a device command to be processed before the driver can continue.
A wakeup() is required in that case to interrupt the corresponding tsleep().
But when the driver is submitting a packet for Tx there is no need to wait.



Re: athn(4) USB question: Where is Tx interrupt handler?

2022-05-06 Thread Stefan Sperling
On Thu, May 05, 2022 at 01:19:08PM -0400, Farhan Khan wrote:
> Hi all,
> 
> Summary Question:
> 
> Broadly, I am trying to understand where a interrupt callback is specified if 
> not already specified by usbd_open_pipe_intr(9). Specifically, for the 
> athn(4) 
> driver, I am trying to understand if/how athn_usb_intr() is executed for Tx 
> interrupts. This seems necessary yet I do not see a callback specified by 
> usbd_setup_xfer(9) or by usbd_open_pipe_intr(9).
> 
> All code is located in sys/dev/usb/if_athn_usb.c.
> 
> Question Walk-through:
> 
> >From reading the code, it seems that the athn_usb_intr() function is called 
> whenever a Tx interrupt is triggered. The reason I think this is because 
> there 
> is a tsleep_nsec(9) for a Tx interrupt that awaits for a wakeup(9) that only 
> happens in athn_usb_intr().
> 
> The 3 relevant steps are listed below in athn_usb_htc_setup() under the 
> comment "Set credits for WLAN Tx pipe":
> 
> 1. athn_usb_htc_msg(), which runs usbd_setup_xfer(9) and usbd_transfer(9) for 
> a Tx interrupt. The callback is set to NULL.
> 2. usc->wait_msg_id is set to AR_HTC_MSG_CONF_PIPE_RSP.
> 3. A tsleep_nsec() on >wait_msg_id
> 
> The only place I see a wakeup(9) on >wait_msg_id is within 
> athn_usb_intr(), on condition that usc->wait_msg_id is set to 
> AR_HTC_MSG_CONF_PIPE_RSP. Seems like a perfect match. Additionally, I do not 
> see an Rx interrupt anywhere else. But even if it does happen somewhere and I 
> am just missing it, the only place AR_HTC_MSG_CONF_PIPE_RSP is used is step 2.
> 
> Rx interrupt callbacks to athn_usb_intr() are specified by the 
> usbd_open_pipe_intr(9) call in athn_usb_open_pipes(). That seems explicit. 
> But 
> for the Tx interrupt, I do not see where the mapping to athn_usb_intr() is.
> 
> Please assist, thank you.

Everything related to Tx is happening in athn_usb_tx() and athn_usb_txoef().

usbd_setup_xfer() gets a function pointer to call when the USB transfer
has completed. This function pointer is athn_usb_txeof():

usbd_setup_xfer(data->xfer, usc->tx_data_pipe, data, data->buf,
xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT,
athn_usb_txeof);

athn_usb_txeof() puts the buffer associated with the Tx attempt back onto
the list of free buffers, and schedules more Tx attempts if needed by
calling if_start().

The associated mbuf is freed quite early, before the Tx attempt is even made,
because the entire packet gets copied into the Tx command sent to the device:

/* Copy payload. */
m_copydata(m, 0, m->m_pkthdr.len, frm);
frm += m->m_pkthdr.len;
m_freem(m);



Re: patch: if_iwx.c add support for ax201 with subsystem id 0x0030

2022-04-09 Thread Stefan Sperling
On Sat, Apr 09, 2022 at 05:46:29PM +0200, Sven Wolf wrote:
> Hi Stefan,
> 
> thanks for your effort.
> I've successfully tested your latest patch.
> I also got the sw_hw_rev:
> 
> sc_hw_rev=354

Thank you! Now everything makes sense :)



Re: patch: if_iwx.c add support for ax201 with subsystem id 0x0030

2022-04-09 Thread Stefan Sperling
On Sat, Apr 09, 2022 at 04:53:50PM +0200, Stefan Sperling wrote:
> On Sat, Apr 09, 2022 at 04:52:12PM +0200, Stefan Sperling wrote:
> > On Sat, Apr 09, 2022 at 04:29:42PM +0200, Stefan Sperling wrote:
> > > As sthen points out, please show sc_hw_rev without any of its bits
> > > masked out, with a patch like this:
> > 
> > Nevermind, I found a bug in my patch which most certainly
> > breaks your device.
> > 
> > Please try this on top of the patch I sent out, without any
> > other modifcations. Your device should work with this change.
> 
> And for everyone else, here is a new complete diff with this
> fix rolled in.

And looking over the linux code again, I realized there is a whole
class of devices ("Qu C0") which our code didn't handle yet.
Fixed here.

diff refs/heads/master refs/heads/iwx-match
blob - df5614f9f6140ba069db8d60e724b1ab36d124a2
blob + 69f489127b1a6898d12f5f5b2683cb7b3558293b
--- share/man/man4/iwx.4
+++ share/man/man4/iwx.4
@@ -84,8 +84,12 @@ which are loaded when an interface is brought up:
 .Pp
 .Bl -tag -width Ds -offset indent -compact
 .It Pa /etc/firmware/iwx-cc-a0-67
-.It Pa /etc/firmware/iwx-QuZ-a0-hr-b0-67
+.It Pa /etc/firmware/iwx-Qu-b0-hr-b0-63
+.It Pa /etc/firmware/iwx-Qu-b0-jf-b0-63
 .It Pa /etc/firmware/iwx-Qu-c0-hr-b0-63
+.It Pa /etc/firmware/iwx-Qu-c0-jf-b0-63
+.It Pa /etc/firmware/iwx-QuZ-a0-hr-b0-67
+.It Pa /etc/firmware/iwx-QuZ-a0-jf-b0-63
 .El
 .Pp
 These firmware files are not free because Intel refuses to grant
blob - 11f582e67321c9782b9cb38e6ce948b465522c94
blob + 8e21d8db3c63b3644f366a112404a174b8cbd722
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -491,6 +491,7 @@ int iwx_intr_msix(void *);
 intiwx_match(struct device *, void *, void *);
 intiwx_preinit(struct iwx_softc *);
 void   iwx_attach_hook(struct device *);
+const struct iwx_device_cfg *iwx_find_device_cfg(struct iwx_softc *);
 void   iwx_attach(struct device *, struct device *, void *);
 void   iwx_init_task(void *);
 intiwx_activate(struct device *, int);
@@ -870,7 +871,7 @@ iwx_ctxt_info_init(struct iwx_softc *sc, const struct 
/* size is in DWs */
ctxt_info->version.size = htole16(sizeof(*ctxt_info) / 4);
 
-   if (sc->sc_device_family >= IWX_DEVICE_FAMILY_22560)
+   if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
rb_size = IWX_CTXT_INFO_RB_SIZE_2K;
else
rb_size = IWX_CTXT_INFO_RB_SIZE_4K;
@@ -9392,61 +9393,192 @@ static const struct pci_matchid iwx_devices[] = {
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_3 },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_4,},
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_5,},
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_6,},
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_7,},
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_8,},
 };
 
-static const struct pci_matchid iwx_subsystem_id_ax201[] = {
-   { PCI_VENDOR_INTEL, 0x0070 },
-   { PCI_VENDOR_INTEL, 0x0074 },
-   { PCI_VENDOR_INTEL, 0x0078 },
-   { PCI_VENDOR_INTEL, 0x007c },
-   { PCI_VENDOR_INTEL, 0x0310 },
-   { PCI_VENDOR_INTEL, 0x2074 },
-   { PCI_VENDOR_INTEL, 0x4070 },
-   /* TODO: There are more ax201 devices with "main" product ID 0x06f0 */
-};
 
 int
 iwx_match(struct device *parent, iwx_match_t match __unused, void *aux)
 {
struct pci_attach_args *pa = aux;
-   pcireg_t subid;
-   pci_vendor_id_t svid;
-   pci_product_id_t spid;
-   int i;
-
-   if (!pci_matchbyid(pa, iwx_devices, nitems(iwx_devices)))
-   return 0;
-
-   /*
-* Some PCI product IDs are shared among devices which use distinct
-* chips or firmware. We need to match the subsystem ID as well to
-* ensure that we have in fact found a supported device.
-*/
-   subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
-   svid = PCI_VENDOR(subid);
-   spid = PCI_PRODUCT(subid);
-
-   switch (PCI_PRODUCT(pa->pa_id)) {
-   case PCI_PRODUCT_INTEL_WL_22500_1: /* AX200 */
-   return 1; /* match any device */
-   case PCI_PRODUCT_INTEL_WL_22500_2: /* AX201 */
-   case PCI_PRODUCT_INTEL_WL_22500_3: /* AX201 */
-   case PCI_PRODUCT_INTEL_WL_22500_4: /* AX201 */
-   case PCI_PRODUCT_INTEL_WL_22500_5: /* AX201 */
-   for (i = 0; i < nitems(iwx_subsystem_id_ax201); i++) {
-   if (svid == iwx_subsystem_id_ax201[i].pm_vid &&
-   spid == iwx_subsystem_id_ax201[i].pm_pid)
-   return 1;
-
-   }
-   break;
-   default:
-   break;
-   }
-
-   return 0;
+   return pci_matchbyid(pa, iwx_devices, nitems(iwx_devices));
 }
 
+/*
+ * The device info table below contains device-sp

Re: patch: if_iwx.c add support for ax201 with subsystem id 0x0030

2022-04-09 Thread Stefan Sperling
On Sat, Apr 09, 2022 at 04:52:12PM +0200, Stefan Sperling wrote:
> On Sat, Apr 09, 2022 at 04:29:42PM +0200, Stefan Sperling wrote:
> > As sthen points out, please show sc_hw_rev without any of its bits
> > masked out, with a patch like this:
> 
> Nevermind, I found a bug in my patch which most certainly
> breaks your device.
> 
> Please try this on top of the patch I sent out, without any
> other modifcations. Your device should work with this change.

And for everyone else, here is a new complete diff with this
fix rolled in.

diff refs/heads/master refs/heads/iwx-match
blob - df5614f9f6140ba069db8d60e724b1ab36d124a2
blob + 69f489127b1a6898d12f5f5b2683cb7b3558293b
--- share/man/man4/iwx.4
+++ share/man/man4/iwx.4
@@ -84,8 +84,12 @@ which are loaded when an interface is brought up:
 .Pp
 .Bl -tag -width Ds -offset indent -compact
 .It Pa /etc/firmware/iwx-cc-a0-67
-.It Pa /etc/firmware/iwx-QuZ-a0-hr-b0-67
+.It Pa /etc/firmware/iwx-Qu-b0-hr-b0-63
+.It Pa /etc/firmware/iwx-Qu-b0-jf-b0-63
 .It Pa /etc/firmware/iwx-Qu-c0-hr-b0-63
+.It Pa /etc/firmware/iwx-Qu-c0-jf-b0-63
+.It Pa /etc/firmware/iwx-QuZ-a0-hr-b0-67
+.It Pa /etc/firmware/iwx-QuZ-a0-jf-b0-63
 .El
 .Pp
 These firmware files are not free because Intel refuses to grant
blob - 11f582e67321c9782b9cb38e6ce948b465522c94
blob + 01d00599c7368fe1aef249a48b110104c980b52c
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -491,6 +491,7 @@ int iwx_intr_msix(void *);
 intiwx_match(struct device *, void *, void *);
 intiwx_preinit(struct iwx_softc *);
 void   iwx_attach_hook(struct device *);
+const struct iwx_device_cfg *iwx_find_device_cfg(struct iwx_softc *);
 void   iwx_attach(struct device *, struct device *, void *);
 void   iwx_init_task(void *);
 intiwx_activate(struct device *, int);
@@ -870,7 +871,7 @@ iwx_ctxt_info_init(struct iwx_softc *sc, const struct 
/* size is in DWs */
ctxt_info->version.size = htole16(sizeof(*ctxt_info) / 4);
 
-   if (sc->sc_device_family >= IWX_DEVICE_FAMILY_22560)
+   if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
rb_size = IWX_CTXT_INFO_RB_SIZE_2K;
else
rb_size = IWX_CTXT_INFO_RB_SIZE_4K;
@@ -9392,61 +9393,192 @@ static const struct pci_matchid iwx_devices[] = {
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_3 },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_4,},
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_5,},
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_6,},
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_7,},
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_8,},
 };
 
-static const struct pci_matchid iwx_subsystem_id_ax201[] = {
-   { PCI_VENDOR_INTEL, 0x0070 },
-   { PCI_VENDOR_INTEL, 0x0074 },
-   { PCI_VENDOR_INTEL, 0x0078 },
-   { PCI_VENDOR_INTEL, 0x007c },
-   { PCI_VENDOR_INTEL, 0x0310 },
-   { PCI_VENDOR_INTEL, 0x2074 },
-   { PCI_VENDOR_INTEL, 0x4070 },
-   /* TODO: There are more ax201 devices with "main" product ID 0x06f0 */
-};
 
 int
 iwx_match(struct device *parent, iwx_match_t match __unused, void *aux)
 {
struct pci_attach_args *pa = aux;
-   pcireg_t subid;
-   pci_vendor_id_t svid;
-   pci_product_id_t spid;
-   int i;
-
-   if (!pci_matchbyid(pa, iwx_devices, nitems(iwx_devices)))
-   return 0;
-
-   /*
-* Some PCI product IDs are shared among devices which use distinct
-* chips or firmware. We need to match the subsystem ID as well to
-* ensure that we have in fact found a supported device.
-*/
-   subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
-   svid = PCI_VENDOR(subid);
-   spid = PCI_PRODUCT(subid);
-
-   switch (PCI_PRODUCT(pa->pa_id)) {
-   case PCI_PRODUCT_INTEL_WL_22500_1: /* AX200 */
-   return 1; /* match any device */
-   case PCI_PRODUCT_INTEL_WL_22500_2: /* AX201 */
-   case PCI_PRODUCT_INTEL_WL_22500_3: /* AX201 */
-   case PCI_PRODUCT_INTEL_WL_22500_4: /* AX201 */
-   case PCI_PRODUCT_INTEL_WL_22500_5: /* AX201 */
-   for (i = 0; i < nitems(iwx_subsystem_id_ax201); i++) {
-   if (svid == iwx_subsystem_id_ax201[i].pm_vid &&
-   spid == iwx_subsystem_id_ax201[i].pm_pid)
-   return 1;
-
-   }
-   break;
-   default:
-   break;
-   }
-
-   return 0;
+   return pci_matchbyid(pa, iwx_devices, nitems(iwx_devices));
 }
 
+/*
+ * The device info table below contains device-specific config overrides.
+ * The most important parameter derived from this table is the name of the
+ * firmware image to load.
+ *
+ * The Linux iwlwifi driver uses an "old" and a "new" device info table.
+ * The "old" table matches devices based on P

Re: patch: if_iwx.c add support for ax201 with subsystem id 0x0030

2022-04-09 Thread Stefan Sperling
On Sat, Apr 09, 2022 at 04:29:42PM +0200, Stefan Sperling wrote:
> As sthen points out, please show sc_hw_rev without any of its bits
> masked out, with a patch like this:

Nevermind, I found a bug in my patch which most certainly
breaks your device.

Please try this on top of the patch I sent out, without any
other modifcations. Your device should work with this change.

diff 64e15b2294bce6a08025941cf9440784a6b2e1f2 /usr/src
blob - 9ffa40d1606fc261ed610984b82e0dbcada90340
file + sys/dev/pci/if_iwx.c
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -9860,13 +9860,12 @@ iwx_attach(struct device *parent, struct device *self,
case PCI_PRODUCT_INTEL_WL_22500_7:
case PCI_PRODUCT_INTEL_WL_22500_8:
if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ)
sc->sc_fwname = IWX_QU_B_HR_B_FW;
else
sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
-   sc->sc_fwname = IWX_QU_C_HR_B_FW;
sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
sc->sc_integrated = 1;
sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_1820;
sc->sc_low_latency_xtal = 0;
sc->sc_xtal_latency = 1820;
sc->sc_tx_with_siso_diversity = 0;



Re: patch: if_iwx.c add support for ax201 with subsystem id 0x0030

2022-04-09 Thread Stefan Sperling
On Sat, Apr 09, 2022 at 03:28:14PM +0200, Stefan Sperling wrote:
> On Sat, Apr 09, 2022 at 12:47:56PM +0200, Sven Wolf wrote:
> > Hi Stefan,
> > 
> > sorry, I'm not sure how I can get the sc_hw_rev value.
> > Hopefully this is the requested value:
> > 
> > iwx0: hw rev 0x350, fw ver 67.8f59b80b.0
> 
> This is not the "QuZ" (0x354) hardware revision.

So this is in fact very complicated.

Intel changed the layout of hw revision ID bits in hardware, but the
Linux driver had a workaround (which iwx is using as well) to store these
bits in the previous format. Later they changed the Linux driver again,
and now our definition of "QuZ" is different from that of Linux.
I cannot be sure anymore if our code is doing the right thing :-/

As sthen points out, please show sc_hw_rev without any of its bits
masked out, with a patch like this:

diff a26af1db5d30d7a58f91742886569d0d8891b827 /usr/src
blob - 2e96219c0dcfeaa4d24912b7e16f22dd617fe828
file + sys/dev/pci/if_iwx.c
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -9483,6 +9483,7 @@ iwx_preinit(struct iwx_softc *sc)
printf("%s: hw rev 0x%x, fw ver %s, address %s\n",
DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
+   printf("sc_hw_rev=%x\n", sc->sc_hw_rev);
 
if (sc->sc_nvm.sku_cap_11n_enable)
iwx_setup_ht_rates(sc);



Re: patch: if_iwx.c add support for ax201 with subsystem id 0x0030

2022-04-09 Thread Stefan Sperling
On Sat, Apr 09, 2022 at 12:47:56PM +0200, Sven Wolf wrote:
> Hi Stefan,
> 
> sorry, I'm not sure how I can get the sc_hw_rev value.
> Hopefully this is the requested value:
> 
> iwx0: hw rev 0x350, fw ver 67.8f59b80b.0

This is not the "QuZ" (0x354) hardware revision.

However, Linux obviously loads QuZ firmware anyway.
So either there is an override for your device in the iwlwifi dev_info
table, or all Qu devices must be treated QuZ unless overridden.

To proceed I need to know the output of pcidump -v on your system.

We already know the product ID (4df0). The device table also contains
the "subsystem" product ID which matters for the overrides table.
The relevant line from pcidump should look something like:
0x002c: Subsystem Vendor ID: 8086 Product ID: "
in the "Intel Wi-Fi 6 AX201" section.



Re: ral(4) 11n? I have spare hardware

2022-04-09 Thread Stefan Sperling
On Sat, Apr 09, 2022 at 03:26:03AM +0200, stolen data wrote:
> It's been great seeing iwm/iwn/iwx/athn getting a lot of updates lately. I
> wonder if there's any work planned for getting 11n support to some of the
> older but still capable Realtek chipsets in ral(4)?
> 
> I have a spare RT2860+RT2820 PCI card - Edimax EW-7728In - that I could
> part with if any developer would be interested. Perhaps stsp@?
> 

I already have ral(4) hardware, but not enough time to implement
802.11n across all drivers myself. It would be great to get some help.



Re: patch: if_iwx.c add support for ax201 with subsystem id 0x0030

2022-04-09 Thread Stefan Sperling
On Sat, Apr 09, 2022 at 12:31:09AM +0200, Sven Wolf wrote:
> Hi Stefan,
> 
> on my device WL_22500_8   0x4df0 this patch doesn't work directly.
> I get the error message:
> iwx0: could not load firmware, 35
> iwx0: failed to load init firmware
> 
> Under Linux the firmware iwlwifi-QuZ-a0-hr-b0-67.ucode is loaded for this
> device. Also my old patch
> (https://marc.info/?l=openbsd-bugs=164201744804674=2) works with the
> firmware for the WL_22500_5 devices.
> 
> With this small patch to your patch, wireless is working.
> 
> *** 9829,9834 
> --- 9829,9835 
>   break;
>   case PCI_PRODUCT_INTEL_WL_22500_2:
>   case PCI_PRODUCT_INTEL_WL_22500_5:
> + case PCI_PRODUCT_INTEL_WL_22500_8:
>   /* These devices should be QuZ only. */
>   if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ) {
>   printf("%s: unsupported AX201 adapter\n", DEVNAME(sc));
> ***
> *** 9858,9864 
>   break;
>   case PCI_PRODUCT_INTEL_WL_22500_4:
>   case PCI_PRODUCT_INTEL_WL_22500_7:
> - case PCI_PRODUCT_INTEL_WL_22500_8:
>   if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ)

Thanks Sven!

What is the value of sc_hw_rev on this 0x4df0 device?

>   sc->sc_fwname = IWX_QU_B_HR_B_FW;
>   else
> --- 9859,9864 
> 
> 
> Thanks,
> Sven
> 
> 
> 
> On 4/8/22 14:40, Stefan Sperling wrote:
> > On Tue, Jan 11, 2022 at 10:33:39PM +, Iraklis Karagkiozoglou wrote:
> > > Hello Stefan,
> > > 
> > > I tried to port the firmware detection and config values
> > > from iwlwifi.
> > > 
> > > On iwx_cfg_trans_params and iwx_cfg structs I ported only
> > > the fields iwx_attach was setting based on the iwx_device.
> > > 
> > > With best regards,
> > > Iraklis Karagkiozoglou
> > 
> > Hi Iraklis,
> > 
> > It took me some time to get back to this, sorry about that.
> > 
> > The new patch below attempts to add support for any AX200/AX201 devices
> > which have firmware available in fw_update(4). This will hopefully cover
> > devices which people have reported as not detected and which should
> > already be working as long as we load the correct firmware image.
> > 
> > This new patch is based on your patch from January.
> > Thank you very much for doing the initial work on this.
> > 
> > After studying the Linux driver for some time I believe the following
> > approach could work for us: We only need a table for devices which
> > require overrides that cannot be detected on PCI vendor/product ID alone.
> > The rest of the Linux driver's table is not needed. We can simply set
> > default values based on the PCI vendor/product ID as we have always done.
> > 
> > My AX200 and AX201 devices are still working fine with this.
> > Tests on more devices would be very welcome, especially ones that are
> > not yet detected in -current.
> > 
> > 
> > diff refs/heads/master refs/heads/iwx-match
> > blob - df5614f9f6140ba069db8d60e724b1ab36d124a2
> > blob + 69f489127b1a6898d12f5f5b2683cb7b3558293b
> > --- share/man/man4/iwx.4
> > +++ share/man/man4/iwx.4
> > @@ -84,8 +84,12 @@ which are loaded when an interface is brought up:
> >   .Pp
> >   .Bl -tag -width Ds -offset indent -compact
> >   .It Pa /etc/firmware/iwx-cc-a0-67
> > -.It Pa /etc/firmware/iwx-QuZ-a0-hr-b0-67
> > +.It Pa /etc/firmware/iwx-Qu-b0-hr-b0-63
> > +.It Pa /etc/firmware/iwx-Qu-b0-jf-b0-63
> >   .It Pa /etc/firmware/iwx-Qu-c0-hr-b0-63
> > +.It Pa /etc/firmware/iwx-Qu-c0-jf-b0-63
> > +.It Pa /etc/firmware/iwx-QuZ-a0-hr-b0-67
> > +.It Pa /etc/firmware/iwx-QuZ-a0-jf-b0-63
> >   .El
> >   .Pp
> >   These firmware files are not free because Intel refuses to grant
> > blob - 11f582e67321c9782b9cb38e6ce948b465522c94
> > blob + 9ffa40d1606fc261ed610984b82e0dbcada90340
> > --- sys/dev/pci/if_iwx.c
> > +++ sys/dev/pci/if_iwx.c
> > @@ -491,6 +491,7 @@ int iwx_intr_msix(void *);
> >   int   iwx_match(struct device *, void *, void *);
> >   int   iwx_preinit(struct iwx_softc *);
> >   void  iwx_attach_hook(struct device *);
> > +const struct iwx_device_cfg *iwx_find_device_cfg(struct iwx_softc *);
> >   void  iwx_attach(struct device *, struct device *, void *);
> >   void  iwx_init_task(void *);
> >   int   iwx_activate(struct device *, int);
> > @@ -870,7 +871,7 @@ iwx_ctxt_info_init(struct iwx_softc *sc, const struct
> > /* size is in DWs */
> >  

Re: patch: if_iwx.c add support for ax201 with subsystem id 0x0030

2022-04-08 Thread Stefan Sperling
On Tue, Jan 11, 2022 at 10:33:39PM +, Iraklis Karagkiozoglou wrote:
> Hello Stefan,
> 
> I tried to port the firmware detection and config values
> from iwlwifi.
> 
> On iwx_cfg_trans_params and iwx_cfg structs I ported only
> the fields iwx_attach was setting based on the iwx_device.
> 
> With best regards,
> Iraklis Karagkiozoglou

Hi Iraklis,

It took me some time to get back to this, sorry about that.

The new patch below attempts to add support for any AX200/AX201 devices
which have firmware available in fw_update(4). This will hopefully cover
devices which people have reported as not detected and which should
already be working as long as we load the correct firmware image.

This new patch is based on your patch from January.
Thank you very much for doing the initial work on this.

After studying the Linux driver for some time I believe the following
approach could work for us: We only need a table for devices which
require overrides that cannot be detected on PCI vendor/product ID alone.
The rest of the Linux driver's table is not needed. We can simply set
default values based on the PCI vendor/product ID as we have always done.

My AX200 and AX201 devices are still working fine with this.
Tests on more devices would be very welcome, especially ones that are
not yet detected in -current.


diff refs/heads/master refs/heads/iwx-match
blob - df5614f9f6140ba069db8d60e724b1ab36d124a2
blob + 69f489127b1a6898d12f5f5b2683cb7b3558293b
--- share/man/man4/iwx.4
+++ share/man/man4/iwx.4
@@ -84,8 +84,12 @@ which are loaded when an interface is brought up:
 .Pp
 .Bl -tag -width Ds -offset indent -compact
 .It Pa /etc/firmware/iwx-cc-a0-67
-.It Pa /etc/firmware/iwx-QuZ-a0-hr-b0-67
+.It Pa /etc/firmware/iwx-Qu-b0-hr-b0-63
+.It Pa /etc/firmware/iwx-Qu-b0-jf-b0-63
 .It Pa /etc/firmware/iwx-Qu-c0-hr-b0-63
+.It Pa /etc/firmware/iwx-Qu-c0-jf-b0-63
+.It Pa /etc/firmware/iwx-QuZ-a0-hr-b0-67
+.It Pa /etc/firmware/iwx-QuZ-a0-jf-b0-63
 .El
 .Pp
 These firmware files are not free because Intel refuses to grant
blob - 11f582e67321c9782b9cb38e6ce948b465522c94
blob + 9ffa40d1606fc261ed610984b82e0dbcada90340
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -491,6 +491,7 @@ int iwx_intr_msix(void *);
 intiwx_match(struct device *, void *, void *);
 intiwx_preinit(struct iwx_softc *);
 void   iwx_attach_hook(struct device *);
+const struct iwx_device_cfg *iwx_find_device_cfg(struct iwx_softc *);
 void   iwx_attach(struct device *, struct device *, void *);
 void   iwx_init_task(void *);
 intiwx_activate(struct device *, int);
@@ -870,7 +871,7 @@ iwx_ctxt_info_init(struct iwx_softc *sc, const struct 
/* size is in DWs */
ctxt_info->version.size = htole16(sizeof(*ctxt_info) / 4);
 
-   if (sc->sc_device_family >= IWX_DEVICE_FAMILY_22560)
+   if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
rb_size = IWX_CTXT_INFO_RB_SIZE_2K;
else
rb_size = IWX_CTXT_INFO_RB_SIZE_4K;
@@ -9392,61 +9393,192 @@ static const struct pci_matchid iwx_devices[] = {
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_3 },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_4,},
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_5,},
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_6,},
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_7,},
+   { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_8,},
 };
 
-static const struct pci_matchid iwx_subsystem_id_ax201[] = {
-   { PCI_VENDOR_INTEL, 0x0070 },
-   { PCI_VENDOR_INTEL, 0x0074 },
-   { PCI_VENDOR_INTEL, 0x0078 },
-   { PCI_VENDOR_INTEL, 0x007c },
-   { PCI_VENDOR_INTEL, 0x0310 },
-   { PCI_VENDOR_INTEL, 0x2074 },
-   { PCI_VENDOR_INTEL, 0x4070 },
-   /* TODO: There are more ax201 devices with "main" product ID 0x06f0 */
-};
 
 int
 iwx_match(struct device *parent, iwx_match_t match __unused, void *aux)
 {
struct pci_attach_args *pa = aux;
-   pcireg_t subid;
-   pci_vendor_id_t svid;
-   pci_product_id_t spid;
-   int i;
-
-   if (!pci_matchbyid(pa, iwx_devices, nitems(iwx_devices)))
-   return 0;
-
-   /*
-* Some PCI product IDs are shared among devices which use distinct
-* chips or firmware. We need to match the subsystem ID as well to
-* ensure that we have in fact found a supported device.
-*/
-   subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
-   svid = PCI_VENDOR(subid);
-   spid = PCI_PRODUCT(subid);
-
-   switch (PCI_PRODUCT(pa->pa_id)) {
-   case PCI_PRODUCT_INTEL_WL_22500_1: /* AX200 */
-   return 1; /* match any device */
-   case PCI_PRODUCT_INTEL_WL_22500_2: /* AX201 */
-   case PCI_PRODUCT_INTEL_WL_22500_3: /* AX201 */
-   case PCI_PRODUCT_INTEL_WL_22500_4: /* AX201 */
-   case PCI_PRODUCT_INTEL_WL_22500_5: /* AX201 */
-   for (i = 0; i < nitems(iwx_subsystem_id_ax201); i++) 

Re: ure(4): add support for RTL8156B

2022-03-31 Thread Stefan Sperling
On Thu, Mar 31, 2022 at 09:41:09PM +0800, Kevin Lo wrote:
> This diff adds preliminary support for RTL8156B to ure(4) and
> bug fixes for RTL8153/RTL8156.
> 
> Tested:
> ure0 at uhub0 port 12 configuration 1 interface 0 "Realtek USB 10/100/1G/2.5G 
> LAN" rev 3.20/31.00 addr 3
> ure0: RTL8156B (0x7410), address 00:e0:4c:xx:xx:xx

Works for me. ok stsp@, with one question about the diff below:

> Index: sys/dev/usb/if_ure.c
> ===
> RCS file: /cvs/src/sys/dev/usb/if_ure.c,v
> retrieving revision 1.28
> diff -u -p -u -p -r1.28 if_ure.c
> --- sys/dev/usb/if_ure.c  20 Aug 2021 04:54:10 -  1.28
> +++ sys/dev/usb/if_ure.c  31 Mar 2022 08:35:04 -
> @@ -197,7 +197,8 @@ void  ure_rtl8153_init(struct ure_softc 
>  void ure_rtl8153b_init(struct ure_softc *);
>  void ure_rtl8152_nic_reset(struct ure_softc *);
>  void ure_rtl8153_nic_reset(struct ure_softc *);
> -void ure_rtl8153_phy_status(struct ure_softc *, int);
> +uint16_t ure_rtl8153_phy_status(struct ure_softc *, int);

The function ure_rtl8153_phy_status() now returns a value,
but no caller is checking this value. Is this intentional?


Tested with xhci(4) and:

ure0 at uhub2 port 1 configuration 1 interface 0 "Lenovo Thinkpad USB LAN" rev 
3.00/30.00 addr 6
ure0: RTL8153 (0x5c20), address 3c:18:a0:a0:95:2b
rgephy0 at ure0 phy 0: RTL8251 PHY, rev. 0

This chip still works fine:

Conn:   1 Mbps:   91.315 Peak Mbps:   92.233 Avg Mbps:   91.315
   27086   10557368   84.459  100.00%
Conn:   1 Mbps:   84.459 Peak Mbps:   92.233 Avg Mbps:   84.459
   280899950656   79.367  100.00%
Conn:   1 Mbps:   79.367 Peak Mbps:   92.233 Avg Mbps:   79.367
   290919335256   74.607  100.00%
Conn:   1 Mbps:   74.607 Peak Mbps:   92.233 Avg Mbps:   74.607
   30091   10476280   83.810  100.00%
Conn:   1 Mbps:   83.810 Peak Mbps:   92.233 Avg Mbps:   83.810
   310949746488   77.739  100.00%
Conn:   1 Mbps:   77.739 Peak Mbps:   92.233 Avg Mbps:   77.739
   320959582864   76.663  100.00%
Conn:   1 Mbps:   76.663 Peak Mbps:   92.233 Avg Mbps:   76.663
   33098   10091112   80.487  100.00%
Conn:   1 Mbps:   80.487 Peak Mbps:   92.233 Avg Mbps:   80.487
   341018650352   68.996  100.00%
Conn:   1 Mbps:   68.996 Peak Mbps:   92.233 Avg Mbps:   68.996
   351069438064   75.204  100.00%
Conn:   1 Mbps:   75.204 Peak Mbps:   92.233 Avg Mbps:   75.204
^C
--- 192.168.1.1 tcpbench statistics ---
350301608 bytes sent over 35.602 seconds
bandwidth min/avg/max/std-dev = 26.875/78.824/92.233/11.918 Mbps



Re: XBox One gamecontroller support

2022-03-21 Thread Stefan Sperling
On Sun, Mar 20, 2022 at 05:00:13PM -0600, Thomas Frohwein wrote:
> I updated the diff for the controller with your diff. Below is the
> complete diff for all the files involved. I tested it again with my
> controller and sdl-jstest (in ports); it continues to work as intended.
> 
> ok?

Thanks! Ok by me.



Tx rate selection fixes for iwm(4) 11ac mode

2022-03-20 Thread Stefan Sperling
This patch fixes a couple of issues in the VHT rate adaptation code,
and with the data which iwm(4) is feeding into it.

Testing 11ac mode from a distance to my AP, I found that iwm(4) tends
to pick a Tx rate which is too high, resulting in too much of a drop
in throughput.

With this patch, iwm(4) hovers around VHT-MCS4 or VHT-MCS5, instead of
trying to reach the AP on VHT-MCS8 or VHT-MCS9 with heavy retries.
Effective throughput changes from 30Mbit/s to about 100Mbit/s, though
the rate is a bit jumpy and less stable than from a short distance.
A quick test suggests that this patch improves the effective data rate
at a short distance, too.

iwm(4) didn't attribute retries to the correct MCS, resulting in lower
MCS being punished unfairly while a higher MCS keeps failing.
This is what made us pick an Tx that is too high.

Another bug is that we didn't actually set rn->best_nss after deciding
on a new best rate. ieee80211_ra_vht_best_rate() would have to return
two values (mcs, nss), so just make it avoid and let it set rn->best_mcs
and rn->best_nss directly. With this, we are switching between SISO and
MIMO rates as intended.

When switching between ratesets, avoid switching directly to the highest
rate in the new rateset, which might be MCS 9 and not work at all from a
distance. Instead, use the most recently determined best rate in the set.
I plan to make this change in ieee80211_ra.c for 11n mode as well.

A non-obvious fix involves the rn->probed_rates[] array.
The bit which corresponds to the current best MS will not be set in
this array while we are probing an MCS other than the best.
So checking for this bit is simply wrong and prevents us from probing
the next rateset unless we manage to successfully probe up all the way
to MCS 9 in the current set.
This fix might also be needed in ieee80211_ra.c for 11n mode, but I will
deal with this later.

ok?

diff f186611d55a60b95262b00c94ece78add3698ea8 
f5d662f7a36c876abaa8b0987deef01a3fa99b0f
blob - ed592c9012b6ed157d2ab3457d6894f0e68a4f50
blob + ad7e788d6aace58e20247e5c522622e84c649667
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -5532,6 +5532,8 @@ iwm_vht_single_rate_control(struct iwm_softc *sc, stru
 {
struct ieee80211com *ic = >sc_ic;
struct iwm_node *in = (void *)ni;
+   uint8_t vht_chan_width = IEEE80211_VHTOP0_CHAN_WIDTH_80;
+   uint8_t sco = IEEE80211_HTOP0_SCO_SCN;
 
/* Ignore Tx reports which don't match our last LQ command. */
if (txmcs != ni->ni_txmcs || nss != ni->ni_vht_ss) {
@@ -5544,13 +5546,34 @@ iwm_vht_single_rate_control(struct iwm_softc *sc, stru
int mcs = txmcs;
unsigned int retries = 0, i;
 
+   if (in->in_phyctxt) {
+   vht_chan_width = in->in_phyctxt->vht_chan_width;
+   sco = in->in_phyctxt->sco;
+   }
in->lq_rate_mismatch = 0;
 
for (i = 0; i < failure_frame; i++) {
if (mcs > 0) {
ieee80211_ra_vht_add_stats(>in_rn_vht,
ic, ni, mcs, nss, 1, 1);
-   mcs--;
+   if (vht_chan_width >=
+   IEEE80211_VHTOP0_CHAN_WIDTH_80) {
+   /*
+* First 4 Tx attempts used same MCS,
+* twice at 80MHz and twice at 40MHz.
+*/
+   if (i >= 4)
+   mcs--;
+   } else if (sco == IEEE80211_HTOP0_SCO_SCA ||
+   sco == IEEE80211_HTOP0_SCO_SCB) {
+   /*
+* First 4 Tx attempts used same MCS,
+* four times at 40MHz.
+*/
+   if (i >= 4)
+   mcs--;
+   } else
+   mcs--;
} else
retries++;
}
@@ -9234,7 +9257,7 @@ iwm_set_rate_table_vht(struct iwm_node *in, struct iwm
}
 
/*
-* First two Tx attempts may use 80MHz/SGI.
+* First two Tx attempts may use 80MHz/40MHz/SGI.
 * Next two Tx attempts may use 40MHz/SGI.
 * Beyond that use 20 MHz and decrease the rate.
 * As a special case, MCS 9 is invalid on 20 Mhz.
@@ -9257,7 +9280,7 @@ iwm_set_rate_table_vht(struct iwm_node *in, struct iwm
tab |= IWM_RATE_MCS_RTS_REQUIRED_MSK;
if 

Re: XBox One gamecontroller support

2022-03-19 Thread Stefan Sperling
On Fri, Jan 15, 2021 at 06:32:04AM -0700, Thomas Frohwein wrote:
> @@ -557,6 +571,23 @@ uhidev_open(struct uhidev *scd)
>   DPRINTF(("uhidev_open: couldn't allocate owxfer\n"));
>   error = ENOMEM;
>   goto out3;
> + }
> +
> + /* XBox One controller initialization */

Shouldn't this initialization code be under #ifndef SMALL_KERNEL,
like the rest of the code your patch is adding to this file?

> + if (sc->sc_flags & UHIDEV_F_XB1) {
> + uint8_t init_data[] = { 0x05, 0x20, 0x00, 0x01, 0x00 };
> + int init_data_len = sizeof(init_data);

I would use 'size_t init_data_len' instead of 'int init_data_len'.
Largely a matter of taste, but this way everything stays unsigned.
usbd_setup_xfer() expects an unsigned int.

> + usbd_setup_xfer(sc->sc_oxfer, sc->sc_opipe, 0,
> + init_data, init_data_len,
> + USBD_SYNCHRONOUS | USBD_CATCH, USBD_NO_TIMEOUT,
> + NULL);
> + err = usbd_transfer(sc->sc_oxfer);
> + if (err != USBD_NORMAL_COMPLETION) {
> + DPRINTF(("uhidev_open: xb1 init failed, "
> + "error=%d\n", err));
> + error = EIO;
> + goto out3;
> + }
>   }
>   }

Both of the above suggestions as a diff:

diff 978a5fa5205c9adcf7df6f7cb4e82b0fc5f3612a /usr/src
blob - 2aa48d139f7b1a0ddedd79e53da2f0c846ca2745
file + sys/dev/usb/uhidev.c
--- sys/dev/usb/uhidev.c
+++ sys/dev/usb/uhidev.c
@@ -599,11 +599,11 @@ uhidev_open(struct uhidev *scd)
error = ENOMEM;
goto out3;
}
-
+#ifndef SMALL_KERNEL
/* XBox One controller initialization */
if (sc->sc_flags & UHIDEV_F_XB1) {
uint8_t init_data[] = { 0x05, 0x20 };
-   int init_data_len = sizeof(init_data);
+   size_t init_data_len = sizeof(init_data);
usbd_setup_xfer(sc->sc_oxfer, sc->sc_opipe, 0,
init_data, init_data_len,
USBD_SYNCHRONOUS | USBD_CATCH, USBD_NO_TIMEOUT,
@@ -616,6 +616,7 @@ uhidev_open(struct uhidev *scd)
goto out3;
}
}
+#endif
}
 
return (0);



fix iwm/iwx announcing VHT on 2GHz during scans

2022-03-19 Thread Stefan Sperling
Both iwm and iwx are currently writing VHT capabilities into
the "common" secion of the firmware's probe request frame template.
This "common" section is used on both 2GHz and 5GHz bands.

Announcing VHT capabilities on 2GHz makes no sense.
Move them into the 5GHz-only section.

ok?

diff f6c92c11f983c9e9dd370657ab43ccf9feb56be5 /usr/src
blob - e82db1f229ad0141f2bedfe4fa81cb46267f2588
file + sys/dev/pci/if_iwm.c
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -7661,6 +7661,12 @@ iwm_fill_probe_req(struct iwm_softc *sc, struct iwm_sc
frm = ieee80211_add_xrates(frm, rs);
preq->band_data[1].len = htole16(frm - pos);
remain -= frm - pos;
+   if (ic->ic_flags & IEEE80211_F_VHTON) {
+   if (remain < 14)
+   return ENOBUFS;
+   frm = ieee80211_add_vhtcaps(frm, ic);
+   remain -= frm - pos;
+   }
}
 
/* Send 11n IEs on both 2GHz and 5GHz bands. */
@@ -7674,12 +7680,6 @@ iwm_fill_probe_req(struct iwm_softc *sc, struct iwm_sc
remain -= frm - pos;
}
 
-   if (ic->ic_flags & IEEE80211_F_VHTON) {
-   if (remain < 14)
-   return ENOBUFS;
-   frm = ieee80211_add_vhtcaps(frm, ic);
-   }
-
preq->common_data.len = htole16(frm - pos);
 
return 0;
blob - 6c1c1647fbcd6d6e71f2d6c08e178fc533650239
file + sys/dev/pci/if_iwx.c
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -6200,6 +6200,12 @@ iwx_fill_probe_req(struct iwx_softc *sc, struct iwx_sc
frm = ieee80211_add_xrates(frm, rs);
preq->band_data[1].len = htole16(frm - pos);
remain -= frm - pos;
+   if (ic->ic_flags & IEEE80211_F_VHTON) {
+   if (remain < 14)
+   return ENOBUFS;
+   frm = ieee80211_add_vhtcaps(frm, ic);
+   remain -= frm - pos;
+   }
}
 
/* Send 11n IEs on both 2GHz and 5GHz bands. */
@@ -6213,12 +6219,6 @@ iwx_fill_probe_req(struct iwx_softc *sc, struct iwx_sc
remain -= frm - pos;
}
 
-   if (ic->ic_flags & IEEE80211_F_VHTON) {
-   if (remain < 14)
-   return ENOBUFS;
-   frm = ieee80211_add_vhtcaps(frm, ic);
-   }
-
preq->common_data.len = htole16(frm - pos);
 
return 0;



Re: net80211: fix Rx channel hack used by bwfm, iwn, iwm, and iwx

2022-03-19 Thread Stefan Sperling
On Sat, Mar 19, 2022 at 05:32:48PM +0100, Stefan Sperling wrote:
> The net80211 input routine expects that ic->ic_bss->ni_chan will always
> correspond to the channel which is currently being scanned. This dates
> back to older devices which are manually tuned to the next channel by the
> driver during SCAN->SCAN state transitions. And this must of course be
> kept working for these drivers.
> 
> However, this approach is very awkward for drivers which scan across a
> whole range of channels in firmware. Right now such drivers have an ugly
> workaround around in place which changes the ni_chan variable for each
> received frame.
> 
> This patch introduces a channel number field in the Rx info struct which
> can be used to indicate the hardware channel number on which a frame was
> received. If this field is set, net80211 will use it instead of using the
> current channel of ic_bss.
> 
> Works for me on iwm(4).
> Additional tests on iwn, iwm, iwx, and bwfm would be good.

jmc@ managed to trigger a bug where the interface ended up in 11ac
mode on a 2GHz channel. Should be fixed in this version of the diff.

diff 72ccef0dd6ed210ccf409e8bd0918949ccb70238 
2b44274faa697c674c40e5a1ba5ca818cdf5caf4
blob - 15e712c92ee21ac76262d534d58b7f5548341107
blob + ef8ea9876a4f77106aa42033fdff7f8f2bb53d4c
--- sys/dev/ic/bwfm.c
+++ sys/dev/ic/bwfm.c
@@ -2703,8 +2703,6 @@ bwfm_scan_node(struct bwfm_softc *sc, struct bwfm_bss_
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct ieee80211_rxinfo rxi;
-   struct ieee80211_channel *bss_chan;
-   uint8_t saved_bssid[IEEE80211_ADDR_LEN] = { 0 };
struct mbuf *m;
uint32_t pktlen, ieslen;
uint16_t iesoff;
@@ -2739,28 +2737,14 @@ bwfm_scan_node(struct bwfm_softc *sc, struct bwfm_bss_
/* Finalize mbuf. */
m->m_pkthdr.len = m->m_len = pktlen;
ni = ieee80211_find_rxnode(ic, wh);
-   if (ni == ic->ic_bss) {
-   /*
-* We may switch ic_bss's channel during scans.
-* Record the current channel so we can restore it later.
-*/
-   bss_chan = ni->ni_chan;
-   IEEE80211_ADDR_COPY(_bssid, ni->ni_macaddr);
-   }
/* Channel mask equals IEEE80211_CHAN_MAX */
chanidx = bwfm_spec2chan(sc, letoh32(bss->chanspec));
-   ni->ni_chan = >ic_channels[chanidx];
/* Supply RSSI */
rxi.rxi_flags = 0;
rxi.rxi_rssi = (int16_t)letoh16(bss->rssi);
rxi.rxi_tstamp = 0;
+   rxi.rxi_chan = chanidx;
ieee80211_input(ifp, m, ni, );
-   /*
-* ieee80211_input() might have changed our BSS.
-* Restore ic_bss's channel if we are still in the same BSS.
-*/
-   if (ni == ic->ic_bss && IEEE80211_ADDR_EQ(saved_bssid, ni->ni_macaddr))
-   ni->ni_chan = bss_chan;
/* Node is no longer needed. */
ieee80211_release_node(ic, ni);
 }
blob - c7115ed57c8f3367983d438ade529d39a8cd2872
blob + 984ac6f8913c3f576a724e13dbaf9371d14b3d9a
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -4775,24 +4775,12 @@ iwm_rx_frame(struct iwm_softc *sc, struct mbuf *m, int
struct ifnet *ifp = IC2IFP(ic);
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
-   struct ieee80211_channel *bss_chan;
-   uint8_t saved_bssid[IEEE80211_ADDR_LEN] = { 0 };
 
if (chanidx < 0 || chanidx >= nitems(ic->ic_channels))  
chanidx = ieee80211_chan2ieee(ic, ic->ic_ibss_chan);
 
wh = mtod(m, struct ieee80211_frame *);
ni = ieee80211_find_rxnode(ic, wh);
-   if (ni == ic->ic_bss) {
-   /* 
-* We may switch ic_bss's channel during scans.
-* Record the current channel so we can restore it later.
-*/
-   bss_chan = ni->ni_chan;
-   IEEE80211_ADDR_COPY(_bssid, ni->ni_macaddr);
-   }
-   ni->ni_chan = >ic_channels[chanidx];
-
if ((rxi->rxi_flags & IEEE80211_RXI_HWDEC) &&
iwm_ccmp_decap(sc, m, ni, rxi) != 0) {
ifp->if_ierrors++;
@@ -4856,12 +4844,6 @@ iwm_rx_frame(struct iwm_softc *sc, struct mbuf *m, int
}
 #endif
ieee80211_inputm(IC2IFP(ic), m, ni, rxi, ml);
-   /*
-* ieee80211_inputm() might have changed our BSS.
-* Restore ic_bss's channel if we are still in the same BSS.
-*/
-   if (ni == ic->ic_bss && IEEE80211_ADDR_EQ(saved_bssid, ni->ni_macaddr))
-   ni->ni_chan = bss_chan;
ieee80211_release_node(ic, ni);
 }
 
@@ -4935,6 +4917,7 @@ iwm_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, void
 
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = device_timestamp;
+   rxi.rxi_chan = chanidx;
 
iwm_rx_frame(sc, m, chanidx, rx_pkt_s

net80211: fix Rx channel hack used by bwfm, iwn, iwm, and iwx

2022-03-19 Thread Stefan Sperling
The net80211 input routine expects that ic->ic_bss->ni_chan will always
correspond to the channel which is currently being scanned. This dates
back to older devices which are manually tuned to the next channel by the
driver during SCAN->SCAN state transitions. And this must of course be
kept working for these drivers.

However, this approach is very awkward for drivers which scan across a
whole range of channels in firmware. Right now such drivers have an ugly
workaround around in place which changes the ni_chan variable for each
received frame.

This patch introduces a channel number field in the Rx info struct which
can be used to indicate the hardware channel number on which a frame was
received. If this field is set, net80211 will use it instead of using the
current channel of ic_bss.

Works for me on iwm(4).
Additional tests on iwn, iwm, iwx, and bwfm would be good.

ok?

 introduce rxi_chan to communicate Rx channel to net80211
 get rid of saved_bssid hacks in drivers
 
diff 72ccef0dd6ed210ccf409e8bd0918949ccb70238 
20d70a4353a34d2cb2f94d8a15fd7b3b8cdd7158
blob - 15e712c92ee21ac76262d534d58b7f5548341107
blob + ef8ea9876a4f77106aa42033fdff7f8f2bb53d4c
--- sys/dev/ic/bwfm.c
+++ sys/dev/ic/bwfm.c
@@ -2703,8 +2703,6 @@ bwfm_scan_node(struct bwfm_softc *sc, struct bwfm_bss_
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct ieee80211_rxinfo rxi;
-   struct ieee80211_channel *bss_chan;
-   uint8_t saved_bssid[IEEE80211_ADDR_LEN] = { 0 };
struct mbuf *m;
uint32_t pktlen, ieslen;
uint16_t iesoff;
@@ -2739,28 +2737,14 @@ bwfm_scan_node(struct bwfm_softc *sc, struct bwfm_bss_
/* Finalize mbuf. */
m->m_pkthdr.len = m->m_len = pktlen;
ni = ieee80211_find_rxnode(ic, wh);
-   if (ni == ic->ic_bss) {
-   /*
-* We may switch ic_bss's channel during scans.
-* Record the current channel so we can restore it later.
-*/
-   bss_chan = ni->ni_chan;
-   IEEE80211_ADDR_COPY(_bssid, ni->ni_macaddr);
-   }
/* Channel mask equals IEEE80211_CHAN_MAX */
chanidx = bwfm_spec2chan(sc, letoh32(bss->chanspec));
-   ni->ni_chan = >ic_channels[chanidx];
/* Supply RSSI */
rxi.rxi_flags = 0;
rxi.rxi_rssi = (int16_t)letoh16(bss->rssi);
rxi.rxi_tstamp = 0;
+   rxi.rxi_chan = chanidx;
ieee80211_input(ifp, m, ni, );
-   /*
-* ieee80211_input() might have changed our BSS.
-* Restore ic_bss's channel if we are still in the same BSS.
-*/
-   if (ni == ic->ic_bss && IEEE80211_ADDR_EQ(saved_bssid, ni->ni_macaddr))
-   ni->ni_chan = bss_chan;
/* Node is no longer needed. */
ieee80211_release_node(ic, ni);
 }
blob - c7115ed57c8f3367983d438ade529d39a8cd2872
blob + 984ac6f8913c3f576a724e13dbaf9371d14b3d9a
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -4775,24 +4775,12 @@ iwm_rx_frame(struct iwm_softc *sc, struct mbuf *m, int
struct ifnet *ifp = IC2IFP(ic);
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
-   struct ieee80211_channel *bss_chan;
-   uint8_t saved_bssid[IEEE80211_ADDR_LEN] = { 0 };
 
if (chanidx < 0 || chanidx >= nitems(ic->ic_channels))  
chanidx = ieee80211_chan2ieee(ic, ic->ic_ibss_chan);
 
wh = mtod(m, struct ieee80211_frame *);
ni = ieee80211_find_rxnode(ic, wh);
-   if (ni == ic->ic_bss) {
-   /* 
-* We may switch ic_bss's channel during scans.
-* Record the current channel so we can restore it later.
-*/
-   bss_chan = ni->ni_chan;
-   IEEE80211_ADDR_COPY(_bssid, ni->ni_macaddr);
-   }
-   ni->ni_chan = >ic_channels[chanidx];
-
if ((rxi->rxi_flags & IEEE80211_RXI_HWDEC) &&
iwm_ccmp_decap(sc, m, ni, rxi) != 0) {
ifp->if_ierrors++;
@@ -4856,12 +4844,6 @@ iwm_rx_frame(struct iwm_softc *sc, struct mbuf *m, int
}
 #endif
ieee80211_inputm(IC2IFP(ic), m, ni, rxi, ml);
-   /*
-* ieee80211_inputm() might have changed our BSS.
-* Restore ic_bss's channel if we are still in the same BSS.
-*/
-   if (ni == ic->ic_bss && IEEE80211_ADDR_EQ(saved_bssid, ni->ni_macaddr))
-   ni->ni_chan = bss_chan;
ieee80211_release_node(ic, ni);
 }
 
@@ -4935,6 +4917,7 @@ iwm_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, void
 
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = device_timestamp;
+   rxi.rxi_chan = chanidx;
 
iwm_rx_frame(sc, m, chanidx, rx_pkt_status,
(phy_flags & IWM_PHY_INFO_FLAG_SHPREAMBLE),
@@ -5465,6 +5448,7 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, struct mbuf *m, v
 
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = le64toh(desc->v1.tsf_on_air_rise);
+   rxi.rxi_chan = chanidx;
 
if (iwm_rx_reorder(sc, m, chanidx, 

Re: initial 11ac support for iwm(4)

2022-03-19 Thread Stefan Sperling
On Fri, Mar 18, 2022 at 11:36:50AM +0100, Stefan Sperling wrote:
> On Fri, Mar 18, 2022 at 05:25:42AM +0100, Landry Breuil wrote:
> > interestingly, when associated over ac to the livebox the background
> > scans only shows the 5ghz channels from both APs, but when im associated
> > to my regular AP the background scans shows both 2ghz and 5ghz chans.
> > not sure that matters.
> 
> Thanks for pointing this out!
> Background scan should indeed still report APs on all channels.
> I will try to find a fix for this. It can be fixed independently from
> the iwm 11ac patch. This will likely already affect iwx(4) as well.

This fixes bgscan in 11ac mode for me. Can you confirm?
 
diff 24953ebb6e9389b0238498b9d17801bff188cdc9 
72ccef0dd6ed210ccf409e8bd0918949ccb70238
blob - 6ce36c2abb0de676c636cec098c176f55b737072
blob + 29e79454bd5f94785ab0c1f39a0e8e61b997aae2
--- sys/net80211/ieee80211_input.c
+++ sys/net80211/ieee80211_input.c
@@ -1736,7 +1736,9 @@ ieee80211_recv_probe_resp(struct ieee80211com *ic, str
 #if IEEE80211_CHAN_MAX < 255
chan > IEEE80211_CHAN_MAX ||
 #endif
-   isclr(ic->ic_chan_active, chan)) {
+   (isclr(ic->ic_chan_active, chan) &&
+((ic->ic_caps & IEEE80211_C_SCANALL) == 0 ||
+(ic->ic_flags & IEEE80211_F_BGSCAN) == 0))) {
DPRINTF(("ignore %s with invalid channel %u\n",
isprobe ? "probe response" : "beacon", chan));
ic->ic_stats.is_rx_badchan++;
blob - aeae4edc6f02c6c10b125d89763812a39ddc5146
blob + a756880e173a53d59e4e5bea783f69f9f0459149
--- sys/net80211/ieee80211_node.c
+++ sys/net80211/ieee80211_node.c
@@ -1056,7 +1056,8 @@ ieee80211_match_bss(struct ieee80211com *ic, struct ie
int fail;
 
fail = 0;
-   if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ni->ni_chan)))
+   if ((ic->ic_flags & IEEE80211_F_BGSCAN) == 0 &&
+   isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ni->ni_chan)))
fail |= IEEE80211_NODE_ASSOCFAIL_CHAN;
if (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
ni->ni_chan != ic->ic_des_chan)





two net80211 AP selection fixes

2022-03-19 Thread Stefan Sperling
Fix number 1:
During network selection (for 'ifconfig join'), give APs which support
11n and 11ac a higher score. VHT implies HT, so 11ac networks receive
2 additional points while 11n-only networks receive one additional point.

Fix number 2:
During AP selection within a given network, we would like to prefer 5GHz APs.
However, this check was incorrectly implemented for drivers which report
RSSI as a percentage, such as iwm(4) or iwx(4). Fix this such that APs with
at least 50% rssi level will be preferred, as was intended. We can use an
already existing function which performs this check correctly instead of
hand-rolling the check.

ok?

diff 15b71cdf8530b1f64fb85d50873b1ff1fad3f0e8 /usr/src
blob - 229636579d3554154733676cc8deb0004f8ce173
file + sys/net80211/ieee80211_node.c
--- sys/net80211/ieee80211_node.c
+++ sys/net80211/ieee80211_node.c
@@ -480,6 +480,12 @@ ieee80211_ess_calculate_score(struct ieee80211com *ic,
ni->ni_rssi > min_5ghz_rssi)
score += 2;
 
+   /* HT/VHT available */
+   if (ieee80211_node_supports_ht(ni))
+   score++;
+   if (ieee80211_node_supports_vht(ni))
+   score++;
+
/* Boost this AP if it had no auth/assoc failures in the past. */
if (ni->ni_fails == 0)
score += 21;
@@ -493,6 +499,7 @@ ieee80211_ess_calculate_score(struct ieee80211com *ic,
  *
  *  crypto: wpa2 > wpa1 > wep > open
  *  band: 5 GHz > 2 GHz provided 5 GHz rssi is above threshold
+ *  supported standard revisions: 11ac > 11n > 11a/b/g
  *  rssi: rssi1 > rssi2 as a numeric comparison with a slight
  * disadvantage for 2 GHz APs
  *
@@ -1413,7 +1420,7 @@ ieee80211_node_choose_bss(struct ieee80211com *ic, int
 * (as long as it meets the minimum RSSI threshold) since the 5Ghz band
 * is usually less saturated.
 */
-   if (selbs5 && selbs5->ni_rssi > min_5ghz_rssi)
+   if (selbs5 && (*ic->ic_node_checkrssi)(ic, selbs5))
selbs = selbs5;
else if (selbs5 && selbs2)
selbs = (selbs5->ni_rssi >= selbs2->ni_rssi ? selbs5 : selbs2);





fix wrong logic in iwm_vht_single_rate_control()

2022-03-19 Thread Stefan Sperling
I botched the logic used by a check in iwm_vht_single_rate_control().

ok?

diff 15b71cdf8530b1f64fb85d50873b1ff1fad3f0e8 /usr/src
blob - 2c01f718d47acb01a227795fef659ef353f5c7f6
file + sys/dev/pci/if_iwm.c
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -5550,7 +5550,7 @@ iwm_vht_single_rate_control(struct iwm_softc *sc, stru
struct iwm_node *in = (void *)ni;
 
/* Ignore Tx reports which don't match our last LQ command. */
-   if (txmcs != ni->ni_txmcs && nss != ni->ni_vht_ss) {
+   if (txmcs != ni->ni_txmcs || nss != ni->ni_vht_ss) {
if (++in->lq_rate_mismatch > 15) {
/* Try to sync firmware with the driver... */
iwm_setrates(in, 1);



Re: fix multiple iwm/iwx interfaces

2022-03-19 Thread Stefan Sperling
On Wed, Mar 16, 2022 at 10:03:36PM +0100, Stefan Sperling wrote:
> On Wed, Mar 16, 2022 at 08:46:01PM +0100, Jeremie Courreges-Anglas wrote:
> > On Mon, Mar 14 2022, Stefan Sperling  wrote:
> > > It is currently impossible to use more than one iwm or iwx interface
> > > in a system because I don't understand C.
> > >
> > > Trying to bring up an uninitialized interface anyway results in a
> > > kernel panic ("bogus channel pointer" from net80211), so prevent
> > > the device from being used in case we never managed to initialize it.
> > >
> > > ok?
> > 
> > I only tested iwm(4) 8265 but the change makes sense, ok jca@
> 
> I will need to revisit this later.
> 
> Somehow it fails in bsd.rd. The interface remains unusable.
> Firmware load fails because of rootfs not being mounted yet (expected),
> and it still doesn't work once firmware becomes available (not expected).

Just moving the variable to the soft fixes the multi-device problem,
and it works in bsd.rd. ok?

I will leave the issue of partial initialization due to errors for later.
That problem already affects the existing code and there is no need to
fix it in the same diff.
 
diff 216d1e6a5ea1a2af70c6b285d1b35ab0008729c4 
24648d7cb335eaa6548221fea3e70572f6349676
blob - 19ca8c08d3bf6cbeeedfc8b19de01aab5bc531f9
blob + 2c01f718d47acb01a227795fef659ef353f5c7f6
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -11558,7 +11558,6 @@ iwm_preinit(struct iwm_softc *sc)
struct ieee80211com *ic = >sc_ic;
struct ifnet *ifp = IC2IFP(ic);
int err;
-   static int attached;
 
err = iwm_prepare_card_hw(sc);
if (err) {
@@ -11566,7 +11565,7 @@ iwm_preinit(struct iwm_softc *sc)
return err;
}
 
-   if (attached) {
+   if (sc->attached) {
/* Update MAC in case the upper layers changed it. */
IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
((struct arpcom *)ifp)->ac_enaddr);
@@ -11585,7 +11584,7 @@ iwm_preinit(struct iwm_softc *sc)
return err;
 
/* Print version info and MAC address on first successful fw load. */
-   attached = 1;
+   sc->attached = 1;
printf("%s: hw rev 0x%x, fw ver %s, address %s\n",
DEVNAME(sc), sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK,
sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
blob - 53693a914a0e1fe20b0954322a7487ada68be821
blob + 5c2e387480d3ad45f585e4c84bd7162d2ef70df9
--- sys/dev/pci/if_iwmvar.h
+++ sys/dev/pci/if_iwmvar.h
@@ -476,6 +476,7 @@ struct iwm_softc {
struct ieee80211com sc_ic;
int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int);
int sc_newstate_pending;
+   int attached;
 
struct ieee80211_amrr sc_amrr;
struct timeout sc_calib_to;
blob - f2f6c046b4266e5c9f214cfcb0b6c9b1069341fc
blob + ba54430a5bbe62eea3749d62d72ee14d97ffb11e
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -9470,7 +9470,6 @@ iwx_preinit(struct iwx_softc *sc)
struct ieee80211com *ic = >sc_ic;
struct ifnet *ifp = IC2IFP(ic);
int err;
-   static int attached;
 
err = iwx_prepare_card_hw(sc);
if (err) {
@@ -9478,7 +9477,7 @@ iwx_preinit(struct iwx_softc *sc)
return err;
}
 
-   if (attached) {
+   if (sc->attached) {
/* Update MAC in case the upper layers changed it. */
IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
((struct arpcom *)ifp)->ac_enaddr);
@@ -9497,7 +9496,7 @@ iwx_preinit(struct iwx_softc *sc)
return err;
 
/* Print version info and MAC address on first successful fw load. */
-   attached = 1;
+   sc->attached = 1;
printf("%s: hw rev 0x%x, fw ver %s, address %s\n",
DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
blob - 0cd898b16c4e2a59efe22d1f61ca9a37429a590b
blob + 255c28db4dd487f497b26eaaef2a12fd12ef5c66
--- sys/dev/pci/if_iwxvar.h
+++ sys/dev/pci/if_iwxvar.h
@@ -456,6 +456,7 @@ struct iwx_softc {
struct ieee80211com sc_ic;
int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int);
int sc_newstate_pending;
+   int attached;
 
struct task init_task; /* NB: not reference-counted */
struct refcnt   task_refs;



Re: initial 11ac support for iwm(4)

2022-03-18 Thread Stefan Sperling
On Fri, Mar 18, 2022 at 01:39:01PM +0100, Marcus MERIGHI wrote:
> Hello, 
> 
> s...@stsp.name (Stefan Sperling), 2022.03.17 (Thu) 21:09 (CET):
> > On Thu, Mar 17, 2022 at 07:02:06PM +0100, Marcus MERIGHI wrote:
> > > s...@stsp.name (Stefan Sperling), 2022.03.16 (Wed) 16:11 (CET):
> > > > This patch adds initial 11ac support to the iwm(4) driver.
> > > > It allows use of 80 MHz channels and VHT MCS.
> > > [...]
> > > > So far, I have tested this successfully on iwm(4) 8265.
> > > 
> > > With this patch a "larger" file transfer will reliably panic my machine.
> > > "large" means even small files. 
> > > ICMP and NTP (and probably DNS) seem to work, though.
> > > I've tried it six times, it always crashed.
> > > 
> > > This is with:
> > > iwm0 at pci2 dev 0 function 0 "Intel Dual Band Wireless-AC 8265" rev 
> > > 0x88, msi
> > > iwm0: hw rev 0x230, fw ver 36.ca7b901d.0, address 00:28:f8:xx:yy:zz
> > 
> > If you have not done so yet, could you please try the revised
> > version of the patch which I posted here?
> > https://marc.info/?l=openbsd-tech=164746924001340=2
> > I believe this should fix your issue.
> > 
> > Below is the difference between the two versions, in case it is easier
> > for you to apply the fix on top of the first version of the patch.
> 
> this did the trick. Thank you and sorry for the noise.

Not worries at all, this was informative. You have a fairly unique test case.
The bug triggered because your AP is using 11ac without MIMO, while everyone
else is testing on a MIMO-capable AP.



Re: initial 11ac support for iwm(4)

2022-03-18 Thread Stefan Sperling
On Fri, Mar 18, 2022 at 05:25:42AM +0100, Landry Breuil wrote:
> interestingly, when associated over ac to the livebox the background
> scans only shows the 5ghz channels from both APs, but when im associated
> to my regular AP the background scans shows both 2ghz and 5ghz chans.
> not sure that matters.

Thanks for pointing this out!
Background scan should indeed still report APs on all channels.
I will try to find a fix for this. It can be fixed independently from
the iwm 11ac patch. This will likely already affect iwx(4) as well.



Re: initial 11ac support for iwm(4)

2022-03-17 Thread Stefan Sperling
On Thu, Mar 17, 2022 at 02:43:14PM -0700, Mike Larkin wrote:
> On Wed, Mar 16, 2022 at 11:17:47PM +0100, Stefan Sperling wrote:
> > On Wed, Mar 16, 2022 at 04:11:41PM +0100, Stefan Sperling wrote:
> > > This patch adds initial 11ac support to the iwm(4) driver.
> > > It allows use of 80 MHz channels and VHT MCS.
> >
> > Updated patch. Fixes a fatal firmware error on devices which
> > do not support MIMO, such as the 3160.
> >
> 
> Works great here on
> 
> iwm0 at pci3 dev 0 function 0 "Intel AC 7265" rev 0x59, msi
> iwm0: hw rev 0x210, fw ver 17.3216344376.0
> 
> One thing I did notice is that after ZZZ/un-ZZZ, it won't move out of 11n mode
> until I ifconfig iwm0 down / up. Then it picks up the VHT rate again.

The device must have used an AP on a 2 GHz channel when it stayed
in 11n mode. This is expected because 11ac only works on 5GHz channels.

Our AP selection is not based on AP capabilities, only on the received
signal strength. I don't want to change this right now, the changes
are large enough as it is. But we could tweak this in the future such
that 11ac gets preferred over 11n if possible.



Re: initial 11ac support for iwm(4)

2022-03-17 Thread Stefan Sperling
On Thu, Mar 17, 2022 at 07:02:06PM +0100, Marcus MERIGHI wrote:
> Hello!
> 
> Thanks for your work on this!
> 
> s...@stsp.name (Stefan Sperling), 2022.03.16 (Wed) 16:11 (CET):
> > This patch adds initial 11ac support to the iwm(4) driver.
> > It allows use of 80 MHz channels and VHT MCS.
> [...]
> > So far, I have tested this successfully on iwm(4) 8265.
> 
> With this patch a "larger" file transfer will reliably panic my machine.
> "large" means even small files. 
> ICMP and NTP (and probably DNS) seem to work, though.
> I've tried it six times, it always crashed.
> 
> This is with:
> iwm0 at pci2 dev 0 function 0 "Intel Dual Band Wireless-AC 8265" rev 0x88, msi
> iwm0: hw rev 0x230, fw ver 36.ca7b901d.0, address 00:28:f8:xx:yy:zz

If you have not done so yet, could you please try the revised
version of the patch which I posted here?
https://marc.info/?l=openbsd-tech=164746924001340=2
I believe this should fix your issue.

Below is the difference between the two versions, in case it is easier
for you to apply the fix on top of the first version of the patch.
 
diff 0191ab443b6994d9adb38f5f22f66ffea008c0b7 
00811a880ed9b9c98b475f172bf5f6fe3e31811f
blob - 3d13d9f024f349521cdf890955a4b6ce2e88fd5d
blob + dea634bcb86b2e41a7da27dd7be552b751eb1b66
--- sys/net80211/ieee80211_ra_vht.c
+++ sys/net80211/ieee80211_ra_vht.c
@@ -233,7 +233,7 @@ const struct ieee80211_vht_rateset *
 ieee80211_ra_vht_next_rateset(struct ieee80211_ra_vht_node *rn,
 struct ieee80211_node *ni)
 {
-   const struct ieee80211_vht_rateset *rs;
+   const struct ieee80211_vht_rateset *rs, *rsnext;
int next;
int sgi = ieee80211_ra_vht_use_sgi(ni);
int mcs = ni->ni_txmcs;
@@ -269,7 +269,11 @@ ieee80211_ra_vht_next_rateset(struct ieee80211_ra_vht_
} else
panic("%s: invalid probing mode %d", __func__, rn->probing);
 
-   return _std_ratesets_11ac[next];
+   rsnext = _std_ratesets_11ac[next];
+   if (rn->valid_rates[rsnext->num_ss - 1] == 0)
+   return NULL;
+
+   return rsnext;
 }
 
 int



Re: initial 11ac support for iwm(4)

2022-03-17 Thread Stefan Sperling
On Thu, Mar 17, 2022 at 01:07:42AM +, Stuart Henderson wrote:
> 802.11 flags=0<>: beacon, ...

> 191:12 0xb109cb33aaff1806aaff1806, 192:5 0x00aaff,

Now is probably a good time to start pretty-printing these fields in tcpdump.

ok?

diff 140ae54c8a573c04824dd96957ebff4e069b2dfd /usr/src
blob - 4af7bdb9350f0feaff2e562ee2a6ec0982de7a70
file + usr.sbin/tcpdump/print-802_11.c
--- usr.sbin/tcpdump/print-802_11.c
+++ usr.sbin/tcpdump/print-802_11.c
@@ -101,6 +101,8 @@ void ieee80211_print_essid(u_int8_t *, u_int);
 voidieee80211_print_country(u_int8_t *, u_int);
 voidieee80211_print_htcaps(u_int8_t *, u_int);
 voidieee80211_print_htop(u_int8_t *, u_int);
+voidieee80211_print_vhtcaps(u_int8_t *, u_int);
+voidieee80211_print_vhtop(u_int8_t *, u_int);
 voidieee80211_print_rsncipher(u_int8_t []);
 voidieee80211_print_akm(u_int8_t []);
 voidieee80211_print_rsn(u_int8_t *, u_int);
@@ -607,6 +609,199 @@ ieee80211_print_htop(u_int8_t *data, u_int len)
 }
 
 void
+print_vht_mcsmap(uint16_t mcsmap)
+{
+   int nss, mcs;
+
+   for (nss = 1; nss < IEEE80211_VHT_NUM_SS; nss++) {
+   mcs = (mcsmap & IEEE80211_VHT_MCS_FOR_SS_MASK(nss)) >>
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(nss);
+   switch (mcs) {
+   case IEEE80211_VHT_MCS_0_9:
+   printf(" 0-9@%uSS", nss);
+   break;
+   case IEEE80211_VHT_MCS_0_8:
+   printf(" 0-8@%uSS", nss);
+   break;
+   case IEEE80211_VHT_MCS_0_7:
+   printf(" 0-7@%uSS", nss);
+   break;
+   case IEEE80211_VHT_MCS_SS_NOT_SUPP:
+   default:
+   break;
+   }
+   }
+}
+
+/* Caller checks len */
+void
+ieee80211_print_vhtcaps(u_int8_t *data, u_int len)
+{
+   uint32_t vhtcaps;
+   uint16_t rxmcs, txmcs, max_lgi;
+   uint32_t rxstbc, num_sts, max_ampdu, link_adapt;
+
+   if (len < 12) {
+   ieee80211_print_element(data, len);
+   return;
+   }
+
+   vhtcaps = (data[0] | (data[1] << 8) | data[2] << 16 |
+   data[3] << 24);
+   printf("=<");
+
+   /* max MPDU length */
+   switch (vhtcaps & IEEE80211_VHTCAP_MAX_MPDU_LENGTH_MASK) {
+   case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_11454:
+   printf("max MPDU 11454");
+   break;
+   case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_7991:
+   printf("max MPDU 7991");
+   break;
+   case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_3895:
+   default:
+   printf("max MPDU 3895");
+   break;
+   }
+
+   /* supported channel widths */
+   switch ((vhtcaps & IEEE80211_VHTCAP_CHAN_WIDTH_MASK) <<
+   IEEE80211_VHTCAP_CHAN_WIDTH_SHIFT) {
+   case IEEE80211_VHTCAP_CHAN_WIDTH_160_8080:
+   printf(",80+80MHz");
+   /* fallthrough */
+   case IEEE80211_VHTCAP_CHAN_WIDTH_160:
+   printf(",160MHz");
+   /* fallthrough */
+   case IEEE80211_VHTCAP_CHAN_WIDTH_80:
+   default:
+   printf(",80MHz");
+   break;
+   }
+
+   /* LDPC coding */
+   if (vhtcaps & IEEE80211_VHTCAP_RX_LDPC)
+   printf(",LDPC");
+
+   /* short guard interval */
+   if (vhtcaps & IEEE80211_VHTCAP_SGI80)
+   printf(",SGI@80MHz");
+   if (vhtcaps & IEEE80211_VHTCAP_SGI160)
+   printf(",SGI@160MHz");
+
+   /* space-time block coding */
+   if (vhtcaps & IEEE80211_VHTCAP_TX_STBC)
+   printf(",TxSTBC");
+   rxstbc = (vhtcaps & IEEE80211_VHTCAP_RX_STBC_SS_MASK)
+   >> IEEE80211_VHTCAP_RX_STBC_SS_SHIFT;
+   if (rxstbc > 0 && rxstbc <= 7)
+   printf(",RxSTBC %d stream", rxstbc);
+
+   /* beamforming */
+   if (vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMER) {
+   printf(",beamformer");
+   num_sts = ((vhtcaps & IEEE80211_VHTCAP_NUM_STS_MASK) >>
+   IEEE80211_VHTCAP_NUM_STS_SHIFT);
+   if (num_sts)
+   printf(" STS %u", num_sts);
+   }
+   if (vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMEE) {
+   printf(",beamformee");
+   num_sts = ((vhtcaps & IEEE80211_VHTCAP_BEAMFORMEE_STS_MASK) >>
+   IEEE80211_VHTCAP_BEAMFORMEE_STS_SHIFT);
+   if (num_sts)
+   printf(" STS %u", num_sts);
+   }
+
+   if (vhtcaps & IEEE80211_VHTCAP_TXOP_PS)
+   printf(",TXOP PS");
+   if (vhtcaps & IEEE80211_VHTCAP_HTC_VHT)
+   printf(",+HTC VHT");
+
+   /* max A-MPDU length */
+   max_ampdu = ((vhtcaps & IEEE80211_VHTCAP_MAX_AMPDU_LEN_MASK) >>
+   IEEE80211_VHTCAP_MAX_AMPDU_LEN_SHIFT);
+   if (max_ampdu >= IEEE80211_VHTCAP_MAX_AMPDU_LEN_8K &&
+   max_ampdu <= IEEE80211_VHTCAP_MAX_AMPDU_LEN_1024K)

Re: initial 11ac support for iwm(4)

2022-03-16 Thread Stefan Sperling
On Wed, Mar 16, 2022 at 04:11:41PM +0100, Stefan Sperling wrote:
> This patch adds initial 11ac support to the iwm(4) driver.
> It allows use of 80 MHz channels and VHT MCS.

Updated patch. Fixes a fatal firmware error on devices which
do not support MIMO, such as the 3160.

diff refs/heads/master refs/heads/11ac
blob - 7df604d4b6e3913ffeef8c16e7e47637c84af881
blob + 8ed3356b0144a014bece57fa7dcf734624be9fbb
--- sys/conf/files
+++ sys/conf/files
@@ -847,6 +847,7 @@ file net80211/ieee80211_pae_input.c wlan
 file net80211/ieee80211_pae_output.c   wlan
 file net80211/ieee80211_proto.cwlan
 file net80211/ieee80211_ra.c   wlan
+file net80211/ieee80211_ra_vht.c   wlan
 file net80211/ieee80211_rssadapt.c wlan
 file net80211/ieee80211_regdomain.cwlan
 file netinet/if_ether.cether
blob - 7e0e0f4841d3ba61fcf8335bc21c0df2fb416801
blob + ddb2d586ed0ed8c43da2c38d982d47685db940b3
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -143,6 +143,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include  /* for SEQ_LT */
 #undef DPRINTF /* defined in ieee80211_priv.h */
@@ -222,7 +223,7 @@ const struct iwm_rate {
 #define IWM_RVAL_IS_OFDM(_i_) ((_i_) >= 12 && (_i_) != 22)
 
 /* Convert an MCS index into an iwm_rates[] index. */
-const int iwm_mcs2ridx[] = {
+const int iwm_ht_mcs2ridx[] = {
IWM_RATE_MCS_0_INDEX,
IWM_RATE_MCS_1_INDEX,
IWM_RATE_MCS_2_INDEX,
@@ -247,7 +248,7 @@ struct iwm_nvm_section {
 };
 
 intiwm_is_mimo_ht_plcp(uint8_t);
-intiwm_is_mimo_mcs(int);
+intiwm_is_mimo_ht_mcs(int);
 intiwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t);
 intiwm_firmware_store_section(struct iwm_softc *, enum iwm_ucode_type,
uint8_t *, size_t);
@@ -334,6 +335,7 @@ voidiwm_init_channel_map(struct iwm_softc *, const 
ui
const uint8_t *nvm_channels, int nchan);
 intiwm_mimo_enabled(struct iwm_softc *);
 void   iwm_setup_ht_rates(struct iwm_softc *);
+void   iwm_setup_vht_rates(struct iwm_softc *);
 void   iwm_mac_ctxt_task(void *);
 void   iwm_phy_ctxt_task(void *);
 void   iwm_updateprot(struct ieee80211com *);
@@ -396,6 +398,8 @@ voidiwm_rx_frame(struct iwm_softc *, struct mbuf *, 
i
uint32_t, struct ieee80211_rxinfo *, struct mbuf_list *);
 void   iwm_ht_single_rate_control(struct iwm_softc *, struct ieee80211_node *,
int, uint8_t, int);
+void   iwm_vht_single_rate_control(struct iwm_softc *, struct ieee80211_node *,
+   int, int, uint8_t, int);
 void   iwm_rx_tx_cmd_single(struct iwm_softc *, struct iwm_rx_packet *,
struct iwm_node *, int, int);
 void   iwm_txd_done(struct iwm_softc *, struct iwm_tx_data *);
@@ -409,14 +413,15 @@ void  iwm_rx_compressed_ba(struct iwm_softc *, struct 
i
 void   iwm_rx_bmiss(struct iwm_softc *, struct iwm_rx_packet *,
struct iwm_rx_data *);
 intiwm_binding_cmd(struct iwm_softc *, struct iwm_node *, uint32_t);
+uint8_tiwm_get_vht_ctrl_pos(struct ieee80211com *, struct 
ieee80211_channel *);
 intiwm_phy_ctxt_cmd_uhb(struct iwm_softc *, struct iwm_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint32_t, uint8_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, uint8_t);
+   struct ieee80211_channel *, uint8_t, 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);
+   uint8_t, uint32_t, uint32_t, uint8_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 *);
@@ -428,7 +433,7 @@ voidiwm_free_resp(struct iwm_softc *, struct 
iwm_host
 void   iwm_cmd_done(struct iwm_softc *, int, int, int);
 void   iwm_update_sched(struct iwm_softc *, int, int, uint8_t, uint16_t);
 void   iwm_reset_sched(struct iwm_softc *, int, int, uint8_t);
-const struct iwm_rate *iwm_tx_fill_cmd(struct iwm_softc *, struct iwm_node *,
+uint8_tiwm_tx_fill_cmd(struct iwm_softc *, struct iwm_node *,
struct ieee80211_frame *, struct iwm_tx_cmd *);
 intiwm_tx(struct iwm_softc *, struct mbuf *, struct ieee80211_node *, int);
 intiwm_flush_tx_path(struct iwm_softc *, int);
@@ -484,7 +489,8 @@ 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, uint8_t);
+   struct ieee80211_channel *, uint8_t, uint8_t, 

Re: fix multiple iwm/iwx interfaces

2022-03-16 Thread Stefan Sperling
On Wed, Mar 16, 2022 at 08:46:01PM +0100, Jeremie Courreges-Anglas wrote:
> On Mon, Mar 14 2022, Stefan Sperling  wrote:
> > It is currently impossible to use more than one iwm or iwx interface
> > in a system because I don't understand C.
> >
> > Trying to bring up an uninitialized interface anyway results in a
> > kernel panic ("bogus channel pointer" from net80211), so prevent
> > the device from being used in case we never managed to initialize it.
> >
> > ok?
> 
> I only tested iwm(4) 8265 but the change makes sense, ok jca@

I will need to revisit this later.

Somehow it fails in bsd.rd. The interface remains unusable.
Firmware load fails because of rootfs not being mounted yet (expected),
and it still doesn't work once firmware becomes available (not expected).



initial 11ac support for iwm(4)

2022-03-16 Thread Stefan Sperling
This patch adds initial 11ac support to the iwm(4) driver.
It allows use of 80 MHz channels and VHT MCS.

In net80211 I added a new rate control module to support VHT rates, as
a new file called ieee80211_ra_vht.c, derived from ieee80211_ra.c which
we use in 11n mode. The task of this code is to determine the fastest
VHT rate that is usable. (This was not needed to add 11ac support to
iwx(4) because iwx(4) devices perform this task in firmware.)
Retries at lower rates must be handled by the driver. iwm(4) does this via
the "LQ" command which sends a table of Tx rates the firmware should use.

So far, I have tested this successfully on iwm(4) 8265.
In my testing performance peaks at around 250Mbit/s.
There is no device-specific code involved so I would expect this to
work on all cards supported by the driver.

I will test a few more devices I have here soon, but I don't have
access to all iwm(4) hardware variants at the moment. Testing on any
iwm(4) device would be appreciated. Please be precise about which model
of iwm(4) you are testing on when reporting results.

diff refs/heads/master refs/heads/11ac
blob - 7df604d4b6e3913ffeef8c16e7e47637c84af881
blob + 8ed3356b0144a014bece57fa7dcf734624be9fbb
--- sys/conf/files
+++ sys/conf/files
@@ -847,6 +847,7 @@ file net80211/ieee80211_pae_input.c wlan
 file net80211/ieee80211_pae_output.c   wlan
 file net80211/ieee80211_proto.cwlan
 file net80211/ieee80211_ra.c   wlan
+file net80211/ieee80211_ra_vht.c   wlan
 file net80211/ieee80211_rssadapt.c wlan
 file net80211/ieee80211_regdomain.cwlan
 file netinet/if_ether.cether
blob - 7e0e0f4841d3ba61fcf8335bc21c0df2fb416801
blob + ddb2d586ed0ed8c43da2c38d982d47685db940b3
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -143,6 +143,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include  /* for SEQ_LT */
 #undef DPRINTF /* defined in ieee80211_priv.h */
@@ -222,7 +223,7 @@ const struct iwm_rate {
 #define IWM_RVAL_IS_OFDM(_i_) ((_i_) >= 12 && (_i_) != 22)
 
 /* Convert an MCS index into an iwm_rates[] index. */
-const int iwm_mcs2ridx[] = {
+const int iwm_ht_mcs2ridx[] = {
IWM_RATE_MCS_0_INDEX,
IWM_RATE_MCS_1_INDEX,
IWM_RATE_MCS_2_INDEX,
@@ -247,7 +248,7 @@ struct iwm_nvm_section {
 };
 
 intiwm_is_mimo_ht_plcp(uint8_t);
-intiwm_is_mimo_mcs(int);
+intiwm_is_mimo_ht_mcs(int);
 intiwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t);
 intiwm_firmware_store_section(struct iwm_softc *, enum iwm_ucode_type,
uint8_t *, size_t);
@@ -334,6 +335,7 @@ voidiwm_init_channel_map(struct iwm_softc *, const 
ui
const uint8_t *nvm_channels, int nchan);
 intiwm_mimo_enabled(struct iwm_softc *);
 void   iwm_setup_ht_rates(struct iwm_softc *);
+void   iwm_setup_vht_rates(struct iwm_softc *);
 void   iwm_mac_ctxt_task(void *);
 void   iwm_phy_ctxt_task(void *);
 void   iwm_updateprot(struct ieee80211com *);
@@ -396,6 +398,8 @@ voidiwm_rx_frame(struct iwm_softc *, struct mbuf *, 
i
uint32_t, struct ieee80211_rxinfo *, struct mbuf_list *);
 void   iwm_ht_single_rate_control(struct iwm_softc *, struct ieee80211_node *,
int, uint8_t, int);
+void   iwm_vht_single_rate_control(struct iwm_softc *, struct ieee80211_node *,
+   int, int, uint8_t, int);
 void   iwm_rx_tx_cmd_single(struct iwm_softc *, struct iwm_rx_packet *,
struct iwm_node *, int, int);
 void   iwm_txd_done(struct iwm_softc *, struct iwm_tx_data *);
@@ -409,14 +413,15 @@ void  iwm_rx_compressed_ba(struct iwm_softc *, struct 
i
 void   iwm_rx_bmiss(struct iwm_softc *, struct iwm_rx_packet *,
struct iwm_rx_data *);
 intiwm_binding_cmd(struct iwm_softc *, struct iwm_node *, uint32_t);
+uint8_tiwm_get_vht_ctrl_pos(struct ieee80211com *, struct 
ieee80211_channel *);
 intiwm_phy_ctxt_cmd_uhb(struct iwm_softc *, struct iwm_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint32_t, uint8_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, uint8_t);
+   struct ieee80211_channel *, uint8_t, 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);
+   uint8_t, uint32_t, uint32_t, uint8_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 *);
@@ -428,7 +433,7 @@ voidiwm_free_resp(struct iwm_softc *, struct 
iwm_host
 void   iwm_cmd_done(struct iwm_softc *, int, int, int);
 void   iwm_update_sched(struct iwm_softc *, int, int, 

fix multiple iwm/iwx interfaces

2022-03-14 Thread Stefan Sperling
It is currently impossible to use more than one iwm or iwx interface
in a system because I don't understand C.

Trying to bring up an uninitialized interface anyway results in a
kernel panic ("bogus channel pointer" from net80211), so prevent
the device from being used in case we never managed to initialize it.

ok?

diff 239e5514c8225a567e26e4070116f5d41f8e7f87 /usr/src
blob - eece4e0d25a8eecb50627233341ffe836c5a99cb
file + sys/dev/pci/if_iwm.c
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -9971,6 +9971,9 @@ iwm_init(struct ifnet *ifp)
struct ieee80211com *ic = >sc_ic;
int err, generation;
 
+   if (!sc->attached)
+   return ENXIO;
+
rw_assert_wrlock(>ioctl_rwl);
 
generation = ++sc->sc_generation;
@@ -11189,7 +11192,6 @@ iwm_preinit(struct iwm_softc *sc)
struct ieee80211com *ic = >sc_ic;
struct ifnet *ifp = IC2IFP(ic);
int err;
-   static int attached;
 
err = iwm_prepare_card_hw(sc);
if (err) {
@@ -11197,7 +11199,7 @@ iwm_preinit(struct iwm_softc *sc)
return err;
}
 
-   if (attached) {
+   if (sc->attached) {
/* Update MAC in case the upper layers changed it. */
IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
((struct arpcom *)ifp)->ac_enaddr);
@@ -11216,7 +11218,7 @@ iwm_preinit(struct iwm_softc *sc)
return err;
 
/* Print version info and MAC address on first successful fw load. */
-   attached = 1;
+   sc->attached = 1;
printf("%s: hw rev 0x%x, fw ver %s, address %s\n",
DEVNAME(sc), sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK,
sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
blob - 4de3e2bfefe4760baecbccee7739972f6d36fb92
file + sys/dev/pci/if_iwmvar.h
--- sys/dev/pci/if_iwmvar.h
+++ sys/dev/pci/if_iwmvar.h
@@ -473,6 +473,7 @@ struct iwm_softc {
struct ieee80211com sc_ic;
int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int);
int sc_newstate_pending;
+   int attached;
 
struct ieee80211_amrr sc_amrr;
struct timeout sc_calib_to;
blob - ff436be11d9ff000250bc7fdc4e6056fa80a327a
file + sys/dev/pci/if_iwx.c
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -8223,6 +8223,9 @@ iwx_init(struct ifnet *ifp)
struct ieee80211com *ic = >sc_ic;
int err, generation;
 
+   if (!sc->attached)
+   return ENXIO;
+
rw_assert_wrlock(>ioctl_rwl);
 
generation = ++sc->sc_generation;
@@ -9470,7 +9473,6 @@ iwx_preinit(struct iwx_softc *sc)
struct ieee80211com *ic = >sc_ic;
struct ifnet *ifp = IC2IFP(ic);
int err;
-   static int attached;
 
err = iwx_prepare_card_hw(sc);
if (err) {
@@ -9478,7 +9480,7 @@ iwx_preinit(struct iwx_softc *sc)
return err;
}
 
-   if (attached) {
+   if (sc->attached) {
/* Update MAC in case the upper layers changed it. */
IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
((struct arpcom *)ifp)->ac_enaddr);
@@ -9497,7 +9499,7 @@ iwx_preinit(struct iwx_softc *sc)
return err;
 
/* Print version info and MAC address on first successful fw load. */
-   attached = 1;
+   sc->attached = 1;
printf("%s: hw rev 0x%x, fw ver %s, address %s\n",
DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
blob - 39c4c34e97ef9d27c645a73123b48fce64ba4445
file + sys/dev/pci/if_iwxvar.h
--- sys/dev/pci/if_iwxvar.h
+++ sys/dev/pci/if_iwxvar.h
@@ -456,6 +456,7 @@ struct iwx_softc {
struct ieee80211com sc_ic;
int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int);
int sc_newstate_pending;
+   int attached;
 
struct task init_task; /* NB: not reference-counted */
struct refcnt   task_refs;



Re: initial iwx(4) 11ac patch for testing

2022-03-10 Thread Stefan Sperling
On Thu, Mar 10, 2022 at 01:56:19PM -0500, Dave Voutila wrote:
> 
> Stefan Sperling  writes:
> 
> > On Thu, Mar 10, 2022 at 12:25:17PM +0100, Stefan Sperling wrote:
> >> Unless anyone else finds a problem, this patch can be considered ready
> >> for review and commit.
> >
> > Of course, I forgot to apply my sysassert fix to the second phy context
> > command function...  Fixed here.
> >
> 
> Looking good on the 3 devices I've tested, with one minor nit. All 3
> devices are similar AX200s like so:
> 
> iwx0 at pci3 dev 0 function 0 "Intel Wi-Fi 6 AX200" rev 0x1a, msix
> iwx0: hw rev 0x340, fw ver 67.8f59b80b.0, address ...
> 
> For some reason, on my lenovo x13 I had to manually enable 11ac mode via
> ifconfig. No idea why. It was sitting on the table next to my Go 2 that
> automatically picked up on 11ac mode.

Which channel was it on while not in 11ac mode?
Only the 5GHz channel range (chan 36+) can use 11ac.

In the 2GHz channel range (chan 1-12 for the US) 11ac cannot be used.
In that range it should autoselect mode 11n, or 11g/11b for very old APs.

We could tweak access point selection heuristics to prefer 11ac over 11n
if both are available for a given SSID. But that can be done in a later
patch.

> In all 3 cases I tested with tpcbench between my apu2 gateway connected
> to my Synology RT2600ac and the client machine. In all 3 cases I saw
> close to a 100% increase in average bandwidth reported. :-)

Very nice. Thanks for testing!



Re: initial iwx(4) 11ac patch for testing

2022-03-10 Thread Stefan Sperling
On Thu, Mar 10, 2022 at 12:25:17PM +0100, Stefan Sperling wrote:
> Unless anyone else finds a problem, this patch can be considered ready
> for review and commit.

Of course, I forgot to apply my sysassert fix to the second phy context
command function...  Fixed here.

diff refs/heads/master refs/heads/11ac
blob - 57bdcce64458e7f9d5802ce4247d5651f9183200
blob + 61022a02f457141e31ec6c04351519fedf7b5782
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -304,6 +304,7 @@ int iwx_schedule_session_protection(struct iwx_softc *
uint32_t);
 void   iwx_init_channel_map(struct iwx_softc *, uint16_t *, uint32_t *, int);
 void   iwx_setup_ht_rates(struct iwx_softc *);
+void   iwx_setup_vht_rates(struct iwx_softc *);
 intiwx_mimo_enabled(struct iwx_softc *);
 void   iwx_mac_ctxt_task(void *);
 void   iwx_phy_ctxt_task(void *);
@@ -363,12 +364,13 @@ void  iwx_clear_oactive(struct iwx_softc *, struct 
iwx_
 void   iwx_rx_bmiss(struct iwx_softc *, struct iwx_rx_packet *,
struct iwx_rx_data *);
 intiwx_binding_cmd(struct iwx_softc *, struct iwx_node *, uint32_t);
+uint8_tiwx_get_vht_ctrl_pos(struct ieee80211com *, struct 
ieee80211_channel *);
 intiwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *, struct iwx_phy_ctxt *, 
uint8_t,
-   uint8_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint8_t, uint8_t);
 intiwx_phy_ctxt_cmd_v3(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint8_t, uint8_t);
 intiwx_phy_ctxt_cmd(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint32_t, uint8_t, uint8_t);
 intiwx_send_cmd(struct iwx_softc *, struct iwx_host_cmd *);
 intiwx_send_cmd_pdu(struct iwx_softc *, uint32_t, uint32_t, uint16_t,
const void *);
@@ -430,10 +432,12 @@ int   iwx_scan_abort(struct iwx_softc *);
 intiwx_enable_mgmt_queue(struct iwx_softc *);
 intiwx_rs_rval2idx(uint8_t);
 uint16_t iwx_rs_ht_rates(struct iwx_softc *, struct ieee80211_node *, int);
+uint16_t iwx_rs_vht_rates(struct iwx_softc *, struct ieee80211_node *, int);
 intiwx_rs_init(struct iwx_softc *, struct iwx_node *);
 intiwx_enable_data_tx_queues(struct iwx_softc *);
 intiwx_phy_ctxt_update(struct iwx_softc *, struct iwx_phy_ctxt *,
-   struct ieee80211_channel *, uint8_t, uint8_t, uint32_t, uint8_t);
+   struct ieee80211_channel *, uint8_t, uint8_t, uint32_t, uint8_t,
+   uint8_t);
 intiwx_auth(struct iwx_softc *);
 intiwx_deauth(struct iwx_softc *);
 intiwx_run(struct iwx_softc *);
@@ -2812,6 +2816,12 @@ iwx_init_channel_map(struct iwx_softc *sc, uint16_t *c
if (ch_flags & IWX_NVM_CHANNEL_40MHZ)
channel->ic_flags |= IEEE80211_CHAN_40MHZ;
}
+
+   if (is_5ghz && data->sku_cap_11ac_enable) {
+   channel->ic_flags |= IEEE80211_CHAN_VHT;
+   if (ch_flags & IWX_NVM_CHANNEL_80MHZ)
+   channel->ic_xflags |= IEEE80211_CHANX_80MHZ;
+   }
}
 }
 
@@ -2846,6 +2856,34 @@ iwx_setup_ht_rates(struct iwx_softc *sc)
 }
 
 void
+iwx_setup_vht_rates(struct iwx_softc *sc)
+{
+   struct ieee80211com *ic = >sc_ic;
+   uint8_t rx_ant = iwx_fw_valid_rx_ant(sc);
+   int n;
+
+   ic->ic_vht_rxmcs = (IEEE80211_VHT_MCS_0_9 <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(1));
+
+   if (iwx_mimo_enabled(sc) &&
+   ((rx_ant & IWX_ANT_AB) == IWX_ANT_AB ||
+   (rx_ant & IWX_ANT_BC) == IWX_ANT_BC)) {
+   ic->ic_vht_rxmcs |= (IEEE80211_VHT_MCS_0_9 <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(2));
+   } else {
+   ic->ic_vht_rxmcs |= (IEEE80211_VHT_MCS_SS_NOT_SUPP <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(2));
+   }
+
+   for (n = 3; n <= IEEE80211_VHT_NUM_SS; n++) {
+   ic->ic_vht_rxmcs |= (IEEE80211_VHT_MCS_SS_NOT_SUPP <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(n));
+   }
+
+   ic->ic_vht_txmcs = ic->ic_vht_rxmcs;
+}
+
+void
 iwx_init_reorder_buffer(struct iwx_reorder_buffer *reorder_buf,
 uint16_t ssn, uint16_t buf_size)
 {
@@ -3147,7 +3185,7 @@ iwx_phy_ctxt_task(void *arg)
struct ieee80211com *ic = >sc_ic;
struct iwx_node *in = (void *)ic->ic_bss;
struct ieee80211_node *ni = >in_ni;
-   uint8_t chains, sco;
+   uint8_t chains, sco, vht_chan_width;
int err, s = splnet();
 
if ((sc->sc_flags & IWX_FLAG_SHUTDOWN) ||
@@ -3159,13 +3197,23 @@ iwx_phy_ctxt_task(void *arg)
}
 
chains = iwx_mimo_enabled(sc) ? 2 : 1;
-   if (ieee80211_node_supports_ht_chan40(ni))
+   if ((ni->ni_flags & IEEE80211_NODE_HT) &&

Re: initial iwx(4) 11ac patch for testing

2022-03-10 Thread Stefan Sperling
On Wed, Mar 09, 2022 at 01:07:47PM +0100, Stefan Sperling wrote:
> This patch adds initial 11ac support to the iwx(4) driver.
> This means that 80MHz channels can be used. No other 11ac features
> are enabled yet.
> 
> This is not yet a patch which could be committed. Apart from debug
> prints which need to go, there is a known issue found by dv@ where
> this patch causes a firmware error, sysassert 0x20101A25. The reason
> for this is not known.
> It would help to get more testing to see if more clues can be found
> based on where this error pops up. I cannot reproduce the error myself.

Thanks to a hint from Johannes Berg from Linux/Intel, the above problem
has been found.

In some channel configurations we would end up running the PHY at 20MHz
but ask for Tx rates using 80MHz, which caused sysassert 0x20101A25.
This is fixed here.

I have also removed debug prints.

Unless anyone else finds a problem, this patch can be considered ready
for review and commit.

diff refs/heads/master refs/heads/11ac
blob - 57bdcce64458e7f9d5802ce4247d5651f9183200
blob + f423379b313d1dbdba3c05e45c7d35e74056409b
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -304,6 +304,7 @@ int iwx_schedule_session_protection(struct iwx_softc *
uint32_t);
 void   iwx_init_channel_map(struct iwx_softc *, uint16_t *, uint32_t *, int);
 void   iwx_setup_ht_rates(struct iwx_softc *);
+void   iwx_setup_vht_rates(struct iwx_softc *);
 intiwx_mimo_enabled(struct iwx_softc *);
 void   iwx_mac_ctxt_task(void *);
 void   iwx_phy_ctxt_task(void *);
@@ -363,12 +364,13 @@ void  iwx_clear_oactive(struct iwx_softc *, struct 
iwx_
 void   iwx_rx_bmiss(struct iwx_softc *, struct iwx_rx_packet *,
struct iwx_rx_data *);
 intiwx_binding_cmd(struct iwx_softc *, struct iwx_node *, uint32_t);
+uint8_tiwx_get_vht_ctrl_pos(struct ieee80211com *, struct 
ieee80211_channel *);
 intiwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *, struct iwx_phy_ctxt *, 
uint8_t,
-   uint8_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint8_t, uint8_t);
 intiwx_phy_ctxt_cmd_v3(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint8_t, uint8_t);
 intiwx_phy_ctxt_cmd(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint32_t, uint8_t, uint8_t);
 intiwx_send_cmd(struct iwx_softc *, struct iwx_host_cmd *);
 intiwx_send_cmd_pdu(struct iwx_softc *, uint32_t, uint32_t, uint16_t,
const void *);
@@ -430,10 +432,12 @@ int   iwx_scan_abort(struct iwx_softc *);
 intiwx_enable_mgmt_queue(struct iwx_softc *);
 intiwx_rs_rval2idx(uint8_t);
 uint16_t iwx_rs_ht_rates(struct iwx_softc *, struct ieee80211_node *, int);
+uint16_t iwx_rs_vht_rates(struct iwx_softc *, struct ieee80211_node *, int);
 intiwx_rs_init(struct iwx_softc *, struct iwx_node *);
 intiwx_enable_data_tx_queues(struct iwx_softc *);
 intiwx_phy_ctxt_update(struct iwx_softc *, struct iwx_phy_ctxt *,
-   struct ieee80211_channel *, uint8_t, uint8_t, uint32_t, uint8_t);
+   struct ieee80211_channel *, uint8_t, uint8_t, uint32_t, uint8_t,
+   uint8_t);
 intiwx_auth(struct iwx_softc *);
 intiwx_deauth(struct iwx_softc *);
 intiwx_run(struct iwx_softc *);
@@ -2812,6 +2816,12 @@ iwx_init_channel_map(struct iwx_softc *sc, uint16_t *c
if (ch_flags & IWX_NVM_CHANNEL_40MHZ)
channel->ic_flags |= IEEE80211_CHAN_40MHZ;
}
+
+   if (is_5ghz && data->sku_cap_11ac_enable) {
+   channel->ic_flags |= IEEE80211_CHAN_VHT;
+   if (ch_flags & IWX_NVM_CHANNEL_80MHZ)
+   channel->ic_xflags |= IEEE80211_CHANX_80MHZ;
+   }
}
 }
 
@@ -2846,6 +2856,34 @@ iwx_setup_ht_rates(struct iwx_softc *sc)
 }
 
 void
+iwx_setup_vht_rates(struct iwx_softc *sc)
+{
+   struct ieee80211com *ic = >sc_ic;
+   uint8_t rx_ant = iwx_fw_valid_rx_ant(sc);
+   int n;
+
+   ic->ic_vht_rxmcs = (IEEE80211_VHT_MCS_0_9 <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(1));
+
+   if (iwx_mimo_enabled(sc) &&
+   ((rx_ant & IWX_ANT_AB) == IWX_ANT_AB ||
+   (rx_ant & IWX_ANT_BC) == IWX_ANT_BC)) {
+   ic->ic_vht_rxmcs |= (IEEE80211_VHT_MCS_0_9 <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(2));
+   } else {
+   ic->ic_vht_rxmcs |= (IEEE80211_VHT_MCS_SS_NOT_SUPP <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(2));
+   }
+
+   for (n = 3; n <= IEEE80211_VHT_NUM_SS; n++) {
+   ic->ic_vht_rxmcs |= (IEEE80211_VHT_MCS_SS_NOT_SUPP <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(n));
+   }
+
+   ic->ic_vht_

Re: initial iwx(4) 11ac patch for testing

2022-03-10 Thread Stefan Sperling
On Wed, Mar 09, 2022 at 07:16:41PM +0300, Mikhail wrote:
> On Wed, Mar 09, 2022 at 01:07:47PM +0100, Stefan Sperling wrote:
> >  /*
> > + * Install received VHT caps information in the node's state block.
> > + */
> > +void
> > +ieee80211_setup_vhtcaps(struct ieee80211_node *ni, const uint8_t *data,
> > +uint8_t len)
> > +{
> > +   if (len != 12)
> > +   return;
> > +
> > +   ni->ni_vhtcaps = (data[0] | (data[1] << 8) | data[2] << 16 |
> > +   data[3] << 24);
> > +   ni->ni_vht_rxmcs = (data[4] | (data[5] << 8));
> > +   ni->ni_vht_rx_max_lgi_mbit_s = ((data[6] | (data[7] << 8)) &
> > +   IEEE80211_VHT_MAX_LGI_MBIT_S_MASK);
> > +   ni->ni_vht_txmcs = (data[8] | (data[9] << 8));
> > +   ni->ni_vht_tx_max_lgi_mbit_s = ((data[10] | (data[11] << 8)) &
> > +   IEEE80211_VHT_MAX_LGI_MBIT_S_MASK);
> > +
> > +   ni->ni_flags |= IEEE80211_NODE_VHTCAP;
> > +}
> 
> I understand that this function do things like ieee80211_setup_htcaps()
> (HT, 802.11n), which is mature, working and stable, but is there a
> reason not to return 0 on error, 1 on success, and check it in the
> caller (like in ieee80211_setup_vhtop())?

Doesn't really matter. We can decide to ignore just the VHT cap IE, or
we can discard the whole beacon. Either way, VHT won't be enabled.

> > +/* Check if the peer supports VHT short guard interval (SGI) on 160 MHz. */
> > +static inline int
> > +ieee80211_node_supports_vht_sgi160(struct ieee80211_node *ni)
> > +{
> > +   return ieee80211_node_supports_vht(ni) &&
> > +   (ni->ni_vhtcaps & IEEE80211_VHTCAP_SGI160);
> > +}
> 
> This function is unused.

I added it for future use.

> The patch for whitespacing:

Thanks. I will keep this for later instead of mixing it in right now.
I can then commit it separately and attribute it to you in the log message.



initial iwx(4) 11ac patch for testing

2022-03-09 Thread Stefan Sperling
This patch adds initial 11ac support to the iwx(4) driver.
This means that 80MHz channels can be used. No other 11ac features
are enabled yet.

This is not yet a patch which could be committed. Apart from debug
prints which need to go, there is a known issue found by dv@ where
this patch causes a firmware error, sysassert 0x20101A25. The reason
for this is not known.
It would help to get more testing to see if more clues can be found
based on where this error pops up. I cannot reproduce the error myself.

When sending feedback, please be clear about which iwx(4) device and
which access point has been tested. Thanks!

The patch works for me on AX200 and AX201 with a pepwave AC one mini AP,
although throughput is not much different to 11n 40MHz with this AP.

diff refs/heads/master refs/heads/11ac
blob - 57bdcce64458e7f9d5802ce4247d5651f9183200
blob + a56c59f82c854c282a61c302162df4eae3c27fb8
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -304,6 +304,7 @@ int iwx_schedule_session_protection(struct iwx_softc *
uint32_t);
 void   iwx_init_channel_map(struct iwx_softc *, uint16_t *, uint32_t *, int);
 void   iwx_setup_ht_rates(struct iwx_softc *);
+void   iwx_setup_vht_rates(struct iwx_softc *);
 intiwx_mimo_enabled(struct iwx_softc *);
 void   iwx_mac_ctxt_task(void *);
 void   iwx_phy_ctxt_task(void *);
@@ -363,12 +364,13 @@ void  iwx_clear_oactive(struct iwx_softc *, struct 
iwx_
 void   iwx_rx_bmiss(struct iwx_softc *, struct iwx_rx_packet *,
struct iwx_rx_data *);
 intiwx_binding_cmd(struct iwx_softc *, struct iwx_node *, uint32_t);
+uint8_tiwx_get_vht_ctrl_pos(struct ieee80211com *, struct 
ieee80211_channel *);
 intiwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *, struct iwx_phy_ctxt *, 
uint8_t,
-   uint8_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint8_t, uint8_t);
 intiwx_phy_ctxt_cmd_v3(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint8_t, uint8_t);
 intiwx_phy_ctxt_cmd(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
-   uint8_t, uint32_t, uint32_t, uint8_t);
+   uint8_t, uint32_t, uint32_t, uint8_t, uint8_t);
 intiwx_send_cmd(struct iwx_softc *, struct iwx_host_cmd *);
 intiwx_send_cmd_pdu(struct iwx_softc *, uint32_t, uint32_t, uint16_t,
const void *);
@@ -430,10 +432,12 @@ int   iwx_scan_abort(struct iwx_softc *);
 intiwx_enable_mgmt_queue(struct iwx_softc *);
 intiwx_rs_rval2idx(uint8_t);
 uint16_t iwx_rs_ht_rates(struct iwx_softc *, struct ieee80211_node *, int);
+uint16_t iwx_rs_vht_rates(struct iwx_softc *, struct ieee80211_node *, int);
 intiwx_rs_init(struct iwx_softc *, struct iwx_node *);
 intiwx_enable_data_tx_queues(struct iwx_softc *);
 intiwx_phy_ctxt_update(struct iwx_softc *, struct iwx_phy_ctxt *,
-   struct ieee80211_channel *, uint8_t, uint8_t, uint32_t, uint8_t);
+   struct ieee80211_channel *, uint8_t, uint8_t, uint32_t, uint8_t,
+   uint8_t);
 intiwx_auth(struct iwx_softc *);
 intiwx_deauth(struct iwx_softc *);
 intiwx_run(struct iwx_softc *);
@@ -2812,6 +2816,15 @@ iwx_init_channel_map(struct iwx_softc *sc, uint16_t *c
if (ch_flags & IWX_NVM_CHANNEL_40MHZ)
channel->ic_flags |= IEEE80211_CHAN_40MHZ;
}
+
+   if (is_5ghz && data->sku_cap_11ac_enable) {
+   channel->ic_flags |= IEEE80211_CHAN_VHT;
+   if (ch_flags & IWX_NVM_CHANNEL_80MHZ) {
+   printf("%s: channel %d 80MHz ok\n", __func__, 
hw_value);
+   channel->ic_xflags |= IEEE80211_CHANX_80MHZ;
+   } else
+   printf("%s: channel %d 80MHz NOT ok\n", 
__func__, hw_value);
+   }
}
 }
 
@@ -2846,6 +2859,34 @@ iwx_setup_ht_rates(struct iwx_softc *sc)
 }
 
 void
+iwx_setup_vht_rates(struct iwx_softc *sc)
+{
+   struct ieee80211com *ic = >sc_ic;
+   uint8_t rx_ant = iwx_fw_valid_rx_ant(sc);
+   int n;
+
+   ic->ic_vht_rxmcs = (IEEE80211_VHT_MCS_0_9 <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(1));
+
+   if (iwx_mimo_enabled(sc) &&
+   ((rx_ant & IWX_ANT_AB) == IWX_ANT_AB ||
+   (rx_ant & IWX_ANT_BC) == IWX_ANT_BC)) {
+   ic->ic_vht_rxmcs |= (IEEE80211_VHT_MCS_0_9 <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(2));
+   } else {
+   ic->ic_vht_rxmcs |= (IEEE80211_VHT_MCS_SS_NOT_SUPP <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(2));
+   }
+
+   for (n = 3; n <= IEEE80211_VHT_NUM_SS; n++) {
+   ic->ic_vht_rxmcs |= (IEEE80211_VHT_MCS_SS_NOT_SUPP <<
+   IEEE80211_VHT_MCS_FOR_SS_SHIFT(n));
+   }
+
+   ic->ic_vht_txmcs = ic->ic_vht_rxmcs;
+}
+
+void
 iwx_init_reorder_buffer(struct iwx_reorder_buffer *reorder_buf,
 

Re: ieee80211_stats userland vs. kernel

2022-03-09 Thread Stefan Sperling
On Tue, Mar 08, 2022 at 02:38:39PM -0700, Theo de Raadt wrote:
> Stefan Sperling  wrote:
> > In this case it is not ifconfig, but netstat -W iwm0.
> > Which is a debugging tool, like netstat -s.
> 
> We don't care when netstat breaks

Alright, then this diff is indeed not necessary.



Re: ieee80211_stats userland vs. kernel

2022-03-08 Thread Stefan Sperling
On Tue, Mar 08, 2022 at 12:58:27PM -0700, Theo de Raadt wrote:
> Claudio Jeker  wrote:
> 
> > Honestly I think this is overkill. There is no stat struct where we do
> > this dance. It is accepted that netstat needs to keep in sync for these
> > structs to work. Why is it necessary to disconnect the kernel and userland
> > for this?
> 
> Actually there is a major one: it is how ps works.
> 
> I think the problem is when this struct is changed, ifconfig becomes unusable?

In this case it is not ifconfig, but netstat -W iwm0.
Which is a debugging tool, like netstat -s.



Re: ieee80211_stats userland vs. kernel

2022-03-08 Thread Stefan Sperling
On Tue, Mar 08, 2022 at 03:55:48PM +0100, Stefan Sperling wrote:
> On Mon, Mar 07, 2022 at 03:04:06PM -0700, Theo de Raadt wrote:
> > > For now, the structs are identical so the code copying data out is
> > > kept simple.
> > 
> > I think this is unwise, and you should write the field-by-field copying
> > function at the same time, otherwise this is just asking for trouble.
> > You really cannot wait until an intentional change.
> 
> Sure, here it is.

On second thought, avoiding the malloc/free dance is better.
The struct is still small enough to fit on the stack.

diff refs/heads/master refs/heads/statsreq
blob - 85d795d745eb21fd218056c2f3faf7fbc2c7fe49
blob + 62938001ed22fc133a0c98e27ef5690c978e21f3
--- sys/net80211/ieee80211_ioctl.c
+++ sys/net80211/ieee80211_ioctl.c
@@ -55,6 +55,8 @@ void   ieee80211_node2req(struct ieee80211com *,
const struct ieee80211_node *, struct ieee80211_nodereq *);
 voidieee80211_req2node(struct ieee80211com *,
const struct ieee80211_nodereq *, struct ieee80211_node *);
+void ieee80211_stats2req(struct ieee80211_statsreq *,
+   struct ieee80211_stats *);
 
 void
 ieee80211_node2req(struct ieee80211com *ic, const struct ieee80211_node *ni,
@@ -180,6 +182,89 @@ ieee80211_req2node(struct ieee80211com *ic, const stru
 }
 
 void
+ieee80211_stats2req(struct ieee80211_statsreq *req,
+struct ieee80211_stats *stats)
+{
+   memset(req, 0, sizeof(*req));
+
+   req->is_rx_badversion = stats->is_rx_badversion;
+   req->is_rx_tooshort = stats->is_rx_tooshort;
+   req->is_rx_wrongbss = stats->is_rx_wrongbss;
+   req->is_rx_dup = stats->is_rx_dup;
+   req->is_rx_wrongdir = stats->is_rx_wrongdir;
+   req->is_rx_mcastecho = stats->is_rx_mcastecho;
+   req->is_rx_notassoc = stats->is_rx_notassoc;
+   req->is_rx_nowep = stats->is_rx_nowep;
+   req->is_rx_unencrypted = stats->is_rx_unencrypted;
+   req->is_rx_wepfail = stats->is_rx_wepfail;
+   req->is_rx_decap = stats->is_rx_decap;
+   req->is_rx_mgtdiscard = stats->is_rx_mgtdiscard;
+   req->is_rx_ctl = stats->is_rx_ctl;
+   req->is_rx_rstoobig = stats->is_rx_rstoobig;
+   req->is_rx_elem_missing = stats->is_rx_elem_missing;
+   req->is_rx_elem_toobig = stats->is_rx_elem_toobig;
+   req->is_rx_elem_toosmall = stats->is_rx_elem_toosmall;
+   req->is_rx_badchan = stats->is_rx_badchan;
+   req->is_rx_chanmismatch = stats->is_rx_chanmismatch;
+   req->is_rx_nodealloc = stats->is_rx_nodealloc;
+   req->is_rx_ssidmismatch = stats->is_rx_ssidmismatch;
+   req->is_rx_auth_unsupported = stats->is_rx_auth_unsupported;
+   req->is_rx_auth_fail = stats->is_rx_auth_fail;
+   req->is_rx_assoc_bss = stats->is_rx_assoc_bss;
+   req->is_rx_assoc_notauth = stats->is_rx_assoc_notauth;
+   req->is_rx_assoc_capmismatch = stats->is_rx_assoc_capmismatch;
+   req->is_rx_assoc_norate = stats->is_rx_assoc_norate;
+   req->is_rx_deauth = stats->is_rx_deauth;
+   req->is_rx_disassoc = stats->is_rx_disassoc;
+   req->is_rx_badsubtype = stats->is_rx_badsubtype;
+   req->is_rx_nombuf = stats->is_rx_nombuf;
+   req->is_rx_decryptcrc = stats->is_rx_decryptcrc;
+   req->is_rx_ahdemo_mgt = stats->is_rx_ahdemo_mgt;
+   req->is_rx_bad_auth = stats->is_rx_bad_auth;
+   req->is_tx_nombuf = stats->is_tx_nombuf;
+   req->is_tx_nonode = stats->is_tx_nonode;
+   req->is_tx_unknownmgt = stats->is_tx_unknownmgt;
+   req->is_scan_active = stats->is_scan_active;
+   req->is_scan_passive = stats->is_scan_passive;
+   req->is_node_timeout = stats->is_node_timeout;
+   req->is_crypto_nomem = stats->is_crypto_nomem;
+   req->is_rx_assoc_badrsnie = stats->is_rx_assoc_badrsnie;
+   req->is_rx_unauth = stats->is_rx_unauth;
+   req->is_tx_noauth = stats->is_tx_noauth;
+   req->is_rx_eapol_key = stats->is_rx_eapol_key;
+   req->is_rx_eapol_replay = stats->is_rx_eapol_replay;
+   req->is_rx_eapol_badmic = stats->is_rx_eapol_badmic;
+   req->is_rx_remmicfail = stats->is_rx_remmicfail;
+   req->is_rx_locmicfail = stats->is_rx_locmicfail;
+   req->is_tkip_replays = stats->is_tkip_replays;
+   req->is_tkip_icv_errs = stats->is_tkip_icv_errs;
+   req->is_ccmp_replays = stats->is_ccmp_replays;
+   req->is_ccmp_dec_errs = stats->is_ccmp_dec_errs;
+   req->is_cmac_replays = stats->is_cmac_replays;
+   req->is_cmac_icv_errs = stats->is_cmac_icv_errs;
+   req->is_pbac_errs = stats->is_pbac_errs;
+   req->is_ht_nego_no_mandatory_mcs = stats->is_ht_nego_no_ma

Re: ieee80211_stats userland vs. kernel

2022-03-08 Thread Stefan Sperling
On Mon, Mar 07, 2022 at 03:04:06PM -0700, Theo de Raadt wrote:
> > For now, the structs are identical so the code copying data out is
> > kept simple.
> 
> I think this is unwise, and you should write the field-by-field copying
> function at the same time, otherwise this is just asking for trouble.
> You really cannot wait until an intentional change.

Sure, here it is.

diff 0ed925b6612724f216b84360a04117aad1c6df9b 
6615def0a9e782a7fd930d75fda1ae4ec0f90dd2
blob - 85d795d745eb21fd218056c2f3faf7fbc2c7fe49
blob + d4f6b536b2eb2165f85f9df7c08a1cee36a428a4
--- sys/net80211/ieee80211_ioctl.c
+++ sys/net80211/ieee80211_ioctl.c
@@ -55,6 +55,7 @@ void   ieee80211_node2req(struct ieee80211com *,
const struct ieee80211_node *, struct ieee80211_nodereq *);
 voidieee80211_req2node(struct ieee80211com *,
const struct ieee80211_nodereq *, struct ieee80211_node *);
+struct ieee80211_statsreq *ieee80211_stats2req(struct ieee80211_stats *);
 
 void
 ieee80211_node2req(struct ieee80211com *ic, const struct ieee80211_node *ni,
@@ -179,6 +180,94 @@ ieee80211_req2node(struct ieee80211com *ic, const stru
ni->ni_state = nr->nr_state;
 }
 
+struct ieee80211_statsreq *
+ieee80211_stats2req(struct ieee80211_stats *stats)
+{
+   struct ieee80211_statsreq *req;
+
+   req = malloc(sizeof(*req), M_DEVBUF, M_ZERO | M_WAITOK | M_CANFAIL);
+   if (req == NULL)
+   return NULL;
+
+   req->is_rx_badversion = stats->is_rx_badversion;
+   req->is_rx_tooshort = stats->is_rx_tooshort;
+   req->is_rx_wrongbss = stats->is_rx_wrongbss;
+   req->is_rx_dup = stats->is_rx_dup;
+   req->is_rx_wrongdir = stats->is_rx_wrongdir;
+   req->is_rx_mcastecho = stats->is_rx_mcastecho;
+   req->is_rx_notassoc = stats->is_rx_notassoc;
+   req->is_rx_nowep = stats->is_rx_nowep;
+   req->is_rx_unencrypted = stats->is_rx_unencrypted;
+   req->is_rx_wepfail = stats->is_rx_wepfail;
+   req->is_rx_decap = stats->is_rx_decap;
+   req->is_rx_mgtdiscard = stats->is_rx_mgtdiscard;
+   req->is_rx_ctl = stats->is_rx_ctl;
+   req->is_rx_rstoobig = stats->is_rx_rstoobig;
+   req->is_rx_elem_missing = stats->is_rx_elem_missing;
+   req->is_rx_elem_toobig = stats->is_rx_elem_toobig;
+   req->is_rx_elem_toosmall = stats->is_rx_elem_toosmall;
+   req->is_rx_badchan = stats->is_rx_badchan;
+   req->is_rx_chanmismatch = stats->is_rx_chanmismatch;
+   req->is_rx_nodealloc = stats->is_rx_nodealloc;
+   req->is_rx_ssidmismatch = stats->is_rx_ssidmismatch;
+   req->is_rx_auth_unsupported = stats->is_rx_auth_unsupported;
+   req->is_rx_auth_fail = stats->is_rx_auth_fail;
+   req->is_rx_assoc_bss = stats->is_rx_assoc_bss;
+   req->is_rx_assoc_notauth = stats->is_rx_assoc_notauth;
+   req->is_rx_assoc_capmismatch = stats->is_rx_assoc_capmismatch;
+   req->is_rx_assoc_norate = stats->is_rx_assoc_norate;
+   req->is_rx_deauth = stats->is_rx_deauth;
+   req->is_rx_disassoc = stats->is_rx_disassoc;
+   req->is_rx_badsubtype = stats->is_rx_badsubtype;
+   req->is_rx_nombuf = stats->is_rx_nombuf;
+   req->is_rx_decryptcrc = stats->is_rx_decryptcrc;
+   req->is_rx_ahdemo_mgt = stats->is_rx_ahdemo_mgt;
+   req->is_rx_bad_auth = stats->is_rx_bad_auth;
+   req->is_tx_nombuf = stats->is_tx_nombuf;
+   req->is_tx_nonode = stats->is_tx_nonode;
+   req->is_tx_unknownmgt = stats->is_tx_unknownmgt;
+   req->is_scan_active = stats->is_scan_active;
+   req->is_scan_passive = stats->is_scan_passive;
+   req->is_node_timeout = stats->is_node_timeout;
+   req->is_crypto_nomem = stats->is_crypto_nomem;
+   req->is_rx_assoc_badrsnie = stats->is_rx_assoc_badrsnie;
+   req->is_rx_unauth = stats->is_rx_unauth;
+   req->is_tx_noauth = stats->is_tx_noauth;
+   req->is_rx_eapol_key = stats->is_rx_eapol_key;
+   req->is_rx_eapol_replay = stats->is_rx_eapol_replay;
+   req->is_rx_eapol_badmic = stats->is_rx_eapol_badmic;
+   req->is_rx_remmicfail = stats->is_rx_remmicfail;
+   req->is_rx_locmicfail = stats->is_rx_locmicfail;
+   req->is_tkip_replays = stats->is_tkip_replays;
+   req->is_tkip_icv_errs = stats->is_tkip_icv_errs;
+   req->is_ccmp_replays = stats->is_ccmp_replays;
+   req->is_ccmp_dec_errs = stats->is_ccmp_dec_errs;
+   req->is_cmac_replays = stats->is_cmac_replays;
+   req->is_cmac_icv_errs = stats->is_cmac_icv_errs;
+   req->is_pbac_errs = stats->is_pbac_errs;
+   req->is_ht_nego_no_mandatory_mcs = stats->is_ht_nego_no_mandatory_mcs;
+   req->is_ht_nego_no_basic_mcs = stats->is_ht_nego_no_basic_mcs;
+   req->is_ht_nego_bad_crypto = stats->is_ht_nego_bad_crypto;
+   req->is_ht_prot_change = stats->is_ht_prot_change;
+   req->is_ht_rx_ba_agreements = stats->is_ht_rx_ba_agreements;
+   req->is_ht_tx_ba_agreements = stats->is_ht_tx_ba_agreements;
+   req->is_ht_rx_frame_below_ba_winstart =
+   

ieee80211_stats userland vs. kernel

2022-03-07 Thread Stefan Sperling
There is another net80211 ioctl which shares a struct between kernel
and userland: struct ieee80211_stats shown by the netstat -W command.

While it is trivial to recompile netstat when this struct is changed,
giving the kernel a separate struct type would allow us to add, change,
or remove counters in the kernel without impacting userland immediately.
Is this worth it?

For now, the structs are identical so the code copying data out is
kept simple.

The struct is quite large and we could probably get rid of some of these
counters without losing useful debugging information, but that is a
separate problem.

Warning: This diff seems to overflow miniroot71.img on amd64,
breaking 'make release' builds without further changes.

diff 7f506de28f9813c0e2213a45686e27166679219e 
64e5109ffcdce254aca22d4a8a40991e792c0738
blob - 85d795d745eb21fd218056c2f3faf7fbc2c7fe49
blob + a3a734d32123ff96870e24efeb30651bfd0b50be
--- sys/net80211/ieee80211_ioctl.c
+++ sys/net80211/ieee80211_ioctl.c
@@ -810,17 +810,11 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t
break;
}
break;
-#if 0
-   case SIOCG80211ZSTATS:
-#endif
case SIOCG80211STATS:
ifr = (struct ifreq *)data;
error = copyout(>ic_stats, ifr->ifr_data,
-   sizeof(ic->ic_stats));
-#if 0
-   if (cmd == SIOCG80211ZSTATS)
-   memset(>ic_stats, 0, sizeof(ic->ic_stats));
-#endif
+   MIN(sizeof(struct ieee80211_statsreq),
+   sizeof(struct ieee80211_stats)));
break;
case SIOCS80211TXPOWER:
if ((error = suser(curproc)) != 0)
blob - 65e93c23da2d86c0ad259f77b7c9affc85d9038b
blob + fa95ad15b809e16868e2eba4dba66568b5a66cfe
--- sys/net80211/ieee80211_ioctl.h
+++ sys/net80211/ieee80211_ioctl.h
@@ -37,8 +37,8 @@
  * IEEE 802.11 ioctls.
  */
 
-/* per-interface statistics */
-struct ieee80211_stats {
+/* per-interface statistics, corresponds to struct ieee80211_stats */
+struct ieee80211_statsreq {
u_int32_t   is_rx_badversion;   /* rx frame with bad version */
u_int32_t   is_rx_tooshort; /* rx frame too short */
u_int32_t   is_rx_wrongbss; /* rx from wrong bssid */
blob - 161853a629887a1aa997480d605d4febd66dd2db
blob + d8845bfc6aa1331110ca22ec949a00932645907e
--- sys/net80211/ieee80211_var.h
+++ sys/net80211/ieee80211_var.h
@@ -214,6 +214,81 @@ struct ieee80211_defrag {
 
 struct ieee80211_node_switch_bss_arg;
 
+/* per-interface statistics */
+struct ieee80211_stats {
+   u_int32_t   is_rx_badversion;   /* rx frame with bad version */
+   u_int32_t   is_rx_tooshort; /* rx frame too short */
+   u_int32_t   is_rx_wrongbss; /* rx from wrong bssid */
+   u_int32_t   is_rx_dup;  /* rx discard 'cuz dup */
+   u_int32_t   is_rx_wrongdir; /* rx w/ wrong direction */
+   u_int32_t   is_rx_mcastecho;/* rx discard 'cuz mcast echo */
+   u_int32_t   is_rx_notassoc; /* rx discard 'cuz sta !assoc */
+   u_int32_t   is_rx_nowep;/* rx w/ wep but wep !config */
+   u_int32_t   is_rx_unencrypted;  /* rx w/o wep but wep config */
+   u_int32_t   is_rx_wepfail;  /* rx wep processing failed */
+   u_int32_t   is_rx_decap;/* rx decapsulation failed */
+   u_int32_t   is_rx_mgtdiscard;   /* rx discard mgt frames */
+   u_int32_t   is_rx_ctl;  /* rx discard ctrl frames */
+   u_int32_t   is_rx_rstoobig; /* rx rate set truncated */
+   u_int32_t   is_rx_elem_missing; /* rx required element missing*/
+   u_int32_t   is_rx_elem_toobig;  /* rx element too big */
+   u_int32_t   is_rx_elem_toosmall;/* rx element too small */
+   u_int32_t   is_rx_badchan;  /* rx frame w/ invalid chan */
+   u_int32_t   is_rx_chanmismatch; /* rx frame chan mismatch */
+   u_int32_t   is_rx_nodealloc;/* rx frame dropped */
+   u_int32_t   is_rx_ssidmismatch; /* rx frame ssid mismatch  */
+   u_int32_t   is_rx_auth_unsupported; /* rx w/ unsupported auth alg */
+   u_int32_t   is_rx_auth_fail;/* rx sta auth failure */
+   u_int32_t   is_rx_assoc_bss;/* rx assoc from wrong bssid */
+   u_int32_t   is_rx_assoc_notauth;/* rx assoc w/o auth */
+   u_int32_t   is_rx_assoc_capmismatch;/* rx assoc w/ cap mismatch */
+   u_int32_t   is_rx_assoc_norate; /* rx assoc w/ no rate match */
+   u_int32_t   is_rx_deauth;   /* rx deauthentication */
+   u_int32_t   is_rx_disassoc; /* rx disassociation */
+   u_int32_t   is_rx_badsubtype;   /* rx frame w/ unknown subtype*/
+   u_int32_t   is_rx_nombuf;   /* rx 

Re: add openvpn 1194/udp/tcp port to /etc/services

2022-03-01 Thread Stefan Sperling
On Tue, Mar 01, 2022 at 10:41:14AM +, Stuart Henderson wrote:
> Probably best to wait a bit for other feedback, but: OK sthen

Ok from me, too. Some of my subnets are routed to me via OpenVPN so
I will be forced to keep using it for the foreseeable future.

I have $openvpn_port variables in some pf.conf files...



Re: A program compiled with '-pg' option always gets SEGV on its execution.

2022-02-21 Thread Stefan Sperling
On Mon, Feb 21, 2022 at 10:20:17AM +0100, Marc Espie wrote:
> On Mon, Feb 21, 2022 at 05:36:16PM +0900, Yuichiro NAITO wrote:
> > Of course, all programs compiled without '-pg' work fine for me.
> > I found this issue when I profile my application with gprof(1).
> > For example, following example C source code fails to execute on OpenBSD 
> > 7.0.
> 
> Profile is partly broken and has been for a while.
> 
> Compiling with -static and removing any pledge() call allow profiling to work.

Yes, and the proposed patch effectively enables -static if -pg is used.
I don't know if this the best fix. But this issue keeps popping up and
it would be nice to have something that works out of the box.
I would not mind this patch going in.

Pledge and unveil interfering with profiling is a separate issue which
is more obvious when it occurs and can easily be worked around by the
developer.



Re: fix active scan on iwm and iwx

2022-02-08 Thread Stefan Sperling
On Tue, Jan 25, 2022 at 11:22:45AM +0100, Mark Kettenis wrote:
> > The KASSERT triggers but for the wrong reason: We don't have outstanding
> > tasks, we have a bad reference counter. Only setting the ref counter to 1 if
> > we are about to launch a task during resume should fix it, and this matches
> > what iwx(4) is doing:
> 
> Running this now.  May take some time to reproduce the issue though.

Any news?  I would like to commit this patch.

> > diff d26399562c831a7212cebc57463cc9931ff8aff2 /usr/src
> > blob - 937f2cc28f6c85502031e4c9efa0a02c75fd1a6d
> > file + sys/dev/pci/if_iwm.c
> > --- sys/dev/pci/if_iwm.c
> > +++ sys/dev/pci/if_iwm.c
> > @@ -11719,8 +11719,6 @@ iwm_wakeup(struct iwm_softc *sc)
> > struct ifnet *ifp = >sc_ic.ic_if;
> > int err;
> >  
> > -   refcnt_init(>task_refs);
> > -
> > err = iwm_start_hw(sc);
> > if (err)
> > return err;
> > @@ -11729,6 +11727,7 @@ iwm_wakeup(struct iwm_softc *sc)
> > if (err)
> > return err;
> >  
> > +   refcnt_init(>task_refs);
> > ifq_clr_oactive(>if_snd);
> > ifp->if_flags |= IFF_RUNNING;
> >  
> > 
> 



Re: fix active scan on iwm and iwx

2022-01-25 Thread Stefan Sperling
On Tue, Jan 25, 2022 at 09:32:21AM +0100, Mark Kettenis wrote:
> Happened again while still on a Jan 16 snapshot kernel.  So it is not
> related to that diff.
> 
> Here is the panic message and backtrace:
> 
> panic: kernel diagnostic assertion "sc->task_refs.refs == 0" failed: file 
> "/usr/src/sys/dev/pci/if_iwm.c", line 9981
> Stopped at  db_enter+0x10:  popq%rbp
> TIDPIDUID PRFLAGS PFLAGS  CPU  COMMAND
> *120744  85293  0 0x3  00K ifconfig
> db_enter() at db_enter+0x10
> panic() at panic+0xbf
> __assert() at __assert+0x25
> iwm_init() at iwm_init+0x254
> iwm_ioctl() at iwm_ioctl+0xf9
> ifioctl() at ifioctl+0x92b
> soo_ioctl() at soo_ioctl+0x161
> sys_ioctl() at sys_ioctl+0x2c4
> syscall() at syscall+0x374
> Xsyscall() at Xsyscall+0x128
> end of kernel
> 

Please try this patch.

Upon resume we, set the task ref count to 1 in anticipation of
the newstate task that will be triggered to move into SCAN state.
iwm_add_task would bump the refcount to 2. The task would decrease
refcount again when it is done, and refcnt_finalize() in iwm_stop()
would eventually let the counter drop back to zero.

Now, for some reason on your system the device is not responding to
the driver's attempt to claim ownership. This looks like maybe some
problem with the bus the device is attached to. I am not in a position
to debug that issue, perhaps you could try? In any case, iwx_wakeup()
errors out early, with task refcount 1 but with no task scheduled and
IFF_RUNNING not set (meaning ioctl will not call iwm_stop()).

Later, you run ifconfig, the ioctl handler runs, and calls iwm_init().
This function expects that we are in a clean initial state (as after boot),
such that iwm_stop() was called beforehand to clear out any tasks, dropping
the task ref counter back to zero.

The KASSERT triggers but for the wrong reason: We don't have outstanding
tasks, we have a bad reference counter. Only setting the ref counter to 1 if
we are about to launch a task during resume should fix it, and this matches
what iwx(4) is doing:

diff d26399562c831a7212cebc57463cc9931ff8aff2 /usr/src
blob - 937f2cc28f6c85502031e4c9efa0a02c75fd1a6d
file + sys/dev/pci/if_iwm.c
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -11719,8 +11719,6 @@ iwm_wakeup(struct iwm_softc *sc)
struct ifnet *ifp = >sc_ic.ic_if;
int err;
 
-   refcnt_init(>task_refs);
-
err = iwm_start_hw(sc);
if (err)
return err;
@@ -11729,6 +11727,7 @@ iwm_wakeup(struct iwm_softc *sc)
if (err)
return err;
 
+   refcnt_init(>task_refs);
ifq_clr_oactive(>if_snd);
ifp->if_flags |= IFF_RUNNING;
 



Re: fix active scan on iwm and iwx

2022-01-21 Thread Stefan Sperling
On Sun, Jan 16, 2022 at 07:38:11PM +0100, Mark Kettenis wrote:
> > Date: Sun, 16 Jan 2022 19:28:06 +0100
> > From: Stefan Sperling 
> > 
> > On Sun, Jan 16, 2022 at 03:50:55PM +0100, Mark Kettenis wrote:
> > > However, running this diff I had a problem after resuming my laptop
> > > twice. After resume the interface didn't work and I found the
> > > following in dmesg:
> > > 
> > > iwm0: could not initialize hardware
> > > 
> > > I tried to reset the interface by bringing it down and up again, which
> > > crashed the machine.  It must have been in ddb since typing "bo re"
> > > made it reset.  Unfortunately I don't have further information since I
> > > was in X.
> > 
> > Did you try reproducing this problem without the patch in place?
> > It would be good to know whether this problem is being introduced by
> > this patch. I don't believe this is likely, my bet would be that this
> > is an existing problem. But it would be good to know for sure.
> 
> Yes.  I switched back to regular snapshots.  Will keep you posted.
> 

Any news?

I have unsuccessfully tried to reproduce this problem on a laptop
with a 9560 iwm device, via both S3 suspend and hibernate.
I do not have a 9260 device in a machine which can suspend, unfortunately.

This was not a problem that occurred for you consistently, was it?
If so, even if you have not yet seen the failure without the patch,
I would like to commit this patch to unblock further progress. If the
error happens for more people afterwards we could investigate further.
Hopefully someone will be able to provide a trace from ddb.



Re: fix active scan on iwm and iwx

2022-01-16 Thread Stefan Sperling
On Sun, Jan 16, 2022 at 03:50:55PM +0100, Mark Kettenis wrote:
> However, running this diff I had a problem after resuming my laptop
> twice. After resume the interface didn't work and I found the
> following in dmesg:
> 
> iwm0: could not initialize hardware
> 
> I tried to reset the interface by bringing it down and up again, which
> crashed the machine.  It must have been in ddb since typing "bo re"
> made it reset.  Unfortunately I don't have further information since I
> was in X.

Did you try reproducing this problem without the patch in place?
It would be good to know whether this problem is being introduced by
this patch. I don't believe this is likely, my bet would be that this
is an existing problem. But it would be good to know for sure.



Re: AX210 wifi

2022-01-16 Thread Stefan Sperling
On Sun, Jan 16, 2022 at 05:51:03PM +0300, Alex Beakes wrote:
> FreeBSD has tested iwlwifi with Intel(R) Wi-Fi 6 AX210 160MHz, REV=0x420.
> Wifi 6E, ty-a0-gf-a0-63.ucode.
> 
> Is there a way of implementing this and making the wifi module work.
> 
> https://wiki.freebsd.org/WiFi/Iwlwifi

I will likely work on AX210 suport sometimebut this year.
If anyone else has already done work on this and can provide working diffs
against the OpenBSD drivers I would be happy to review them.

Since FreeBSD has decided to no longer help with developing iwm or iwx
drivers, but implement a completely different approach instead, there is
no chance of cross-polination between the projects to make this any easier.



  1   2   3   4   5   6   7   8   9   10   >