summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc64/conf/files.sparc647
-rw-r--r--sys/arch/sparc64/dev/ldc.c435
-rw-r--r--sys/arch/sparc64/dev/ldcvar.h135
-rw-r--r--sys/arch/sparc64/dev/vnet.c639
4 files changed, 658 insertions, 558 deletions
diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64
index cb72ccec588..5404afd8df6 100644
--- a/sys/arch/sparc64/conf/files.sparc64
+++ b/sys/arch/sparc64/conf/files.sparc64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc64,v 1.114 2009/01/04 17:24:06 kettenis Exp $
+# $OpenBSD: files.sparc64,v 1.115 2009/01/10 17:13:28 kettenis Exp $
# $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $
# maxpartitions must be first item in files.${ARCH}
@@ -385,8 +385,11 @@ device vrtc
attach vrtc at vbus
file arch/sparc64/dev/vrtc.c vrtc
+define ldc
+file arch/sparc64/dev/ldc.c ldc
+
# Virtual network
-device vnet
+device vnet: ldc
attach vnet at cbus
file arch/sparc64/dev/vnet.c vnet
diff --git a/sys/arch/sparc64/dev/ldc.c b/sys/arch/sparc64/dev/ldc.c
new file mode 100644
index 00000000000..85eb3883bf5
--- /dev/null
+++ b/sys/arch/sparc64/dev/ldc.c
@@ -0,0 +1,435 @@
+/* $OpenBSD: ldc.c,v 1.1 2009/01/10 17:13:28 kettenis Exp $ */
+/*
+ * Copyright (c) 2009 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+#include <machine/hypervisor.h>
+
+#include <sparc64/dev/ldcvar.h>
+
+#ifdef LDC_DEBUG
+#define DPRINTF(x) printf x
+#else
+#define DPRINTF(x)
+#endif
+
+void ldc_rx_ctrl_vers(struct ldc_conn *, struct ldc_pkt *);
+void ldc_rx_ctrl_rtr(struct ldc_conn *, struct ldc_pkt *);
+void ldc_rx_ctrl_rts(struct ldc_conn *, struct ldc_pkt *);
+
+void ldc_send_rtr(struct ldc_conn *);
+void ldc_send_rts(struct ldc_conn *);
+void ldc_send_rdx(struct ldc_conn *);
+
+void
+ldc_rx_ctrl(struct ldc_conn *lc, struct ldc_pkt *lp)
+{
+ switch (lp->ctrl) {
+ case LDC_VERS:
+ ldc_rx_ctrl_vers(lc, lp);
+ break;
+
+ case LDC_RTS:
+ ldc_rx_ctrl_rts(lc, lp);
+ break;
+
+ case LDC_RTR:
+ ldc_rx_ctrl_rtr(lc, lp);
+ break;
+
+ default:
+ DPRINTF(("CTRL/0x%02x/0x%02x\n", lp->stype, lp->ctrl));
+ ldc_reset(lc);
+ break;
+ }
+}
+
+void
+ldc_rx_ctrl_vers(struct ldc_conn *lc, struct ldc_pkt *lp)
+{
+ switch (lp->stype) {
+ case LDC_INFO:
+ /* XXX do nothing for now. */
+ break;
+
+ case LDC_ACK:
+ if (lc->lc_state != LDC_SND_VERS) {
+ DPRINTF(("Spurious CTRL/ACK/VERS: state %d\n",
+ lc->lc_state));
+ ldc_reset(lc);
+ return;
+ }
+ DPRINTF(("CTRL/ACK/VERS\n"));
+ ldc_send_rts(lc);
+ break;
+
+ case LDC_NACK:
+ DPRINTF(("CTRL/NACK/VERS\n"));
+ ldc_reset(lc);
+ break;
+
+ default:
+ DPRINTF(("CTRL/0x%02x/VERS\n", lp->stype));
+ ldc_reset(lc);
+ break;
+ }
+}
+
+void
+ldc_rx_ctrl_rts(struct ldc_conn *lc, struct ldc_pkt *lp)
+{
+ switch (lp->stype) {
+ case LDC_INFO:
+ if (lc->lc_state != LDC_RCV_VERS) {
+ DPRINTF(("Suprious CTRL/INFO/RTS: state %d\n",
+ lc->lc_state));
+ ldc_reset(lc);
+ return;
+ }
+ DPRINTF(("CTRL/INFO/RTS\n"));
+ ldc_send_rtr(lc);
+ break;
+
+ case LDC_ACK:
+ DPRINTF(("CTRL/ACK/RTS\n"));
+ ldc_reset(lc);
+ break;
+
+ case LDC_NACK:
+ DPRINTF(("CTRL/NACK/RTS\n"));
+ ldc_reset(lc);
+ break;
+
+ default:
+ DPRINTF(("CTRL/0x%02x/RTS\n", lp->stype));
+ ldc_reset(lc);
+ break;
+ }
+}
+
+void
+ldc_rx_ctrl_rtr(struct ldc_conn *lc, struct ldc_pkt *lp)
+{
+ switch (lp->stype) {
+ case LDC_INFO:
+ if (lc->lc_state != LDC_SND_RTS) {
+ DPRINTF(("Spurious CTRL/INFO/RTR: state %d\n",
+ lc->lc_state));
+ ldc_reset(lc);
+ return;
+ }
+ DPRINTF(("CTRL/INFO/RTR\n"));
+ ldc_send_rdx(lc);
+ break;
+
+ case LDC_ACK:
+ DPRINTF(("CTRL/ACK/RTR\n"));
+ ldc_reset(lc);
+ break;
+
+ case LDC_NACK:
+ DPRINTF(("CTRL/NACK/RTR\n"));
+ ldc_reset(lc);
+ break;
+
+ default:
+ DPRINTF(("CTRL/0x%02x/RTR\n", lp->stype));
+ ldc_reset(lc);
+ break;
+ }
+}
+
+void
+ldc_rx_data(struct ldc_conn *lc, struct ldc_pkt *lp)
+{
+ if (lp->stype != LDC_INFO) {
+ DPRINTF(("DATA/0x%02x\n", lp->stype));
+ ldc_reset(lc);
+ return;
+ }
+
+ if (lc->lc_state != LDC_SND_RTR &&
+ lc->lc_state != LDC_SND_RDX) {
+ DPRINTF(("Spurious DATA/INFO: state %d\n", lc->lc_state));
+ ldc_reset(lc);
+ return;
+ }
+
+ lc->lc_rx_data(lc, lp);
+}
+
+void
+ldc_send_vers(struct ldc_conn *lc)
+{
+ struct ldc_pkt *lp;
+ uint64_t tx_head, tx_tail, tx_state;
+ int err;
+
+ err = hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state);
+ if (err != H_EOK || tx_state != LDC_CHANNEL_UP)
+ return;
+
+ lp = (struct ldc_pkt *)(lc->lc_txq->lq_va + tx_tail);
+ bzero(lp, sizeof(struct ldc_pkt));
+ lp->type = LDC_CTRL;
+ lp->stype = LDC_INFO;
+ lp->ctrl = LDC_VERS;
+ lp->major = 1;
+ lp->minor = 0;
+
+ tx_tail += sizeof(*lp);
+ tx_tail &= ((lc->lc_txq->lq_nentries * sizeof(*lp)) - 1);
+ err = hv_ldc_tx_set_qtail(lc->lc_id, tx_tail);
+ if (err != H_EOK) {
+ printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err);
+ return;
+ }
+
+ lc->lc_state = LDC_SND_VERS;
+}
+
+void
+ldc_send_rts(struct ldc_conn *lc)
+{
+ struct ldc_pkt *lp;
+ uint64_t tx_head, tx_tail, tx_state;
+ int err;
+
+ err = hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state);
+ if (err != H_EOK || tx_state != LDC_CHANNEL_UP)
+ return;
+
+ lp = (struct ldc_pkt *)(lc->lc_txq->lq_va + tx_tail);
+ bzero(lp, sizeof(struct ldc_pkt));
+ lp->type = LDC_CTRL;
+ lp->stype = LDC_INFO;
+ lp->ctrl = LDC_RTS;
+ lp->env = LDC_MODE_UNRELIABLE;
+ lp->seqid = lc->lc_tx_seqid++;
+
+ tx_tail += sizeof(*lp);
+ tx_tail &= ((lc->lc_txq->lq_nentries * sizeof(*lp)) - 1);
+ err = hv_ldc_tx_set_qtail(lc->lc_id, tx_tail);
+ if (err != H_EOK) {
+ printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err);
+ return;
+ }
+
+ lc->lc_state = LDC_SND_RTS;
+}
+
+void
+ldc_send_rtr(struct ldc_conn *lc)
+{
+ struct ldc_pkt *lp;
+ uint64_t tx_head, tx_tail, tx_state;
+ int err;
+
+ err = hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state);
+ if (err != H_EOK || tx_state != LDC_CHANNEL_UP)
+ return;
+
+ lp = (struct ldc_pkt *)(lc->lc_txq->lq_va + tx_tail);
+ bzero(lp, sizeof(struct ldc_pkt));
+ lp->type = LDC_CTRL;
+ lp->stype = LDC_INFO;
+ lp->ctrl = LDC_RTR;
+ lp->env = LDC_MODE_UNRELIABLE;
+ lp->seqid = lc->lc_tx_seqid++;
+
+ tx_tail += sizeof(*lp);
+ tx_tail &= ((lc->lc_txq->lq_nentries * sizeof(*lp)) - 1);
+ err = hv_ldc_tx_set_qtail(lc->lc_id, tx_tail);
+ if (err != H_EOK)
+ printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err);
+
+ lc->lc_state = LDC_SND_RTR;
+}
+
+void
+ldc_send_rdx(struct ldc_conn *lc)
+{
+ struct ldc_pkt *lp;
+ uint64_t tx_head, tx_tail, tx_state;
+ int err;
+
+ err = hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state);
+ if (err != H_EOK || tx_state != LDC_CHANNEL_UP)
+ return;
+
+ lp = (struct ldc_pkt *)(lc->lc_txq->lq_va + tx_tail);
+ bzero(lp, sizeof(struct ldc_pkt));
+ lp->type = LDC_CTRL;
+ lp->stype = LDC_INFO;
+ lp->ctrl = LDC_RDX;
+ lp->env = LDC_MODE_UNRELIABLE;
+ lp->seqid = lc->lc_tx_seqid++;
+
+ tx_tail += sizeof(*lp);
+ tx_tail &= ((lc->lc_txq->lq_nentries * sizeof(*lp)) - 1);
+ err = hv_ldc_tx_set_qtail(lc->lc_id, tx_tail);
+ if (err != H_EOK)
+ printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err);
+
+ lc->lc_state = LDC_SND_RDX;
+}
+
+void
+ldc_reset(struct ldc_conn *lc)
+{
+ int err;
+
+ DPRINTF(("Resetting connection\n"));
+ hv_ldc_tx_qconf(lc->lc_id, 0, 0);
+ hv_ldc_rx_qconf(lc->lc_id, 0, 0);
+ lc->lc_tx_state = lc->lc_rx_state = LDC_CHANNEL_DOWN;
+
+ err = hv_ldc_tx_qconf(lc->lc_id,
+ lc->lc_txq->lq_map->dm_segs[0].ds_addr, lc->lc_txq->lq_nentries);
+ if (err != H_EOK)
+ printf("%s: hv_ldc_tx_qconf %d\n", __func__, err);
+
+ err = hv_ldc_rx_qconf(lc->lc_id,
+ lc->lc_rxq->lq_map->dm_segs[0].ds_addr, lc->lc_rxq->lq_nentries);
+ if (err != H_EOK)
+ printf("%s: hv_ldc_rx_qconf %d\n", __func__, err);
+
+ lc->lc_tx_seqid = 0;
+ lc->lc_state = 0;
+ lc->lc_reset(lc);
+}
+
+struct ldc_queue *
+ldc_queue_alloc(bus_dma_tag_t t, int nentries)
+{
+ struct ldc_queue *lq;
+ bus_size_t size;
+ caddr_t va;
+ int nsegs;
+
+ lq = malloc(sizeof(struct ldc_queue), M_DEVBUF, M_NOWAIT);
+ if (lq == NULL)
+ return NULL;
+
+ size = roundup(nentries * sizeof(struct ldc_pkt), PAGE_SIZE);
+
+ if (bus_dmamap_create(t, size, 1, size, 0,
+ BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &lq->lq_map) != 0)
+ return (NULL);
+
+ if (bus_dmamem_alloc(t, size, PAGE_SIZE, 0, &lq->lq_seg, 1,
+ &nsegs, BUS_DMA_NOWAIT) != 0)
+ goto destroy;
+
+ if (bus_dmamem_map(t, &lq->lq_seg, 1, size, &va,
+ BUS_DMA_NOWAIT) != 0)
+ goto free;
+
+ if (bus_dmamap_load(t, lq->lq_map, va, size, NULL,
+ BUS_DMA_NOWAIT) != 0)
+ goto unmap;
+
+ lq->lq_va = va;
+ lq->lq_nentries = nentries;
+ return (lq);
+
+unmap:
+ bus_dmamem_unmap(t, va, size);
+free:
+ bus_dmamem_free(t, &lq->lq_seg, 1);
+destroy:
+ bus_dmamap_destroy(t, lq->lq_map);
+
+ return (NULL);
+}
+
+void
+ldc_queue_free(bus_dma_tag_t t, struct ldc_queue *lq)
+{
+ bus_size_t size;
+
+ size = roundup(lq->lq_nentries * sizeof(struct ldc_pkt), PAGE_SIZE);
+
+ bus_dmamap_unload(t, lq->lq_map);
+ bus_dmamem_unmap(t, lq->lq_va, size);
+ bus_dmamem_free(t, &lq->lq_seg, 1);
+ bus_dmamap_destroy(t, lq->lq_map);
+ free(lq, M_DEVBUF);
+}
+
+struct ldc_map *
+ldc_map_alloc(bus_dma_tag_t t, int nentries)
+{
+ struct ldc_map *lm;
+ bus_size_t size;
+ caddr_t va;
+ int nsegs;
+
+ lm = malloc(sizeof(struct ldc_map), M_DEVBUF, M_NOWAIT);
+ if (lm == NULL)
+ return NULL;
+
+ size = roundup(nentries * sizeof(struct ldc_map_slot), PAGE_SIZE);
+
+ if (bus_dmamap_create(t, size, 1, size, 0,
+ BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &lm->lm_map) != 0)
+ return (NULL);
+
+ if (bus_dmamem_alloc(t, size, PAGE_SIZE, 0, &lm->lm_seg, 1,
+ &nsegs, BUS_DMA_NOWAIT) != 0)
+ goto destroy;
+
+ if (bus_dmamem_map(t, &lm->lm_seg, 1, size, &va,
+ BUS_DMA_NOWAIT) != 0)
+ goto free;
+
+ if (bus_dmamap_load(t, lm->lm_map, va, size, NULL,
+ BUS_DMA_NOWAIT) != 0)
+ goto unmap;
+
+ lm->lm_slot = (struct ldc_map_slot *)va;
+ lm->lm_nentries = nentries;
+ bzero(lm->lm_slot, nentries * sizeof(struct ldc_map_slot));
+ return (lm);
+
+unmap:
+ bus_dmamem_unmap(t, va, size);
+free:
+ bus_dmamem_free(t, &lm->lm_seg, 1);
+destroy:
+ bus_dmamap_destroy(t, lm->lm_map);
+
+ return (NULL);
+}
+
+void
+ldc_map_free(bus_dma_tag_t t, struct ldc_map *lm)
+{
+ bus_size_t size;
+
+ size = lm->lm_nentries * sizeof(struct ldc_map_slot);
+ size = roundup(size, PAGE_SIZE);
+
+ bus_dmamap_unload(t, lm->lm_map);
+ bus_dmamem_unmap(t, (caddr_t)lm->lm_slot, size);
+ bus_dmamem_free(t, &lm->lm_seg, 1);
+ bus_dmamap_destroy(t, lm->lm_map);
+ free(lm, M_DEVBUF);
+}
diff --git a/sys/arch/sparc64/dev/ldcvar.h b/sys/arch/sparc64/dev/ldcvar.h
new file mode 100644
index 00000000000..618265c7761
--- /dev/null
+++ b/sys/arch/sparc64/dev/ldcvar.h
@@ -0,0 +1,135 @@
+/* $OpenBSD: ldcvar.h,v 1.1 2009/01/10 17:13:28 kettenis Exp $ */
+/*
+ * Copyright (c) 2009 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * LDC queues.
+ */
+
+struct ldc_queue {
+ bus_dmamap_t lq_map;
+ bus_dma_segment_t lq_seg;
+ caddr_t lq_va;
+ int lq_nentries;
+};
+
+struct ldc_queue *ldc_queue_alloc(bus_dma_tag_t, int);
+void ldc_queue_free(bus_dma_tag_t, struct ldc_queue *);
+
+/*
+ * LDC virtual link layer protocol.
+ */
+
+struct ldc_pkt {
+ uint8_t type;
+ uint8_t stype;
+ uint8_t ctrl;
+ uint8_t env;
+ uint32_t seqid;
+
+ uint16_t major;
+ uint16_t minor;
+ uint32_t _reserved[13];
+};
+
+/* Packet types. */
+#define LDC_CTRL 0x01
+#define LDC_DATA 0x02
+#define LDC_ERR 0x10
+
+/* Packet subtypes. */
+#define LDC_INFO 0x01
+#define LDC_ACK 0x02
+#define LDC_NACK 0x04
+
+/* Control info values. */
+#define LDC_VERS 0x01
+#define LDC_RTS 0x02
+#define LDC_RTR 0x03
+#define LDC_RDX 0x04
+
+/* Packet envelope. */
+#define LDC_MODE_RAW 0x00
+#define LDC_MODE_UNRELIABLE 0x01
+#define LDC_MODE_RELIABLE 0x03
+
+#define LDC_LEN_MASK 0x3f
+#define LDC_FRAG_MASK 0xc0
+#define LDC_FRAG_START 0x40
+#define LDC_FRAG_STOP 0x80
+
+struct ldc_conn {
+ uint64_t lc_id;
+
+ struct ldc_queue *lc_txq;
+ struct ldc_queue *lc_rxq;
+ uint64_t lc_tx_state;
+ uint64_t lc_rx_state;
+
+ uint32_t lc_tx_seqid;
+ uint8_t lc_state;
+#define LDC_SND_VERS 1
+#define LDC_RCV_VERS 2
+#define LDC_SND_RTS 3
+#define LDC_SND_RTR 4
+#define LDC_SND_RDX 5
+
+ void *lc_sc;
+ void (*lc_reset)(struct ldc_conn *);
+ void (*lc_rx_data)(struct ldc_conn *, struct ldc_pkt *);
+};
+
+void ldc_rx_ctrl(struct ldc_conn *, struct ldc_pkt *);
+void ldc_rx_data(struct ldc_conn *, struct ldc_pkt *);
+
+void ldc_send_vers(struct ldc_conn *);
+
+void ldc_reset(struct ldc_conn *);
+
+/*
+ * LDC map tables.
+ */
+
+struct ldc_map_slot {
+ uint64_t entry;
+ uint64_t cookie;
+};
+
+#define LDC_MTE_R 0x0000000000000010ULL
+#define LDC_MTE_W 0x0000000000000020ULL
+#define LDC_MTE_X 0x0000000000000040ULL
+#define LDC_MTE_IOR 0x0000000000000080ULL
+#define LDC_MTE_IOW 0x0000000000000100ULL
+#define LDC_MTE_CPR 0x0000000000000200ULL
+#define LDC_MTE_CPW 0x0000000000000400ULL
+#define LDC_MTE_RA_MASK 0x007fffffffffe000ULL
+
+struct ldc_map {
+ bus_dmamap_t lm_map;
+ bus_dma_segment_t lm_seg;
+ struct ldc_map_slot *lm_slot;
+ int lm_nentries;
+ int lm_next;
+ int lm_count;
+};
+
+struct ldc_map *ldc_map_alloc(bus_dma_tag_t, int);
+void ldc_map_free(bus_dma_tag_t, struct ldc_map *);
+
+struct ldc_cookie {
+ uint64_t addr;
+ uint64_t size;
+};
diff --git a/sys/arch/sparc64/dev/vnet.c b/sys/arch/sparc64/dev/vnet.c
index 2be853eb579..d5a9295f69e 100644
--- a/sys/arch/sparc64/dev/vnet.c
+++ b/sys/arch/sparc64/dev/vnet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnet.c,v 1.5 2009/01/10 14:23:59 kettenis Exp $ */
+/* $OpenBSD: vnet.c,v 1.6 2009/01/10 17:13:28 kettenis Exp $ */
/*
* Copyright (c) 2009 Mark Kettenis
*
@@ -46,6 +46,7 @@
#include <dev/rndvar.h>
#include <sparc64/dev/cbusvar.h>
+#include <sparc64/dev/ldcvar.h>
/* XXX the following declaration should be elsewhere */
extern void myetheraddr(u_char *);
@@ -56,83 +57,6 @@ extern void myetheraddr(u_char *);
#define DPRINTF(x)
#endif
-struct ldc_msg {
- uint8_t type;
- uint8_t stype;
- uint8_t ctrl;
- uint8_t env;
- uint32_t seqid;
-
- uint16_t major;
- uint16_t minor;
- uint32_t _reserved[13];
-};
-
-#define LDC_MSGSZ sizeof(struct ldc_msg)
-
-#define LDC_CTRL 0x01
-#define LDC_DATA 0x02
-#define LDC_ERR 0x10
-
-#define LDC_INFO 0x01
-#define LDC_ACK 0x02
-#define LDC_NACK 0x04
-
-#define LDC_VERS 0x01
-#define LDC_RTS 0x02
-#define LDC_RTR 0x03
-#define LDC_RDX 0x04
-
-#define LDC_MODE_RAW 0x00
-#define LDC_MODE_UNRELIABLE 0x01
-#define LDC_MODE_RELIABLE 0x03
-
-#define LDC_LEN_MASK 0x3f
-#define LDC_FRAG_MASK 0xc0
-#define LDC_FRAG_START 0x40
-#define LDC_FRAG_STOP 0x80
-
-struct ldc_queue {
- bus_dmamap_t lq_map;
- bus_dma_segment_t lq_seg;
- caddr_t lq_va;
- int lq_nentries;
-};
-
-struct ldc_cookie {
- uint64_t addr;
- uint64_t size;
-};
-
-struct ldc_queue *ldc_queue_alloc(bus_dma_tag_t, int);
-void ldc_queue_free(bus_dma_tag_t, struct ldc_queue *);
-
-struct ldc_map_slot {
- uint64_t entry;
- uint64_t cookie;
-};
-
-#define LDC_MTE_R 0x0000000000000010ULL
-#define LDC_MTE_W 0x0000000000000020ULL
-#define LDC_MTE_X 0x0000000000000040ULL
-#define LDC_MTE_IOR 0x0000000000000080ULL
-#define LDC_MTE_IOW 0x0000000000000100ULL
-#define LDC_MTE_CPR 0x0000000000000200ULL
-#define LDC_MTE_CPW 0x0000000000000400ULL
-#define LDC_MTE_RA_MASK 0x007fffffffffe000ULL
-
-struct ldc_map {
- bus_dmamap_t lm_map;
- bus_dma_segment_t lm_seg;
- struct ldc_map_slot *lm_slot;
- int lm_nentries;
- int lm_next;
- int lm_count;
-};
-
-struct ldc_map *ldc_map_alloc(bus_dma_tag_t, int);
-void ldc_map_free(bus_dma_tag_t, struct ldc_map *);
-
#define VNET_TX_ENTRIES 32
#define VNET_RX_ENTRIES 32
@@ -289,25 +213,10 @@ struct vnet_softc {
bus_space_tag_t sc_bustag;
bus_dma_tag_t sc_dmatag;
- uint64_t sc_id;
-
void *sc_tx_ih;
void *sc_rx_ih;
- struct ldc_queue *sc_txq;
- struct ldc_queue *sc_rxq;
-
- uint64_t sc_tx_state;
- uint64_t sc_rx_state;
-
- uint32_t sc_tx_seqid;
-
- uint8_t sc_ldc_state;
-#define LDC_SND_VERS 1
-#define LDC_RCV_VERS 2
-#define LDC_SND_RTS 3
-#define LDC_SND_RTR 4
-#define LDC_SND_RDX 5
+ struct ldc_conn sc_lc;
uint8_t sc_vio_state;
#define VIO_ESTABLISHED 8
@@ -348,12 +257,7 @@ struct cfdriver vnet_cd = {
int vnet_tx_intr(void *);
int vnet_rx_intr(void *);
-void vnet_rx_ctrl(struct vnet_softc *, struct ldc_msg *);
-void vnet_rx_ctrl_vers(struct vnet_softc *, struct ldc_msg *);
-void vnet_rx_ctrl_rtr(struct vnet_softc *, struct ldc_msg *);
-void vnet_rx_ctrl_rts(struct vnet_softc *, struct ldc_msg *);
-
-void vnet_rx_data(struct vnet_softc *, struct ldc_msg *);
+void vio_rx_data(struct ldc_conn *, struct ldc_pkt *);
void vnet_rx_vio_ctrl(struct vnet_softc *, struct vio_msg *);
void vnet_rx_vio_ver_info(struct vnet_softc *, struct vio_msg_tag *);
void vnet_rx_vio_attr_info(struct vnet_softc *, struct vio_msg_tag *);
@@ -362,11 +266,7 @@ void vnet_rx_vio_rdx(struct vnet_softc *sc, struct vio_msg_tag *);
void vnet_rx_vio_data(struct vnet_softc *sc, struct vio_msg *);
void vnet_rx_vio_dring_data(struct vnet_softc *sc, struct vio_msg_tag *);
-void ldc_send_vers(struct vnet_softc *);
-void ldc_send_rtr(struct vnet_softc *);
-void ldc_send_rts(struct vnet_softc *);
-void ldc_send_rdx(struct vnet_softc *);
-void ldc_reset(struct vnet_softc *);
+void vnet_reset(struct ldc_conn *);
void vio_sendmsg(struct vnet_softc *, void *, size_t);
void vio_send_ver_info(struct vnet_softc *, uint16_t, uint16_t);
@@ -404,14 +304,13 @@ vnet_attach(struct device *parent, struct device *self, void *aux)
{
struct vnet_softc *sc = (struct vnet_softc *)self;
struct cbus_attach_args *ca = aux;
+ struct ldc_conn *lc;
struct ifnet *ifp;
uint64_t sysino[2];
sc->sc_bustag = ca->ca_bustag;
sc->sc_dmatag = ca->ca_dmatag;
- sc->sc_id = ca->ca_id;
-
if (OF_getprop(ca->ca_node, "local-mac-address", sc->sc_ac.ac_enaddr,
ETHER_ADDR_LEN) <= 0)
myetheraddr(sc->sc_ac.ac_enaddr);
@@ -427,8 +326,8 @@ vnet_attach(struct device *parent, struct device *self, void *aux)
* Un-configure queues before registering interrupt handlers,
* such that we dont get any stale LDC packets or events.
*/
- hv_ldc_tx_qconf(sc->sc_id, 0, 0);
- hv_ldc_rx_qconf(sc->sc_id, 0, 0);
+ hv_ldc_tx_qconf(ca->ca_id, 0, 0);
+ hv_ldc_rx_qconf(ca->ca_id, 0, 0);
sc->sc_tx_ih = bus_intr_establish(ca->ca_bustag, sysino[0], IPL_NET,
0, vnet_tx_intr, sc, sc->sc_dv.dv_xname);
@@ -439,14 +338,20 @@ vnet_attach(struct device *parent, struct device *self, void *aux)
return;
}
- sc->sc_txq = ldc_queue_alloc(sc->sc_dmatag, VNET_TX_ENTRIES);
- if (sc->sc_txq == NULL) {
+ lc = &sc->sc_lc;
+ lc->lc_id = ca->ca_id;
+ lc->lc_sc = sc;
+ lc->lc_reset = vnet_reset;
+ lc->lc_rx_data = vio_rx_data;
+
+ lc->lc_txq = ldc_queue_alloc(sc->sc_dmatag, VNET_TX_ENTRIES);
+ if (lc->lc_txq == NULL) {
printf(", can't allocate tx queue\n");
return;
}
- sc->sc_rxq = ldc_queue_alloc(sc->sc_dmatag, VNET_RX_ENTRIES);
- if (sc->sc_rxq == NULL) {
+ lc->lc_rxq = ldc_queue_alloc(sc->sc_dmatag, VNET_RX_ENTRIES);
+ if (lc->lc_rxq == NULL) {
printf(", can't allocate rx queue\n");
goto free_txqueue;
}
@@ -477,7 +382,7 @@ vnet_attach(struct device *parent, struct device *self, void *aux)
return;
free_txqueue:
- ldc_queue_free(sc->sc_dmatag, sc->sc_txq);
+ ldc_queue_free(sc->sc_dmatag, lc->lc_txq);
return;
}
@@ -485,10 +390,11 @@ int
vnet_tx_intr(void *arg)
{
struct vnet_softc *sc = arg;
+ struct ldc_conn *lc = &sc->sc_lc;
uint64_t tx_head, tx_tail, tx_state;
- hv_ldc_tx_get_state(sc->sc_id, &tx_head, &tx_tail, &tx_state);
- if (tx_state != sc->sc_tx_state) {
+ hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state);
+ if (tx_state != lc->lc_tx_state) {
switch (tx_state) {
case LDC_CHANNEL_DOWN:
DPRINTF(("Tx link down\n"));
@@ -500,7 +406,7 @@ vnet_tx_intr(void *arg)
DPRINTF(("Tx link reset\n"));
break;
}
- sc->sc_tx_state = tx_state;
+ lc->lc_tx_state = tx_state;
}
return (1);
@@ -510,12 +416,13 @@ int
vnet_rx_intr(void *arg)
{
struct vnet_softc *sc = arg;
+ struct ldc_conn *lc = &sc->sc_lc;
uint64_t rx_head, rx_tail, rx_state;
- struct ldc_msg *lm;
+ struct ldc_pkt *lp;
uint64_t *msg;
int err;
- err = hv_ldc_rx_get_state(sc->sc_id, &rx_head, &rx_tail, &rx_state);
+ err = hv_ldc_rx_get_state(lc->lc_id, &rx_head, &rx_tail, &rx_state);
if (err == H_EINVAL)
return (0);
if (err != H_EOK) {
@@ -523,29 +430,29 @@ vnet_rx_intr(void *arg)
return (0);
}
- if (rx_state != sc->sc_rx_state) {
+ if (rx_state != lc->lc_rx_state) {
sc->sc_tx_cnt = sc->sc_tx_prod = sc->sc_tx_cons = 0;
- sc->sc_tx_seqid = 0;
- sc->sc_ldc_state = 0;
sc->sc_vio_state = 0;
+ lc->lc_tx_seqid = 0;
+ lc->lc_state = 0;
switch (rx_state) {
case LDC_CHANNEL_DOWN:
DPRINTF(("Rx link down\n"));
break;
case LDC_CHANNEL_UP:
DPRINTF(("Rx link up\n"));
- ldc_send_vers(sc);
+ ldc_send_vers(lc);
break;
case LDC_CHANNEL_RESET:
DPRINTF(("Rx link reset\n"));
break;
}
- sc->sc_rx_state = rx_state;
- hv_ldc_rx_set_qhead(sc->sc_id, rx_tail);
+ lc->lc_rx_state = rx_state;
+ hv_ldc_rx_set_qhead(lc->lc_id, rx_tail);
return (1);
}
- msg = (uint64_t *)(sc->sc_rxq->lq_va + rx_head);
+ msg = (uint64_t *)(lc->lc_rxq->lq_va + rx_head);
#if 0
{
int i;
@@ -556,29 +463,29 @@ vnet_rx_intr(void *arg)
printf("word %d: 0x%016lx\n", i, msg[i]);
}
#endif
- lm = (struct ldc_msg *)(sc->sc_rxq->lq_va + rx_head);
- switch (lm->type) {
+ lp = (struct ldc_pkt *)(lc->lc_rxq->lq_va + rx_head);
+ switch (lp->type) {
case LDC_CTRL:
- vnet_rx_ctrl(sc, lm);
+ ldc_rx_ctrl(lc, lp);
break;
case LDC_DATA:
- vnet_rx_data(sc, lm);
+ ldc_rx_data(lc, lp);
break;
default:
- DPRINTF(("%0x02/%0x02/%0x02\n", lm->type, lm->stype,
- lm->ctrl));
- ldc_reset(sc);
+ DPRINTF(("%0x02/%0x02/%0x02\n", lp->type, lp->stype,
+ lp->ctrl));
+ ldc_reset(lc);
break;
}
- if (sc->sc_ldc_state == 0)
+ if (lc->lc_state == 0)
return (1);
- rx_head += LDC_MSGSZ;
- rx_head &= ((sc->sc_rxq->lq_nentries * LDC_MSGSZ) - 1);
- err = hv_ldc_rx_set_qhead(sc->sc_id, rx_head);
+ rx_head += sizeof(*lp);
+ rx_head &= ((lc->lc_rxq->lq_nentries * sizeof(*lp)) - 1);
+ err = hv_ldc_rx_set_qhead(lc->lc_id, rx_head);
if (err != H_EOK)
printf("%s: hv_ldc_rx_set_qhead %d\n", __func__, err);
@@ -586,159 +493,27 @@ vnet_rx_intr(void *arg)
}
void
-vnet_rx_ctrl(struct vnet_softc *sc, struct ldc_msg *lm)
+vio_rx_data(struct ldc_conn *lc, struct ldc_pkt *lp)
{
- switch (lm->ctrl) {
- case LDC_VERS:
- vnet_rx_ctrl_vers(sc, lm);
- break;
+ struct vio_msg *vm = (struct vio_msg *)lp;
- case LDC_RTS:
- vnet_rx_ctrl_rts(sc, lm);
- break;
-
- case LDC_RTR:
- vnet_rx_ctrl_rtr(sc, lm);
- break;
-
- default:
- DPRINTF(("CTRL/0x%02x/0x%02x\n", lm->stype, lm->ctrl));
- ldc_reset(sc);
- break;
- }
-}
-
-void
-vnet_rx_ctrl_vers(struct vnet_softc *sc, struct ldc_msg *lm)
-{
- switch (lm->stype) {
- case LDC_INFO:
- /* XXX do nothing for now. */
- break;
-
- case LDC_ACK:
- if (sc->sc_ldc_state != LDC_SND_VERS) {
- DPRINTF(("Spurious CTRL/ACK/VERS: state %d\n",
- sc->sc_ldc_state));
- ldc_reset(sc);
- return;
- }
- DPRINTF(("CTRL/ACK/VERS\n"));
- ldc_send_rts(sc);
- break;
-
- case LDC_NACK:
- DPRINTF(("CTRL/NACK/VERS\n"));
- ldc_reset(sc);
- break;
-
- default:
- DPRINTF(("CTRL/0x%02x/VERS\n", lm->stype));
- ldc_reset(sc);
- break;
- }
-}
-
-void
-vnet_rx_ctrl_rts(struct vnet_softc *sc, struct ldc_msg *lm)
-{
- switch (lm->stype) {
- case LDC_INFO:
- if (sc->sc_ldc_state != LDC_RCV_VERS) {
- DPRINTF(("Suprious CTRL/INFO/RTS: state %d\n",
- sc->sc_ldc_state));
- ldc_reset(sc);
- return;
- }
- DPRINTF(("CTRL/INFO/RTS\n"));
- ldc_send_rtr(sc);
- break;
-
- case LDC_ACK:
- DPRINTF(("CTRL/ACK/RTS\n"));
- ldc_reset(sc);
- break;
-
- case LDC_NACK:
- DPRINTF(("CTRL/NACK/RTS\n"));
- ldc_reset(sc);
- break;
-
- default:
- DPRINTF(("CTRL/0x%02x/RTS\n", lm->stype));
- ldc_reset(sc);
- break;
- }
-}
-
-void
-vnet_rx_ctrl_rtr(struct vnet_softc *sc, struct ldc_msg *lm)
-{
- switch (lm->stype) {
- case LDC_INFO:
- if (sc->sc_ldc_state != LDC_SND_RTS) {
- DPRINTF(("Spurious CTRL/INFO/RTR: state %d\n",
- sc->sc_ldc_state));
- ldc_reset(sc);
- return;
- }
- DPRINTF(("CTRL/INFO/RTR\n"));
- ldc_send_rdx(sc);
- break;
-
- case LDC_ACK:
- DPRINTF(("CTRL/ACK/RTR\n"));
- ldc_reset(sc);
- break;
-
- case LDC_NACK:
- DPRINTF(("CTRL/NACK/RTR\n"));
- ldc_reset(sc);
- break;
-
- default:
- DPRINTF(("CTRL/0x%02x/RTR\n", lm->stype));
- ldc_reset(sc);
- break;
- }
-}
-
-void
-vnet_rx_data(struct vnet_softc *sc, struct ldc_msg *lm)
-{
- struct vio_msg *vm;
-
- if (lm->stype != LDC_INFO) {
- DPRINTF(("DATA/0x%02x\n", lm->stype));
- ldc_reset(sc);
- return;
- }
-
- if (sc->sc_ldc_state != LDC_SND_RTR &&
- sc->sc_ldc_state != LDC_SND_RDX) {
- DPRINTF(("Spurious DATA/INFO: state %d\n", sc->sc_ldc_state));
- ldc_reset(sc);
- return;
- }
-
- vm = (struct vio_msg *)lm;
switch (vm->type) {
case VIO_TYPE_CTRL:
- if ((lm->env & LDC_FRAG_START) == 0 &&
- (lm->env & LDC_FRAG_STOP) == 0)
+ if ((lp->env & LDC_FRAG_START) == 0 &&
+ (lp->env & LDC_FRAG_STOP) == 0)
return;
- vnet_rx_vio_ctrl(sc, vm);
+ vnet_rx_vio_ctrl(lc->lc_sc, vm);
break;
case VIO_TYPE_DATA:
- if((lm->env & LDC_FRAG_START) == 0)
+ if((lp->env & LDC_FRAG_START) == 0)
return;
- vnet_rx_vio_data(sc, vm);
+ vnet_rx_vio_data(lc->lc_sc, vm);
break;
default:
DPRINTF(("Unhandled packet type 0x%02x\n", vm->type));
- ldc_reset(sc);
+ ldc_reset(lc);
break;
}
}
@@ -934,6 +709,7 @@ void
vnet_rx_vio_dring_data(struct vnet_softc *sc, struct vio_msg_tag *tag)
{
struct vnet_dring_msg *dm = (struct vnet_dring_msg *)tag;
+ struct ldc_conn *lc = &sc->sc_lc;
struct ifnet *ifp = &sc->sc_ac.ac_if;
struct mbuf *m;
paddr_t pa;
@@ -954,7 +730,7 @@ vnet_rx_vio_dring_data(struct vnet_softc *sc, struct vio_msg_tag *tag)
cookie += idx * sc->sc_peer_desc_size;
nbytes = sc->sc_peer_desc_size;
pmap_extract(pmap_kernel(), (vaddr_t)&desc, &desc_pa);
- err = hv_ldc_copy(sc->sc_id, LDC_COPY_IN, cookie,
+ err = hv_ldc_copy(lc->lc_id, LDC_COPY_IN, cookie,
desc_pa, nbytes, &nbytes);
if (err != H_EOK) {
printf("hv_ldc_copy_in %d\n", err);
@@ -978,7 +754,7 @@ vnet_rx_vio_dring_data(struct vnet_softc *sc, struct vio_msg_tag *tag)
nbytes = roundup(desc.nbytes + VNET_ETHER_ALIGN, 8);
pmap_extract(pmap_kernel(), (vaddr_t)m->m_data, &pa);
- err = hv_ldc_copy(sc->sc_id, LDC_COPY_IN,
+ err = hv_ldc_copy(lc->lc_id, LDC_COPY_IN,
desc.cookie[0].addr, pa, nbytes, &nbytes);
if (err != H_EOK) {
#if 0
@@ -1007,7 +783,7 @@ vnet_rx_vio_dring_data(struct vnet_softc *sc, struct vio_msg_tag *tag)
skip:
desc.hdr.dstate = VIO_DESC_DONE;
nbytes = sc->sc_peer_desc_size;
- err = hv_ldc_copy(sc->sc_id, LDC_COPY_OUT, cookie,
+ err = hv_ldc_copy(lc->lc_id, LDC_COPY_OUT, cookie,
desc_pa, nbytes, &nbytes);
if (err != H_EOK)
printf("hv_ldc_copy_out %d\n", err);
@@ -1065,169 +841,36 @@ vnet_rx_vio_dring_data(struct vnet_softc *sc, struct vio_msg_tag *tag)
}
void
-ldc_send_vers(struct vnet_softc *sc)
-{
- struct ldc_msg *lm;
- uint64_t tx_head, tx_tail, tx_state;
- int err;
-
- err = hv_ldc_tx_get_state(sc->sc_id, &tx_head, &tx_tail, &tx_state);
- if (err != H_EOK || tx_state != LDC_CHANNEL_UP)
- return;
-
- lm = (struct ldc_msg *)(sc->sc_txq->lq_va + tx_tail);
- bzero(lm, sizeof(struct ldc_msg));
- lm->type = LDC_CTRL;
- lm->stype = LDC_INFO;
- lm->ctrl = LDC_VERS;
- lm->major = 1;
- lm->minor = 0;
-
- tx_tail += LDC_MSGSZ;
- tx_tail &= ((sc->sc_txq->lq_nentries * LDC_MSGSZ) - 1);
- err = hv_ldc_tx_set_qtail(sc->sc_id, tx_tail);
- if (err != H_EOK) {
- printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err);
- return;
- }
-
- sc->sc_ldc_state = LDC_SND_VERS;
-}
-
-void
-ldc_send_rts(struct vnet_softc *sc)
-{
- struct ldc_msg *lm;
- uint64_t tx_head, tx_tail, tx_state;
- int err;
-
- err = hv_ldc_tx_get_state(sc->sc_id, &tx_head, &tx_tail, &tx_state);
- if (err != H_EOK || tx_state != LDC_CHANNEL_UP)
- return;
-
- lm = (struct ldc_msg *)(sc->sc_txq->lq_va + tx_tail);
- bzero(lm, sizeof(struct ldc_msg));
- lm->type = LDC_CTRL;
- lm->stype = LDC_INFO;
- lm->ctrl = LDC_RTS;
- lm->env = LDC_MODE_UNRELIABLE;
- lm->seqid = sc->sc_tx_seqid++;
-
- tx_tail += LDC_MSGSZ;
- tx_tail &= ((sc->sc_txq->lq_nentries * LDC_MSGSZ) - 1);
- err = hv_ldc_tx_set_qtail(sc->sc_id, tx_tail);
- if (err != H_EOK) {
- printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err);
- return;
- }
-
- sc->sc_ldc_state = LDC_SND_RTS;
-}
-
-void
-ldc_send_rtr(struct vnet_softc *sc)
-{
- struct ldc_msg *lm;
- uint64_t tx_head, tx_tail, tx_state;
- int err;
-
- err = hv_ldc_tx_get_state(sc->sc_id, &tx_head, &tx_tail, &tx_state);
- if (err != H_EOK || tx_state != LDC_CHANNEL_UP)
- return;
-
- lm = (struct ldc_msg *)(sc->sc_txq->lq_va + tx_tail);
- bzero(lm, sizeof(struct ldc_msg));
- lm->type = LDC_CTRL;
- lm->stype = LDC_INFO;
- lm->ctrl = LDC_RTR;
- lm->env = LDC_MODE_UNRELIABLE;
- lm->seqid = sc->sc_tx_seqid++;
-
- tx_tail += LDC_MSGSZ;
- tx_tail &= ((sc->sc_txq->lq_nentries * LDC_MSGSZ) - 1);
- err = hv_ldc_tx_set_qtail(sc->sc_id, tx_tail);
- if (err != H_EOK)
- printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err);
-
- sc->sc_ldc_state = LDC_SND_RTR;
-}
-
-void
-ldc_send_rdx(struct vnet_softc *sc)
+vnet_reset(struct ldc_conn *lc)
{
- struct ldc_msg *lm;
- uint64_t tx_head, tx_tail, tx_state;
- int err;
-
- err = hv_ldc_tx_get_state(sc->sc_id, &tx_head, &tx_tail, &tx_state);
- if (err != H_EOK || tx_state != LDC_CHANNEL_UP)
- return;
-
- lm = (struct ldc_msg *)(sc->sc_txq->lq_va + tx_tail);
- bzero(lm, sizeof(struct ldc_msg));
- lm->type = LDC_CTRL;
- lm->stype = LDC_INFO;
- lm->ctrl = LDC_RDX;
- lm->env = LDC_MODE_UNRELIABLE;
- lm->seqid = sc->sc_tx_seqid++;
-
- tx_tail += LDC_MSGSZ;
- tx_tail &= ((sc->sc_txq->lq_nentries * LDC_MSGSZ) - 1);
- err = hv_ldc_tx_set_qtail(sc->sc_id, tx_tail);
- if (err != H_EOK)
- printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err);
-
- sc->sc_ldc_state = LDC_SND_RDX;
-}
-
-void
-ldc_reset(struct vnet_softc *sc)
-{
- int err;
-
- DPRINTF(("Resetting connection\n"));
- hv_ldc_tx_qconf(sc->sc_id, 0, 0);
- hv_ldc_rx_qconf(sc->sc_id, 0, 0);
- sc->sc_tx_state = sc->sc_rx_state = LDC_CHANNEL_DOWN;
-
- err = hv_ldc_tx_qconf(sc->sc_id,
- sc->sc_txq->lq_map->dm_segs[0].ds_addr, sc->sc_txq->lq_nentries);
- if (err != H_EOK)
- printf("%s: hv_ldc_tx_qconf %d\n", __func__, err);
-
- err = hv_ldc_rx_qconf(sc->sc_id,
- sc->sc_rxq->lq_map->dm_segs[0].ds_addr, sc->sc_rxq->lq_nentries);
- if (err != H_EOK)
- printf("%s: hv_ldc_rx_qconf %d\n", __func__, err);
+ struct vnet_softc *sc = lc->lc_sc;
sc->sc_vio_state = 0;
- sc->sc_ldc_state = 0;
- sc->sc_tx_seqid = 0;
-
vnet_link_state(sc);
}
void
vio_sendmsg(struct vnet_softc *sc, void *msg, size_t len)
{
- struct ldc_msg *lm;
+ struct ldc_conn *lc = &sc->sc_lc;
+ struct ldc_pkt *lp;
uint64_t tx_head, tx_tail, tx_state;
int err;
#if 0
printf("%s\n", __func__);
#endif
- err = hv_ldc_tx_get_state(sc->sc_id, &tx_head, &tx_tail, &tx_state);
+ err = hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state);
if (err != H_EOK)
return;
- lm = (struct ldc_msg *)(sc->sc_txq->lq_va + tx_tail);
- bzero(lm, sizeof(struct ldc_msg));
- lm->type = LDC_DATA;
- lm->stype = LDC_INFO;
- lm->env = 56 | LDC_FRAG_STOP | LDC_FRAG_START;
- lm->seqid = sc->sc_tx_seqid++;
- bcopy(msg, &lm->major, len);
+ lp = (struct ldc_pkt *)(lc->lc_txq->lq_va + tx_tail);
+ bzero(lp, sizeof(struct ldc_pkt));
+ lp->type = LDC_DATA;
+ lp->stype = LDC_INFO;
+ lp->env = 56 | LDC_FRAG_STOP | LDC_FRAG_START;
+ lp->seqid = lc->lc_tx_seqid++;
+ bcopy(msg, &lp->major, len);
#if 0
{
@@ -1239,9 +882,9 @@ vio_sendmsg(struct vnet_softc *sc, void *msg, size_t len)
}
#endif
- tx_tail += LDC_MSGSZ;
- tx_tail &= ((sc->sc_txq->lq_nentries * LDC_MSGSZ) - 1);
- err = hv_ldc_tx_set_qtail(sc->sc_id, tx_tail);
+ tx_tail += sizeof(*lp);
+ tx_tail &= ((lc->lc_txq->lq_nentries * sizeof(*lp)) - 1);
+ err = hv_ldc_tx_set_qtail(lc->lc_id, tx_tail);
if (err != H_EOK)
printf("hv_ldc_tx_set_qtail: %d\n", err);
}
@@ -1550,13 +1193,14 @@ void
vnet_init(struct ifnet *ifp)
{
struct vnet_softc *sc = ifp->if_softc;
+ struct ldc_conn *lc = &sc->sc_lc;
int err;
sc->sc_lm = ldc_map_alloc(sc->sc_dmatag, 2048);
if (sc->sc_lm == NULL)
return;
- err = hv_ldc_set_map_table(sc->sc_id,
+ err = hv_ldc_set_map_table(lc->lc_id,
sc->sc_lm->lm_map->dm_segs[0].ds_addr, sc->sc_lm->lm_nentries);
if (err != H_EOK) {
printf("hv_ldc_set_map_table %d\n", err);
@@ -1576,17 +1220,17 @@ vnet_init(struct ifnet *ifp)
sc->sc_lm->lm_next = 1;
sc->sc_lm->lm_count = 1;
- err = hv_ldc_tx_qconf(sc->sc_id,
- sc->sc_txq->lq_map->dm_segs[0].ds_addr, sc->sc_txq->lq_nentries);
+ err = hv_ldc_tx_qconf(lc->lc_id,
+ lc->lc_txq->lq_map->dm_segs[0].ds_addr, lc->lc_txq->lq_nentries);
if (err != H_EOK)
printf("hv_ldc_tx_qconf %d\n", err);
- err = hv_ldc_rx_qconf(sc->sc_id,
- sc->sc_rxq->lq_map->dm_segs[0].ds_addr, sc->sc_rxq->lq_nentries);
+ err = hv_ldc_rx_qconf(lc->lc_id,
+ lc->lc_rxq->lq_map->dm_segs[0].ds_addr, lc->lc_rxq->lq_nentries);
if (err != H_EOK)
printf("hv_ldc_rx_qconf %d\n", err);
- ldc_send_vers(sc);
+ ldc_send_vers(lc);
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
@@ -1596,77 +1240,20 @@ void
vnet_stop(struct ifnet *ifp)
{
struct vnet_softc *sc = ifp->if_softc;
+ struct ldc_conn *lc = &sc->sc_lc;
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
- hv_ldc_tx_qconf(sc->sc_id, 0, 0);
- hv_ldc_rx_qconf(sc->sc_id, 0, 0);
- sc->sc_tx_state = sc->sc_rx_state = LDC_CHANNEL_DOWN;
+ hv_ldc_tx_qconf(lc->lc_id, 0, 0);
+ hv_ldc_rx_qconf(lc->lc_id, 0, 0);
+ lc->lc_tx_state = lc->lc_rx_state = LDC_CHANNEL_DOWN;
vnet_dring_free(sc->sc_dmatag, sc->sc_vd);
- hv_ldc_set_map_table(sc->sc_id, 0, 0);
+ hv_ldc_set_map_table(lc->lc_id, 0, 0);
ldc_map_free(sc->sc_dmatag, sc->sc_lm);
}
-struct ldc_queue *
-ldc_queue_alloc(bus_dma_tag_t t, int nentries)
-{
- struct ldc_queue *lq;
- bus_size_t size;
- caddr_t va;
- int nsegs;
-
- lq = malloc(sizeof(struct ldc_queue), M_DEVBUF, M_NOWAIT);
- if (lq == NULL)
- return NULL;
-
- size = roundup(nentries * LDC_MSGSZ, PAGE_SIZE);
-
- if (bus_dmamap_create(t, size, 1, size, 0,
- BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &lq->lq_map) != 0)
- return (NULL);
-
- if (bus_dmamem_alloc(t, size, PAGE_SIZE, 0, &lq->lq_seg, 1,
- &nsegs, BUS_DMA_NOWAIT) != 0)
- goto destroy;
-
- if (bus_dmamem_map(t, &lq->lq_seg, 1, size, &va,
- BUS_DMA_NOWAIT) != 0)
- goto free;
-
- if (bus_dmamap_load(t, lq->lq_map, va, size, NULL,
- BUS_DMA_NOWAIT) != 0)
- goto unmap;
-
- lq->lq_va = va;
- lq->lq_nentries = nentries;
- return (lq);
-
-unmap:
- bus_dmamem_unmap(t, va, size);
-free:
- bus_dmamem_free(t, &lq->lq_seg, 1);
-destroy:
- bus_dmamap_destroy(t, lq->lq_map);
-
- return (NULL);
-}
-
-void
-ldc_queue_free(bus_dma_tag_t t, struct ldc_queue *lq)
-{
- bus_size_t size;
-
- size = roundup(lq->lq_nentries * LDC_MSGSZ, PAGE_SIZE);
-
- bus_dmamap_unload(t, lq->lq_map);
- bus_dmamem_unmap(t, lq->lq_va, size);
- bus_dmamem_free(t, &lq->lq_seg, 1);
- bus_dmamap_destroy(t, lq->lq_map);
- free(lq, M_DEVBUF);
-}
-
struct vnet_dring *
vnet_dring_alloc(bus_dma_tag_t t, int nentries)
{
@@ -1729,63 +1316,3 @@ vnet_dring_free(bus_dma_tag_t t, struct vnet_dring *vd)
bus_dmamap_destroy(t, vd->vd_map);
free(vd, M_DEVBUF);
}
-
-struct ldc_map *
-ldc_map_alloc(bus_dma_tag_t t, int nentries)
-{
- struct ldc_map *lm;
- bus_size_t size;
- caddr_t va;
- int nsegs;
-
- lm = malloc(sizeof(struct ldc_map), M_DEVBUF, M_NOWAIT);
- if (lm == NULL)
- return NULL;
-
- size = roundup(nentries * sizeof(struct ldc_map_slot), PAGE_SIZE);
-
- if (bus_dmamap_create(t, size, 1, size, 0,
- BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &lm->lm_map) != 0)
- return (NULL);
-
- if (bus_dmamem_alloc(t, size, PAGE_SIZE, 0, &lm->lm_seg, 1,
- &nsegs, BUS_DMA_NOWAIT) != 0)
- goto destroy;
-
- if (bus_dmamem_map(t, &lm->lm_seg, 1, size, &va,
- BUS_DMA_NOWAIT) != 0)
- goto free;
-
- if (bus_dmamap_load(t, lm->lm_map, va, size, NULL,
- BUS_DMA_NOWAIT) != 0)
- goto unmap;
-
- lm->lm_slot = (struct ldc_map_slot *)va;
- lm->lm_nentries = nentries;
- bzero(lm->lm_slot, nentries * sizeof(struct ldc_map_slot));
- return (lm);
-
-unmap:
- bus_dmamem_unmap(t, va, size);
-free:
- bus_dmamem_free(t, &lm->lm_seg, 1);
-destroy:
- bus_dmamap_destroy(t, lm->lm_map);
-
- return (NULL);
-}
-
-void
-ldc_map_free(bus_dma_tag_t t, struct ldc_map *lm)
-{
- bus_size_t size;
-
- size = lm->lm_nentries * sizeof(struct ldc_map_slot);
- size = roundup(size, PAGE_SIZE);
-
- bus_dmamap_unload(t, lm->lm_map);
- bus_dmamem_unmap(t, (caddr_t)lm->lm_slot, size);
- bus_dmamem_free(t, &lm->lm_seg, 1);
- bus_dmamap_destroy(t, lm->lm_map);
- free(lm, M_DEVBUF);
-}