summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4v/sys
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/sun4v/sys')
-rw-r--r--usr/src/uts/sun4v/sys/ldc_impl.h2
-rw-r--r--usr/src/uts/sun4v/sys/vdsk_common.h2
-rw-r--r--usr/src/uts/sun4v/sys/vio_mailbox.h15
-rw-r--r--usr/src/uts/sun4v/sys/vio_util.h127
-rw-r--r--usr/src/uts/sun4v/sys/vldc_impl.h3
-rw-r--r--usr/src/uts/sun4v/sys/vnet.h1
-rw-r--r--usr/src/uts/sun4v/sys/vnet_common.h4
-rw-r--r--usr/src/uts/sun4v/sys/vnet_gen.h52
-rw-r--r--usr/src/uts/sun4v/sys/vsw.h21
9 files changed, 196 insertions, 31 deletions
diff --git a/usr/src/uts/sun4v/sys/ldc_impl.h b/usr/src/uts/sun4v/sys/ldc_impl.h
index 84fcc52b1f..4064ef99c3 100644
--- a/usr/src/uts/sun4v/sys/ldc_impl.h
+++ b/usr/src/uts/sun4v/sys/ldc_impl.h
@@ -427,6 +427,7 @@ struct ldc_chan {
boolean_t intr_pending; /* TRUE if interrupts are pending */
+ kmutex_t tx_lock; /* Transmit lock */
uint64_t tx_q_entries; /* Num entries in transmit queue */
uint64_t tx_q_va; /* Virtual addr of transmit queue */
uint64_t tx_q_ra; /* Real addr of transmit queue */
@@ -451,7 +452,6 @@ struct ldc_chan {
uint8_t pkt_payload; /* Size of packet payload */
- uint32_t first_fragment; /* Seqid of first msg fragment */
uint32_t last_msg_snt; /* Seqid of last packet sent */
uint32_t last_ack_rcd; /* Seqid of last ACK recd */
uint32_t last_msg_rcd; /* Seqid of last packet received */
diff --git a/usr/src/uts/sun4v/sys/vdsk_common.h b/usr/src/uts/sun4v/sys/vdsk_common.h
index b8251afea2..b4e6d4351f 100644
--- a/usr/src/uts/sun4v/sys/vdsk_common.h
+++ b/usr/src/uts/sun4v/sys/vdsk_common.h
@@ -79,7 +79,7 @@ extern "C" {
#define VD_MAX_COOKIES ((VD_MAX_BLOCK_SIZE / PAGESIZE) + 1)
#define VD_USEC_TIMEOUT 20000
#define VD_LDC_IDS_PROP "ldc-ids"
-#define VD_LDC_QLEN 32
+#define VD_LDC_QLEN VD_DRING_LEN
/*
* Flags used by ioctl routines to indicate if a copyin/copyout is needed
diff --git a/usr/src/uts/sun4v/sys/vio_mailbox.h b/usr/src/uts/sun4v/sys/vio_mailbox.h
index 66de0722e6..c3b74ac9be 100644
--- a/usr/src/uts/sun4v/sys/vio_mailbox.h
+++ b/usr/src/uts/sun4v/sys/vio_mailbox.h
@@ -120,6 +120,13 @@ extern "C" {
#define VIO_PAYLOAD_ELEMS (VIO_PAYLOAD_SZ / LDC_ELEM_SIZE) /* num words */
/*
+ * Peer dring processing state. Either actively processing dring
+ * or stopped.
+ */
+#define VIO_DP_ACTIVE 1
+#define VIO_DP_STOPPED 2
+
+/*
* VIO device message tag.
*
* These 64 bits are used as a common header for all VIO message types.
@@ -169,7 +176,6 @@ typedef struct vio_ver_msg {
uint64_t resv3[VIO_PAYLOAD_ELEMS - 1];
} vio_ver_msg_t;
-
/*
* VIO Descriptor Ring Register message.
*
@@ -260,10 +266,15 @@ typedef struct vio_dring_msg {
uint32_t start_idx; /* Indx of first updated elem */
int32_t end_idx; /* Indx of last updated elem */
+ uint8_t dring_process_state; /* Processing state */
+
/*
* Padding.
*/
- uint64_t resv[VIO_PAYLOAD_ELEMS - 3];
+ uint8_t resv1;
+ uint16_t resv2;
+ uint32_t resv3;
+ uint64_t resv4[VIO_PAYLOAD_ELEMS - 4];
} vio_dring_msg_t;
/*
diff --git a/usr/src/uts/sun4v/sys/vio_util.h b/usr/src/uts/sun4v/sys/vio_util.h
new file mode 100644
index 0000000000..ab7a255f1e
--- /dev/null
+++ b/usr/src/uts/sun4v/sys/vio_util.h
@@ -0,0 +1,127 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _VIO_UTIL_H
+#define _VIO_UTIL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/stream.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A message is composed of three structures. A message block (mblk_t), a
+ * data block to which it points and a data buffer. desballoc(9F) allows
+ * the caller to specify the data buffer and a free function which will
+ * be invoked when freeb(9F) is called to free the message. This allows
+ * the user to reclaim and reuse the data buffer, as opposed to using
+ * allocb(9F) where the message block, data block and data buffer are
+ * all destroyed by freeb().
+ *
+ * Note that even with desballoc the message and data blocks are destroyed
+ * by freeb() and must be recreated. It is only the data buffer which is
+ * preserved.
+ *
+ * The caller first creates a pool of vio_mblk_t's by invoking
+ * vio_create_mblks() and specifying the number of mblks and the size of the
+ * associated data buffers. Each vio_mblk_t contains a pointer to the
+ * mblk_t, a pointer to the data buffer and a function pointer to the
+ * reclaim function. The caller is returned a pointer to the pool which is
+ * used in subsequent allocation/destroy requests.
+ *
+ * The pool is managed as a circular queue with a head and tail pointer.
+ * Allocation requests result in the head index being incremented, mblks
+ * being returned to the pool result in the tail pointer being incremented.
+ *
+ * The pool can only be destroyed when all the mblks have been returned. It
+ * is the responsibility of the caller to ensure that all vio_allocb()
+ * requests have been completed before the pool is destroyed.
+ *
+ *
+ * vio_mblk_pool_t
+ * +-------------+
+ * | tail |--------------------------------+
+ * +-------------+ |
+ * | head |--------+ |
+ * +-------------+ | |
+ * ............... V V
+ * +-------------+ +-------+-------+-------+-------+
+ * | quep |---->| vmp_t | vmp_t | vmp_t | vmp_t |
+ * +-------------+ +-------+-------+-------+-------+
+ * | | | | | |
+ * ... | | | | +------------+
+ * | | | +-->| data block |
+ * | | | +------------+
+ * | | | +------------+
+ * | | +-->| data block |
+ * | | +------------+
+ * | | +------------+
+ * | +-->| data block |
+ * | +------------+
+ * | +------------+
+ * +-->| data block |
+ * +------------+
+ *
+ */
+
+struct vio_mblk_pool;
+
+typedef struct vio_mblk {
+ uint8_t *datap; /* data buffer */
+ mblk_t *mp; /* mblk using datap */
+ frtn_t reclaim; /* mblk reclaim routine */
+ struct vio_mblk_pool *vmplp; /* pointer to parent pool */
+} vio_mblk_t;
+
+typedef struct vio_mblk_pool {
+ struct vio_mblk_pool *nextp; /* next in a list */
+ kmutex_t hlock; /* sync access to head */
+ kmutex_t tlock; /* sync access to tail */
+ vio_mblk_t *basep; /* base pointer to pool of vio_mblks */
+ vio_mblk_t **quep; /* queue of free vio_mblks */
+ uint8_t *datap; /* rx data buffer area */
+ uint32_t head; /* queue head */
+ uint32_t tail; /* queue tail */
+ uint64_t quelen; /* queue len (# mblks) */
+ uint64_t quemask; /* quelen - 1 */
+ size_t mblk_size; /* data buf size of each mblk */
+} vio_mblk_pool_t;
+
+int vio_create_mblks(uint64_t num_mblks,
+ size_t mblk_size, vio_mblk_pool_t **);
+int vio_destroy_mblks(vio_mblk_pool_t *);
+mblk_t *vio_allocb(vio_mblk_pool_t *);
+void vio_freeb(void *arg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VIO_UTIL_H */
diff --git a/usr/src/uts/sun4v/sys/vldc_impl.h b/usr/src/uts/sun4v/sys/vldc_impl.h
index 8610344b42..ffdd97636b 100644
--- a/usr/src/uts/sun4v/sys/vldc_impl.h
+++ b/usr/src/uts/sun4v/sys/vldc_impl.h
@@ -52,6 +52,8 @@ extern "C" {
#define VLDC_MINOR_MASK (VLDC_MAX_PORTS - 1)
#define VLDC_INST_SHIFT 11
+#define VLDC_HVCTL_SVCNAME "hvctl"
+
/* get port number from minor number */
#define VLDCPORT(vldcp, minor) \
((vldcp)->minor_tbl[(minor) & VLDC_MINOR_MASK].portno)
@@ -95,6 +97,7 @@ typedef struct vldc_port {
uint32_t mtu; /* port mtu */
caddr_t send_buf; /* send buffer */
caddr_t recv_buf; /* receive buffer */
+ caddr_t cookie_buf; /* rd/wr cookie buffer */
uint64_t ldc_id; /* Channel number */
ldc_handle_t ldc_handle; /* Channel handle */
diff --git a/usr/src/uts/sun4v/sys/vnet.h b/usr/src/uts/sun4v/sys/vnet.h
index c43af5bfab..53202f7601 100644
--- a/usr/src/uts/sun4v/sys/vnet.h
+++ b/usr/src/uts/sun4v/sys/vnet.h
@@ -44,6 +44,7 @@ extern "C" {
#define VNET_LDCWD_INTERVAL 1000 /* watchdog freq in msec */
#define VNET_LDCWD_TXTIMEOUT 1000 /* tx timeout in msec */
#define VNET_LDC_QLEN 1024 /* ldc qlen */
+#define VNET_NRBUFS 512 /* number of receive bufs */
/*
* vnet proxy transport layer information. There is one instance of this for
diff --git a/usr/src/uts/sun4v/sys/vnet_common.h b/usr/src/uts/sun4v/sys/vnet_common.h
index feed7025a2..575db18efb 100644
--- a/usr/src/uts/sun4v/sys/vnet_common.h
+++ b/usr/src/uts/sun4v/sys/vnet_common.h
@@ -43,11 +43,13 @@ extern "C" {
*/
/* max # of cookies per frame size */
-#define MAX_COOKIES ((ETHERMAX >> MMU_PAGESHIFT) + 2)
+#define MAX_COOKIES ((ETHERMAX >> MMU_PAGESHIFT) + 2ULL)
/* initial send sequence number */
#define VNET_ISS 0x1
+#define VNET_IPALIGN 6 /* padding for IP header alignment */
+
/* vnet descriptor */
typedef struct vnet_public_desc {
vio_dring_entry_hdr_t hdr; /* descriptor header */
diff --git a/usr/src/uts/sun4v/sys/vnet_gen.h b/usr/src/uts/sun4v/sys/vnet_gen.h
index c6ad5fe8c0..3166a3412d 100644
--- a/usr/src/uts/sun4v/sys/vnet_gen.h
+++ b/usr/src/uts/sun4v/sys/vnet_gen.h
@@ -69,7 +69,7 @@ extern "C" {
#define LDC_TO_VNET(ldcp) ((ldcp)->portp->vgenp->vnetp)
#define LDC_TO_VGEN(ldcp) ((ldcp)->portp->vgenp)
-#define VGEN_TX_DBLK_SZ 2048 /* tx data buffer size */
+#define VGEN_DBLK_SZ 2048 /* data buffer size */
#define VGEN_LDC_UP_DELAY 100 /* usec delay between ldc_up retries */
/* get the address of next tbuf */
@@ -107,7 +107,6 @@ typedef struct vgen_priv_desc {
ldc_mem_handle_t memhandle; /* mem handle for data */
caddr_t datap; /* prealloc'd tx data buffer */
uint64_t datalen; /* total actual datalen */
- uint64_t seqnum; /* sequence number of pkt */
uint64_t ncookies; /* num ldc_mem_cookies */
ldc_mem_cookie_t memcookie[MAX_COOKIES]; /* data cookies */
} vgen_private_desc_t;
@@ -147,13 +146,10 @@ typedef struct vgen_ver {
typedef struct vgen_stats {
/* Link Input/Output stats */
- uint64_t ipackets;
- uint64_t ierrors;
- uint64_t opackets;
- uint64_t oerrors;
-#if 0
- uint64_t collisions;
-#endif
+ uint64_t ipackets; /* # rx packets */
+ uint64_t ierrors; /* # rx error */
+ uint64_t opackets; /* # tx packets */
+ uint64_t oerrors; /* # tx error */
/* MIB II variables */
uint64_t rbytes; /* # bytes received */
@@ -166,17 +162,18 @@ typedef struct vgen_stats {
uint32_t noxmtbuf; /* # xmit packets discarded */
/* Tx Statistics */
- uint32_t tx_no_desc;
- uint32_t tx_allocb_fail;
+ uint32_t tx_no_desc; /* # out of transmit descriptors */
/* Rx Statistics */
- uint32_t rx_no_desc;
- uint32_t rx_allocb_fail;
- uint32_t rx_lost_pkts;
+ uint32_t rx_allocb_fail; /* # rx buf allocb() failures */
+ uint32_t rx_vio_allocb_fail; /* # vio_allocb() failures */
+ uint32_t rx_lost_pkts; /* # rx lost packets */
/* Callback statistics */
- uint32_t callbacks;
- uint32_t dring_data_acks;
+ uint32_t callbacks; /* # callbacks */
+ uint32_t dring_data_acks; /* # dring data acks recvd */
+ uint32_t dring_stopped_acks; /* # dring stopped acks recvd */
+ uint32_t dring_data_msgs; /* # dring data msgs sent */
} vgen_stats_t;
@@ -190,9 +187,7 @@ typedef struct vgen_kstats {
kstat_named_t opackets;
kstat_named_t opackets64;
kstat_named_t oerrors;
-#if 0
- kstat_named_t collisions;
-#endif
+
/*
* required by kstat for MIB II objects(RFC 1213)
*/
@@ -208,17 +203,18 @@ typedef struct vgen_kstats {
kstat_named_t noxmtbuf; /* MIB - ifOutDiscards */
/* Tx Statistics */
- kstat_named_t tx_no_desc;
- kstat_named_t tx_allocb_fail;
+ kstat_named_t tx_no_desc; /* # out of transmit descriptors */
/* Rx Statistics */
- kstat_named_t rx_no_desc;
- kstat_named_t rx_allocb_fail;
- kstat_named_t rx_lost_pkts;
+ kstat_named_t rx_allocb_fail; /* # rx buf allocb failures */
+ kstat_named_t rx_vio_allocb_fail; /* # vio_allocb() failures */
+ kstat_named_t rx_lost_pkts; /* # rx lost packets */
/* Callback statistics */
- kstat_named_t callbacks;
- kstat_named_t dring_data_acks;
+ kstat_named_t callbacks; /* # callbacks */
+ kstat_named_t dring_data_acks; /* # dring data acks recvd */
+ kstat_named_t dring_stopped_acks; /* # dring stopped acks recvd */
+ kstat_named_t dring_data_msgs; /* # dring data msgs sent */
} vgen_kstats_t;
@@ -277,6 +273,8 @@ typedef struct vgen_ldc {
uint32_t next_rxi; /* next expected recv index */
uint32_t num_rxds; /* number of rx descriptors */
caddr_t tx_datap; /* prealloc'd tx data area */
+ vio_mblk_pool_t *rmp; /* rx mblk pool */
+ uint32_t num_rbufs; /* number of rx bufs */
/* misc */
uint32_t flags; /* flags */
@@ -284,6 +282,7 @@ typedef struct vgen_ldc {
boolean_t need_ldc_reset; /* ldc_reset needed */
boolean_t need_mcast_sync; /* sync mcast table with vsw */
uint32_t hretries; /* handshake retry count */
+ boolean_t resched_peer; /* send tx msg to peer */
/* channel statistics */
vgen_stats_t *statsp; /* channel statistics */
@@ -329,6 +328,7 @@ typedef struct vgen {
struct ether_addr *mctab; /* multicast addr table */
uint32_t mcsize; /* allocated size of mctab */
uint32_t mccount; /* # of valid addrs in mctab */
+ vio_mblk_pool_t *rmp; /* rx mblk pools to be freed */
} vgen_t;
#ifdef __cplusplus
diff --git a/usr/src/uts/sun4v/sys/vsw.h b/usr/src/uts/sun4v/sys/vsw.h
index fccb3c6fb8..b1df247547 100644
--- a/usr/src/uts/sun4v/sys/vsw.h
+++ b/usr/src/uts/sun4v/sys/vsw.h
@@ -82,6 +82,7 @@ extern "C" {
#include <sys/vio_mailbox.h>
#include <sys/vnet_common.h>
#include <sys/ethernet.h>
+#include <sys/vio_util.h>
/*
* Default message type.
@@ -209,9 +210,21 @@ typedef struct ver_sup {
#define VSW_MAX_COOKIES ((ETHERMTU >> MMU_PAGESHIFT) + 2)
/*
+ * Size and number of mblks to be created in free pool.
+ */
+#define VSW_MBLK_SIZE 2048
+#define VSW_NUM_MBLKS 1024
+
+/*
* Private descriptor
*/
typedef struct vsw_private_desc {
+ /*
+ * Below lock must be held when accessing the state of
+ * a descriptor on either the private or public sections
+ * of the ring.
+ */
+ kmutex_t dstate_lock;
uint64_t dstate;
vnet_public_desc_t *descp;
ldc_mem_handle_t memhandle;
@@ -237,6 +250,10 @@ typedef struct dring_info {
ldc_dring_handle_t handle;
uint64_t ident; /* identifier sent to peer */
uint64_t end_idx; /* last idx processed */
+ int64_t last_ack_recv;
+
+ kmutex_t restart_lock;
+ boolean_t restart_reqd; /* send restart msg */
/*
* base address of private and public portions of the
@@ -258,6 +275,7 @@ typedef struct lane {
uint64_t lstate; /* Lane state */
uint32_t ver_major:16, /* Version major number */
ver_minor:16; /* Version minor number */
+ kmutex_t seq_lock;
uint64_t seq_num; /* Sequence number */
uint64_t mtu; /* ETHERMTU */
uint64_t addr; /* Unique physical address */
@@ -295,6 +313,7 @@ typedef struct vsw_ldc {
lane_t lane_in; /* Inbound lane */
lane_t lane_out; /* Outbound lane */
uint8_t dev_class; /* Peer device class */
+ vio_mblk_pool_t *rxh; /* Receive pool handle */
} vsw_ldc_t;
/* list of ldcs per port */
@@ -407,6 +426,8 @@ typedef struct vsw {
mod_hash_t *mfdb; /* multicast FDB */
krwlock_t mfdbrw; /* rwlock for mFDB */
+ vio_mblk_pool_t *rxh; /* Receive pool handle */
+
/* mac layer */
mac_handle_t mh;
mac_rx_handle_t mrh;