Delete flowrings when we take the interface down or change its
authorpatrick <patrick@openbsd.org>
Mon, 8 Jan 2018 00:46:15 +0000 (00:46 +0000)
committerpatrick <patrick@openbsd.org>
Mon, 8 Jan 2018 00:46:15 +0000 (00:46 +0000)
settings.

sys/dev/ic/bwfm.c
sys/dev/pci/if_bwfm_pci.c

index 5903821..53838cf 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwfm.c,v 1.27 2018/01/05 23:13:04 patrick Exp $ */
+/* $OpenBSD: bwfm.c,v 1.28 2018/01/08 00:46:15 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
  * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
@@ -318,6 +318,9 @@ bwfm_init(struct ifnet *ifp)
        uint8_t evmask[BWFM_EVENT_MASK_LEN];
        struct bwfm_join_pref_params join_pref[2];
 
+       if (sc->sc_bus_ops->bs_init)
+               sc->sc_bus_ops->bs_init(sc);
+
        if (bwfm_fwvar_var_set_int(sc, "mpc", 1)) {
                printf("%s: could not set mpc\n", DEVNAME(sc));
                return;
@@ -424,6 +427,9 @@ bwfm_stop(struct ifnet *ifp)
 
        bwfm_fwvar_cmd_set_int(sc, BWFM_C_DOWN, 1);
        bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PM, 0);
+
+       if (sc->sc_bus_ops->bs_stop)
+               sc->sc_bus_ops->bs_stop(sc);
 }
 
 void
index 8fef982..62da92c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_bwfm_pci.c,v 1.7 2018/01/07 22:08:04 patrick Exp $ */
+/*     $OpenBSD: if_bwfm_pci.c,v 1.8 2018/01/08 00:46:15 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
  * Copyright (c) 2017 Patrick Wildt <patrick@blueri.se>
@@ -251,7 +251,9 @@ int          bwfm_pci_flowring_lookup(struct bwfm_pci_softc *,
 void            bwfm_pci_flowring_create(struct bwfm_pci_softc *,
                     struct mbuf *);
 void            bwfm_pci_flowring_create_cb(struct bwfm_softc *, void *);
+void            bwfm_pci_flowring_delete(struct bwfm_pci_softc *, int);
 
+void            bwfm_pci_stop(struct bwfm_softc *);
 int             bwfm_pci_txdata(struct bwfm_softc *, struct mbuf *);
 void            bwfm_pci_debug_console(struct bwfm_pci_softc *);
 
@@ -271,7 +273,7 @@ struct bwfm_buscore_ops bwfm_pci_buscore_ops = {
 
 struct bwfm_bus_ops bwfm_pci_bus_ops = {
        .bs_init = NULL,
-       .bs_stop = NULL,
+       .bs_stop = bwfm_pci_stop,
        .bs_txdata = bwfm_pci_txdata,
        .bs_txctl = NULL,
        .bs_rxctl = NULL,
@@ -1186,6 +1188,7 @@ bwfm_pci_msg_rx(struct bwfm_pci_softc *sc, void *buf)
        struct msgbuf_rx_event *event;
        struct msgbuf_common_hdr *msg;
        struct msgbuf_flowring_create_resp *fcr;
+       struct msgbuf_flowring_delete_resp *fdr;
        struct bwfm_pci_msgring *ring;
        struct mbuf *m;
        int flowid;
@@ -1214,6 +1217,25 @@ bwfm_pci_msg_rx(struct bwfm_pci_softc *sc, void *buf)
                ring->status = RING_OPEN;
                ifq_restart(&ifp->if_snd);
                break;
+       case MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT:
+               fdr = (struct msgbuf_flowring_delete_resp *)buf;
+               flowid = letoh16(fdr->compl_hdr.flow_ring_id);
+               if (flowid < 2)
+                       break;
+               flowid -= 2;
+               if (flowid >= sc->sc_max_flowrings)
+                       break;
+               ring = &sc->sc_flowrings[flowid];
+               if (ring->status != RING_CLOSING)
+                       break;
+               if (fdr->compl_hdr.status) {
+                       printf("%s: failed to delete flowring %d\n",
+                           DEVNAME(sc), flowid);
+                       break;
+               }
+               bwfm_pci_dmamem_free(sc, ring->ring);
+               ring->status = RING_CLOSED;
+               break;
        case MSGBUF_TYPE_IOCTLPTR_REQ_ACK:
                break;
        case MSGBUF_TYPE_IOCTL_CMPLT:
@@ -1434,7 +1456,7 @@ bwfm_pci_flowring_lookup(struct bwfm_pci_softc *sc, struct mbuf *m)
                if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
                    sc->sc_flowrings[flowid].status >= RING_OPEN &&
                    sc->sc_flowrings[flowid].fifo == fifo &&
-                   memcmp(sc->sc_flowrings[flowid].mac, da, ETHER_ADDR_LEN)) {
+                   !memcmp(sc->sc_flowrings[flowid].mac, da, ETHER_ADDR_LEN)) {
                        found = 1;
                        break;
                }
@@ -1547,6 +1569,49 @@ bwfm_pci_flowring_create_cb(struct bwfm_softc *bwfm, void *arg)
        bwfm_pci_ring_write_commit(sc, &sc->sc_ctrl_submit);
 }
 
+void
+bwfm_pci_flowring_delete(struct bwfm_pci_softc *sc, int flowid)
+{
+       struct msgbuf_tx_flowring_delete_req *req;
+       struct bwfm_pci_msgring *ring;
+
+       ring = &sc->sc_flowrings[flowid];
+       if (ring->status != RING_OPEN) {
+               printf("%s: flowring not open\n", DEVNAME(sc));
+               return;
+       }
+
+       req = bwfm_pci_ring_write_reserve(sc, &sc->sc_ctrl_submit);
+       if (req == NULL) {
+               printf("%s: cannot reserve for flowring\n", DEVNAME(sc));
+               return;
+       }
+
+       ring->status = RING_CLOSING;
+
+       req->msg.msgtype = MSGBUF_TYPE_FLOW_RING_DELETE;
+       req->msg.ifidx = 0;
+       req->msg.request_id = 0;
+       req->flow_ring_id = letoh16(flowid + 2);
+       req->reason = 0;
+
+       bwfm_pci_ring_write_commit(sc, &sc->sc_ctrl_submit);
+}
+
+void
+bwfm_pci_stop(struct bwfm_softc *bwfm)
+{
+       struct bwfm_pci_softc *sc = (void *)bwfm;
+       struct bwfm_pci_msgring *ring;
+       int i;
+
+       for (i = 0; i < sc->sc_max_flowrings; i++) {
+               ring = &sc->sc_flowrings[i];
+               if (ring->status == RING_OPEN)
+                       bwfm_pci_flowring_delete(sc, i);
+       }
+}
+
 int
 bwfm_pci_txdata(struct bwfm_softc *bwfm, struct mbuf *m)
 {