Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic From OpenBSD:



details:   https://anonhg.NetBSD.org/src/rev/39a507c9bea9
branches:  trunk
changeset: 453912:39a507c9bea9
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sun Sep 01 05:40:39 2019 +0000

description:
>From OpenBSD:
- move event handling to workqueue
- check for save/restore capability
Tag work queue as MPsafe and increase length.
Juse use bpf_mtap(), the 802.11 encapsulation is handled by firmware.

diffstat:

 sys/dev/ic/bwfm.c    |  128 +++++++++++++++++++++++++++++++++++---------------
 sys/dev/ic/bwfmreg.h |    3 +-
 sys/dev/ic/bwfmvar.h |    8 ++-
 3 files changed, 98 insertions(+), 41 deletions(-)

diffs (truncated from 303 to 300 lines):

diff -r 2f2e05d0d743 -r 39a507c9bea9 sys/dev/ic/bwfm.c
--- a/sys/dev/ic/bwfm.c Sun Sep 01 01:23:14 2019 +0000
+++ b/sys/dev/ic/bwfm.c Sun Sep 01 05:40:39 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bwfm.c,v 1.14 2018/09/02 19:46:53 maya Exp $ */
+/* $NetBSD: bwfm.c,v 1.15 2019/09/01 05:40:39 mlelstv Exp $ */
 /* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
@@ -114,7 +114,8 @@
 void    bwfm_connect(struct bwfm_softc *);
 
 void    bwfm_rx(struct bwfm_softc *, struct mbuf *);
-void    bwfm_rx_event(struct bwfm_softc *, char *, size_t);
+void    bwfm_rx_event(struct bwfm_softc *, struct mbuf *);
+void    bwfm_rx_event_cb(struct bwfm_softc *, struct mbuf *);
 void    bwfm_scan_node(struct bwfm_softc *, struct bwfm_bss_info *, size_t);
 
 uint8_t bwfm_2ghz_channels[] = {
@@ -142,7 +143,7 @@
        int i, j, error;
 
        error = workqueue_create(&sc->sc_taskq, DEVNAME(sc),
-           bwfm_task, sc, PRI_NONE, IPL_NET, 0);
+           bwfm_task, sc, PRI_NONE, IPL_NET, WQ_MPSAFE);
        if (error != 0) {
                printf("%s: could not create workqueue\n", DEVNAME(sc));
                return;
@@ -304,9 +305,6 @@
        /* TODO: return if no link? */
 
        for (;;) {
-               struct ieee80211_node *ni;
-               struct ether_header *eh;
-
                /* Discard management packets (fw handles this for us) */
                IF_DEQUEUE(&ic->ic_mgtq, m);
                if (m != NULL) {
@@ -323,36 +321,19 @@
                if (m == NULL)
                        break;
 
-               eh = mtod(m, struct ether_header *);
-               ni = ieee80211_find_txnode(ic, eh->ether_dhost);
-               if (ni == NULL) {
-                       ifp->if_oerrors++;
-                       m_freem(m);
-                       continue;
-               }
-
-               if (ieee80211_classify(ic, m, ni) != 0) {
-                       ifp->if_oerrors++;
-                       m_freem(m);
-                       ieee80211_free_node(ni);
-                       continue;
-               }
-
                error = sc->sc_bus_ops->bs_txdata(sc, &m);
                if (error == ENOBUFS) {
                        IF_PREPEND(&ifp->if_snd, m);
                        ifp->if_flags |= IFF_OACTIVE;
                        break;
                }
-
                if (error != 0) {
                        ifp->if_oerrors++;
                        m_freem(m);
-                       if (ni != NULL)
-                               ieee80211_free_node(ni);
-               } else {
-                       bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT);
+                       continue;
                }
+
+               bpf_mtap(ifp, m, BPF_D_OUT);
        }
 }
 
@@ -770,6 +751,9 @@
        case BWFM_TASK_KEY_DELETE:
                bwfm_key_delete_cb(sc, &t->t_key);
                break;
+       case BWFM_TASK_RX_EVENT:
+               bwfm_rx_event_cb(sc, t->t_mbuf);
+               break;
        default:
                panic("bwfm: unknown task command %d", t->t_cmd);
        }
@@ -1261,6 +1245,52 @@
        }
 }
 
+int
+bwfm_chip_sr_capable(struct bwfm_softc *sc)
+{
+       struct bwfm_core *core;
+       uint32_t reg;
+
+       if (sc->sc_chip.ch_pmurev < 17)
+               return 0;
+
+       switch (sc->sc_chip.ch_chip) {
+       case BRCM_CC_4345_CHIP_ID:
+       case BRCM_CC_4354_CHIP_ID:
+       case BRCM_CC_4356_CHIP_ID:
+               core = bwfm_chip_get_pmu(sc);
+               sc->sc_buscore_ops->bc_write(sc, core->co_base +
+                   BWFM_CHIP_REG_CHIPCONTROL_ADDR, 3);
+               reg = sc->sc_buscore_ops->bc_read(sc, core->co_base +
+                   BWFM_CHIP_REG_CHIPCONTROL_DATA);
+               return (reg & (1 << 2)) != 0;
+       case BRCM_CC_43241_CHIP_ID:
+       case BRCM_CC_4335_CHIP_ID:
+       case BRCM_CC_4339_CHIP_ID:
+               core = bwfm_chip_get_pmu(sc);
+               sc->sc_buscore_ops->bc_write(sc, core->co_base +
+                   BWFM_CHIP_REG_CHIPCONTROL_ADDR, 3);
+               reg = sc->sc_buscore_ops->bc_read(sc, core->co_base +
+                   BWFM_CHIP_REG_CHIPCONTROL_DATA);
+               return reg != 0;
+       case BRCM_CC_43430_CHIP_ID:
+               core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_CHIPCOMMON);
+               reg = sc->sc_buscore_ops->bc_read(sc, core->co_base +
+                   BWFM_CHIP_REG_SR_CONTROL1);
+               return reg != 0;
+       default:
+               core = bwfm_chip_get_pmu(sc);
+               reg = sc->sc_buscore_ops->bc_read(sc, core->co_base +
+                   BWFM_CHIP_REG_PMUCAPABILITIES_EXT);
+               if ((reg & BWFM_CHIP_REG_PMUCAPABILITIES_SR_SUPP) == 0)
+                       return 0;
+               reg = sc->sc_buscore_ops->bc_read(sc, core->co_base +
+                   BWFM_CHIP_REG_RETENTION_CTL);
+               return (reg & (BWFM_CHIP_REG_RETENTION_CTL_MACPHY_DIS |
+                              BWFM_CHIP_REG_RETENTION_CTL_LOGIC_DIS)) == 0;
+       }
+}
+
 /* RAM size helpers */
 void
 bwfm_chip_socram_ramsize(struct bwfm_softc *sc, struct bwfm_core *core)
@@ -1455,8 +1485,6 @@
        }
 
        if (buf) {
-               if (size > *len)
-                       size = *len;
                if (size < *len)
                        *len = size;
                memcpy(buf, dcmd->buf, *len);
@@ -1772,39 +1800,59 @@
            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, mtod(m, char *), m->m_len);
-               m_freem(m);
+               bwfm_rx_event(sc, m);
+               // m_freem(m);
                return;
        }
 
        s = splnet();
 
-       if ((ifp->if_flags & IFF_RUNNING) != 0) {
+       //if ((ifp->if_flags & IFF_RUNNING) != 0) {
                m_set_rcvif(m, ifp);
                if_percpuq_enqueue(ifp->if_percpuq, m);
-       }
+       //}
 
        splx(s);
 }
 
 void
-bwfm_rx_event(struct bwfm_softc *sc, char *buf, size_t len)
+bwfm_rx_event(struct bwfm_softc *sc, struct mbuf *m)
+{
+       struct bwfm_task *t;
+
+       t = pcq_get(sc->sc_freetask);
+       if (t == NULL) {
+               m_freem(m);
+               printf("%s: no free tasks\n", DEVNAME(sc));
+               return;
+       }
+
+       t->t_cmd = BWFM_TASK_RX_EVENT;
+       t->t_mbuf = m;
+       workqueue_enqueue(sc->sc_taskq, (struct work*)t, NULL);
+}
+
+void
+bwfm_rx_event_cb(struct bwfm_softc *sc, struct mbuf *m)
 {
        struct ieee80211com *ic = &sc->sc_ic;
-       struct bwfm_event *e = (void *)buf;
+       struct bwfm_event *e = mtod(m, void *);
+       size_t len = m->m_len;
        int s;
 
-       DPRINTF(("%s: buf %p len %lu datalen %u code %u status %u"
-           " reason %u\n", __func__, buf, len, ntohl(e->msg.datalen),
+       DPRINTF(("%s: event %p len %lu datalen %u code %u status %u"
+           " reason %u\n", __func__, e, len, ntohl(e->msg.datalen),
            ntohl(e->msg.event_type), ntohl(e->msg.status),
            ntohl(e->msg.reason)));
 
-       if (ntohl(e->msg.event_type) >= BWFM_E_LAST)
+       if (ntohl(e->msg.event_type) >= BWFM_E_LAST) {
+               m_freem(m);
                return;
+       }
 
        switch (ntohl(e->msg.event_type)) {
        case BWFM_E_ESCAN_RESULT: {
-               struct bwfm_escan_results *res = (void *)(buf + sizeof(*e));
+               struct bwfm_escan_results *res = (void *)&e[1];
                struct bwfm_bss_info *bss;
                int i;
                if (ntohl(e->msg.status) != BWFM_E_STATUS_PARTIAL) {
@@ -1817,11 +1865,13 @@
                }
                len -= sizeof(*e);
                if (len < sizeof(*res) || len < le32toh(res->buflen)) {
+                       m_freem(m);
                        printf("%s: results too small\n", DEVNAME(sc));
                        return;
                }
                len -= sizeof(*res);
                if (len < le16toh(res->bss_count) * sizeof(struct bwfm_bss_info)) {
+                       m_freem(m);
                        printf("%s: results too small\n", DEVNAME(sc));
                        return;
                }
@@ -1874,6 +1924,8 @@
        default:
                break;
        }
+
+       m_freem(m);
 }
 
 void
diff -r 2f2e05d0d743 -r 39a507c9bea9 sys/dev/ic/bwfmreg.h
--- a/sys/dev/ic/bwfmreg.h      Sun Sep 01 01:23:14 2019 +0000
+++ b/sys/dev/ic/bwfmreg.h      Sun Sep 01 05:40:39 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bwfmreg.h,v 1.3 2018/05/11 07:41:11 maya Exp $ */
+/* $NetBSD: bwfmreg.h,v 1.4 2019/09/01 05:40:39 mlelstv Exp $ */
 /* $OpenBSD: bwfmreg.h,v 1.16 2018/02/07 21:44:09 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
@@ -644,3 +644,4 @@
        struct bwfm_ethhdr hdr;
        struct bwfm_event_msg msg;
 } __packed;
+
diff -r 2f2e05d0d743 -r 39a507c9bea9 sys/dev/ic/bwfmvar.h
--- a/sys/dev/ic/bwfmvar.h      Sun Sep 01 01:23:14 2019 +0000
+++ b/sys/dev/ic/bwfmvar.h      Sun Sep 01 05:40:39 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bwfmvar.h,v 1.3 2018/09/01 22:01:03 riastradh Exp $ */
+/* $NetBSD: bwfmvar.h,v 1.4 2019/09/01 05:40:39 mlelstv Exp $ */
 /* $OpenBSD: bwfmvar.h,v 1.1 2017/10/11 17:19:50 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
@@ -57,7 +57,7 @@
 #define BWFM_DEFAULT_SCAN_UNASSOC_TIME 40
 #define BWFM_DEFAULT_SCAN_PASSIVE_TIME 120
 
-#define        BWFM_TASK_COUNT                 32
+#define        BWFM_TASK_COUNT                 256
 
 
 struct bwfm_softc;
@@ -119,6 +119,7 @@
        BWFM_TASK_NEWSTATE,
        BWFM_TASK_KEY_SET,
        BWFM_TASK_KEY_DELETE,
+       BWFM_TASK_RX_EVENT,
 };
 
 struct bwfm_cmd_newstate {
@@ -138,9 +139,11 @@
        union {
                struct bwfm_cmd_newstate        newstate;
                struct bwfm_cmd_key             key;
+               struct mbuf                     *mbuf;
        } t_u;
 #define        t_newstate      t_u.newstate
 #define        t_key           t_u.key
+#define        t_mbuf          t_u.mbuf
 };
 
 struct bwfm_softc {
@@ -178,6 +181,7 @@
 int bwfm_chip_attach(struct bwfm_softc *);
 int bwfm_chip_set_active(struct bwfm_softc *, uint32_t);
 void bwfm_chip_set_passive(struct bwfm_softc *);
+int bwfm_chip_sr_capable(struct bwfm_softc *);



Home | Main Index | Thread Index | Old Index