diff options
author | 2017-11-18 11:27:37 +0000 | |
---|---|---|
committer | 2017-11-18 11:27:37 +0000 | |
commit | 4e19228d91fbc9384a7e8ea9e9cca6e512928ecb (patch) | |
tree | 1c135e6bf4a40c636b0c75f718f196f03425c72c | |
parent | merge the masquerade and missing domain header callbacks into one function. (diff) | |
download | wireguard-openbsd-4e19228d91fbc9384a7e8ea9e9cca6e512928ecb.tar.xz wireguard-openbsd-4e19228d91fbc9384a7e8ea9e9cca6e512928ecb.zip |
Move the packet input work requesting inside if_cnmac.c. This removes
a layer of abstraction that would complicate upcoming changes.
-rw-r--r-- | sys/arch/octeon/dev/cn30xxpow.c | 37 | ||||
-rw-r--r-- | sys/arch/octeon/dev/cn30xxpowvar.h | 38 | ||||
-rw-r--r-- | sys/arch/octeon/dev/if_cnmac.c | 51 |
3 files changed, 74 insertions, 52 deletions
diff --git a/sys/arch/octeon/dev/cn30xxpow.c b/sys/arch/octeon/dev/cn30xxpow.c index 1865b937998..89aadd9c2d6 100644 --- a/sys/arch/octeon/dev/cn30xxpow.c +++ b/sys/arch/octeon/dev/cn30xxpow.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cn30xxpow.c,v 1.14 2017/11/05 05:17:55 visa Exp $ */ +/* $OpenBSD: cn30xxpow.c,v 1.15 2017/11/18 11:27:37 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -51,8 +51,6 @@ void cn30xxpow_bootstrap(struct octeon_config *); void cn30xxpow_init(struct cn30xxpow_softc *); void cn30xxpow_init_regs(struct cn30xxpow_softc *); -int cn30xxpow_tag_sw_poll(void); -void cn30xxpow_tag_sw_wait(void); void cn30xxpow_config_int_pc(struct cn30xxpow_softc *, int); void cn30xxpow_config_int(struct cn30xxpow_softc *, int, uint64_t, uint64_t, uint64_t); @@ -119,39 +117,6 @@ cn30xxpow_work_response_async(uint64_t scraddr) result & POW_IOBDMA_GET_WORK_RESULT_ADDR, CCA_CACHED); } -/* ---- tag switch */ - -/* - * "RDHWR rt, $30" returns: - * 0 => pending bit is set - * 1 => pending bit is clear - */ - -/* return 1 if pending bit is clear (ready) */ -int -cn30xxpow_tag_sw_poll(void) -{ - uint64_t result; - - __asm volatile ( - " .set push \n" - " .set noreorder \n" - " .set arch=mips64r2 \n" - " rdhwr %[result], $30 \n" - " .set pop \n" - : [result]"=r"(result) - ); - return (int)result; -} - -void -cn30xxpow_tag_sw_wait(void) -{ - - while (cn30xxpow_tag_sw_poll() == 0) - continue; -} - /* -------------------------------------------------------------------------- */ /* ---- initialization and configuration */ diff --git a/sys/arch/octeon/dev/cn30xxpowvar.h b/sys/arch/octeon/dev/cn30xxpowvar.h index bf30f4b05d4..88f79f02040 100644 --- a/sys/arch/octeon/dev/cn30xxpowvar.h +++ b/sys/arch/octeon/dev/cn30xxpowvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cn30xxpowvar.h,v 1.3 2017/04/30 04:32:58 visa Exp $ */ +/* $OpenBSD: cn30xxpowvar.h,v 1.4 2017/11/18 11:27:37 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -46,6 +46,8 @@ #define POW_WAIT 1 #define POW_NO_WAIT 0 +#define POW_WORKQ_IRQ(group) (group) + /* XXX */ struct cn30xxpow_softc { struct device sc_dev; @@ -329,6 +331,40 @@ cn30xxpow_ops_nop(void) 0); /* tag (not used for NOP) */ } +/* + * Check if there is a pending POW tag switch. + */ +static inline int +cn30xxpow_tag_sw_pending(void) +{ + int result; + + /* + * "RDHWR rt, $30" returns: + * 0 => pending bit is set + * 1 => pending bit is clear + */ + + __asm volatile ( + " .set push\n" + " .set noreorder\n" + " .set arch=mips64r2\n" + " rdhwr %0, $30\n" + " .set pop\n" + : "=r" (result)); + return result == 0; +} + +/* + * Wait until there is no pending POW tag switch. + */ +static inline void +cn30xxpow_tag_sw_wait(void) +{ + while (cn30xxpow_tag_sw_pending()) + continue; +} + /* -------------------------------------------------------------------------- */ /* diff --git a/sys/arch/octeon/dev/if_cnmac.c b/sys/arch/octeon/dev/if_cnmac.c index 6fa65b3cc84..f48c985223d 100644 --- a/sys/arch/octeon/dev/if_cnmac.c +++ b/sys/arch/octeon/dev/if_cnmac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_cnmac.c,v 1.69 2017/11/18 06:11:58 visa Exp $ */ +/* $OpenBSD: if_cnmac.c,v 1.70 2017/11/18 11:27:37 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -165,7 +165,7 @@ int cnmac_recv_mbuf(struct cnmac_softc *, uint64_t *, struct mbuf **, int *); int cnmac_recv_check(struct cnmac_softc *, uint64_t); int cnmac_recv(struct cnmac_softc *, uint64_t *); -void cnmac_recv_intr(void *, uint64_t *); +int cnmac_intr(void *); int cnmac_mbuf_alloc(int); @@ -323,9 +323,8 @@ cnmac_attach(struct device *parent, struct device *self, void *aux) cnmac_buf_init(sc); - sc->sc_ih = cn30xxpow_intr_establish( - sc->sc_powgroup, IPL_NET | IPL_MPSAFE, - cnmac_recv_intr, NULL, sc, sc->sc_dev.dv_xname); + sc->sc_ih = octeon_intr_establish(POW_WORKQ_IRQ(sc->sc_powgroup), + IPL_NET | IPL_MPSAFE, cnmac_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) panic("%s: could not set up interrupt", sc->sc_dev.dv_xname); } @@ -1269,22 +1268,44 @@ drop: return 1; } -void -cnmac_recv_intr(void *data, uint64_t *work) +int +cnmac_intr(void *arg) { - struct cnmac_softc *sc = data; + struct cnmac_softc *sc = arg; + uint64_t *work; + uint64_t wqmask = 1ull << sc->sc_powgroup; + uint32_t coreid = octeon_get_coreid(); uint32_t port; - port = (work[1] & PIP_WQE_WORD1_IPRT) >> 42; - if (port != sc->sc_port) { - printf("%s: unexpected wqe port %u, should be %u\n", - sc->sc_dev.dv_xname, port, sc->sc_port); - goto wqe_error; + _POW_WR8(sc->sc_pow, POW_PP_GRP_MSK_OFFSET(coreid), wqmask); + + cn30xxpow_tag_sw_wait(); + cn30xxpow_work_request_async(OCTEON_CVMSEG_OFFSET(csm_pow_intr), + POW_NO_WAIT); + + for (;;) { + work = (uint64_t *)cn30xxpow_work_response_async( + OCTEON_CVMSEG_OFFSET(csm_pow_intr)); + if (work == NULL) + break; + + cn30xxpow_tag_sw_wait(); + cn30xxpow_work_request_async( + OCTEON_CVMSEG_OFFSET(csm_pow_intr), POW_NO_WAIT); + + port = (work[1] & PIP_WQE_WORD1_IPRT) >> 42; + if (port != sc->sc_port) { + printf("%s: unexpected wqe port %u, should be %u\n", + sc->sc_dev.dv_xname, port, sc->sc_port); + goto wqe_error; + } + + (void)cnmac_recv(sc, work); } - (void)cnmac_recv(sc, work); + _POW_WR8(sc->sc_pow, POW_WQ_INT_OFFSET, wqmask); - return; + return 1; wqe_error: printf("word0: 0x%016llx\n", work[0]); |