diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2018-07-17 19:44:39 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2018-07-17 19:44:39 +0000 |
commit | 1c8ea1699773f22dd11a33a203fac1100575df17 (patch) | |
tree | c04ce0c64ff83d8692fac39d21f907b83a154710 /sys/dev/usb | |
parent | 8927199aee01250e43a96ee269017bf6f0659321 (diff) |
TX packets, which can be either Ethernet or control packets, must be
sent in order. Otherwise it is possible that the key is set before
we send out the EAPOL packet, or that packets are sent out before
the key is set. Thus modify the SDIO backend to put both types into
the same internal TX queue, which will be sent asynchronously.
Discussed with bluhm@
Diffstat (limited to 'sys/dev/usb')
-rw-r--r-- | sys/dev/usb/if_bwfm_usb.c | 96 |
1 files changed, 46 insertions, 50 deletions
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; } |