Module Name: src
Committed By: mlelstv
Date: Sat Dec 3 16:06:20 UTC 2022
Modified Files:
src/sys/dev/ic: bwfm.c bwfmvar.h
src/sys/dev/sdmmc: if_bwfm_sdio.c
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/ic/bwfm.c
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/ic/bwfmvar.h
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/sdmmc/if_bwfm_sdio.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/ic/bwfm.c
diff -u src/sys/dev/ic/bwfm.c:1.32 src/sys/dev/ic/bwfm.c:1.33
--- src/sys/dev/ic/bwfm.c:1.32 Mon Mar 14 06:40:12 2022
+++ src/sys/dev/ic/bwfm.c Sat Dec 3 16:06:20 2022
@@ -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 @@ bwfm_start(struct ifnet *ifp)
/* 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 @@ bwfm_init(struct ifnet *ifp)
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 @@ bwfm_init(struct ifnet *ifp)
* 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 @@ bwfm_stop(struct ifnet *ifp, int disable
if (sc->sc_bus_ops->bs_stop)
sc->sc_bus_ops->bs_stop(sc);
+
+ sc->sc_setpm = true;
}
void
@@ -728,22 +732,25 @@ bwfm_ioctl(struct ifnet *ifp, u_long cmd
{
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;
Index: src/sys/dev/ic/bwfmvar.h
diff -u src/sys/dev/ic/bwfmvar.h:1.13 src/sys/dev/ic/bwfmvar.h:1.14
--- src/sys/dev/ic/bwfmvar.h:1.13 Mon Mar 14 06:40:12 2022
+++ src/sys/dev/ic/bwfmvar.h Sat Dec 3 16:06:20 2022
@@ -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 @@ struct bwfm_softc {
size_t sc_txcapsize;
uint8_t *sc_cal;
size_t sc_calsize;
+
+ int sc_pm;
+ bool sc_setpm;
};
void bwfm_attach(struct bwfm_softc *);
Index: src/sys/dev/sdmmc/if_bwfm_sdio.c
diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.29 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.30
--- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.29 Sat Jun 18 08:22:10 2022
+++ src/sys/dev/sdmmc/if_bwfm_sdio.c Sat Dec 3 16:06:20 2022
@@ -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 int bwfm_sdio_match(device_t, cfd
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 struct mbuf *bwfm_sdio_newbuf(voi
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 @@ static const struct bwfm_sdio_product {
},
};
+#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 @@ bwfm_sdio_attach(device_t parent, device
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 @@ bwfm_sdio_attach(device_t parent, device
/* 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 @@ bwfm_sdio_attach(device_t parent, device
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 @@ bwfm_sdio_attach(device_t parent, device
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_sdio_attachhook(device_t self)
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 @@ bwfm_sdio_attachhook(device_t self)
}
#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_sdio_attachhook(device_t self)
bwfm_firmware_close(&fwctx);
}
+#ifdef FDT
static int
bwfm_fdt_find_phandle(device_t self, device_t parent)
{
@@ -596,10 +616,12 @@ bwfm_fdt_find_phandle(device_t self, dev
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 @@ bwfm_fdt_get_model(void)
}
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 @@ bwfm_sdio_detach(device_t self, int flag
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 @@ bwfm_sdio_buf_write(struct bwfm_sdio_sof
return err;
}
-static uint32_t
+static int
bwfm_sdio_ram_read_write(struct bwfm_sdio_softc *sc, uint32_t reg,
char *data, size_t left, int write)
{
@@ -829,7 +856,7 @@ bwfm_sdio_ram_read_write(struct bwfm_sdi
return err;
}
-static uint32_t
+static int
bwfm_sdio_frame_read_write(struct bwfm_sdio_softc *sc,
char *data, size_t size, int write)
{
@@ -842,13 +869,11 @@ bwfm_sdio_frame_read_write(struct bwfm_s
addr &= BWFM_SDIO_SB_OFT_ADDR_MASK;
addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG;
- if (write)
+ if (write) {
err = bwfm_sdio_buf_write(sc, sc->sc_sf[2], addr, data, size);
- else
+ } else {
err = bwfm_sdio_buf_read(sc, sc->sc_sf[2], addr, data, size);
-
- if (err)
- printf("%s: error %d\n", __func__, err);
+ }
return err;
}
@@ -1133,7 +1158,7 @@ bwfm_sdio_load_microcode(struct bwfm_sdi
{
struct bwfm_softc *bwfm = &sc->sc_sc;
char *verify = NULL;
- int err = 0;
+ int err;
bwfm_sdio_clkctl(sc, CLK_AVAIL, false);
@@ -1522,7 +1547,9 @@ bwfm_sdio_task1(struct bwfm_sdio_softc *
}
}
-if (!dosend && MBUFQ_FIRST(&sc->sc_tx_queue)) printf("%s: flowctl\n", DEVNAME(sc));
+ if (!dosend && MBUFQ_FIRST(&sc->sc_tx_queue))
+ printf("%s: pause\n", DEVNAME(sc));
+
if (dosend && MBUFQ_FIRST(&sc->sc_tx_queue)) {
DPRINTF(("%s: xmit\n", DEVNAME(sc)));
bwfm_sdio_tx_frames(sc);
@@ -1576,7 +1603,8 @@ bwfm_sdio_tx_ctrlframe(struct bwfm_sdio_
struct bwfm_sdio_hwhdr *hwhdr;
struct bwfm_sdio_swhdr *swhdr;
size_t len, roundto;
-
+ int err;
+
len = sizeof(*hwhdr) + sizeof(*swhdr) + m->m_len;
/* Zero-pad to either block-size or 4-byte alignment. */
@@ -1603,9 +1631,12 @@ bwfm_sdio_tx_ctrlframe(struct bwfm_sdio_
if (roundup(len, roundto) != len)
memset(sc->sc_bounce_buf + len, 0,
roundup(len, roundto) - len);
-
- bwfm_sdio_frame_read_write(sc, sc->sc_bounce_buf,
+
+ err = bwfm_sdio_frame_read_write(sc, sc->sc_bounce_buf,
roundup(len, roundto), 1);
+
+ if (err)
+ printf("%s: error %d\n",__func__,err);
}
static void
@@ -1615,6 +1646,7 @@ bwfm_sdio_tx_dataframe(struct bwfm_sdio_
struct bwfm_sdio_swhdr *swhdr;
struct bwfm_proto_bcdc_hdr *bcdc;
size_t len, roundto;
+ int err;
len = sizeof(*hwhdr) + sizeof(*swhdr) + sizeof(*bcdc)
+ m->m_pkthdr.len;
@@ -1650,9 +1682,12 @@ bwfm_sdio_tx_dataframe(struct bwfm_sdio_
memset(sc->sc_bounce_buf + len, 0,
roundup(len, roundto) - len);
- bwfm_sdio_frame_read_write(sc, sc->sc_bounce_buf,
+ err = bwfm_sdio_frame_read_write(sc, sc->sc_bounce_buf,
roundup(len, roundto), 1);
+ if (err)
+ printf("%s: error %d\n",__func__,err);
+
sc->sc_tx_count--;
}
@@ -1697,7 +1732,8 @@ bwfm_sdio_rx_frames(struct bwfm_sdio_sof
size_t flen, off, hoff;
char *data;
int nsub;
- size_t subsize;
+ size_t subsize, len;
+ const size_t hdrlen = sizeof(*hwhdr) + sizeof(*swhdr);
hwhdr = (struct bwfm_sdio_hwhdr *)sc->sc_bounce_buf;
swhdr = (struct bwfm_sdio_swhdr *)&hwhdr[1];
@@ -1706,20 +1742,24 @@ bwfm_sdio_rx_frames(struct bwfm_sdio_sof
for (;;) {
/* If we know the next size, just read ahead. */
if (nextlen) {
- if (bwfm_sdio_frame_read_write(sc, sc->sc_bounce_buf,
- nextlen, 0))
- break;
+ len = nextlen;
nextlen = 0;
} else {
- if (bwfm_sdio_frame_read_write(sc, sc->sc_bounce_buf,
- sizeof(*hwhdr) + sizeof(*swhdr), 0))
- break;
+ len = hdrlen;
+ }
+
+ if (bwfm_sdio_frame_read_write(sc, sc->sc_bounce_buf,
+ len, 0)) {
+ printf("%s: read error %zu bytes\n",
+ DEVNAME(sc), len);
+ break;
}
hwhdr->frmlen = le16toh(hwhdr->frmlen);
hwhdr->cksum = le16toh(hwhdr->cksum);
if (hwhdr->frmlen == 0 && hwhdr->cksum == 0) {
+ /* printf("%s: null frame\n", DEVNAME(sc)); */
break;
}
@@ -1728,20 +1768,20 @@ bwfm_sdio_rx_frames(struct bwfm_sdio_sof
break;
}
- if (hwhdr->frmlen < sizeof(*hwhdr) + sizeof(*swhdr)) {
+ if (hwhdr->frmlen < hdrlen) {
printf("%s: length error\n", DEVNAME(sc));
break;
}
- if (nextlen && hwhdr->frmlen > nextlen) {
- printf("%s: read ahead length error (%u > %u)\n",
+ if (len > hdrlen && hwhdr->frmlen > len) {
+ printf("%s: length error (%u > %u)\n",
DEVNAME(sc), hwhdr->frmlen, nextlen);
break;
}
sc->sc_tx_max_seq = swhdr->maxseqnr;
- flen = hwhdr->frmlen - (sizeof(*hwhdr) + sizeof(*swhdr));
+ flen = hwhdr->frmlen - hdrlen;
if (flen == 0) {
DPRINTF(("%s: empty payload (frmlen=%u)\n",
DEVNAME(sc), hwhdr->frmlen));
@@ -1749,24 +1789,24 @@ bwfm_sdio_rx_frames(struct bwfm_sdio_sof
continue;
}
- if (!nextlen) {
+ if (len <= hdrlen) {
KASSERT(roundup(flen, 4) <= sc->sc_bounce_size -
(sizeof(*hwhdr) + sizeof(*swhdr)));
if (bwfm_sdio_frame_read_write(sc, data,
roundup(flen, 4), 0)) {
- printf("%s: I/O error roundup(%zu, 4) bytes\n",
+ printf("%s: read error roundup(%zu, 4) bytes\n",
DEVNAME(sc), flen);
break;
}
}
- if (swhdr->dataoff < (sizeof(*hwhdr) + sizeof(*swhdr))) {
+ if (swhdr->dataoff < hdrlen) {
printf("%s: data offset %u in header\n",
DEVNAME(sc), swhdr->dataoff);
break;
}
- off = swhdr->dataoff - (sizeof(*hwhdr) + sizeof(*swhdr));
+ off = swhdr->dataoff - hdrlen;
if (off > flen) {
printf("%s: offset %zu beyond end %zu\n",
DEVNAME(sc), off, flen);
@@ -1776,8 +1816,11 @@ bwfm_sdio_rx_frames(struct bwfm_sdio_sof
switch (swhdr->chanflag & BWFM_SDIO_SWHDR_CHANNEL_MASK) {
case BWFM_SDIO_SWHDR_CHANNEL_CONTROL:
m = bwfm_sdio_newbuf();
- if (m == NULL)
+ if (m == NULL) {
+ printf("%s: channel control: no buffer\n",
+ DEVNAME(sc));
break;
+ }
if (flen - off > m->m_len) {
printf("%s: ctl bigger than anticipated\n",
DEVNAME(sc));
@@ -1793,8 +1836,11 @@ bwfm_sdio_rx_frames(struct bwfm_sdio_sof
case BWFM_SDIO_SWHDR_CHANNEL_EVENT:
case BWFM_SDIO_SWHDR_CHANNEL_DATA:
m = bwfm_sdio_newbuf();
- if (m == NULL)
+ if (m == NULL) {
+ printf("%s: channel data: no buffer\n",
+ DEVNAME(sc));
break;
+ }
if (flen - off > m->m_len) {
printf("%s: frame bigger than anticipated\n",
DEVNAME(sc));
@@ -1854,14 +1900,18 @@ bwfm_sdio_rx_glom(struct bwfm_sdio_softc
struct mbuf *m, *m0;
size_t flen, off, hoff;
int i;
+ const size_t hdrlen = sizeof(hwhdr) + sizeof(swhdr);
- if (nsub == 0)
+ if (nsub == 0) {
+ printf("%s: rx_glom nsub == 0\n", DEVNAME(sc));
return;
+ }
m0 = NULL;
for (i = 0; i < nsub; i++) {
m = bwfm_sdio_newbuf();
if (m == NULL) {
+ printf("%s: rx_glom no buffer\n", DEVNAME(sc));
m_freem(m0);
return;
}
@@ -1880,7 +1930,7 @@ bwfm_sdio_rx_glom(struct bwfm_sdio_softc
m->m_len = m->m_pkthdr.len = le16toh(sublen[i]);
}
- if (m0->m_len >= sizeof(hwhdr) + sizeof(swhdr)) {
+ if (m0->m_len >= hdrlen) {
m_copydata(m0, 0, sizeof(hwhdr), &hwhdr);
m_copydata(m0, sizeof(hwhdr), sizeof(swhdr), &swhdr);
@@ -1893,7 +1943,7 @@ bwfm_sdio_rx_glom(struct bwfm_sdio_softc
*nextlen = 0;
while ((m = bwfm_qget(&m0)) != NULL) {
- if (m->m_len < sizeof(hwhdr) + sizeof(swhdr)) {
+ if (m->m_len < hdrlen) {
printf("%s: tiny mbuf %d < %zu\n", DEVNAME(sc),
m->m_len, sizeof(hwhdr) + sizeof(swhdr));
goto drop;
@@ -1905,23 +1955,26 @@ bwfm_sdio_rx_glom(struct bwfm_sdio_softc
hwhdr.frmlen = le16toh(hwhdr.frmlen);
hwhdr.cksum = le16toh(hwhdr.cksum);
- if (hwhdr.frmlen == 0 && hwhdr.cksum == 0)
+ if (hwhdr.frmlen == 0 && hwhdr.cksum == 0) {
+ printf("%s: rx_glom null frame\n", DEVNAME(sc));
goto drop;
+ }
if ((hwhdr.frmlen ^ hwhdr.cksum) != 0xffff) {
printf("%s: checksum error\n", DEVNAME(sc));
goto drop;
}
-
- if (hwhdr.frmlen < sizeof(hwhdr) + sizeof(swhdr)) {
+ if (hwhdr.frmlen < hdrlen) {
printf("%s: length error\n", DEVNAME(sc));
goto drop;
}
- flen = hwhdr.frmlen - (sizeof(hwhdr) + sizeof(swhdr));
- if (flen == 0)
+ flen = hwhdr.frmlen - hdrlen;
+ if (flen == 0) {
+ printf("%s: rx_glom empty payload\n", DEVNAME(sc));
goto drop;
+ }
if (hwhdr.frmlen > m->m_len) {
printf("%s: short mbuf %d < %zu\n",
@@ -1929,13 +1982,13 @@ bwfm_sdio_rx_glom(struct bwfm_sdio_softc
goto drop;
}
- if (swhdr.dataoff < (sizeof(hwhdr) + sizeof(swhdr))) {
+ if (swhdr.dataoff < hdrlen) {
printf("%s: data offset %u in header\n",
DEVNAME(sc), swhdr.dataoff);
goto drop;
}
- off = swhdr.dataoff - (sizeof(hwhdr) + sizeof(swhdr));
+ off = swhdr.dataoff - hdrlen;
if (off > flen) {
printf("%s: offset %zu beyond end %zu\n",
DEVNAME(sc), off, flen);
@@ -1964,6 +2017,7 @@ bwfm_sdio_rx_glom(struct bwfm_sdio_softc
m_adj(m, hoff);
/* don't pass empty packet to stack */
if (m->m_len == 0) {
+ printf("%s: rx_glom empty packet\n", DEVNAME(sc));
m_freem(m);
break;
}