diff options
-rw-r--r-- | sys/dev/ic/bwfm.c | 6 | ||||
-rw-r--r-- | sys/dev/ic/bwfmvar.h | 5 | ||||
-rw-r--r-- | sys/dev/sdmmc/if_bwfm_sdio.c | 201 | ||||
-rw-r--r-- | sys/dev/usb/if_bwfm_usb.c | 96 |
4 files changed, 158 insertions, 150 deletions
diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c index 27c5307c9f0..1c7f2820241 100644 --- a/sys/dev/ic/bwfm.c +++ b/sys/dev/ic/bwfm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfm.c,v 1.52 2018/07/16 13:46:17 patrick Exp $ */ +/* $OpenBSD: bwfm.c,v 1.53 2018/07/17 19:44:38 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -174,7 +174,6 @@ bwfm_attach(struct bwfm_softc *sc) struct ifnet *ifp = &ic->ic_if; TAILQ_INIT(&sc->sc_bcdc_rxctlq); - TAILQ_INIT(&sc->sc_bcdc_txctlq); /* Init host async commands ring. */ sc->sc_cmdq.cur = sc->sc_cmdq.next = sc->sc_cmdq.queued = 0; @@ -1359,9 +1358,8 @@ bwfm_proto_bcdc_txctl(struct bwfm_softc *sc, int reqid, char *buf, size_t *len) ctl->reqid = reqid; ctl->buf = buf; ctl->len = *len; - TAILQ_INSERT_TAIL(&sc->sc_bcdc_txctlq, ctl, next); - if (sc->sc_bus_ops->bs_txctl(sc)) { + if (sc->sc_bus_ops->bs_txctl(sc, ctl)) { DPRINTF(("%s: tx failed\n", DEVNAME(sc))); return 1; } diff --git a/sys/dev/ic/bwfmvar.h b/sys/dev/ic/bwfmvar.h index 250aba20bc4..7ea91a21a28 100644 --- a/sys/dev/ic/bwfmvar.h +++ b/sys/dev/ic/bwfmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfmvar.h,v 1.14 2018/05/23 11:32:14 patrick Exp $ */ +/* $OpenBSD: bwfmvar.h,v 1.15 2018/07/17 19:44:38 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -89,7 +89,7 @@ struct bwfm_bus_ops { void (*bs_stop)(struct bwfm_softc *); int (*bs_txcheck)(struct bwfm_softc *); int (*bs_txdata)(struct bwfm_softc *, struct mbuf *); - int (*bs_txctl)(struct bwfm_softc *); + int (*bs_txctl)(struct bwfm_softc *, void *); }; struct bwfm_buscore_ops { @@ -169,7 +169,6 @@ struct bwfm_softc { struct task sc_task; int sc_bcdc_reqid; - TAILQ_HEAD(, bwfm_proto_bcdc_ctl) sc_bcdc_txctlq; TAILQ_HEAD(, bwfm_proto_bcdc_ctl) sc_bcdc_rxctlq; }; diff --git a/sys/dev/sdmmc/if_bwfm_sdio.c b/sys/dev/sdmmc/if_bwfm_sdio.c index 38ac463889c..b55957e4317 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.22 2018/07/16 13:46:17 patrick Exp $ */ +/* $OpenBSD: if_bwfm_sdio.c,v 1.23 2018/07/17 19:44:38 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -99,7 +99,8 @@ struct bwfm_sdio_softc { uint8_t sc_tx_seq; uint8_t sc_tx_max_seq; - struct mbuf_queue sc_txdata_queue; + struct mbuf_list sc_tx_queue; + int sc_tx_count; struct task sc_task; }; @@ -147,15 +148,16 @@ void bwfm_sdio_buscore_activate(struct bwfm_softc *, uint32_t); struct mbuf * bwfm_sdio_newbuf(void); int bwfm_sdio_tx_ok(struct bwfm_sdio_softc *); -void bwfm_sdio_tx_ctrlframe(struct bwfm_sdio_softc *); -void bwfm_sdio_tx_dataframe(struct bwfm_sdio_softc *); +void bwfm_sdio_tx_frames(struct bwfm_sdio_softc *); +void bwfm_sdio_tx_ctrlframe(struct bwfm_sdio_softc *, struct mbuf *); +void bwfm_sdio_tx_dataframe(struct bwfm_sdio_softc *, struct mbuf *); void bwfm_sdio_rx_frames(struct bwfm_sdio_softc *); void bwfm_sdio_rx_glom(struct bwfm_sdio_softc *, uint16_t *, int, uint16_t *); int bwfm_sdio_txcheck(struct bwfm_softc *); int bwfm_sdio_txdata(struct bwfm_softc *, struct mbuf *); -int bwfm_sdio_txctl(struct bwfm_softc *); +int bwfm_sdio_txctl(struct bwfm_softc *, void *); #ifdef BWFM_DEBUG void bwfm_sdio_debug_console(struct bwfm_sdio_softc *); @@ -246,7 +248,7 @@ bwfm_sdio_attach(struct device *parent, struct device *self, void *aux) printf("\n"); task_set(&sc->sc_task, bwfm_sdio_task, sc); - mq_init(&sc->sc_txdata_queue, 16, IPL_SOFTNET); + ml_init(&sc->sc_tx_queue); sc->sc_bounce_size = 64 * 1024; sc->sc_bounce_buf = dma_alloc(sc->sc_bounce_size, PR_WAITOK); sc->sc_tx_seq = 0xff; @@ -684,12 +686,8 @@ bwfm_sdio_task(void *v) bwfm_sdio_rx_frames(sc); } - if (!TAILQ_EMPTY(&sc->sc_sc.sc_bcdc_txctlq)) { - bwfm_sdio_tx_ctrlframe(sc); - } - - if (!mq_empty(&sc->sc_txdata_queue)) { - bwfm_sdio_tx_dataframe(sc); + if (!ml_empty(&sc->sc_tx_queue)) { + bwfm_sdio_tx_frames(sc); } #ifdef BWFM_DEBUG @@ -1034,115 +1032,117 @@ bwfm_sdio_tx_ok(struct bwfm_sdio_softc *sc) } void -bwfm_sdio_tx_ctrlframe(struct bwfm_sdio_softc *sc) +bwfm_sdio_tx_frames(struct bwfm_sdio_softc *sc) { - struct bwfm_sdio_hwhdr *hwhdr; - struct bwfm_sdio_swhdr *swhdr; - struct bwfm_proto_bcdc_ctl *ctl, *tmp; - size_t len, roundto; + struct ifnet *ifp = &sc->sc_sc.sc_ic.ic_if; + struct mbuf *m; + int i; if (!bwfm_sdio_tx_ok(sc)) return; - TAILQ_FOREACH_SAFE(ctl, &sc->sc_sc.sc_bcdc_txctlq, next, tmp) { - TAILQ_REMOVE(&sc->sc_sc.sc_bcdc_txctlq, ctl, next); - - len = sizeof(*hwhdr) + sizeof(*swhdr) + ctl->len; + i = min((uint8_t)(sc->sc_tx_max_seq - sc->sc_tx_seq), 32); + while (i--) { + m = ml_dequeue(&sc->sc_tx_queue); + if (m == NULL) + break; - /* Zero-pad to either block-size or 4-byte alignment. */ - if (len > 512 && (len % 512) != 0) - roundto = 512; + if (m->m_type == MT_CONTROL) + bwfm_sdio_tx_ctrlframe(sc, m); else - roundto = 4; + bwfm_sdio_tx_dataframe(sc, m); - KASSERT(roundup(len, roundto) <= sc->sc_bounce_size); + m_freem(m); + } + + if (sc->sc_tx_count < 64) + ifq_restart(&ifp->if_snd); +} - hwhdr = (void *)sc->sc_bounce_buf; - hwhdr->frmlen = htole16(len); - hwhdr->cksum = htole16(~len); +void +bwfm_sdio_tx_ctrlframe(struct bwfm_sdio_softc *sc, struct mbuf *m) +{ + struct bwfm_sdio_hwhdr *hwhdr; + struct bwfm_sdio_swhdr *swhdr; + size_t len, roundto; - swhdr = (void *)&hwhdr[1]; - swhdr->seqnr = sc->sc_tx_seq++; - swhdr->chanflag = BWFM_SDIO_SWHDR_CHANNEL_CONTROL; - swhdr->nextlen = 0; - swhdr->dataoff = sizeof(*hwhdr) + sizeof(*swhdr); - swhdr->maxseqnr = 0; + len = sizeof(*hwhdr) + sizeof(*swhdr) + m->m_len; - memcpy(&swhdr[1], ctl->buf, ctl->len); + /* Zero-pad to either block-size or 4-byte alignment. */ + if (len > 512 && (len % 512) != 0) + roundto = 512; + else + roundto = 4; - if (roundup(len, roundto) != len) - memset(sc->sc_bounce_buf + len, 0, - roundup(len, roundto) - len); + KASSERT(roundup(len, roundto) <= sc->sc_bounce_size); - bwfm_sdio_frame_read_write(sc, sc->sc_bounce_buf, - roundup(len, roundto), 1); + hwhdr = (void *)sc->sc_bounce_buf; + hwhdr->frmlen = htole16(len); + hwhdr->cksum = htole16(~len); - TAILQ_INSERT_TAIL(&sc->sc_sc.sc_bcdc_rxctlq, ctl, next); - } + swhdr = (void *)&hwhdr[1]; + swhdr->seqnr = sc->sc_tx_seq++; + swhdr->chanflag = BWFM_SDIO_SWHDR_CHANNEL_CONTROL; + swhdr->nextlen = 0; + swhdr->dataoff = sizeof(*hwhdr) + sizeof(*swhdr); + swhdr->maxseqnr = 0; + + m_copydata(m, 0, m->m_len, (caddr_t)&swhdr[1]); + + 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, + roundup(len, roundto), 1); } void -bwfm_sdio_tx_dataframe(struct bwfm_sdio_softc *sc) +bwfm_sdio_tx_dataframe(struct bwfm_sdio_softc *sc, struct mbuf *m) { - struct ifnet *ifp = &sc->sc_sc.sc_ic.ic_if; struct bwfm_sdio_hwhdr *hwhdr; struct bwfm_sdio_swhdr *swhdr; struct bwfm_proto_bcdc_hdr *bcdc; size_t len, roundto; - struct mbuf *m; - int i; - if (!bwfm_sdio_tx_ok(sc)) - return; - - i = min((uint8_t)(sc->sc_tx_max_seq - sc->sc_tx_seq), 32); - while (i--) { - m = mq_dequeue(&sc->sc_txdata_queue); - if (m == NULL) - break; + len = sizeof(*hwhdr) + sizeof(*swhdr) + sizeof(*bcdc) + + m->m_pkthdr.len; - len = sizeof(*hwhdr) + sizeof(*swhdr) + sizeof(*bcdc) - + m->m_pkthdr.len; - - /* Zero-pad to either block-size or 4-byte alignment. */ - if (len > 512 && (len % 512) != 0) - roundto = 512; - else - roundto = 4; - - KASSERT(roundup(len, roundto) <= sc->sc_bounce_size); + /* Zero-pad to either block-size or 4-byte alignment. */ + if (len > 512 && (len % 512) != 0) + roundto = 512; + else + roundto = 4; - hwhdr = (void *)sc->sc_bounce_buf; - hwhdr->frmlen = htole16(len); - hwhdr->cksum = htole16(~len); + KASSERT(roundup(len, roundto) <= sc->sc_bounce_size); - swhdr = (void *)&hwhdr[1]; - swhdr->seqnr = sc->sc_tx_seq++; - swhdr->chanflag = BWFM_SDIO_SWHDR_CHANNEL_DATA; - swhdr->nextlen = 0; - swhdr->dataoff = sizeof(*hwhdr) + sizeof(*swhdr); - swhdr->maxseqnr = 0; + hwhdr = (void *)sc->sc_bounce_buf; + hwhdr->frmlen = htole16(len); + hwhdr->cksum = htole16(~len); - bcdc = (void *)&swhdr[1]; - bcdc->data_offset = 0; - bcdc->priority = ieee80211_classify(&sc->sc_sc.sc_ic, m); - bcdc->flags = BWFM_BCDC_FLAG_VER(BWFM_BCDC_FLAG_PROTO_VER); - bcdc->flags2 = 0; + swhdr = (void *)&hwhdr[1]; + swhdr->seqnr = sc->sc_tx_seq++; + swhdr->chanflag = BWFM_SDIO_SWHDR_CHANNEL_DATA; + swhdr->nextlen = 0; + swhdr->dataoff = sizeof(*hwhdr) + sizeof(*swhdr); + swhdr->maxseqnr = 0; - m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&bcdc[1]); + bcdc = (void *)&swhdr[1]; + bcdc->data_offset = 0; + bcdc->priority = ieee80211_classify(&sc->sc_sc.sc_ic, m); + bcdc->flags = BWFM_BCDC_FLAG_VER(BWFM_BCDC_FLAG_PROTO_VER); + bcdc->flags2 = 0; - if (roundup(len, roundto) != len) - memset(sc->sc_bounce_buf + len, 0, - roundup(len, roundto) - len); + m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&bcdc[1]); - bwfm_sdio_frame_read_write(sc, sc->sc_bounce_buf, - roundup(len, roundto), 1); + if (roundup(len, roundto) != len) + memset(sc->sc_bounce_buf + len, 0, + roundup(len, roundto) - len); - m_freem(m); - } + bwfm_sdio_frame_read_write(sc, sc->sc_bounce_buf, + roundup(len, roundto), 1); - if (!mq_full(&sc->sc_txdata_queue)) - ifq_restart(&ifp->if_snd); + sc->sc_tx_count--; } void @@ -1372,7 +1372,7 @@ bwfm_sdio_txcheck(struct bwfm_softc *bwfm) { struct bwfm_sdio_softc *sc = (void *)bwfm; - if (mq_full(&sc->sc_txdata_queue)) + if (sc->sc_tx_count >= 64) return ENOBUFS; return 0; @@ -1383,18 +1383,33 @@ bwfm_sdio_txdata(struct bwfm_softc *bwfm, struct mbuf *m) { struct bwfm_sdio_softc *sc = (void *)bwfm; - if (mq_full(&sc->sc_txdata_queue)) + if (sc->sc_tx_count >= 64) return ENOBUFS; - mq_enqueue(&sc->sc_txdata_queue, m); + sc->sc_tx_count++; + ml_enqueue(&sc->sc_tx_queue, m); task_add(systq, &sc->sc_task); return 0; } int -bwfm_sdio_txctl(struct bwfm_softc *bwfm) +bwfm_sdio_txctl(struct bwfm_softc *bwfm, void *arg) { struct bwfm_sdio_softc *sc = (void *)bwfm; + struct bwfm_proto_bcdc_ctl *ctl = arg; + struct mbuf *m; + + MGET(m, M_DONTWAIT, MT_CONTROL); + if (m == NULL || M_TRAILINGSPACE(m) < ctl->len) { + free(ctl->buf, M_TEMP, ctl->len); + free(ctl, M_TEMP, sizeof(*ctl)); + return 1; + } + memcpy(mtod(m, char *), ctl->buf, ctl->len); + m->m_len = ctl->len; + + TAILQ_INSERT_TAIL(&sc->sc_sc.sc_bcdc_rxctlq, ctl, next); + ml_enqueue(&sc->sc_tx_queue, m); task_add(systq, &sc->sc_task); return 0; } diff --git a/sys/dev/usb/if_bwfm_usb.c b/sys/dev/usb/if_bwfm_usb.c index 505bb91cc9d..148de48ef91 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.15 2018/05/23 14:15:06 patrick Exp $ */ +/* $OpenBSD: if_bwfm_usb.c,v 1.16 2018/07/17 19:44:38 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -201,7 +201,7 @@ void bwfm_usb_free_tx_list(struct bwfm_usb_softc *); int bwfm_usb_preinit(struct bwfm_softc *); int bwfm_usb_txcheck(struct bwfm_softc *); int bwfm_usb_txdata(struct bwfm_softc *, struct mbuf *); -int bwfm_usb_txctl(struct bwfm_softc *); +int bwfm_usb_txctl(struct bwfm_softc *, void *); void bwfm_usb_txctl_cb(struct usbd_xfer *, void *, usbd_status); struct mbuf * bwfm_usb_newbuf(void); @@ -801,10 +801,10 @@ bwfm_usb_txdata(struct bwfm_softc *bwfm, struct mbuf *m) } int -bwfm_usb_txctl(struct bwfm_softc *bwfm) +bwfm_usb_txctl(struct bwfm_softc *bwfm, void *arg) { struct bwfm_usb_softc *sc = (void *)bwfm; - struct bwfm_proto_bcdc_ctl *ctl, *tmp; + struct bwfm_proto_bcdc_ctl *ctl = arg; usb_device_request_t req; struct usbd_xfer *xfer; usbd_status error; @@ -812,58 +812,54 @@ bwfm_usb_txctl(struct bwfm_softc *bwfm) DPRINTFN(2, ("%s: %s\n", DEVNAME(sc), __func__)); - TAILQ_FOREACH_SAFE(ctl, &sc->sc_sc.sc_bcdc_txctlq, next, tmp) { - TAILQ_REMOVE(&sc->sc_sc.sc_bcdc_txctlq, ctl, next); - - /* Send out control packet. */ - req.bmRequestType = UT_WRITE_CLASS_INTERFACE; - req.bRequest = 0; - USETW(req.wValue, 0); - USETW(req.wIndex, sc->sc_ifaceno); - USETW(req.wLength, ctl->len); - - error = usbd_do_request(sc->sc_udev, &req, ctl->buf); - if (error != 0) { - printf("%s: could not write ctl packet: %s\n", - DEVNAME(sc), usbd_errstr(error)); - free(ctl->buf, M_TEMP, ctl->len); - free(ctl, M_TEMP, sizeof(*ctl)); - return 1; - } + /* Send out control packet. */ + req.bmRequestType = UT_WRITE_CLASS_INTERFACE; + req.bRequest = 0; + USETW(req.wValue, 0); + USETW(req.wIndex, sc->sc_ifaceno); + USETW(req.wLength, ctl->len); - /* Setup asynchronous receive. */ - if ((xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) { - free(ctl->buf, M_TEMP, ctl->len); - free(ctl, M_TEMP, sizeof(*ctl)); - return 1; - } - if ((buf = usbd_alloc_buffer(xfer, ctl->len)) == NULL) { - free(ctl->buf, M_TEMP, ctl->len); - free(ctl, M_TEMP, sizeof(*ctl)); - usbd_free_xfer(xfer); - return 1; - } + error = usbd_do_request(sc->sc_udev, &req, ctl->buf); + if (error != 0) { + printf("%s: could not write ctl packet: %s\n", + DEVNAME(sc), usbd_errstr(error)); + free(ctl->buf, M_TEMP, ctl->len); + free(ctl, M_TEMP, sizeof(*ctl)); + return 1; + } - memset(buf, 0, ctl->len); - req.bmRequestType = UT_READ_CLASS_INTERFACE; - req.bRequest = 1; - USETW(req.wValue, 0); - USETW(req.wIndex, sc->sc_ifaceno); - USETW(req.wLength, ctl->len); + /* Setup asynchronous receive. */ + if ((xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) { + free(ctl->buf, M_TEMP, ctl->len); + free(ctl, M_TEMP, sizeof(*ctl)); + return 1; + } + if ((buf = usbd_alloc_buffer(xfer, ctl->len)) == NULL) { + free(ctl->buf, M_TEMP, ctl->len); + free(ctl, M_TEMP, sizeof(*ctl)); + usbd_free_xfer(xfer); + return 1; + } - error = usbd_request_async(xfer, &req, sc, bwfm_usb_txctl_cb); - if (error != 0) { - printf("%s: could not read ctl packet: %s\n", - DEVNAME(sc), usbd_errstr(error)); - free(ctl->buf, M_TEMP, ctl->len); - free(ctl, M_TEMP, sizeof(*ctl)); - usbd_free_xfer(xfer); - return 1; - } + memset(buf, 0, ctl->len); + req.bmRequestType = UT_READ_CLASS_INTERFACE; + req.bRequest = 1; + USETW(req.wValue, 0); + USETW(req.wIndex, sc->sc_ifaceno); + USETW(req.wLength, ctl->len); - TAILQ_INSERT_TAIL(&sc->sc_sc.sc_bcdc_rxctlq, ctl, next); + error = usbd_request_async(xfer, &req, sc, bwfm_usb_txctl_cb); + if (error != 0) { + printf("%s: could not read ctl packet: %s\n", + DEVNAME(sc), usbd_errstr(error)); + free(ctl->buf, M_TEMP, ctl->len); + free(ctl, M_TEMP, sizeof(*ctl)); + usbd_free_xfer(xfer); + return 1; } + TAILQ_INSERT_TAIL(&sc->sc_sc.sc_bcdc_rxctlq, ctl, next); + return 0; } |