-/* $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 <patrick@blueri.se>
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);
}
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
-/* $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 <patrick@blueri.se>
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 *);
-/* $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 <patrick@blueri.se>
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;
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;
-/* $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 <patrick@blueri.se>
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);
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)
{
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)));
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,