From 8878a15e44c310f3824a86725a44126da66dbffc Mon Sep 17 00:00:00 2001 From: patrick Date: Sun, 11 Feb 2018 05:13:07 +0000 Subject: [PATCH] Since the BCDC header has a variable data offset, so the ethernet packet alignment can be variable, it's better to move taking care of alignment into the BCDC receive code. --- sys/dev/ic/bwfm.c | 21 ++++++++++++++++++++- sys/dev/sdmmc/if_bwfm_sdio.c | 3 +-- sys/dev/usb/if_bwfm_usb.c | 3 +-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c index 68bf91b8f7b..3937dc392a6 100644 --- a/sys/dev/ic/bwfm.c +++ b/sys/dev/ic/bwfm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfm.c,v 1.39 2018/02/08 05:00:38 patrick Exp $ */ +/* $OpenBSD: bwfm.c,v 1.40 2018/02/11 05:13:07 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -1331,6 +1331,10 @@ err: void bwfm_proto_bcdc_rx(struct bwfm_softc *sc, struct mbuf *m) { +#ifdef __STRICT_ALIGNMENT + struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = &ic->ic_if; +#endif struct bwfm_proto_bcdc_hdr *hdr; hdr = mtod(m, struct bwfm_proto_bcdc_hdr *); @@ -1343,6 +1347,21 @@ bwfm_proto_bcdc_rx(struct bwfm_softc *sc, struct mbuf *m) return; } m_adj(m, sizeof(*hdr) + (hdr->data_offset << 2)); + +#ifdef __STRICT_ALIGNMENT + /* Remaining data is an ethernet packet, so align. */ + if ((mtod(m, paddr_t) & 0x3) != ETHER_ALIGN) { + struct mbuf *m0; + m0 = m_devget(mtod(m, caddr_t), m->m_len, ETHER_ALIGN); + m_freem(m); + if (m0 == NULL) { + ifp->if_ierrors++; + return; + } + m = m0; + } +#endif + bwfm_rx(sc, m); } diff --git a/sys/dev/sdmmc/if_bwfm_sdio.c b/sys/dev/sdmmc/if_bwfm_sdio.c index beb6c7a2a7e..9cbc626a946 100644 --- a/sys/dev/sdmmc/if_bwfm_sdio.c +++ b/sys/dev/sdmmc/if_bwfm_sdio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bwfm_sdio.c,v 1.5 2018/02/11 05:07:36 patrick Exp $ */ +/* $OpenBSD: if_bwfm_sdio.c,v 1.6 2018/02/11 05:13:07 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -1077,7 +1077,6 @@ bwfm_sdio_rx_frames(struct bwfm_sdio_softc *sc) m = bwfm_sdio_newbuf(); if (m == NULL) break; - m_adj(m, ETHER_ALIGN); if (flen - off > m->m_len) { printf("%s: frame bigger than anticipated\n", DEVNAME(sc)); diff --git a/sys/dev/usb/if_bwfm_usb.c b/sys/dev/usb/if_bwfm_usb.c index dbc47311407..42e5623d9d8 100644 --- a/sys/dev/usb/if_bwfm_usb.c +++ b/sys/dev/usb/if_bwfm_usb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bwfm_usb.c,v 1.10 2018/02/08 05:00:38 patrick Exp $ */ +/* $OpenBSD: if_bwfm_usb.c,v 1.11 2018/02/11 05:13:07 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -422,7 +422,6 @@ bwfm_usb_newbuf(void) } m->m_len = m->m_pkthdr.len = MCLBYTES; - m_adj(m, ETHER_ALIGN); return (m); } -- 2.20.1