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