From f37fc2369871f9b8196dff3a7b07b00b98162ace Mon Sep 17 00:00:00 2001 From: patrick Date: Wed, 3 Jan 2018 21:01:16 +0000 Subject: [PATCH] Since the PCI attachment code already uses mbufs for RX packets, we can push the mbuf allocation down into the USB attachment code and now pass an mbuf to the bwfm(4) receive function. --- sys/dev/ic/bwfm.c | 32 +++++++------------------------- sys/dev/ic/bwfmvar.h | 4 ++-- sys/dev/pci/if_bwfm_pci.c | 10 +++++----- sys/dev/usb/if_bwfm_usb.c | 33 +++++++++++++++++++++++++++++++-- 4 files changed, 45 insertions(+), 34 deletions(-) diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c index 1756315bced..c610fd5f8f1 100644 --- a/sys/dev/ic/bwfm.c +++ b/sys/dev/ic/bwfm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfm.c,v 1.23 2017/12/26 00:51:29 patrick Exp $ */ +/* $OpenBSD: bwfm.c,v 1.24 2018/01/03 21:01:16 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -118,7 +118,7 @@ void bwfm_set_key_cb(struct bwfm_softc *, void *); void bwfm_delete_key_cb(struct bwfm_softc *, void *); void bwfm_newstate_cb(struct bwfm_softc *, void *); -void bwfm_rx(struct bwfm_softc *, char *, size_t); +void bwfm_rx(struct bwfm_softc *, struct mbuf *); void bwfm_rx_event(struct bwfm_softc *, char *, size_t); void bwfm_scan_node(struct bwfm_softc *, struct bwfm_bss_info *, size_t); @@ -1399,39 +1399,21 @@ bwfm_scan(struct bwfm_softc *sc) } void -bwfm_rx(struct bwfm_softc *sc, char *buf, size_t len) +bwfm_rx(struct bwfm_softc *sc, struct mbuf *m) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; - struct bwfm_event *e = (void *)buf; + struct bwfm_event *e = mtod(m, struct bwfm_event *); struct mbuf_list ml = MBUF_LIST_INITIALIZER(); - struct mbuf *m; - char *mb; - if (len >= sizeof(e->ehdr) && + if (m->m_len >= sizeof(e->ehdr) && ntohs(e->ehdr.ether_type) == BWFM_ETHERTYPE_LINK_CTL && memcmp(BWFM_BRCM_OUI, e->hdr.oui, sizeof(e->hdr.oui)) == 0 && ntohs(e->hdr.usr_subtype) == BWFM_BRCM_SUBTYPE_EVENT) - bwfm_rx_event(sc, buf, len); - - if (__predict_false(len > MCLBYTES)) - return; - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (__predict_false(m == NULL)) - return; - if (len > MHLEN) { - MCLGET(m, M_DONTWAIT); - if (!(m->m_flags & M_EXT)) { - m_free(m); - return; - } - } - mb = mtod(m, char *); - memcpy(mb, buf, len); - m->m_pkthdr.len = m->m_len = len; + bwfm_rx_event(sc, mtod(m, char *), m->m_len); if ((ic->ic_flags & IEEE80211_F_RSNON) && - len >= sizeof(e->ehdr) && + m->m_len >= sizeof(e->ehdr) && ntohs(e->ehdr.ether_type) == ETHERTYPE_PAE) { ifp->if_ipackets++; #if NBPFILTER > 0 diff --git a/sys/dev/ic/bwfmvar.h b/sys/dev/ic/bwfmvar.h index b2fd4126406..d924cab70ba 100644 --- a/sys/dev/ic/bwfmvar.h +++ b/sys/dev/ic/bwfmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfmvar.h,v 1.5 2017/12/16 23:39:58 patrick Exp $ */ +/* $OpenBSD: bwfmvar.h,v 1.6 2018/01/03 21:01:16 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -160,4 +160,4 @@ int bwfm_chip_set_active(struct bwfm_softc *, uint32_t); void bwfm_chip_set_passive(struct bwfm_softc *); struct bwfm_core *bwfm_chip_get_core(struct bwfm_softc *, int); struct bwfm_core *bwfm_chip_get_pmu(struct bwfm_softc *); -void bwfm_rx(struct bwfm_softc *, char *, size_t); +void bwfm_rx(struct bwfm_softc *, struct mbuf *); diff --git a/sys/dev/pci/if_bwfm_pci.c b/sys/dev/pci/if_bwfm_pci.c index a36aba4d8e5..7cb65dde130 100644 --- a/sys/dev/pci/if_bwfm_pci.c +++ b/sys/dev/pci/if_bwfm_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bwfm_pci.c,v 1.4 2018/01/03 08:43:10 patrick Exp $ */ +/* $OpenBSD: if_bwfm_pci.c,v 1.5 2018/01/03 21:01:16 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2017 Patrick Wildt @@ -1165,8 +1165,8 @@ bwfm_pci_msg_rx(struct bwfm_pci_softc *sc, void *buf) if (m == NULL) break; m_adj(m, sc->sc_rx_dataoffset); - bwfm_rx(&sc->sc_sc, mtod(m, char *), letoh16(event->event_data_len)); - m_freem(m); + m->m_len = m->m_pkthdr.len = letoh16(event->event_data_len); + bwfm_rx(&sc->sc_sc, m); if_rxr_put(&sc->sc_event_ring, 1); bwfm_pci_fill_rx_rings(sc); break; @@ -1180,8 +1180,8 @@ bwfm_pci_msg_rx(struct bwfm_pci_softc *sc, void *buf) m_adj(m, letoh16(rx->data_offset)); else if (sc->sc_rx_dataoffset) m_adj(m, sc->sc_rx_dataoffset); - bwfm_rx(&sc->sc_sc, mtod(m, char *), letoh16(rx->data_len)); - m_freem(m); + m->m_len = m->m_pkthdr.len = letoh16(rx->data_len); + bwfm_rx(&sc->sc_sc, m); if_rxr_put(&sc->sc_rxbuf_ring, 1); bwfm_pci_fill_rx_rings(sc); break; diff --git a/sys/dev/usb/if_bwfm_usb.c b/sys/dev/usb/if_bwfm_usb.c index 6029a889274..1d759c3dedb 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.5 2017/10/21 20:19:37 patrick Exp $ */ +/* $OpenBSD: if_bwfm_usb.c,v 1.6 2018/01/03 21:01:16 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -200,6 +200,7 @@ int bwfm_usb_txdata(struct bwfm_softc *, struct mbuf *); int bwfm_usb_txctl(struct bwfm_softc *, char *, size_t); int bwfm_usb_rxctl(struct bwfm_softc *, char *, size_t *); +struct mbuf * bwfm_usb_newbuf(void); void bwfm_usb_rxeof(struct usbd_xfer *, void *, usbd_status); void bwfm_usb_txeof(struct usbd_xfer *, void *, usbd_status); @@ -404,6 +405,27 @@ bwfm_usb_attachhook(struct device *self) bwfm_attach(&sc->sc_sc); } +struct mbuf * +bwfm_usb_newbuf(void) +{ + struct mbuf *m; + + MGETHDR(m, M_DONTWAIT, MT_DATA); + if (m == NULL) + return (NULL); + + MCLGET(m, M_DONTWAIT); + if (!(m->m_flags & M_EXT)) { + m_freem(m); + return (NULL); + } + + m->m_len = m->m_pkthdr.len = MCLBYTES; + m_adj(m, ETHER_ALIGN); + + return (m); +} + void bwfm_usb_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { @@ -412,6 +434,7 @@ bwfm_usb_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) struct bwfm_proto_bcdc_hdr *hdr; usbd_status error; uint32_t len, off; + struct mbuf *m; DPRINTFN(2, ("%s: %s status %s\n", DEVNAME(sc), __func__, usbd_errstr(status))); @@ -437,7 +460,13 @@ bwfm_usb_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) len -= hdr->data_offset << 2; off += hdr->data_offset << 2; - bwfm_rx(&sc->sc_sc, &data->buf[off], len); + m = bwfm_usb_newbuf(); + if (m == NULL) + goto resubmit; + + memcpy(mtod(m, char *), data->buf + off, len); + m->m_len = m->m_pkthdr.len = len; + bwfm_rx(&sc->sc_sc, m); resubmit: usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf, -- 2.20.1