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/cf4c81f55a82
branches: trunk
changeset: 965073:cf4c81f55a82
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 22cb2eb08c12 -r cf4c81f55a82 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 22cb2eb08c12 -r cf4c81f55a82 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 22cb2eb08c12 -r cf4c81f55a82 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