summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2017-11-18 11:27:37 +0000
committervisa <visa@openbsd.org>2017-11-18 11:27:37 +0000
commit4e19228d91fbc9384a7e8ea9e9cca6e512928ecb (patch)
tree1c135e6bf4a40c636b0c75f718f196f03425c72c
parentmerge the masquerade and missing domain header callbacks into one function. (diff)
downloadwireguard-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.c37
-rw-r--r--sys/arch/octeon/dev/cn30xxpowvar.h38
-rw-r--r--sys/arch/octeon/dev/if_cnmac.c51
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]);