Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Fix bug in protocol parser that often caused fatal '...



details:   https://anonhg.NetBSD.org/src/rev/7dc1775923eb
branches:  trunk
changeset: 372504:7dc1775923eb
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sat Dec 03 16:06:20 2022 +0000

description:
Fix bug in protocol parser that often caused fatal 'checksum error'.
Defer power save setting to interface start.
More verbose on errors.
Allow build without FDT.

diffstat:

 sys/dev/ic/bwfm.c            |   29 ++++---
 sys/dev/ic/bwfmvar.h         |    5 +-
 sys/dev/sdmmc/if_bwfm_sdio.c |  156 ++++++++++++++++++++++++++++--------------
 3 files changed, 127 insertions(+), 63 deletions(-)

diffs (truncated from 616 to 300 lines):

diff -r c3bf0ca90d97 -r 7dc1775923eb sys/dev/ic/bwfm.c
--- a/sys/dev/ic/bwfm.c Sat Dec 03 14:04:39 2022 +0000
+++ b/sys/dev/ic/bwfm.c Sat Dec 03 16:06:20 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bwfm.c,v 1.32 2022/03/14 06:40:12 mlelstv Exp $ */
+/* $NetBSD: bwfm.c,v 1.33 2022/12/03 16:06:20 mlelstv Exp $ */
 /* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
@@ -508,6 +508,12 @@
 
        /* TODO: return if no link? */
 
+       if (sc->sc_setpm) {
+               sc->sc_setpm = false;
+               if (bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PM, sc->sc_pm))
+                       printf("%s: could not set power\n", DEVNAME(sc));
+       }
+
        for (;;) {
                /* Discard management packets (fw handles this for us) */
                IF_DEQUEUE(&ic->ic_mgtq, m);
@@ -548,7 +554,6 @@
        struct ieee80211com *ic = &sc->sc_ic;
        uint8_t evmask[BWFM_EVENT_MASK_LEN];
        struct bwfm_join_pref_params join_pref[2];
-       int pm;
 
        if (bwfm_fwvar_var_set_int(sc, "mpc", 1)) {
                printf("%s: could not set mpc\n", DEVNAME(sc));
@@ -630,15 +635,12 @@
          * Use CAM (constantly awake) when we are running as AP
          * otherwise use fast power saving.
          */
-       pm = BWFM_PM_FAST_PS;
+       sc->sc_pm = BWFM_PM_FAST_PS;
 #ifndef IEEE80211_STA_ONLY
        if (ic->ic_opmode == IEEE80211_M_HOSTAP)
-               pm = BWFM_PM_CAM;
+               sc->sc_pm = BWFM_PM_CAM;
 #endif
-       if (bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PM, pm)) {
-               printf("%s: could not set power\n", DEVNAME(sc));
-               return EIO;
-       }
+       sc->sc_setpm = true;
 
        bwfm_fwvar_var_set_int(sc, "txbf", 1);
        bwfm_fwvar_cmd_set_int(sc, BWFM_C_UP, 0);
@@ -702,6 +704,8 @@
 
        if (sc->sc_bus_ops->bs_stop)
                sc->sc_bus_ops->bs_stop(sc);
+
+       sc->sc_setpm = true;
 }
 
 void
@@ -728,22 +732,25 @@
 {
        struct bwfm_softc *sc = ifp->if_softc;
        struct ieee80211com *ic = &sc->sc_ic;
-       int s, error = 0;
+       int s, error = 0, oflags;
 
        s = splnet();
 
        switch (cmd) {
        case SIOCSIFFLAGS:
+               oflags = ifp->if_flags;
                if ((error = ifioctl_common(ifp, cmd, data)) != 0)
                        break;
                switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
                case IFF_UP | IFF_RUNNING:
                        break;
                case IFF_UP:
-                       bwfm_init(ifp);
+                       if ((oflags & IFF_UP) == 0)
+                               bwfm_init(ifp);
                        break;
                case IFF_RUNNING:
-                       bwfm_stop(ifp, 1);
+                       if ((oflags & IFF_UP) != 0)
+                               bwfm_stop(ifp, 1);
                        break;
                case 0:
                        break;
diff -r c3bf0ca90d97 -r 7dc1775923eb sys/dev/ic/bwfmvar.h
--- a/sys/dev/ic/bwfmvar.h      Sat Dec 03 14:04:39 2022 +0000
+++ b/sys/dev/ic/bwfmvar.h      Sat Dec 03 16:06:20 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bwfmvar.h,v 1.13 2022/03/14 06:40:12 mlelstv Exp $ */
+/* $NetBSD: bwfmvar.h,v 1.14 2022/12/03 16:06:20 mlelstv Exp $ */
 /* $OpenBSD: bwfmvar.h,v 1.1 2017/10/11 17:19:50 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
@@ -245,6 +245,9 @@
        size_t                  sc_txcapsize;
        uint8_t                 *sc_cal;
        size_t                  sc_calsize;
+
+       int                     sc_pm;
+       bool                    sc_setpm;
 };
 
 void bwfm_attach(struct bwfm_softc *);
diff -r c3bf0ca90d97 -r 7dc1775923eb sys/dev/sdmmc/if_bwfm_sdio.c
--- a/sys/dev/sdmmc/if_bwfm_sdio.c      Sat Dec 03 14:04:39 2022 +0000
+++ b/sys/dev/sdmmc/if_bwfm_sdio.c      Sat Dec 03 16:06:20 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bwfm_sdio.c,v 1.29 2022/06/18 08:22:10 skrll Exp $ */
+/* $NetBSD: if_bwfm_sdio.c,v 1.30 2022/12/03 16:06:20 mlelstv Exp $ */
 /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
@@ -17,6 +17,10 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef _KERNEL_OPT
+#include "opt_fdt.h"
+#endif
+
 #include <sys/param.h>
 #include <sys/types.h>
 
@@ -41,7 +45,9 @@
 
 #include <net80211/ieee80211_var.h>
 
+#ifdef FDT
 #include <dev/fdt/fdtvar.h>
+#endif
 #include <dev/ic/bwfmreg.h>
 #include <dev/ic/bwfmvar.h>
 #include <dev/ofw/openfirm.h>
@@ -113,8 +119,10 @@
 static void    bwfm_sdio_attach(device_t, device_t, void *);
 static int     bwfm_sdio_detach(device_t, int);
 static void    bwfm_sdio_attachhook(device_t);
+#ifdef FDT
 static int     bwfm_fdt_find_phandle(device_t, device_t);
-static const char *bwfm_fdt_get_model(void);
+#endif
+static const char *bwfm_get_model(void);
 
 static void    bwfm_sdio_backplane(struct bwfm_sdio_softc *, uint32_t);
 static uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t);
@@ -143,9 +151,9 @@
 static void            bwfm_qput(struct mbuf **, struct mbuf *);
 static struct mbuf     *bwfm_qget(struct mbuf **);
 
-static uint32_t        bwfm_sdio_ram_read_write(struct bwfm_sdio_softc *,
+static int     bwfm_sdio_ram_read_write(struct bwfm_sdio_softc *,
                    uint32_t, char *, size_t, int);
-static uint32_t        bwfm_sdio_frame_read_write(struct bwfm_sdio_softc *,
+static int     bwfm_sdio_frame_read_write(struct bwfm_sdio_softc *,
                    char *, size_t, int);
 
 static int     bwfm_sdio_intr1(void *, const char *);
@@ -304,10 +312,12 @@
        },
 };
 
+#ifdef FDT
 static const struct device_compatible_entry compat_data[] = {
        { .compat = "brcm,bcm4329-fmac" },
        DEVICE_COMPAT_EOL
 };
+#endif
 
 static int
 bwfm_sdio_match(device_t parent, cfdata_t match, void *aux)
@@ -357,7 +367,9 @@
        aprint_naive("\n");
        aprint_normal("\n");
 
+#ifdef FDT
        sc->sc_phandle = bwfm_fdt_find_phandle(self, parent);
+#endif
 
        mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
        cv_init(&sc->sc_rxctl_cv, "bwfmctl");
@@ -385,7 +397,7 @@
        /* Enable Function 1. */
        if (sdmmc_io_function_enable(sc->sc_sf[1]) != 0) {
                printf("%s: cannot enable function 1\n", DEVNAME(sc));
-               return;
+               goto err;
        }
 
        DPRINTF(("%s: F1 signature read @0x18000000=%x\n", DEVNAME(sc),
@@ -399,18 +411,19 @@
        sc->sc_sc.sc_buscore_ops = &bwfm_sdio_buscore_ops;
        if (bwfm_chip_attach(&sc->sc_sc) != 0) {
                aprint_error_dev(self, "cannot attach chip\n");
-               return;
+               goto err;
        }
 
        sc->sc_cc = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_CHIPCOMMON);
        if (sc->sc_cc == NULL) {
                aprint_error_dev(self, "cannot find chipcommon core\n");
-               return;
+               goto err;
        }
 
        core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV);
        if (core->co_rev >= 12) {
-               reg = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_SLEEPCSR); if ((reg & BWFM_SDIO_FUNC1_SLEEPCSR_KSO) == 0) {
+               reg = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_SLEEPCSR);
+               if ((reg & BWFM_SDIO_FUNC1_SLEEPCSR_KSO) == 0) {
                        reg |= BWFM_SDIO_FUNC1_SLEEPCSR_KSO;
                        bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SLEEPCSR, reg);
                }
@@ -435,6 +448,10 @@
        sc->sc_clkstate = CLK_SDONLY;
 
        config_mountroot(self, bwfm_sdio_attachhook);
+       return;
+
+err:
+       kmem_free(sc->sc_sf, sc->sc_sf_size);
 }
 
 static void
@@ -459,7 +476,7 @@
 
        bwfm_firmware_context_init(&fwctx,
            bwfm->sc_chip.ch_chip, bwfm->sc_chip.ch_chiprev,
-           bwfm_fdt_get_model(),
+           bwfm_get_model(),
            BWFM_FWREQ(BWFM_FILETYPE_UCODE)
            | BWFM_FWREQ(BWFM_FILETYPE_NVRAM)
            | BWFM_FWOPT(BWFM_FILETYPE_CLM)
@@ -528,11 +545,13 @@
        }
 
 #ifdef notyet
+#ifdef FDT
        if (sc->sc_phandle >= 0) {
                sc->sc_fdtih = fdtbus_intr_establish(sc->sc_phandle,
                    0, IPL_SDMMC, IST_LEVEL, bwfm_sdio_intr, sc);
        }
 #endif
+#endif
        if (sc->sc_fdtih != NULL) {
                aprint_normal_dev(self, "enabling GPIO interrupt\n");
        } else {
@@ -563,6 +582,7 @@
        bwfm_firmware_close(&fwctx);
 }
 
+#ifdef FDT
 static int
 bwfm_fdt_find_phandle(device_t self, device_t parent)
 {
@@ -596,10 +616,12 @@
 
        return phandle;
 }
+#endif
 
 static const char *
-bwfm_fdt_get_model(void)
+bwfm_get_model(void)
 {
+#ifdef FDT
        const char *model;
        int phandle;
 
@@ -611,12 +633,15 @@
        }
 
        return model;
+#else
+       return NULL;
+#endif
 }
 
 static int
 bwfm_sdio_detach(device_t self, int flags)
 {
-       struct bwfm_sdio_softc *sc = (struct bwfm_sdio_softc *)self;
+       struct bwfm_sdio_softc *sc = device_private(self);
 
 #ifdef BWFM_DEBUG
        bwfm_sdio_debug_console(sc);
@@ -626,8 +651,10 @@
                sdmmc_intr_disable(sc->sc_sf[1]);
                if (sc->sc_ih)
                        sdmmc_intr_disestablish(sc->sc_ih);
+#ifdef FDT
                if (sc->sc_fdtih)
                        fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_fdtih);
+#endif
        }
        if (sc->sc_bwfm_attached)
                bwfm_detach(&sc->sc_sc, flags);
@@ -787,7 +814,7 @@



Home | Main Index | Thread Index | Old Index